From 9a8d305befe3218c7523179c0d406d876b5cbbed Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 22 Sep 2014 13:17:48 +0200 Subject: x86: kvm: use alternatives for VMCALL vs. VMMCALL if kernel text is read-only commit c1118b3602c2329671ad5ec8bdf8e374323d6343 upstream. On x86_64, kernel text mappings are mapped read-only with CONFIG_DEBUG_RODATA. In that case, KVM will fail to patch VMCALL instructions to VMMCALL as required on AMD processors. The failure mode is currently a divide-by-zero exception, which obviously is a KVM bug that has to be fixed. However, picking the right instruction between VMCALL and VMMCALL will be faster and will help if you cannot upgrade the hypervisor. Reported-by: Chris Webb Tested-by: Chris Webb Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Acked-by: Borislav Petkov Signed-off-by: Paolo Bonzini [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings --- arch/x86/include/asm/kvm_para.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch/x86/include/asm/kvm_para.h') diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index 734c3767cfac..9f0a680a7e12 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -91,15 +91,21 @@ struct kvm_vcpu_pv_apf_data { #ifdef __KERNEL__ #include +#include extern void kvmclock_init(void); extern int kvm_register_clock(char *txt); -/* This instruction is vmcall. On non-VT architectures, it will generate a - * trap that we will then rewrite to the appropriate instruction. +#ifdef CONFIG_DEBUG_RODATA +#define KVM_HYPERCALL \ + ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL) +#else +/* On AMD processors, vmcall will generate a trap that we will + * then rewrite to the appropriate instruction. */ #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" +#endif /* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun * instruction. The hypervisor may replace it with something else but only the -- cgit v1.2.3