This makes sure that the flags register doesn't get accidentally overwritten due to compiler optimizations or other means Signed-off-by: Bandan Das <bsd@xxxxxxxxxx> --- lib/x86/processor.h | 7 ------- x86/vmx.c | 31 ++++++++++--------------------- x86/vmx.h | 10 ++++++++-- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 7fc1026..f5f1c82 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -351,11 +351,4 @@ static inline void safe_halt(void) asm volatile("sti; hlt"); } -#ifdef __x86_64__ -static inline void write_rflags(u64 r) -{ - asm volatile("push %0; popf\n\t" : : "q"(r) : "cc"); -} -#endif - #endif diff --git a/x86/vmx.c b/x86/vmx.c index 1182eef..768d07f 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -65,8 +65,10 @@ extern void *guest_entry; static int make_vmcs_current(struct vmcs *vmcs) { bool ret; + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - asm volatile ("vmptrld %1; setbe %0" : "=q" (ret) : "m" (vmcs) : "cc"); + asm volatile ("push %1; popf; vmptrld %2; setbe %0" + : "=q" (ret) : "q" (rflags), "m" (vmcs) : "cc"); return ret; } @@ -92,16 +94,19 @@ static void __attribute__((__used__)) syscall_handler(u64 syscall_no) static inline int vmx_on() { bool ret; - asm volatile ("vmxon %1; setbe %0\n\t" - : "=q"(ret) : "m"(vmxon_region) : "cc"); + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; + asm volatile ("push %1; popf; vmxon %2; setbe %0\n\t" + : "=q" (ret) : "q" (rflags), "m" (vmxon_region) : "cc"); return ret; } static inline int vmx_off() { bool ret; - asm volatile("vmxoff; setbe %0\n\t" - : "=q"(ret) : : "cc"); + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; + + asm volatile("push %1; popf; vmxoff; setbe %0\n\t" + : "=q"(ret) : "q" (rflags) : "cc"); return ret; } @@ -129,20 +134,13 @@ void print_vmexit_info() static void test_vmclear(void) { - u64 rflags; - - rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - write_rflags(rflags); report("test vmclear", vmcs_clear(vmcs_root) == 0); } static void test_vmxoff(void) { int ret; - u64 rflags; - rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - write_rflags(rflags); ret = vmx_off(); report("test vmxoff", !ret); } @@ -599,10 +597,7 @@ static int test_vmx_feature_control(void) static int test_vmxon(void) { int ret; - u64 rflags; - rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - write_rflags(rflags); ret = vmx_on(); report("test vmxon", !ret); return ret; @@ -610,27 +605,21 @@ static int test_vmxon(void) static void test_vmptrld(void) { - u64 rflags; struct vmcs *vmcs; vmcs = alloc_page(); vmcs->revision_id = basic.revision; - rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - write_rflags(rflags); report("test vmptrld", make_vmcs_current(vmcs) == 0); } static void test_vmptrst(void) { - u64 rflags; int ret; struct vmcs *vmcs1, *vmcs2; vmcs1 = alloc_page(); memset(vmcs1, 0, PAGE_SIZE); init_vmcs(&vmcs1); - rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - write_rflags(rflags); ret = vmcs_save(&vmcs2); report("test vmptrst", (!ret) && (vmcs1 == vmcs2)); } diff --git a/x86/vmx.h b/x86/vmx.h index 26dd161..86bdf67 100644 --- a/x86/vmx.h +++ b/x86/vmx.h @@ -2,6 +2,7 @@ #define __VMX_H #include "libcflat.h" +#include "processor.h" struct vmcs { u32 revision_id; /* vmcs revision identifier */ @@ -515,7 +516,10 @@ extern union vmx_ept_vpid ept_vpid; static inline int vmcs_clear(struct vmcs *vmcs) { bool ret; - asm volatile ("vmclear %1; setbe %0" : "=q" (ret) : "m" (vmcs) : "cc"); + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; + + asm volatile ("push %1; popf; vmclear %2; setbe %0" + : "=q" (ret) : "q" (rflags), "m" (vmcs) : "cc"); return ret; } @@ -537,8 +541,10 @@ static inline int vmcs_write(enum Encoding enc, u64 val) static inline int vmcs_save(struct vmcs **vmcs) { bool ret; + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; - asm volatile ("vmptrst %1; setbe %0" : "=q" (ret) : "m" (*vmcs) : "cc"); + asm volatile ("push %1; popf; vmptrst %2; setbe %0" + : "=q" (ret) : "q" (rflags), "m" (*vmcs) : "cc"); return ret; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html