From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Ed White <edmund.h.white@intel.com>, xen-devel@lists.xen.org
Cc: Ravi Sahita <ravi.sahita@intel.com>,
Wei Liu <wei.liu2@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>, Tim Deegan <tim@xen.org>,
Jan Beulich <jbeulich@suse.com>,
tlengyel@novetta.com, Daniel De Graaf <dgdegra@tycho.nsa.gov>
Subject: Re: [PATCH v2 05/12] VMX/altp2m: add code to support EPTP switching and #VE.
Date: Wed, 24 Jun 2015 12:59:58 +0100 [thread overview]
Message-ID: <558A9BBE.3050804@citrix.com> (raw)
In-Reply-To: <1434999372-3688-6-git-send-email-edmund.h.white@intel.com>
On 22/06/15 19:56, Ed White wrote:
> Implement and hook up the code to enable VMX support of VMFUNC and #VE.
>
> VMFUNC leaf 0 (EPTP switching) emulation is added in a later patch.
>
> Signed-off-by: Ed White <edmund.h.white@intel.com>
> ---
> xen/arch/x86/hvm/vmx/vmx.c | 132 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 132 insertions(+)
>
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 2d3ad63..e8d9c82 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -56,6 +56,7 @@
> #include <asm/debugger.h>
> #include <asm/apic.h>
> #include <asm/hvm/nestedhvm.h>
> +#include <asm/hvm/altp2mhvm.h>
> #include <asm/event.h>
> #include <asm/monitor.h>
> #include <public/arch-x86/cpuid.h>
> @@ -1763,6 +1764,100 @@ static void vmx_enable_msr_exit_interception(struct domain *d)
> MSR_TYPE_W);
> }
>
> +static void vmx_vcpu_update_eptp(struct vcpu *v)
> +{
> + struct domain *d = v->domain;
> + struct p2m_domain *p2m = NULL;
> + struct ept_data *ept;
> +
> + if ( altp2mhvm_active(d) )
> + p2m = p2m_get_altp2m(v);
> + if ( !p2m )
> + p2m = p2m_get_hostp2m(d);
> +
> + ept = &p2m->ept;
> + ept->asr = pagetable_get_pfn(p2m_get_pagetable(p2m));
> +
> + vmx_vmcs_enter(v);
> +
> + __vmwrite(EPT_POINTER, ept_get_eptp(ept));
> +
> + if ( v->arch.hvm_vmx.secondary_exec_control &
> + SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS )
> + __vmwrite(EPTP_INDEX, vcpu_altp2mhvm(v).p2midx);
> +
> + vmx_vmcs_exit(v);
> +}
> +
> +static void vmx_vcpu_update_vmfunc_ve(struct vcpu *v)
> +{
> + struct domain *d = v->domain;
> + u32 mask = SECONDARY_EXEC_ENABLE_VM_FUNCTIONS;
> +
> + if ( !cpu_has_vmx_vmfunc )
> + return;
> +
> + if ( cpu_has_vmx_virt_exceptions )
> + mask |= SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS;
> +
> + vmx_vmcs_enter(v);
> +
> + if ( !d->is_dying && altp2mhvm_active(d) )
> + {
> + v->arch.hvm_vmx.secondary_exec_control |= mask;
> + __vmwrite(VM_FUNCTION_CONTROL, VMX_VMFUNC_EPTP_SWITCHING);
> + __vmwrite(EPTP_LIST_ADDR, virt_to_maddr(d->arch.altp2m_eptp));
> +
> + if ( cpu_has_vmx_virt_exceptions )
> + {
> + p2m_type_t t;
> + mfn_t mfn;
> +
> + mfn = get_gfn_query_unlocked(d, vcpu_altp2mhvm(v).veinfo_gfn, &t);
get_gfn_query_unlocked() returns _mfn(INVALID_MFN) in the failure case,
which you must not blindly write back.
> + __vmwrite(VIRT_EXCEPTION_INFO, mfn_x(mfn) << PAGE_SHIFT);
pfn_to_paddr() please, rather than opencoding it. (This is a helper
which needs cleaning up, name-wise).
> + }
> + }
> + else
> + v->arch.hvm_vmx.secondary_exec_control &= ~mask;
> +
> + __vmwrite(SECONDARY_VM_EXEC_CONTROL,
> + v->arch.hvm_vmx.secondary_exec_control);
> +
> + vmx_vmcs_exit(v);
> +}
> +
> +static bool_t vmx_vcpu_emulate_ve(struct vcpu *v)
> +{
> + bool_t rc = 0;
> + ve_info_t *veinfo = vcpu_altp2mhvm(v).veinfo_gfn ?
> + hvm_map_guest_frame_rw(vcpu_altp2mhvm(v).veinfo_gfn, 0) : NULL;
gfn 0 is a valid (albeit unlikely) location to request the veinfo page.
Use GFN_INVALID as the sentinel.
> +
> + if ( !veinfo )
> + return 0;
> +
> + if ( veinfo->semaphore != 0 )
> + goto out;
The semantics of this semaphore are not clearly spelled out in the
manual. The only information I can locate concerning this field is in
note in 25.5.6.1 which says:
"Delivery of virtualization exceptions writes the value FFFFFFFFH to
offset 4 in the virtualization-exception informa-
tion area (see Section 25.5.6.2). Thus, once a virtualization exception
occurs, another can occur only if software
clears this field."
I presume this should be taken to mean "software writes 0 to this
field", but some clarification would be nice.
> +
> + rc = 1;
> +
> + veinfo->exit_reason = EXIT_REASON_EPT_VIOLATION;
> + veinfo->semaphore = ~0l;
semaphore is declared as an unsigned field, so should use ~0u.
> + veinfo->eptp_index = vcpu_altp2mhvm(v).p2midx;
> +
> + vmx_vmcs_enter(v);
> + __vmread(EXIT_QUALIFICATION, &veinfo->exit_qualification);
> + __vmread(GUEST_LINEAR_ADDRESS, &veinfo->gla);
> + __vmread(GUEST_PHYSICAL_ADDRESS, &veinfo->gpa);
> + vmx_vmcs_exit(v);
> +
> + hvm_inject_hw_exception(TRAP_virtualisation,
> + HVM_DELIVER_NO_ERROR_CODE);
> +
> +out:
> + hvm_unmap_guest_frame(veinfo, 0);
> + return rc;
> +}
> +
> static struct hvm_function_table __initdata vmx_function_table = {
> .name = "VMX",
> .cpu_up_prepare = vmx_cpu_up_prepare,
> @@ -1822,6 +1917,9 @@ static struct hvm_function_table __initdata vmx_function_table = {
> .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,
> + .ahvm_vcpu_update_eptp = vmx_vcpu_update_eptp,
> + .ahvm_vcpu_update_vmfunc_ve = vmx_vcpu_update_vmfunc_ve,
> + .ahvm_vcpu_emulate_ve = vmx_vcpu_emulate_ve,
> };
>
> const struct hvm_function_table * __init start_vmx(void)
> @@ -2754,6 +2852,40 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
>
> /* Now enable interrupts so it's safe to take locks. */
> local_irq_enable();
> +
> + /*
> + * If the guest has the ability to switch EPTP without an exit,
> + * figure out whether it has done so and update the altp2m data.
> + */
> + if ( altp2mhvm_active(v->domain) &&
> + (v->arch.hvm_vmx.secondary_exec_control &
> + SECONDARY_EXEC_ENABLE_VM_FUNCTIONS) )
> + {
> + unsigned long idx;
> +
> + if ( v->arch.hvm_vmx.secondary_exec_control &
> + SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS )
> + __vmread(EPTP_INDEX, &idx);
> + else
> + {
> + unsigned long eptp;
> +
> + __vmread(EPT_POINTER, &eptp);
> +
> + if ( !p2m_find_altp2m_by_eptp(v->domain, eptp, &idx) )
> + {
> + gdprintk(XENLOG_ERR, "EPTP not found in alternate p2m list\n");
> + domain_crash(v->domain);
> + }
> + }
> +
Is it worth checking that idx is plausible at this point, before blindly
writing it back into the vcpu structure?
~Andrew
> + if ( (uint16_t)idx != vcpu_altp2mhvm(v).p2midx )
> + {
> + atomic_dec(&p2m_get_altp2m(v)->active_vcpus);
> + vcpu_altp2mhvm(v).p2midx = (uint16_t)idx;
> + atomic_inc(&p2m_get_altp2m(v)->active_vcpus);
> + }
> + }
>
> /* XXX: This looks ugly, but we need a mechanism to ensure
> * any pending vmresume has really happened
next prev parent reply other threads:[~2015-06-24 11:59 UTC|newest]
Thread overview: 116+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-22 18:56 [PATCH v2 00/12] Alternate p2m: support multiple copies of host p2m Ed White
2015-06-22 18:56 ` [PATCH v2 01/12] VMX: VMFUNC and #VE definitions and detection Ed White
2015-06-24 8:45 ` Andrew Cooper
2015-06-22 18:56 ` [PATCH v2 02/12] VMX: implement suppress #VE Ed White
2015-06-24 9:35 ` Andrew Cooper
2015-06-29 14:20 ` George Dunlap
2015-06-29 14:31 ` Andrew Cooper
2015-06-29 15:03 ` George Dunlap
2015-06-29 16:21 ` Sahita, Ravi
2015-06-29 16:21 ` Ed White
2015-06-22 18:56 ` [PATCH v2 03/12] x86/HVM: Hardware alternate p2m support detection Ed White
2015-06-24 9:44 ` Andrew Cooper
2015-06-24 10:07 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 04/12] x86/altp2m: basic data structures and support routines Ed White
2015-06-24 10:06 ` Andrew Cooper
2015-06-24 10:23 ` Jan Beulich
2015-06-24 17:20 ` Ed White
2015-06-24 10:29 ` Andrew Cooper
2015-06-24 11:14 ` Andrew Cooper
2015-06-26 21:17 ` Ed White
2015-06-27 19:25 ` Ed White
2015-06-29 13:00 ` Andrew Cooper
2015-06-29 16:23 ` Ed White
2015-06-24 14:44 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 05/12] VMX/altp2m: add code to support EPTP switching and #VE Ed White
2015-06-24 11:59 ` Andrew Cooper [this message]
2015-06-24 17:31 ` Ed White
2015-06-24 17:40 ` Andrew Cooper
2015-06-22 18:56 ` [PATCH v2 06/12] VMX: add VMFUNC leaf 0 (EPTP switching) to emulator Ed White
2015-06-24 12:47 ` Andrew Cooper
2015-06-24 20:29 ` Ed White
2015-06-25 8:26 ` Jan Beulich
2015-06-24 14:26 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 07/12] x86/altp2m: add control of suppress_ve Ed White
2015-06-24 13:05 ` Andrew Cooper
2015-06-24 14:38 ` Jan Beulich
2015-06-24 17:53 ` Ed White
2015-06-25 8:12 ` Jan Beulich
2015-06-25 16:36 ` Ed White
2015-06-26 6:04 ` Jan Beulich
2015-06-26 16:27 ` Ed White
2015-07-06 17:12 ` George Dunlap
2015-07-06 17:35 ` Ed White
2015-07-06 18:29 ` George Dunlap
2015-07-06 18:43 ` Ed White
2015-07-07 10:10 ` George Dunlap
2015-07-07 16:24 ` Ed White
2015-07-07 17:33 ` George Dunlap
2015-07-07 17:38 ` Sahita, Ravi
2015-07-08 7:24 ` Jan Beulich
2015-07-08 10:12 ` Tim Deegan
2015-07-08 12:51 ` George Dunlap
2015-07-08 7:23 ` Jan Beulich
2015-07-07 8:04 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 08/12] x86/altp2m: alternate p2m memory events Ed White
2015-06-24 13:09 ` Andrew Cooper
2015-06-24 16:01 ` Lengyel, Tamas
2015-06-24 18:02 ` Ed White
2015-06-22 18:56 ` [PATCH v2 09/12] x86/altp2m: add remaining support routines Ed White
2015-06-23 18:15 ` Lengyel, Tamas
2015-06-23 18:52 ` Ed White
2015-06-23 19:35 ` Lengyel, Tamas
2015-06-24 13:46 ` Andrew Cooper
2015-06-24 17:47 ` Ed White
2015-06-24 18:19 ` Andrew Cooper
2015-06-26 16:30 ` Ed White
2015-06-29 13:03 ` Andrew Cooper
2015-06-29 16:24 ` Ed White
2015-06-24 16:15 ` Lengyel, Tamas
2015-06-24 18:06 ` Ed White
2015-06-25 8:52 ` Ian Campbell
2015-06-25 16:27 ` Ed White
2015-06-25 12:44 ` Lengyel, Tamas
2015-06-25 13:40 ` Razvan Cojocaru
2015-06-25 16:48 ` Ed White
2015-06-25 17:39 ` Sahita, Ravi
2015-06-25 18:22 ` Razvan Cojocaru
2015-06-25 18:23 ` Lengyel, Tamas
2015-06-25 20:46 ` Ed White
2015-06-25 22:45 ` Lengyel, Tamas
2015-06-25 23:10 ` Ed White
2015-06-25 2:44 ` Lengyel, Tamas
2015-06-25 16:31 ` Ed White
2015-06-25 17:42 ` Lengyel, Tamas
2015-06-25 20:27 ` Ed White
2015-06-25 21:33 ` Lengyel, Tamas
2015-06-22 18:56 ` [PATCH v2 10/12] x86/altp2m: define and implement alternate p2m HVMOP types Ed White
2015-06-24 13:58 ` Andrew Cooper
2015-06-24 14:53 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 11/12] x86/altp2m: Add altp2mhvm HVM domain parameter Ed White
2015-06-24 14:06 ` Andrew Cooper
2015-06-24 14:59 ` Jan Beulich
2015-06-24 17:57 ` Ed White
2015-06-24 18:08 ` Andrew Cooper
2015-06-25 8:34 ` Jan Beulich
2015-06-25 8:33 ` Jan Beulich
2015-06-22 18:56 ` [PATCH v2 12/12] x86/altp2m: XSM hooks for altp2m HVM ops Ed White
2015-06-26 19:24 ` Daniel De Graaf
2015-06-26 19:35 ` Ed White
2015-06-29 17:52 ` Daniel De Graaf
2015-06-29 17:55 ` Sahita, Ravi
2015-06-23 21:27 ` [PATCH v2 00/12] Alternate p2m: support multiple copies of host p2m Lengyel, Tamas
2015-06-23 22:25 ` Ed White
2015-06-24 5:39 ` Razvan Cojocaru
2015-06-24 13:32 ` Lengyel, Tamas
2015-06-24 13:37 ` Razvan Cojocaru
2015-06-24 16:43 ` Ed White
2015-06-24 21:34 ` Lengyel, Tamas
2015-06-24 22:02 ` Ed White
2015-06-24 22:45 ` Lengyel, Tamas
2015-06-24 22:55 ` Ed White
2015-06-25 9:00 ` Andrew Cooper
2015-06-25 16:38 ` Ed White
2015-06-25 17:29 ` Lengyel, Tamas
2015-06-25 20:34 ` Ed White
2015-06-24 14:10 ` Andrew Cooper
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=558A9BBE.3050804@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=edmund.h.white@intel.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=ravi.sahita@intel.com \
--cc=tim@xen.org \
--cc=tlengyel@novetta.com \
--cc=wei.liu2@citrix.com \
--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.