From: "Roger Pau Monné" <roger.pau@citrix.com>
To: "Michał Leszczyński" <michal.leszczynski@cert.pl>
Cc: Kevin Tian <kevin.tian@intel.com>,
tamas.lengyel@intel.com, Jun Nakajima <jun.nakajima@intel.com>,
Wei Liu <wl@xen.org>, Andrew Cooper <andrew.cooper3@citrix.com>,
luwei.kang@intel.com, Jan Beulich <jbeulich@suse.com>,
xen-devel@lists.xenproject.org
Subject: Re: [PATCH v6 07/11] x86/vmx: implement IPT in VMX
Date: Wed, 15 Jul 2020 18:04:30 +0200 [thread overview]
Message-ID: <20200715160430.GE7191@Air-de-Roger> (raw)
In-Reply-To: <7ddfc44d6ffde0fa307f0e074225f588c397aef0.1594150543.git.michal.leszczynski@cert.pl>
On Tue, Jul 07, 2020 at 09:39:46PM +0200, Michał Leszczyński wrote:
> From: Michal Leszczynski <michal.leszczynski@cert.pl>
>
> Use Intel Processor Trace feature to provide vmtrace_pt_*
> interface for HVM/VMX.
>
> Signed-off-by: Michal Leszczynski <michal.leszczynski@cert.pl>
> ---
> xen/arch/x86/hvm/vmx/vmx.c | 110 +++++++++++++++++++++++++++++
> xen/include/asm-x86/hvm/vmx/vmcs.h | 3 +
> xen/include/asm-x86/hvm/vmx/vmx.h | 14 ++++
> 3 files changed, 127 insertions(+)
>
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index cc6d4ece22..63a5a76e16 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -428,6 +428,56 @@ static void vmx_domain_relinquish_resources(struct domain *d)
> vmx_free_vlapic_mapping(d);
> }
>
> +static int vmx_init_pt(struct vcpu *v)
> +{
> + int rc;
> + uint64_t size = v->domain->processor_trace_buf_kb * KB(1);
As I commented in other patches, I don't think there's a need to have
the size in bytes, and hence you could just convert to number of pages?
You might have to check that the value is rounded to a page boundary.
> +
> + if ( !v->vmtrace.pt_buf || !size )
> + return -EINVAL;
> +
> + /*
> + * We don't accept trace buffer size smaller than single page
> + * and the upper bound is defined as 4GB in the specification.
> + * The buffer size must be also a power of 2.
> + */
> + if ( size < PAGE_SIZE || size > GB(4) || (size & (size - 1)) )
> + return -EINVAL;
IMO there should be a hook to sanitize the buffer size before you go
and allocate it. It makes no sense to allocate a buffer to come here
and realize it's not suitable.
> +
> + v->arch.hvm.vmx.ipt_state = xzalloc(struct ipt_state);
> +
Extra newline.
> + if ( !v->arch.hvm.vmx.ipt_state )
> + return -ENOMEM;
> +
> + v->arch.hvm.vmx.ipt_state->output_base =
> + page_to_maddr(v->vmtrace.pt_buf);
The above fits on a single line now. You could also avoid having an
output_base field and just do the conversion in
vmx_restore_guest_msrs, I'm not sure there's much value in having this
cached here.
> + v->arch.hvm.vmx.ipt_state->output_mask.raw = size - 1;
> +
> + rc = vmx_add_host_load_msr(v, MSR_RTIT_CTL, 0);
> +
> + if ( rc )
> + return rc;
> +
> + rc = vmx_add_guest_msr(v, MSR_RTIT_CTL,
> + RTIT_CTL_TRACE_EN | RTIT_CTL_OS |
> + RTIT_CTL_USR | RTIT_CTL_BRANCH_EN);
> +
> + if ( rc )
> + return rc;
We don't usually leave an empty line between setting and testing rc.
> +
> + return 0;
> +}
> +
> +static int vmx_destroy_pt(struct vcpu* v)
> +{
> + if ( v->arch.hvm.vmx.ipt_state )
> + xfree(v->arch.hvm.vmx.ipt_state);
> +
> + v->arch.hvm.vmx.ipt_state = NULL;
> + return 0;
> +}
> +
> +
Double newline, just one newline please between functions.
> static int vmx_vcpu_initialise(struct vcpu *v)
> {
> int rc;
> @@ -471,6 +521,14 @@ static int vmx_vcpu_initialise(struct vcpu *v)
>
> vmx_install_vlapic_mapping(v);
>
> + if ( v->domain->processor_trace_buf_kb )
Can you move this check inside of vmx_init_pt, so that here you just
do:
return vmx_init_pt(v);
> + {
> + rc = vmx_init_pt(v);
> +
> + if ( rc )
> + return rc;
> + }
> +
> return 0;
> }
>
> @@ -483,6 +541,7 @@ static void vmx_vcpu_destroy(struct vcpu *v)
> * prior to vmx_domain_destroy so we need to disable PML for each vcpu
> * separately here.
> */
> + vmx_destroy_pt(v);
> vmx_vcpu_disable_pml(v);
> vmx_destroy_vmcs(v);
> passive_domain_destroy(v);
> @@ -513,6 +572,18 @@ static void vmx_save_guest_msrs(struct vcpu *v)
> * be updated at any time via SWAPGS, which we cannot trap.
> */
> v->arch.hvm.vmx.shadow_gs = rdgsshadow();
> +
> + if ( unlikely(v->arch.hvm.vmx.ipt_state &&
> + v->arch.hvm.vmx.ipt_state->active) )
> + {
> + uint64_t rtit_ctl;
Missing newline.
> + rdmsrl(MSR_RTIT_CTL, rtit_ctl);
> + BUG_ON(rtit_ctl & RTIT_CTL_TRACE_EN);
> +
> + rdmsrl(MSR_RTIT_STATUS, v->arch.hvm.vmx.ipt_state->status);
> + rdmsrl(MSR_RTIT_OUTPUT_MASK,
> + v->arch.hvm.vmx.ipt_state->output_mask.raw);
> + }
> }
>
> static void vmx_restore_guest_msrs(struct vcpu *v)
> @@ -524,6 +595,17 @@ static void vmx_restore_guest_msrs(struct vcpu *v)
>
> if ( cpu_has_msr_tsc_aux )
> wrmsr_tsc_aux(v->arch.msrs->tsc_aux);
> +
> + if ( unlikely(v->arch.hvm.vmx.ipt_state &&
> + v->arch.hvm.vmx.ipt_state->active) )
> + {
> + wrmsrl(MSR_RTIT_OUTPUT_BASE,
> + v->arch.hvm.vmx.ipt_state->output_base);
> + wrmsrl(MSR_RTIT_OUTPUT_MASK,
> + v->arch.hvm.vmx.ipt_state->output_mask.raw);
> + wrmsrl(MSR_RTIT_STATUS,
> + v->arch.hvm.vmx.ipt_state->status);
> + }
> }
>
> void vmx_update_cpu_exec_control(struct vcpu *v)
> @@ -2240,6 +2322,25 @@ static bool vmx_get_pending_event(struct vcpu *v, struct x86_event *info)
> return true;
> }
>
> +static int vmx_control_pt(struct vcpu *v, bool enable)
> +{
> + if ( !v->arch.hvm.vmx.ipt_state )
> + return -EINVAL;
> +
> + v->arch.hvm.vmx.ipt_state->active = enable;
I think you should assert that the vCPU is paused? As doing this on a
non-paused vCPU is not going to work reliably?
> + return 0;
> +}
> +
> +static int vmx_get_pt_offset(struct vcpu *v, uint64_t *offset, uint64_t *size)
> +{
> + if ( !v->arch.hvm.vmx.ipt_state )
> + return -EINVAL;
> +
> + *offset = v->arch.hvm.vmx.ipt_state->output_mask.offset;
> + *size = v->arch.hvm.vmx.ipt_state->output_mask.size + 1;
> + return 0;
> +}
> +
> static struct hvm_function_table __initdata vmx_function_table = {
> .name = "VMX",
> .cpu_up_prepare = vmx_cpu_up_prepare,
> @@ -2295,6 +2396,8 @@ static struct hvm_function_table __initdata vmx_function_table = {
> .altp2m_vcpu_update_vmfunc_ve = vmx_vcpu_update_vmfunc_ve,
> .altp2m_vcpu_emulate_ve = vmx_vcpu_emulate_ve,
> .altp2m_vcpu_emulate_vmfunc = vmx_vcpu_emulate_vmfunc,
> + .vmtrace_control_pt = vmx_control_pt,
> + .vmtrace_get_pt_offset = vmx_get_pt_offset,
> .tsc_scaling = {
> .max_ratio = VMX_TSC_MULTIPLIER_MAX,
> },
> @@ -3674,6 +3777,13 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>
> hvm_invalidate_regs_fields(regs);
>
> + if ( unlikely(v->arch.hvm.vmx.ipt_state &&
> + v->arch.hvm.vmx.ipt_state->active) )
> + {
> + rdmsrl(MSR_RTIT_OUTPUT_MASK,
> + v->arch.hvm.vmx.ipt_state->output_mask.raw);
> + }
Unneeded braces.
Thanks.
next prev parent reply other threads:[~2020-07-15 16:04 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-07 19:39 [PATCH v6 00/11] Implement support for external IPT monitoring Michał Leszczyński
2020-07-07 19:39 ` [PATCH v6 01/11] memory: batch processing in acquire_resource() Michał Leszczyński
2020-07-15 9:36 ` Roger Pau Monné
2020-07-15 12:13 ` Jan Beulich
2020-07-16 8:14 ` Roger Pau Monné
2020-07-15 12:28 ` Jan Beulich
2020-07-17 14:16 ` Julien Grall
2020-07-07 19:39 ` [PATCH v6 02/11] x86/vmx: add Intel PT MSR definitions Michał Leszczyński
2020-07-07 19:39 ` [PATCH v6 03/11] x86/vmx: add IPT cpu feature Michał Leszczyński
2020-07-15 10:02 ` Roger Pau Monné
2020-08-07 14:22 ` Jan Beulich
2020-07-07 19:39 ` [PATCH v6 04/11] common: add vmtrace_pt_size domain parameter Michał Leszczyński
2020-07-15 15:08 ` Roger Pau Monné
2020-08-07 14:29 ` Jan Beulich
2020-07-07 19:39 ` [PATCH v6 05/11] tools/libxl: add vmtrace_pt_size parameter Michał Leszczyński
2020-07-15 15:17 ` Roger Pau Monné
2020-07-07 19:39 ` [PATCH v6 06/11] x86/hvm: processor trace interface in HVM Michał Leszczyński
2020-07-15 15:43 ` Roger Pau Monné
2020-08-07 14:37 ` Jan Beulich
2020-07-07 19:39 ` [PATCH v6 07/11] x86/vmx: implement IPT in VMX Michał Leszczyński
2020-07-15 16:04 ` Roger Pau Monné [this message]
2020-08-07 15:00 ` Jan Beulich
2020-07-07 19:39 ` [PATCH v6 08/11] x86/mm: add vmtrace_buf resource type Michał Leszczyński
2020-07-15 17:20 ` Roger Pau Monné
2020-07-07 19:39 ` [PATCH v6 09/11] x86/domctl: add XEN_DOMCTL_vmtrace_op Michał Leszczyński
2020-07-15 17:32 ` Roger Pau Monné
2020-08-27 14:54 ` Jan Beulich
2020-07-07 19:39 ` [PATCH v6 10/11] tools/libxc: add xc_vmtrace_* functions Michał Leszczyński
2020-07-16 8:26 ` Roger Pau Monné
2020-07-07 19:39 ` [PATCH v6 11/11] tools/proctrace: add proctrace tool Michał Leszczyński
2020-07-16 8:42 ` Roger Pau Monné
2020-07-14 13:11 ` [PATCH v6 00/11] Implement support for external IPT monitoring Michał Leszczyński
2020-07-14 15:05 ` Roger Pau Monné
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200715160430.GE7191@Air-de-Roger \
--to=roger.pau@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=jun.nakajima@intel.com \
--cc=kevin.tian@intel.com \
--cc=luwei.kang@intel.com \
--cc=michal.leszczynski@cert.pl \
--cc=tamas.lengyel@intel.com \
--cc=wl@xen.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.