Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.5:Update
xen.13549
5de0007e-VMX-early-task-switch-failures-semanti...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5de0007e-VMX-early-task-switch-failures-semantics.patch of Package xen.13549
# Commit 943c74bc0ee5044a826e428a3b2ffbdf9a43628d # Date 2019-11-28 17:14:38 +0000 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/vtx: Fix fault semantics for early task switch failures The VT-x task switch handler adds inst_len to %rip before calling hvm_task_switch(), which is problematic in two ways: 1) Early faults (i.e. ones delivered in the context of the old task) get delivered with trap semantics, and break restartibility. 2) The addition isn't truncated to 32 bits. In the corner case of a task switch instruction crossing the 4G->0 boundary taking an early fault (with trap semantics), a VMEntry failure will occur due to %rip being out of range. Instead, pass the instruction length into hvm_task_switch() and write it into the outgoing TSS only, leaving %rip in its original location. For now, pass 0 on the SVM side. This highlights a separate preexisting bug which will be addressed in the following patch. While adjusting call sites, drop the unnecessary uint16_t cast. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2897,7 +2897,7 @@ void hvm_prepare_vm86_tss(struct vcpu *v void hvm_task_switch( uint16_t tss_sel, enum hvm_task_switch_reason taskswitch_reason, - int32_t errcode) + int32_t errcode, unsigned int insn_len) { struct vcpu *v = current; struct cpu_user_regs *regs = guest_cpu_user_regs(); @@ -2971,7 +2971,7 @@ void hvm_task_switch( if ( taskswitch_reason == TSW_iret ) eflags &= ~X86_EFLAGS_NT; - tss.eip = regs->eip; + tss.eip = regs->eip + insn_len; tss.eflags = eflags; tss.eax = regs->eax; tss.ecx = regs->ecx; --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2890,7 +2890,7 @@ void svm_vmexit_handler(struct cpu_user_ */ vmcb->eventinj.bytes = 0; - hvm_task_switch((uint16_t)vmcb->exitinfo1, reason, errcode); + hvm_task_switch(vmcb->exitinfo1, reason, errcode, 0); break; } --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -4062,8 +4062,8 @@ void vmx_vmexit_handler(struct cpu_user_ __vmread(IDT_VECTORING_ERROR_CODE, &ecode); else ecode = -1; - regs->rip += inst_len; - hvm_task_switch((uint16_t)exit_qualification, reasons[source], ecode); + + hvm_task_switch(exit_qualification, reasons[source], ecode, inst_len); break; } case EXIT_REASON_CPUID: --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -302,7 +302,7 @@ void hvm_set_rdtsc_exiting(struct domain enum hvm_task_switch_reason { TSW_jmp, TSW_iret, TSW_call_or_int }; void hvm_task_switch( uint16_t tss_sel, enum hvm_task_switch_reason taskswitch_reason, - int32_t errcode); + int32_t errcode, unsigned int insn_len); enum hvm_access_type { hvm_access_insn_fetch,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor