|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] vvmx: replace vmreturn() by vmsucceed() and vmfail*()
commit 44d3196903f3ae5ac3d27da626107131e3e35603
Author: Haozhong Zhang <haozhong.zhang@xxxxxxxxx>
AuthorDate: Tue Dec 20 09:53:39 2016 +0100
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Dec 20 09:53:39 2016 +0100
vvmx: replace vmreturn() by vmsucceed() and vmfail*()
Replace vmreturn() by vmsucceed(), vmfail(), vmfail_valid() and
vmfail_invalid(), which are consistent to the pseudo code on Intel
SDM, and allow to return VM instruction error numbers to L1
hypervisor.
Signed-off-by: Haozhong Zhang <haozhong.zhang@xxxxxxxxx>
Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
xen/arch/x86/hvm/vmx/vvmx.c | 103 +++++++++++++++++++++----------------
xen/include/asm-x86/hvm/vmx/vmcs.h | 15 ++++--
xen/include/asm-x86/processor.h | 4 ++
3 files changed, 74 insertions(+), 48 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index 9e37d22..6c7e92b 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -469,28 +469,33 @@ gp_fault:
return X86EMUL_EXCEPTION;
}
-static void vmreturn(struct cpu_user_regs *regs, enum vmx_ops_result ops_res)
+static void vmsucceed(struct cpu_user_regs *regs)
{
+ regs->eflags &= ~X86_EFLAGS_ARITH_MASK;
+}
+
+static void vmfail_valid(struct cpu_user_regs *regs, enum vmx_insn_errno errno)
+{
+ struct vcpu *v = current;
unsigned long eflags = regs->eflags;
- unsigned long mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
- X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF;
- eflags &= ~mask;
+ regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_ZF;
+ set_vvmcs(v, VM_INSTRUCTION_ERROR, errno);
+}
- switch ( ops_res ) {
- case VMSUCCEED:
- break;
- case VMFAIL_VALID:
- /* TODO: error number, useful for guest VMM debugging */
- eflags |= X86_EFLAGS_ZF;
- break;
- case VMFAIL_INVALID:
- default:
- eflags |= X86_EFLAGS_CF;
- break;
- }
+static void vmfail_invalid(struct cpu_user_regs *regs)
+{
+ unsigned long eflags = regs->eflags;
+
+ regs->eflags = (eflags & ~X86_EFLAGS_ARITH_MASK) | X86_EFLAGS_CF;
+}
- regs->eflags = eflags;
+static void vmfail(struct cpu_user_regs *regs, enum vmx_insn_errno errno)
+{
+ if ( vcpu_nestedhvm(current).nv_vvmcxaddr != INVALID_PADDR )
+ vmfail_valid(regs, errno);
+ else
+ vmfail_invalid(regs);
}
bool_t nvmx_intercepts_exception(
@@ -1328,7 +1333,7 @@ static void virtual_vmexit(struct cpu_user_regs *regs)
nvmx_update_apicv(v);
nvcpu->nv_vmswitch_in_progress = 0;
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
}
void nvmx_switch_guest(void)
@@ -1382,16 +1387,14 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs)
if ( nvmx_vcpu_in_vmx(v) )
{
- vmreturn(regs,
- nvcpu->nv_vvmcxaddr != INVALID_PADDR ?
- VMFAIL_VALID : VMFAIL_INVALID);
+ vmfail(regs, VMX_INSN_VMXON_IN_VMX_ROOT);
return X86EMUL_OKAY;
}
if ( (gpa & ~PAGE_MASK) ||
(gpa >> (v->domain->arch.paging.gfn_bits + PAGE_SHIFT)) )
{
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
@@ -1400,7 +1403,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs)
(nvmcs_revid & ~VMX_BASIC_REVISION_MASK) ||
((nvmcs_revid ^ vmx_basic_msr) & VMX_BASIC_REVISION_MASK) )
{
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
@@ -1416,7 +1419,7 @@ int nvmx_handle_vmxon(struct cpu_user_regs *regs)
_mfn(PFN_DOWN(v->arch.hvm_vmx.vmcs_pa)));
__vmptrld(v->arch.hvm_vmx.vmcs_pa);
v->arch.hvm_vmx.launched = 0;
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
@@ -1434,7 +1437,7 @@ int nvmx_handle_vmxoff(struct cpu_user_regs *regs)
nvmx_purge_vvmcs(v);
nvmx->vmxon_region_pa = INVALID_PADDR;
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
@@ -1505,7 +1508,7 @@ static int nvmx_vmresume(struct vcpu *v, struct
cpu_user_regs *regs)
!(__n2_exec_control(v) & CPU_BASED_ACTIVATE_IO_BITMAP) ) )
nvcpu->nv_vmentry_pending = 1;
else
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
@@ -1522,15 +1525,16 @@ int nvmx_handle_vmresume(struct cpu_user_regs *regs)
if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
{
- vmreturn (regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
launched = vvmcs_launched(&nvmx->launched_list,
PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr));
- if ( !launched ) {
- vmreturn (regs, VMFAIL_VALID);
- return X86EMUL_OKAY;
+ if ( !launched )
+ {
+ vmfail_valid(regs, VMX_INSN_VMRESUME_NONLAUNCHED_VMCS);
+ return X86EMUL_OKAY;
}
return nvmx_vmresume(v,regs);
}
@@ -1547,15 +1551,16 @@ int nvmx_handle_vmlaunch(struct cpu_user_regs *regs)
if ( vcpu_nestedhvm(v).nv_vvmcxaddr == INVALID_PADDR )
{
- vmreturn (regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
launched = vvmcs_launched(&nvmx->launched_list,
PFN_DOWN(v->arch.hvm_vmx.vmcs_shadow_maddr));
- if ( launched ) {
- vmreturn (regs, VMFAIL_VALID);
- return X86EMUL_OKAY;
+ if ( launched )
+ {
+ vmfail_valid(regs, VMX_INSN_VMLAUNCH_NONCLEAR_VMCS);
+ return X86EMUL_OKAY;
}
else {
rc = nvmx_vmresume(v,regs);
@@ -1583,7 +1588,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
if ( gpa == vcpu_2_nvmx(v).vmxon_region_pa || gpa & 0xfff )
{
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
goto out;
}
@@ -1614,7 +1619,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
!map_io_bitmap_all(v) ||
!_map_msr_bitmap(v) )
{
- vmreturn(regs, VMFAIL_VALID);
+ vmfail_valid(regs, VMX_INSN_VMPTRLD_INVALID_PHYADDR);
goto out;
}
}
@@ -1622,7 +1627,7 @@ int nvmx_handle_vmptrld(struct cpu_user_regs *regs)
if ( cpu_has_vmx_vmcs_shadowing )
nvmx_set_vmcs_pointer(v, nvcpu->nv_vvmcx);
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
out:
return X86EMUL_OKAY;
@@ -1649,7 +1654,7 @@ int nvmx_handle_vmptrst(struct cpu_user_regs *regs)
if ( rc != HVMCOPY_okay )
return X86EMUL_EXCEPTION;
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
@@ -1695,7 +1700,12 @@ int nvmx_handle_vmclear(struct cpu_user_regs *regs)
}
}
- vmreturn(regs, rc);
+ if ( rc == VMSUCCEED )
+ vmsucceed(regs);
+ else if ( rc == VMFAIL_VALID )
+ vmfail_valid(regs, VMX_INSN_VMCLEAR_INVALID_PHYADDR);
+ else
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
@@ -1727,7 +1737,7 @@ int nvmx_handle_vmread(struct cpu_user_regs *regs)
break;
}
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
@@ -1759,7 +1769,10 @@ int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
break;
}
- vmreturn(regs, okay ? VMSUCCEED : VMFAIL_VALID);
+ if ( okay )
+ vmsucceed(regs);
+ else
+ vmfail_valid(regs, VMX_INSN_UNSUPPORTED_VMCS_COMPONENT);
return X86EMUL_OKAY;
}
@@ -1790,10 +1803,10 @@ int nvmx_handle_invept(struct cpu_user_regs *regs)
__invept(INVEPT_ALL_CONTEXT, 0, 0);
break;
default:
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
@@ -1815,11 +1828,11 @@ int nvmx_handle_invvpid(struct cpu_user_regs *regs)
hvm_asid_flush_vcpu_asid(&vcpu_nestedhvm(current).nv_n2asid);
break;
default:
- vmreturn(regs, VMFAIL_INVALID);
+ vmfail_invalid(regs);
return X86EMUL_OKAY;
}
- vmreturn(regs, VMSUCCEED);
+ vmsucceed(regs);
return X86EMUL_OKAY;
}
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h
b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 894093d..6c3d7ba 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -574,9 +574,18 @@ enum vmcs_field {
#define VMX_GUEST_MSR 0
#define VMX_HOST_MSR 1
-/* VM Instruction error numbers. */
-#define VMX_INSN_INVALID_CONTROL_STATE 7
-#define VMX_INSN_INVALID_HOST_STATE 8
+/* VM Instruction error numbers */
+enum vmx_insn_errno
+{
+ VMX_INSN_VMCLEAR_INVALID_PHYADDR = 2,
+ VMX_INSN_VMLAUNCH_NONCLEAR_VMCS = 4,
+ VMX_INSN_VMRESUME_NONLAUNCHED_VMCS = 5,
+ VMX_INSN_INVALID_CONTROL_STATE = 7,
+ VMX_INSN_INVALID_HOST_STATE = 8,
+ VMX_INSN_VMPTRLD_INVALID_PHYADDR = 9,
+ VMX_INSN_UNSUPPORTED_VMCS_COMPONENT = 12,
+ VMX_INSN_VMXON_IN_VMX_ROOT = 15,
+};
void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index eae4af2..9870589 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -53,6 +53,10 @@
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
+#define X86_EFLAGS_ARITH_MASK \
+ (X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | \
+ X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF)
+
/*
* Intel CPU flags in CR0
*/
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |