From: Greg Kroah-Hartman Date: Fri, 23 Mar 2012 17:25:01 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.26~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a25cf4a8509bf67472554cb775718f70603fd0e4;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: kvm-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch kvm-x86-fix-missing-checks-in-syscall-emulation.patch --- diff --git a/queue-3.0/kvm-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch b/queue-3.0/kvm-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch new file mode 100644 index 00000000000..887f4def591 --- /dev/null +++ b/queue-3.0/kvm-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch @@ -0,0 +1,77 @@ +From bdb42f5afebe208eae90406959383856ae2caf2b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= +Date: Thu, 12 Jan 2012 16:43:03 +0100 +Subject: KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid" + +From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= + +commit bdb42f5afebe208eae90406959383856ae2caf2b upstream. + +In order to be able to proceed checks on CPU-specific properties +within the emulator, function "get_cpuid" is introduced. +With "get_cpuid" it is possible to virtually call the guests +"cpuid"-opcode without changing the VM's context. + +[mtosatti: cleanup/beautify code] + +Signed-off-by: Stephan Baerwolf +Signed-off-by: Marcelo Tosatti +Signed-off-by: Stefan Bader +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/kvm_emulate.h | 3 +++ + arch/x86/kvm/x86.c | 23 +++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +--- a/arch/x86/include/asm/kvm_emulate.h ++++ b/arch/x86/include/asm/kvm_emulate.h +@@ -189,6 +189,9 @@ struct x86_emulate_ops { + int (*intercept)(struct x86_emulate_ctxt *ctxt, + struct x86_instruction_info *info, + enum x86_intercept_stage stage); ++ ++ bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, ++ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); + }; + + typedef u32 __attribute__((vector_size(16))) sse128_t; +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4407,6 +4407,28 @@ static int emulator_intercept(struct x86 + return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage); + } + ++static bool emulator_get_cpuid(struct x86_emulate_ctxt *ctxt, ++ u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) ++{ ++ struct kvm_cpuid_entry2 *cpuid = NULL; ++ ++ if (eax && ecx) ++ cpuid = kvm_find_cpuid_entry(emul_to_vcpu(ctxt), ++ *eax, *ecx); ++ ++ if (cpuid) { ++ *eax = cpuid->eax; ++ *ecx = cpuid->ecx; ++ if (ebx) ++ *ebx = cpuid->ebx; ++ if (edx) ++ *edx = cpuid->edx; ++ return true; ++ } ++ ++ return false; ++} ++ + static struct x86_emulate_ops emulate_ops = { + .read_std = kvm_read_guest_virt_system, + .write_std = kvm_write_guest_virt_system, +@@ -4437,6 +4459,7 @@ static struct x86_emulate_ops emulate_op + .get_fpu = emulator_get_fpu, + .put_fpu = emulator_put_fpu, + .intercept = emulator_intercept, ++ .get_cpuid = emulator_get_cpuid, + }; + + static void cache_all_regs(struct kvm_vcpu *vcpu) diff --git a/queue-3.0/kvm-x86-fix-missing-checks-in-syscall-emulation.patch b/queue-3.0/kvm-x86-fix-missing-checks-in-syscall-emulation.patch new file mode 100644 index 00000000000..8b7abadce3b --- /dev/null +++ b/queue-3.0/kvm-x86-fix-missing-checks-in-syscall-emulation.patch @@ -0,0 +1,144 @@ +From c2226fc9e87ba3da060e47333657cd6616652b84 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= +Date: Thu, 12 Jan 2012 16:43:04 +0100 +Subject: KVM: x86: fix missing checks in syscall emulation + +From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= + +commit c2226fc9e87ba3da060e47333657cd6616652b84 upstream. + +On hosts without this patch, 32bit guests will crash (and 64bit guests +may behave in a wrong way) for example by simply executing following +nasm-demo-application: + + [bits 32] + global _start + SECTION .text + _start: syscall + +(I tested it with winxp and linux - both always crashed) + + Disassembly of section .text: + + 00000000 <_start>: + 0: 0f 05 syscall + +The reason seems a missing "invalid opcode"-trap (int6) for the +syscall opcode "0f05", which is not available on Intel CPUs +within non-longmodes, as also on some AMD CPUs within legacy-mode. +(depending on CPU vendor, MSR_EFER and cpuid) + +Because previous mentioned OSs may not engage corresponding +syscall target-registers (STAR, LSTAR, CSTAR), they remain +NULL and (non trapping) syscalls are leading to multiple +faults and finally crashs. + +Depending on the architecture (AMD or Intel) pretended by +guests, various checks according to vendor's documentation +are implemented to overcome the current issue and behave +like the CPUs physical counterparts. + +[mtosatti: cleanup/beautify code] + +Signed-off-by: Stephan Baerwolf +Signed-off-by: Marcelo Tosatti +Signed-off-by: Stefan Bader +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/kvm_emulate.h | 13 +++++++++ + arch/x86/kvm/emulate.c | 51 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+) + +--- a/arch/x86/include/asm/kvm_emulate.h ++++ b/arch/x86/include/asm/kvm_emulate.h +@@ -301,6 +301,19 @@ struct x86_emulate_ctxt { + #define X86EMUL_MODE_PROT (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \ + X86EMUL_MODE_PROT64) + ++/* CPUID vendors */ ++#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541 ++#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163 ++#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65 ++ ++#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41 ++#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574 ++#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273 ++ ++#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547 ++#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e ++#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69 ++ + enum x86_intercept_stage { + X86_ICTP_NONE = 0, /* Allow zero-init to not match anything */ + X86_ICPT_PRE_EXCEPT, +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -1901,6 +1901,51 @@ setup_syscalls_segments(struct x86_emula + ss->p = 1; + } + ++static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt) ++{ ++ struct x86_emulate_ops *ops = ctxt->ops; ++ u32 eax, ebx, ecx, edx; ++ ++ /* ++ * syscall should always be enabled in longmode - so only become ++ * vendor specific (cpuid) if other modes are active... ++ */ ++ if (ctxt->mode == X86EMUL_MODE_PROT64) ++ return true; ++ ++ eax = 0x00000000; ++ ecx = 0x00000000; ++ if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) { ++ /* ++ * Intel ("GenuineIntel") ++ * remark: Intel CPUs only support "syscall" in 64bit ++ * longmode. Also an 64bit guest with a ++ * 32bit compat-app running will #UD !! While this ++ * behaviour can be fixed (by emulating) into AMD ++ * response - CPUs of AMD can't behave like Intel. ++ */ ++ if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx && ++ ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx && ++ edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx) ++ return false; ++ ++ /* AMD ("AuthenticAMD") */ ++ if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx && ++ ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx && ++ edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx) ++ return true; ++ ++ /* AMD ("AMDisbetter!") */ ++ if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx && ++ ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx && ++ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx) ++ return true; ++ } ++ ++ /* default: (not Intel, not AMD), apply Intel's stricter rules... */ ++ return false; ++} ++ + static int + emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) + { +@@ -1915,9 +1960,15 @@ emulate_syscall(struct x86_emulate_ctxt + ctxt->mode == X86EMUL_MODE_VM86) + return emulate_ud(ctxt); + ++ if (!(em_syscall_is_enabled(ctxt))) ++ return emulate_ud(ctxt); ++ + ops->get_msr(ctxt, MSR_EFER, &efer); + setup_syscalls_segments(ctxt, ops, &cs, &ss); + ++ if (!(efer & EFER_SCE)) ++ return emulate_ud(ctxt); ++ + ops->get_msr(ctxt, MSR_STAR, &msr_data); + msr_data >>= 32; + cs_sel = (u16)(msr_data & 0xfffc); diff --git a/queue-3.0/series b/queue-3.0/series index 09d5c2a25db..807f00f37d9 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -62,3 +62,5 @@ ahci-move-ahci_hflags-macro-to-ahci.h.patch pata_legacy-correctly-mask-recovery-field-for-ht6560b.patch firewire-ohci-fix-too-early-completion-of-ir-multichannel-buffers.patch video-uvesafb-fix-oops-that-uvesafb-try-to-execute-nx-protected-page.patch +kvm-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch +kvm-x86-fix-missing-checks-in-syscall-emulation.patch