Configure the Bus Lock intercept when supported by the host. The VMCB counter is initialised to zero so it fires upon the first instruction that locks the bus. On the #VMEXIT handler that counter is set to 1 because it has fault behaviour and the offending instruction needs to re-execute.
Signed-off-by: Alejandro Vallejo <[email protected]> --- v2: * Moved the P() call to this patch. We don't want to print until the feature is fully supported. * Removed the initialisation of the counter to 1 in vmcb.c, so it's implicitly zero-initialised. --- xen/arch/x86/hvm/svm/svm.c | 6 ++++++ xen/arch/x86/hvm/svm/vmcb.c | 3 +++ xen/arch/x86/hvm/svm/vmcb.h | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 5d23603fc1..abda5a9063 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2524,6 +2524,7 @@ const struct hvm_function_table * __init start_svm(void) P(cpu_has_tsc_ratio, "TSC Rate MSR"); P(cpu_has_svm_sss, "NPT Supervisor Shadow Stack"); P(cpu_has_svm_spec_ctrl, "MSR_SPEC_CTRL virtualisation"); + P(cpu_has_svm_bus_lock, "BusLock-Intercept Filter"); #undef P if ( !printed ) @@ -3087,6 +3088,11 @@ void asmlinkage svm_vmexit_handler(void) break; } + case VMEXIT_BUS_LOCK: + perfc_incr(buslock); + vmcb->bus_lock_count = 1; + break; + default: unexpected_exit_type: gprintk(XENLOG_ERR, "Unexpected vmexit: reason %#"PRIx64", " diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index cbee10d046..15223a693e 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -66,6 +66,9 @@ static int construct_vmcb(struct vcpu *v) GENERAL2_INTERCEPT_XSETBV | GENERAL2_INTERCEPT_ICEBP | GENERAL2_INTERCEPT_RDPRU; + if ( cpu_has_svm_bus_lock ) + vmcb->_general3_intercepts |= GENERAL3_INTERCEPT_BUS_LOCK; + /* Intercept all debug-register writes. */ vmcb->_dr_intercepts = ~0u; diff --git a/xen/arch/x86/hvm/svm/vmcb.h b/xen/arch/x86/hvm/svm/vmcb.h index 231f9b1b06..68cf5eaf0b 100644 --- a/xen/arch/x86/hvm/svm/vmcb.h +++ b/xen/arch/x86/hvm/svm/vmcb.h @@ -68,7 +68,7 @@ enum GenericIntercept2bits /* general 3 intercepts */ enum GenericIntercept3bits { - GENERAL3_INTERCEPT_BUS_LOCK_THRESH = 1 << 5, + GENERAL3_INTERCEPT_BUS_LOCK = 1 << 5, }; /* control register intercepts */ @@ -497,7 +497,7 @@ struct vmcb_struct { u8 guest_ins_len; /* offset 0xD0 */ u8 guest_ins[15]; /* offset 0xD1 */ u64 res10a[8]; /* offset 0xE0 */ - u16 bus_lock_thresh; /* offset 0x120 */ + u16 bus_lock_count; /* offset 0x120 */ u16 res10b[3]; /* offset 0x122 */ u64 res10c[91]; /* offset 0x128 pad to save area */ -- 2.43.0
