Message ID | ddfdd8b62faefea191d879b7130cc4ddece9832f.1458340713.git.pfeiner@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
diff --git a/x86/vmx.c b/x86/vmx.c index 107a005..b2e015f 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -925,11 +925,14 @@ static int vmx_run() "1: " "vmresume\n\t" "2: " + SAVE_GPR_C "setbe %0\n\t" + "jmp 3f\n\t" "vmx_return:\n\t" SAVE_GPR_C + "3: \n\t" SAVE_RFLAGS - : "=m"(fail) + : "+m"(fail) : "m"(launched), "i"(HOST_RSP) : "rdi", "rsi", "memory", "cc"
Fixed two problems: 1) Output operands with the '=' constraint are dead-on-arrival. Thus gcc was free to ignore the fail = 0 initialization. Since the asm only set fail when vm{launch,resume} exited early, fail was technically undefined when vm{launch,resume} entered the guest! Using the '+' constraint instead tells gcc the value is live. 2) On early vm{launch,resume} failure, the 'setbe %0' instruction was running with the guest's GPRs since SAVE_GPR_C hadn't run yet. Since %0 is typically replaced with OFFSET(%%rbp), some arbitrary guest stack memory is modified. Solution is to restore the host's registers before using any asm code generated by gcc. Signed-off-by: Peter Feiner <pfeiner@google.com> --- x86/vmx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)