Message ID | 20191003104736.32259-1-andrew.cooper3@citrix.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | x86/vvmx: Fix the use of RDTSCP when it is intercepted at L0 | expand |
On 03.10.19 12:47, Andrew Cooper wrote: > Linux has started using RDTSCP as of v5.1. This has highlighted a bug in Xen, > where virtual vmexit simply gives up. > > (XEN) d1v1 Unhandled nested vmexit: reason 51 > (XEN) domain_crash called from vvmx.c:2671 > (XEN) Domain 1 (vcpu#1) crashed on cpu#2: > > Handle RDTSCP in the virtual vmexit hander in the same was as RDTSC > intercepts. > > Reported-by: Sarah Newman <srn@prgmr.com> > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> > Tested-by: Chris Brannon <cmb@prgmr.com> Release-acked-by: Juergen Gross <jgross@suse.com> Juergen
On Thu, Oct 03, 2019 at 11:47:36AM +0100, Andrew Cooper wrote: > Linux has started using RDTSCP as of v5.1. This has highlighted a bug in Xen, > where virtual vmexit simply gives up. > > (XEN) d1v1 Unhandled nested vmexit: reason 51 > (XEN) domain_crash called from vvmx.c:2671 > (XEN) Domain 1 (vcpu#1) crashed on cpu#2: > > Handle RDTSCP in the virtual vmexit hander in the same was as RDTSC > intercepts. > > Reported-by: Sarah Newman <srn@prgmr.com> > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> > Tested-by: Chris Brannon <cmb@prgmr.com> Reviewed-by: Wei Liu <wl@xen.org>
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index fdf449bfd1..6696bd6240 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -2491,6 +2491,7 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs, nvcpu->nv_vmexit_pending = 1; break; case EXIT_REASON_RDTSC: + case EXIT_REASON_RDTSCP: ctrl = __n2_exec_control(v); if ( ctrl & CPU_BASED_RDTSC_EXITING ) nvcpu->nv_vmexit_pending = 1; @@ -2501,6 +2502,8 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs, * avoiding changing guest_tsc and messing up timekeeping in L1 */ msr_split(regs, hvm_get_guest_tsc(v) + get_vvmcs(v, TSC_OFFSET)); + if ( exit_reason == EXIT_REASON_RDTSCP ) + regs->rcx = v->arch.msrs->tsc_aux; update_guest_eip(); return 1;