From: Kai Huang <kai.huang@linux.intel.com>
To: "Tian, Kevin" <kevin.tian@intel.com>,
"andrew.cooper3@citrix.com" <andrew.cooper3@citrix.com>,
"tim@xen.org" <tim@xen.org>,
"jbeulich@suse.com" <jbeulich@suse.com>,
"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Subject: Re: [v2 06/11] vmx: add help functions to support PML
Date: Fri, 17 Apr 2015 11:15:54 +0800 [thread overview]
Message-ID: <55307AEA.3060308@linux.intel.com> (raw)
In-Reply-To: <AADFC41AFE54684AB9EE6CBC0274A5D126211C21@SHSMSX101.ccr.corp.intel.com>
On 04/17/2015 06:57 AM, Tian, Kevin wrote:
>> From: Kai Huang [mailto:kai.huang@linux.intel.com]
>> Sent: Wednesday, April 15, 2015 3:04 PM
>>
>> This patch adds help functions to enable/disable PML, and flush PML buffer for
>> single vcpu and particular domain for further use.
>>
>> Signed-off-by: Kai Huang <kai.huang@linux.intel.com>
>> ---
>> xen/arch/x86/hvm/vmx/vmcs.c | 178
>> +++++++++++++++++++++++++++++++++++++
>> xen/include/asm-x86/hvm/vmx/vmcs.h | 9 ++
>> 2 files changed, 187 insertions(+)
>>
>> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
>> index d120370..d3cb50f 100644
>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>> @@ -1328,6 +1328,184 @@ void vmx_clear_eoi_exit_bitmap(struct vcpu *v,
>> u8 vector)
>> &v->arch.hvm_vmx.eoi_exitmap_changed);
>> }
>>
>> +bool_t vmx_vcpu_pml_enabled(const struct vcpu *v)
>> +{
>> + return !!(v->arch.hvm_vmx.secondary_exec_control &
>> + SECONDARY_EXEC_ENABLE_PML);
>> +}
>> +
>> +int vmx_vcpu_enable_pml(struct vcpu *v)
>> +{
>> + struct domain *d = v->domain;
>> +
>> + if ( vmx_vcpu_pml_enabled(v) )
>> + return 0;
>> +
>> + v->arch.hvm_vmx.pml_pg = d->arch.paging.alloc_page(d);
>> + if ( !v->arch.hvm_vmx.pml_pg )
>> + return -ENOMEM;
>> +
>> + vmx_vmcs_enter(v);
>> +
>> + __vmwrite(PML_ADDRESS, page_to_mfn(v->arch.hvm_vmx.pml_pg) <<
>> PAGE_SHIFT);
>> + __vmwrite(GUEST_PML_INDEX, NR_PML_ENTRIES - 1);
>> +
>> + v->arch.hvm_vmx.secondary_exec_control |=
>> SECONDARY_EXEC_ENABLE_PML;
>> +
>> + __vmwrite(SECONDARY_VM_EXEC_CONTROL,
>> + v->arch.hvm_vmx.secondary_exec_control);
>> +
>> + vmx_vmcs_exit(v);
>> +
>> + return 0;
>> +}
>> +
>> +void vmx_vcpu_disable_pml(struct vcpu *v)
>> +{
>> + if ( !vmx_vcpu_pml_enabled(v) )
>> + return;
>> +
>> + /* Make sure we don't lose any logged GPAs */
>> + vmx_vcpu_flush_pml_buffer(v);
>> +
>> + vmx_vmcs_enter(v);
>> +
>> + v->arch.hvm_vmx.secondary_exec_control &=
>> ~SECONDARY_EXEC_ENABLE_PML;
>> + __vmwrite(SECONDARY_VM_EXEC_CONTROL,
>> + v->arch.hvm_vmx.secondary_exec_control);
>> +
>> + vmx_vmcs_exit(v);
>> +
>> + v->domain->arch.paging.free_page(v->domain,
>> v->arch.hvm_vmx.pml_pg);
>> + v->arch.hvm_vmx.pml_pg = NULL;
>> +}
>> +
>> +void vmx_vcpu_flush_pml_buffer(struct vcpu *v)
>> +{
>> + uint64_t *pml_buf;
>> + unsigned long pml_idx;
>> +
>> + ASSERT(vmx_vcpu_pml_enabled(v));
>> +
>> + vmx_vmcs_enter(v);
>> +
>> + __vmread(GUEST_PML_INDEX, &pml_idx);
>> +
>> + /* Do nothing if PML buffer is empty */
>> + if ( pml_idx == (NR_PML_ENTRIES - 1) )
>> + goto out;
>> +
>> + pml_buf = __map_domain_page(v->arch.hvm_vmx.pml_pg);
>> +
>> + /*
>> + * PML index can be either 2^16-1 (buffer is full), or 0~511 (buffer is
>> not
> 0~NR_PML_ENTRIES-1
Will do.
>
>> + * full), and in latter case PML index always points to next available
>> + * entity.
>> + */
>> + if (pml_idx >= NR_PML_ENTRIES)
>> + pml_idx = 0;
>> + else
>> + pml_idx++;
>> +
>> + for ( ; pml_idx < NR_PML_ENTRIES; pml_idx++ )
>> + {
>> + unsigned long gfn = pml_buf[pml_idx] >> PAGE_SHIFT;
>> + /*
>> + * Need to change type from log-dirty to normal memory for
>> logged GFN.
>> + * hap_track_dirty_vram depends on it to work. And we really only
>> need
>> + * to mark GFNs which hve been successfully changed from
>> log-dirty to
>> + * normal memory to be dirty.
>> + */
>> + if ( !p2m_change_type_one(v->domain, gfn, p2m_ram_logdirty,
>> + p2m_ram_rw) )
>> + paging_mark_gfn_dirty(v->domain, gfn);
> Should we handle error from p2m_change_type_one and consequently
> making this flush function non-void?
>
>> + }
>> +
>> + unmap_domain_page(pml_buf);
>> +
>> + /* Reset PML index */
>> + __vmwrite(GUEST_PML_INDEX, NR_PML_ENTRIES - 1);
> Like Jan pointed out an assertion of vcpu status is required here otherwise
> blindly reset PML index may race with new logged entries from a running
> vcpu.
Yeah will do.
Thanks,
-Kai
>
>> +
>> +out:
>> + vmx_vmcs_exit(v);
>> +}
>> +
>> +bool_t vmx_domain_pml_enabled(const struct domain *d)
>> +{
>> + return !!(d->arch.hvm_domain.vmx.status &
>> VMX_DOMAIN_PML_ENABLED);
>> +}
>> +
>> +/*
>> + * This function enables PML for particular domain. It should be called when
>> + * domain is paused.
>> + *
>> + * PML needs to be enabled globally for all vcpus of the domain, as PML
>> buffer
>> + * and PML index are pre-vcpu, but EPT table is shared by vcpus, therefore
>> + * enabling PML on partial vcpus won't work.
>> + */
>> +int vmx_domain_enable_pml(struct domain *d)
>> +{
>> + struct vcpu *v;
>> + int rc;
>> +
>> + ASSERT(atomic_read(&d->pause_count));
>> +
>> + if ( vmx_domain_pml_enabled(d) )
>> + return 0;
>> +
>> + for_each_vcpu( d, v )
>> + if ( (rc = vmx_vcpu_enable_pml(v)) != 0 )
>> + goto error;
>> +
>> + d->arch.hvm_domain.vmx.status |= VMX_DOMAIN_PML_ENABLED;
> I didn't see how this domain-wise flag is useful. Or if we really
> want to go this way, you also need to clear this flag if vcpu pml
> enable is failed in vcpu hotplug phase, since the flag itself means
> all vcpus of the domain so we must keep this intention in all
> places.
>
>> +
>> + return 0;
>> +
>> +error:
>> + for_each_vcpu( d, v )
>> + if ( vmx_vcpu_pml_enabled(v) )
>> + vmx_vcpu_disable_pml(v);
>> + return rc;
>> +}
>> +
>> +/*
>> + * Disable PML for particular domain. Called when domain is paused.
>> + *
>> + * The same as enabling PML for domain, disabling PML should be done for
>> all
>> + * vcpus at once.
>> + */
>> +void vmx_domain_disable_pml(struct domain *d)
>> +{
>> + struct vcpu *v;
>> +
>> + ASSERT(atomic_read(&d->pause_count));
>> +
>> + if ( !vmx_domain_pml_enabled(d) )
>> + return;
>> +
>> + for_each_vcpu( d, v )
>> + vmx_vcpu_disable_pml(v);
>> +
>> + d->arch.hvm_domain.vmx.status &= ~VMX_DOMAIN_PML_ENABLED;
>> +}
>> +
>> +/*
>> + * Flush PML buffer of all vcpus, and update the logged dirty pages to
>> log-dirty
>> + * radix tree. Called when domain is paused.
>> + */
>> +void vmx_domain_flush_pml_buffers(struct domain *d)
>> +{
>> + struct vcpu *v;
>> +
>> + ASSERT(atomic_read(&d->pause_count));
>> +
>> + if ( !vmx_domain_pml_enabled(d) )
>> + return;
>> +
>> + for_each_vcpu( d, v )
>> + vmx_vcpu_flush_pml_buffer(v);
>> +}
>> +
>> int vmx_create_vmcs(struct vcpu *v)
>> {
>> struct arch_vmx_struct *arch_vmx = &v->arch.hvm_vmx;
>> diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h
>> b/xen/include/asm-x86/hvm/vmx/vmcs.h
>> index 2c679ac..ceb09bf 100644
>> --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
>> +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
>> @@ -498,6 +498,15 @@ static inline int vmx_add_host_load_msr(u32 msr)
>>
>> DECLARE_PER_CPU(bool_t, vmxon);
>>
>> +bool_t vmx_vcpu_pml_enabled(const struct vcpu *v);
>> +int vmx_vcpu_enable_pml(struct vcpu *v);
>> +void vmx_vcpu_disable_pml(struct vcpu *v);
>> +void vmx_vcpu_flush_pml_buffer(struct vcpu *v);
>> +bool_t vmx_domain_pml_enabled(const struct domain *d);
>> +int vmx_domain_enable_pml(struct domain *d);
>> +void vmx_domain_disable_pml(struct domain *d);
>> +void vmx_domain_flush_pml_buffers(struct domain *d);
>> +
>> #endif /* ASM_X86_HVM_VMX_VMCS_H__ */
>>
>> /*
>> --
>> 2.1.0
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2015-04-17 3:15 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-15 7:03 [v2 00/11] PML (Paging Modification Logging) support Kai Huang
2015-04-15 7:03 ` [v2 01/11] vmx: add new boot parameter to control PML enabling Kai Huang
2015-04-15 10:12 ` Andrew Cooper
2015-04-15 12:20 ` Jan Beulich
2015-04-15 13:20 ` Kai Huang
2015-04-15 13:47 ` Jan Beulich
2015-04-15 7:03 ` [v2 02/11] doc: add description for new PML boot parameter Kai Huang
2015-04-15 10:15 ` Andrew Cooper
2015-04-15 12:17 ` Jan Beulich
2015-04-16 4:47 ` Kai Huang
2015-04-16 14:49 ` Andrew Cooper
2015-04-15 7:03 ` [v2 03/11] log-dirty: add new paging_mark_gfn_dirty Kai Huang
2015-04-15 7:03 ` [v2 04/11] vmx: add PML definition and feature detection Kai Huang
2015-04-16 22:35 ` Tian, Kevin
2015-04-17 2:14 ` Kai Huang
2015-04-15 7:03 ` [v2 05/11] vmx: add new data structure member to support PML Kai Huang
2015-04-16 15:33 ` Jan Beulich
2015-04-17 2:12 ` Kai Huang
2015-04-16 22:39 ` Tian, Kevin
2015-04-17 2:31 ` Kai Huang
2015-04-21 6:04 ` Kai Huang
2015-04-21 13:10 ` Tian, Kevin
2015-04-15 7:03 ` [v2 06/11] vmx: add help functions " Kai Huang
2015-04-16 15:42 ` Jan Beulich
2015-04-17 3:10 ` Kai Huang
2015-04-17 6:23 ` Jan Beulich
2015-04-17 6:51 ` Kai Huang
2015-04-17 6:58 ` Jan Beulich
2015-04-17 7:23 ` Kai Huang
2015-04-17 7:37 ` Jan Beulich
2015-04-17 7:45 ` Kai Huang
2015-04-24 6:32 ` Kai Huang
2015-04-24 7:30 ` Jan Beulich
2015-04-24 7:41 ` Kai Huang
2015-04-16 22:57 ` Tian, Kevin
2015-04-17 0:10 ` Tim Deegan
2015-04-17 3:32 ` Kai Huang
2015-04-17 8:36 ` Tim Deegan
2015-04-17 9:29 ` Kai Huang
2015-04-20 8:29 ` Tim Deegan
2015-04-20 10:08 ` Kai Huang
2015-04-20 10:13 ` Tim Deegan
2015-04-17 3:15 ` Kai Huang [this message]
2015-04-16 22:59 ` Tian, Kevin
2015-04-15 7:03 ` [v2 07/11] vmx: handle PML buffer full VMEXIT Kai Huang
2015-04-15 7:03 ` [v2 08/11] vmx: handle PML enabling in vmx_vcpu_initialise Kai Huang
2015-04-15 7:03 ` [v2 09/11] vmx: disable PML in vmx_vcpu_destroy Kai Huang
2015-04-15 7:03 ` [v2 10/11] log-dirty: refine common code to support PML Kai Huang
2015-04-16 15:51 ` Jan Beulich
2015-04-16 23:07 ` Tian, Kevin
2015-04-17 2:47 ` Kai Huang
2015-04-17 2:46 ` Kai Huang
2015-04-17 6:28 ` Jan Beulich
2015-04-17 6:55 ` Kai Huang
2015-04-15 7:03 ` [v2 11/11] p2m/ept: enable PML in p2m-ept for log-dirty Kai Huang
2015-04-16 15:54 ` Jan Beulich
2015-04-17 2:40 ` Kai Huang
2015-04-17 6:28 ` Jan Beulich
2015-04-17 7:10 ` Kai Huang
2015-04-17 7:33 ` Jan Beulich
2015-04-16 14:41 ` [v2 00/11] PML (Paging Modification Logging) support Tim Deegan
2015-04-16 15:18 ` Kai Huang
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=55307AEA.3060308@linux.intel.com \
--to=kai.huang@linux.intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=kevin.tian@intel.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.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.