From 2e2e22c7d50392fa5cced3e0334b217426f48b7a Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Mon, 19 Aug 2019 16:40:06 +0100 Subject: [PATCH] x86/svm: Intercept and terminate RDPRU with #UD The RDPRU instruction isn't supported at all (and it is unclear how this can ever be offered safely to guests). However, a guest which ignores CPUID and blindly executes RDPRU will find that it functions. Use the intercept and terminate with #UD. While at it, fold SKINIT into the same "unconditionally disabled" path. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- xen/arch/x86/hvm/svm/svm.c | 5 ++--- xen/arch/x86/hvm/svm/vmcb.c | 3 ++- xen/include/asm-x86/hvm/svm/vmcb.h | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 309912a234..afb1ccb342 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2945,6 +2945,8 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) case VMEXIT_MONITOR: case VMEXIT_MWAIT: + case VMEXIT_SKINIT: + case VMEXIT_RDPRU: hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); break; @@ -2963,9 +2965,6 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) case VMEXIT_CLGI: svm_vmexit_do_clgi(regs, v); break; - case VMEXIT_SKINIT: - hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); - break; case VMEXIT_XSETBV: if ( vmcb_get_cpl(vmcb) ) diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index 55da9302e5..565e997155 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -70,7 +70,8 @@ static int construct_vmcb(struct vcpu *v) GENERAL2_INTERCEPT_STGI | GENERAL2_INTERCEPT_CLGI | GENERAL2_INTERCEPT_SKINIT | GENERAL2_INTERCEPT_MWAIT | GENERAL2_INTERCEPT_WBINVD | GENERAL2_INTERCEPT_MONITOR | - GENERAL2_INTERCEPT_XSETBV | GENERAL2_INTERCEPT_ICEBP; + GENERAL2_INTERCEPT_XSETBV | GENERAL2_INTERCEPT_ICEBP | + GENERAL2_INTERCEPT_RDPRU; /* Intercept all debug-register writes. */ vmcb->_dr_intercepts = ~0u; diff --git a/xen/include/asm-x86/hvm/svm/vmcb.h b/xen/include/asm-x86/hvm/svm/vmcb.h index 4fa2ddfb2f..ed7cebea71 100644 --- a/xen/include/asm-x86/hvm/svm/vmcb.h +++ b/xen/include/asm-x86/hvm/svm/vmcb.h @@ -74,7 +74,8 @@ enum GenericIntercept2bits GENERAL2_INTERCEPT_MONITOR = 1 << 10, GENERAL2_INTERCEPT_MWAIT = 1 << 11, GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12, - GENERAL2_INTERCEPT_XSETBV = 1 << 13 + GENERAL2_INTERCEPT_XSETBV = 1 << 13, + GENERAL2_INTERCEPT_RDPRU = 1 << 14, }; @@ -300,6 +301,7 @@ enum VMEXIT_EXITCODE VMEXIT_MWAIT = 139, /* 0x8b */ VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */ VMEXIT_XSETBV = 141, /* 0x8d */ + VMEXIT_RDPRU = 142, /* 0x8e */ VMEXIT_NPF = 1024, /* 0x400, nested paging fault */ VMEXIT_INVALID = -1 }; -- 2.39.5