From patchwork Fri May 6 08:50:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Razvan Cojocaru X-Patchwork-Id: 9030201 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C16E29F39D for ; Fri, 6 May 2016 08:53:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3714A20357 for ; Fri, 6 May 2016 08:53:03 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8098E2034A for ; Fri, 6 May 2016 08:53:01 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aybSr-0003qx-CZ; Fri, 06 May 2016 08:50:25 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1aybSq-0003qr-02 for xen-devel@lists.xen.org; Fri, 06 May 2016 08:50:24 +0000 Received: from [193.109.254.147] by server-2.bemta-14.messagelabs.com id B5/B8-03279-FCA5C275; Fri, 06 May 2016 08:50:23 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprKIsWRWlGSWpSXmKPExsUSfTxjoe65KJ1 wg6bJ/BZLPi5mcWD0OLr7N1MAYxRrZl5SfkUCa8ba9+tYC05MYay4teEvewPjnNIuRk4OIQF3 iQlbLrND2GsYJZ7N9exi5AKyTzJK7Jp8mBWm6O+sbywQiX2MEkveTWEDSbAJGEqs3tgCZosIS Etc+3yZEaSIWaCdSeJe90sWkISwQJDEnTmLmEBsFgFViZknbzKD2LwCHhKnv18H2yAhICdx8t hkKDtHoqetA8jmALKlJP63KoHMlBA4xSKx5MUFNogaGYlHE2+yTWAUWMDIsIpRozi1qCy1SNf QQi+pKDM9oyQ3MTNH19DQRC83tbg4MT01JzGpWC85P3cTIzC46hkYGHcwHtnueYhRkoNJSZR3 1T/tcCG+pPyUyozE4oz4otKc1OJDjDIcHEoSvH2ROuFCgkWp6akVaZk5wDCHSUtw8CiJ8M4GS fMWFyTmFmemQ6ROMSpKifPuB0kIgCQySvPg2mCxdYlRVkqYl5GBgUGIpyC1KDezBFX+FaM4B6 OSMO8bkCk8mXklcNNfAS1mAlr8fq4myOKSRISUVAMj1zX3zKmfjswJDP4Zs1DQ+Ij2g2su2+u ZfsblOoooN9+5bBGyq0670r03/M6iaZ1FR+7eaPnx6jf38rc3RYKvbOdY53kxoeD25j/r1izY 0fBLvuFYee2kSj7DI1VHZvNLMakZ/t87T6xvqtaKJvl9xuGnrRIf+VUxuGULyT3Z94pLbPdiz dWHlViKMxINtZiLihMB6G84BKgCAAA= X-Env-Sender: rcojocaru@bitdefender.com X-Msg-Ref: server-7.tower-27.messagelabs.com!1462524621!39917342!1 X-Originating-IP: [91.199.104.161] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 8.34; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23173 invoked from network); 6 May 2016 08:50:22 -0000 Received: from mx01.bbu.dsd.mx.bitdefender.com (HELO mx01.bbu.dsd.mx.bitdefender.com) (91.199.104.161) by server-7.tower-27.messagelabs.com with DHE-RSA-AES128-GCM-SHA256 encrypted SMTP; 6 May 2016 08:50:22 -0000 Received: (qmail 19562 invoked from network); 6 May 2016 11:50:20 +0300 Received: from unknown (HELO mx-sr.buh.bitdefender.com) (10.17.80.103) by mx01.bbu.dsd.mx.bitdefender.com with AES256-GCM-SHA384 encrypted SMTP; 6 May 2016 11:50:20 +0300 Received: from smtp02.buh.bitdefender.net (unknown [10.17.80.76]) by mx-sr.buh.bitdefender.com (Postfix) with ESMTP id 7DDF37FBF3 for ; Fri, 6 May 2016 11:50:19 +0300 (EEST) Received: (qmail 12620 invoked from network); 6 May 2016 11:50:19 +0300 Received: from xen.dsd.ro (HELO xen.dsd.bitdefender.biz) (rcojocaru@bitdefender.com@10.10.14.109) by smtp02.buh.bitdefender.net with AES128-SHA256 encrypted SMTP; 6 May 2016 11:50:19 +0300 From: Razvan Cojocaru To: xen-devel@lists.xen.org Date: Fri, 6 May 2016 11:50:01 +0300 Message-Id: <1462524601-3713-1-git-send-email-rcojocaru@bitdefender.com> X-Mailer: git-send-email 1.9.1 X-BitDefender-Scanner: Clean, Agent: BitDefender qmail 3.1.6 on smtp02.buh.bitdefender.net, sigver: 7.65445 X-BitDefender-Spam: No (0) X-BitDefender-SpamStamp: Build: [Engines: 2.15.6.911, Dats: 422174, Stamp: 3], Multi: [Enabled, t: (0.000015, 0.013080)], BW: [Enabled, t: (0.000008,0.000001)], RBL DNSBL: [Disabled], APM: [Enabled, Score: 500, t: (0.012360), Flags: BB9BAF5C; NN_LARGISH_BIGGISH; NN_MORE_INFO_ADN; NN_NO_CONTENT_TYPE; NN_LEGIT_SUMM_400_WORDS; NN_NO_LINK_NMD; NN_LEGIT_BITDEFENDER; NN_LEGIT_S_SQARE_BRACKETS; NN_LEGIT_MAILING_LIST_TO], SGN: [Enabled, t: (0.019242)], URL: [Enabled, t: (0.000006)], RTDA: [Enabled, t: (0.012337), Hit: No, Details: v2.4.0; Id: 2m1ghdo.1ahvaoa1f.4j9h], total: 0(775) X-BitDefender-CF-Stamp: none Cc: kevin.tian@intel.com, tamas@tklengyel.com, wei.liu2@citrix.com, jbeulich@suse.com, Razvan Cojocaru , andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com, julien.grall@arm.com, sstabellini@kernel.org, jun.nakajima@intel.com Subject: [Xen-devel] [PATCH V8] vm_event: Allow subscribing to write events for specific MSR-s X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Previously, subscribing to MSR write events was an all-or-none approach, with special cases for introspection MSR-s. This patch allows the vm_event consumer to specify exactly what MSR-s it is interested in, and as a side-effect gets rid of the vmx_introspection_force_enabled_msrs[] special case. The patch also introduces arch_monitor_init_domain() and arch_monitor_cleanup_domain(), to do monitor-specific work (as opposed to the previous way of doing all the setup in vm_event_init_domain() / vm_event_cleanup_domain()). This replaces the previously posted "xen: Filter out MSR write events" patch. Signed-off-by: Razvan Cojocaru Acked-by: Wei Liu Acked-by: Kevin Tian --- Changes since V7: - Added Kevin Tian's ack. - Moved memset()s from arch_monitor_init_domain() to arch_monitor_cleanup_domain(), as suggested by Jan Beulich. - Now using sizeof() instead of ARRAY_SIZE() in monitor_bitmap_for_msr(). - d->arch.monitor_msr_bitmap->{low,hypervisor,high} are now proper bitmaps (unsigned long arrays). - monitor_bitmap_for_msr() now returns unsigned long *. - The array size checks in monitor_bitmap_for_msr() have switched from < 0x1fff to <= 0x1fff. - monitor_msr_bitmap has become msr_bitmap and is now a member of the monitor struct. --- tools/libxc/include/xenctrl.h | 9 ++- tools/libxc/xc_monitor.c | 6 +- xen/arch/x86/hvm/event.c | 3 +- xen/arch/x86/hvm/hvm.c | 3 +- xen/arch/x86/hvm/vmx/vmcs.c | 26 +------- xen/arch/x86/hvm/vmx/vmx.c | 10 +-- xen/arch/x86/monitor.c | 124 +++++++++++++++++++++++++++++++++---- xen/arch/x86/vm_event.c | 3 +- xen/common/vm_event.c | 5 ++ xen/include/asm-arm/monitor.h | 13 ++++ xen/include/asm-x86/domain.h | 3 +- xen/include/asm-x86/hvm/hvm.h | 8 +-- xen/include/asm-x86/hvm/vmx/vmcs.h | 7 --- xen/include/asm-x86/monitor.h | 14 +++++ xen/include/public/domctl.h | 5 +- 15 files changed, 170 insertions(+), 69 deletions(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index dc54612..edb333b 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2153,8 +2153,13 @@ int xc_monitor_get_capabilities(xc_interface *xch, domid_t domain_id, int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t domain_id, uint16_t index, bool enable, bool sync, bool onchangeonly); -int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, bool enable, - bool extended_capture); +/* + * A list of MSR indices can usually be found in /usr/include/asm/msr-index.h. + * Please consult the Intel/AMD manuals for more information on + * non-architectural indices. + */ +int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, uint32_t msr, + bool enable); int xc_monitor_singlestep(xc_interface *xch, domid_t domain_id, bool enable); int xc_monitor_software_breakpoint(xc_interface *xch, domid_t domain_id, bool enable); diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c index b1705dd..78131b2 100644 --- a/tools/libxc/xc_monitor.c +++ b/tools/libxc/xc_monitor.c @@ -86,8 +86,8 @@ int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t domain_id, return do_domctl(xch, &domctl); } -int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, bool enable, - bool extended_capture) +int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, uint32_t msr, + bool enable) { DECLARE_DOMCTL; @@ -96,7 +96,7 @@ int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, bool enable, domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE : XEN_DOMCTL_MONITOR_OP_DISABLE; domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR; - domctl.u.monitor_op.u.mov_to_msr.extended_capture = extended_capture; + domctl.u.monitor_op.u.mov_to_msr.msr = msr; return do_domctl(xch, &domctl); } diff --git a/xen/arch/x86/hvm/event.c b/xen/arch/x86/hvm/event.c index 56c5514..8fdb6f5 100644 --- a/xen/arch/x86/hvm/event.c +++ b/xen/arch/x86/hvm/event.c @@ -57,9 +57,8 @@ bool_t hvm_event_cr(unsigned int index, unsigned long value, unsigned long old) void hvm_event_msr(unsigned int msr, uint64_t value) { struct vcpu *curr = current; - struct arch_domain *ad = &curr->domain->arch; - if ( ad->monitor.mov_to_msr_enabled ) + if ( monitored_msr(curr->domain, msr) ) { vm_event_request_t req = { .reason = VM_EVENT_REASON_MOV_TO_MSR, diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 82e2ed1..799fdeb 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3694,7 +3694,6 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content, bool_t mtrr; unsigned int edx, index; int ret = X86EMUL_OKAY; - struct arch_domain *currad = ¤t->domain->arch; HVMTRACE_3D(MSR_WRITE, msr, (uint32_t)msr_content, (uint32_t)(msr_content >> 32)); @@ -3702,7 +3701,7 @@ int hvm_msr_write_intercept(unsigned int msr, uint64_t msr_content, hvm_cpuid(1, NULL, NULL, NULL, &edx); mtrr = !!(edx & cpufeat_mask(X86_FEATURE_MTRR)); - if ( may_defer && unlikely(currad->monitor.mov_to_msr_enabled) ) + if ( may_defer && unlikely(monitored_msr(v->domain, msr)) ) { ASSERT(v->arch.vm_event); diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 8284281..f8421e8 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -108,18 +109,6 @@ u64 vmx_ept_vpid_cap __read_mostly; u64 vmx_vmfunc __read_mostly; bool_t vmx_virt_exception __read_mostly; -const u32 vmx_introspection_force_enabled_msrs[] = { - MSR_IA32_SYSENTER_EIP, - MSR_IA32_SYSENTER_ESP, - MSR_IA32_SYSENTER_CS, - MSR_IA32_MC0_CTL, - MSR_STAR, - MSR_LSTAR -}; - -const unsigned int vmx_introspection_force_enabled_msrs_size = - ARRAY_SIZE(vmx_introspection_force_enabled_msrs); - static DEFINE_PER_CPU_READ_MOSTLY(paddr_t, vmxon_region); static DEFINE_PER_CPU(paddr_t, current_vmcs); static DEFINE_PER_CPU(struct list_head, active_vmcs_list); @@ -810,17 +799,8 @@ void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type) if ( msr_bitmap == NULL ) return; - if ( unlikely(d->arch.monitor.mov_to_msr_enabled && - d->arch.monitor.mov_to_msr_extended) && - vm_event_check_ring(&d->vm_event->monitor) ) - { - unsigned int i; - - /* Filter out MSR-s needed for memory introspection */ - for ( i = 0; i < vmx_introspection_force_enabled_msrs_size; i++ ) - if ( msr == vmx_introspection_force_enabled_msrs[i] ) - return; - } + if ( unlikely(monitored_msr(d, msr)) ) + return; /* * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index bc4410f..9135441 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1958,16 +1958,12 @@ void vmx_hypervisor_cpuid_leaf(uint32_t sub_idx, *eax |= XEN_HVM_CPUID_X2APIC_VIRT; } -static void vmx_enable_msr_exit_interception(struct domain *d) +static void vmx_enable_msr_interception(struct domain *d, uint32_t msr) { struct vcpu *v; - unsigned int i; - /* Enable interception for MSRs needed for memory introspection. */ for_each_vcpu ( d, v ) - for ( i = 0; i < vmx_introspection_force_enabled_msrs_size; i++ ) - vmx_enable_intercept_for_msr(v, vmx_introspection_force_enabled_msrs[i], - MSR_TYPE_W); + vmx_enable_intercept_for_msr(v, msr, MSR_TYPE_W); } static bool_t vmx_is_singlestep_supported(void) @@ -2166,7 +2162,7 @@ static struct hvm_function_table __initdata vmx_function_table = { .handle_eoi = vmx_handle_eoi, .nhvm_hap_walk_L1_p2m = nvmx_hap_walk_L1_p2m, .hypervisor_cpuid_leaf = vmx_hypervisor_cpuid_leaf, - .enable_msr_exit_interception = vmx_enable_msr_exit_interception, + .enable_msr_interception = vmx_enable_msr_interception, .is_singlestep_supported = vmx_is_singlestep_supported, .set_mode = vmx_set_mode, .altp2m_vcpu_update_p2m = vmx_vcpu_update_eptp, diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c index 1fec412..66494d3 100644 --- a/xen/arch/x86/monitor.c +++ b/xen/arch/x86/monitor.c @@ -22,6 +22,103 @@ #include #include +int arch_monitor_init_domain(struct domain *d) +{ + if ( !d->arch.monitor.msr_bitmap ) + d->arch.monitor.msr_bitmap = xzalloc(struct monitor_msr_bitmap); + + if ( !d->arch.monitor.msr_bitmap ) + return -ENOMEM; + + return 0; +} + +void arch_monitor_cleanup_domain(struct domain *d) +{ + xfree(d->arch.monitor.msr_bitmap); + + memset(&d->arch.monitor, 0, sizeof(d->arch.monitor)); + memset(&d->monitor, 0, sizeof(d->monitor)); +} + +static unsigned long *monitor_bitmap_for_msr(struct domain *d, u32 *msr) +{ + ASSERT(d->arch.monitor.msr_bitmap && msr); + + switch ( *msr ) + { + case 0 ... 0x1fff: + BUILD_BUG_ON(sizeof(d->arch.monitor.msr_bitmap->low) * 8 <= 0x1fff); + return d->arch.monitor.msr_bitmap->low; + + case 0x40000000 ... 0x40001fff: + BUILD_BUG_ON( + sizeof(d->arch.monitor.msr_bitmap->hypervisor) * 8 <= 0x1fff); + *msr &= 0x1fff; + return d->arch.monitor.msr_bitmap->hypervisor; + + case 0xc0000000 ... 0xc0001fff: + BUILD_BUG_ON(sizeof(d->arch.monitor.msr_bitmap->high) * 8 <= 0x1fff); + *msr &= 0x1fff; + return d->arch.monitor.msr_bitmap->high; + + default: + return NULL; + } +} + +static int monitor_enable_msr(struct domain *d, u32 msr) +{ + unsigned long *bitmap; + u32 index = msr; + + if ( !d->arch.monitor.msr_bitmap ) + return -ENXIO; + + bitmap = monitor_bitmap_for_msr(d, &index); + + if ( !bitmap ) + return -EINVAL; + + __set_bit(index, bitmap); + + hvm_enable_msr_interception(d, msr); + + return 0; +} + +static int monitor_disable_msr(struct domain *d, u32 msr) +{ + unsigned long *bitmap; + + if ( !d->arch.monitor.msr_bitmap ) + return -ENXIO; + + bitmap = monitor_bitmap_for_msr(d, &msr); + + if ( !bitmap ) + return -EINVAL; + + __clear_bit(msr, bitmap); + + return 0; +} + +bool_t monitored_msr(struct domain *d, u32 msr) +{ + unsigned long *bitmap; + + if ( !d->arch.monitor.msr_bitmap ) + return 0; + + bitmap = monitor_bitmap_for_msr(d, &msr); + + if ( !bitmap ) + return 0; + + return test_bit(msr, bitmap); +} + int arch_monitor_domctl_event(struct domain *d, struct xen_domctl_monitor_op *mop) { @@ -77,25 +174,28 @@ int arch_monitor_domctl_event(struct domain *d, case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR: { - bool_t old_status = ad->monitor.mov_to_msr_enabled; + bool_t old_status; + int rc; + u32 msr = mop->u.mov_to_msr.msr; - if ( unlikely(old_status == requested_status) ) - return -EEXIST; + domain_pause(d); - if ( requested_status && mop->u.mov_to_msr.extended_capture && - !hvm_enable_msr_exit_interception(d) ) - return -EOPNOTSUPP; + old_status = monitored_msr(d, msr); - domain_pause(d); + if ( unlikely(old_status == requested_status) ) + { + domain_unpause(d); + return -EEXIST; + } - if ( requested_status && mop->u.mov_to_msr.extended_capture ) - ad->monitor.mov_to_msr_extended = 1; + if ( requested_status ) + rc = monitor_enable_msr(d, msr); else - ad->monitor.mov_to_msr_extended = 0; + rc = monitor_disable_msr(d, msr); - ad->monitor.mov_to_msr_enabled = requested_status; domain_unpause(d); - break; + + return rc; } case XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP: diff --git a/xen/arch/x86/vm_event.c b/xen/arch/x86/vm_event.c index 5635603..a9d3861 100644 --- a/xen/arch/x86/vm_event.c +++ b/xen/arch/x86/vm_event.c @@ -20,6 +20,7 @@ #include #include +#include #include /* Implicitly serialized by the domctl lock. */ @@ -56,8 +57,6 @@ void vm_event_cleanup_domain(struct domain *d) } d->arch.mem_access_emulate_each_rep = 0; - memset(&d->arch.monitor, 0, sizeof(d->arch.monitor)); - memset(&d->monitor, 0, sizeof(d->monitor)); } void vm_event_toggle_singlestep(struct domain *d, struct vcpu *v) diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c index 2906407..1ba12cb 100644 --- a/xen/common/vm_event.c +++ b/xen/common/vm_event.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -665,6 +666,9 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, { case XEN_VM_EVENT_ENABLE: /* domain_pause() not required here, see XSA-99 */ + rc = arch_monitor_init_domain(d); + if ( rc ) + break; rc = vm_event_enable(d, vec, ved, _VPF_mem_access, HVM_PARAM_MONITOR_RING_PFN, monitor_notification); @@ -675,6 +679,7 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec, { domain_pause(d); rc = vm_event_disable(d, ved); + arch_monitor_cleanup_domain(d); domain_unpause(d); } break; diff --git a/xen/include/asm-arm/monitor.h b/xen/include/asm-arm/monitor.h index 6e36e99..478f5e9 100644 --- a/xen/include/asm-arm/monitor.h +++ b/xen/include/asm-arm/monitor.h @@ -46,4 +46,17 @@ int arch_monitor_domctl_event(struct domain *d, return -EOPNOTSUPP; } +static inline +int arch_monitor_init_domain(struct domain *d) +{ + /* No arch-specific domain initialization on ARM. */ + return 0; +} + +static inline +void arch_monitor_cleanup_domain(struct domain *d) +{ + /* No arch-specific domain cleanup on ARM. */ +} + #endif /* __ASM_ARM_MONITOR_H__ */ diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 165e533..6f2abdc 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -401,10 +401,9 @@ struct arch_domain unsigned int write_ctrlreg_enabled : 4; unsigned int write_ctrlreg_sync : 4; unsigned int write_ctrlreg_onchangeonly : 4; - unsigned int mov_to_msr_enabled : 1; - unsigned int mov_to_msr_extended : 1; unsigned int singlestep_enabled : 1; unsigned int software_breakpoint_enabled : 1; + struct monitor_msr_bitmap *msr_bitmap; } monitor; /* Mem_access emulation control */ diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 7b7ff3f..9d1c0ef 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -211,7 +211,7 @@ struct hvm_function_table { uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); - void (*enable_msr_exit_interception)(struct domain *d); + void (*enable_msr_interception)(struct domain *d, uint32_t msr); bool_t (*is_singlestep_supported)(void); int (*set_mode)(struct vcpu *v, int mode); @@ -565,11 +565,11 @@ static inline enum hvm_intblk nhvm_interrupt_blocked(struct vcpu *v) return hvm_funcs.nhvm_intr_blocked(v); } -static inline bool_t hvm_enable_msr_exit_interception(struct domain *d) +static inline bool_t hvm_enable_msr_interception(struct domain *d, uint32_t msr) { - if ( hvm_funcs.enable_msr_exit_interception ) + if ( hvm_funcs.enable_msr_interception ) { - hvm_funcs.enable_msr_exit_interception(d); + hvm_funcs.enable_msr_interception(d, msr); return 1; } diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index b54f52f..7bf5326 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -562,13 +562,6 @@ enum vmcs_field { HOST_RIP = 0x00006c16, }; -/* - * A set of MSR-s that need to be enabled for memory introspection - * to work. - */ -extern const u32 vmx_introspection_force_enabled_msrs[]; -extern const unsigned int vmx_introspection_force_enabled_msrs_size; - #define VMCS_VPID_WIDTH 16 #define MSR_TYPE_R 1 diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm-x86/monitor.h index d367099..e93b49b 100644 --- a/xen/include/asm-x86/monitor.h +++ b/xen/include/asm-x86/monitor.h @@ -29,6 +29,14 @@ #define monitor_ctrlreg_bitmask(ctrlreg_index) (1U << (ctrlreg_index)) +#define MONITOR_MSR_BITMAP_SIZE (1024 / sizeof(unsigned long)) + +struct monitor_msr_bitmap { + unsigned long low[MONITOR_MSR_BITMAP_SIZE]; + unsigned long hypervisor[MONITOR_MSR_BITMAP_SIZE]; + unsigned long high[MONITOR_MSR_BITMAP_SIZE]; +}; + static inline int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop) { @@ -60,4 +68,10 @@ int arch_monitor_domctl_op(struct domain *d, struct xen_domctl_monitor_op *mop) int arch_monitor_domctl_event(struct domain *d, struct xen_domctl_monitor_op *mop); +int arch_monitor_init_domain(struct domain *d); + +void arch_monitor_cleanup_domain(struct domain *d); + +bool_t monitored_msr(struct domain *d, u32 msr); + #endif /* __ASM_X86_MONITOR_H__ */ diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 2457698..7be3924 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -37,7 +37,7 @@ #include "hvm/save.h" #include "memory.h" -#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000b +#define XEN_DOMCTL_INTERFACE_VERSION 0x0000000c /* * NB. xen_domctl.domain is an IN/OUT parameter for this operation. @@ -1107,8 +1107,7 @@ struct xen_domctl_monitor_op { } mov_to_cr; struct { - /* Enable the capture of an extended set of MSRs */ - uint8_t extended_capture; + uint32_t msr; } mov_to_msr; struct {