[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 05/11] x86/altp2m: basic data structures and support routines.



On 09/01/15 21:26, Ed White wrote:
> Add the basic data structures needed to support alternate p2m's and
> the functions to initialise them and tear them down.
>
> Although Intel hardware can handle 512 EPTP's per hardware thread
> concurrently, only 10 per domain are supported in this patch for
> performance reasons.
>
> The iterator in hap_enable() does need to handle 512, so that is now
> uint16_t.
>
> Signed-off-by: Ed White <edmund.h.white@xxxxxxxxx>
> ---
>  xen/arch/x86/hvm/Makefile           |   3 +-
>  xen/arch/x86/hvm/altp2mhvm.c        |  77 +++++++++++++++++++++++++++
>  xen/arch/x86/hvm/hvm.c              |  21 ++++++++
>  xen/arch/x86/mm/hap/Makefile        |   1 +
>  xen/arch/x86/mm/hap/altp2m_hap.c    |  66 +++++++++++++++++++++++
>  xen/arch/x86/mm/hap/hap.c           |  30 ++++++++++-
>  xen/arch/x86/mm/mm-locks.h          |   4 ++
>  xen/arch/x86/mm/p2m.c               | 102 
> ++++++++++++++++++++++++++++++++++++
>  xen/include/asm-x86/domain.h        |   7 +++
>  xen/include/asm-x86/hvm/altp2mhvm.h |  36 +++++++++++++
>  xen/include/asm-x86/hvm/hvm.h       |  17 ++++++
>  xen/include/asm-x86/hvm/vcpu.h      |   9 ++++
>  xen/include/asm-x86/p2m.h           |  22 ++++++++
>  13 files changed, 393 insertions(+), 2 deletions(-)
>  create mode 100644 xen/arch/x86/hvm/altp2mhvm.c
>  create mode 100644 xen/arch/x86/mm/hap/altp2m_hap.c
>  create mode 100644 xen/include/asm-x86/hvm/altp2mhvm.h
>
> diff --git a/xen/arch/x86/hvm/Makefile b/xen/arch/x86/hvm/Makefile
> index eea5555..5bf8b4f 100644
> --- a/xen/arch/x86/hvm/Makefile
> +++ b/xen/arch/x86/hvm/Makefile
> @@ -22,4 +22,5 @@ obj-y += vlapic.o
>  obj-y += vmsi.o
>  obj-y += vpic.o
>  obj-y += vpt.o
> -obj-y += vpmu.o
> \ No newline at end of file
> +obj-y += vpmu.o
> +obj-y += altp2mhvm.o
> diff --git a/xen/arch/x86/hvm/altp2mhvm.c b/xen/arch/x86/hvm/altp2mhvm.c
> new file mode 100644
> index 0000000..fa0af0c
> --- /dev/null
> +++ b/xen/arch/x86/hvm/altp2mhvm.c
> @@ -0,0 +1,77 @@
> +/*
> + * Alternate p2m HVM
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program; if not, write to the Free Software Foundation, Inc., 59 
> Temple
> + * Place - Suite 330, Boston, MA 02111-1307 USA.
> + */
> +
> +#include <asm/hvm/support.h>
> +#include <asm/hvm/hvm.h>
> +#include <asm/p2m.h>
> +#include <asm/hvm/altp2mhvm.h>
> +
> +void
> +altp2mhvm_vcpu_reset(struct vcpu *v)
> +{
> +    struct altp2mvcpu *av = &vcpu_altp2mhvm(v);
> +
> +    av->p2midx = 0;
> +    av->veinfo = 0;
> +
> +    if ( hvm_funcs.ahvm_vcpu_reset )
> +        hvm_funcs.ahvm_vcpu_reset(v);
> +}
> +
> +int
> +altp2mhvm_vcpu_initialise(struct vcpu *v)
> +{
> +    int rc = -EOPNOTSUPP;
> +
> +    if ( v != current )
> +        vcpu_pause(v);

Under what circumstances would a vcpu initialisation happen on current? 
All initialisation should happen during domain creation.

> +
> +    if ( !hvm_funcs.ahvm_vcpu_initialise ||
> +         (hvm_funcs.ahvm_vcpu_initialise(v) == 0) )
> +    {
> +        rc = 0;
> +        altp2mhvm_vcpu_reset(v);
> +        cpumask_set_cpu(v->vcpu_id, p2m_get_altp2m(v)->dirty_cpumask);
> +
> +        ahvm_vcpu_update_eptp(v);
> +    }
> +
> +    if ( v != current )
> +        vcpu_unpause(v);
> +
> +    return rc;
> +}
> +
> +void
> +altp2mhvm_vcpu_destroy(struct vcpu *v)
> +{
> +    if ( v != current )
> +        vcpu_pause(v);
> +
> +    if ( hvm_funcs.ahvm_vcpu_destroy )
> +        hvm_funcs.ahvm_vcpu_destroy(v);
> +
> +    cpumask_clear_cpu(v->processor, p2m_get_altp2m(v)->dirty_cpumask);
> +    altp2mhvm_vcpu_reset(v);
> +
> +    ahvm_vcpu_update_eptp(v);
> +    ahvm_vcpu_update_vmfunc_ve(v);
> +
> +    if ( v != current )
> +        vcpu_unpause(v);
> +}
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index b89e9d2..e8787cc 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -60,6 +60,7 @@
>  #include <asm/hvm/cacheattr.h>
>  #include <asm/hvm/trace.h>
>  #include <asm/hvm/nestedhvm.h>
> +#include <asm/hvm/altp2mhvm.h>
>  #include <asm/mtrr.h>
>  #include <asm/apic.h>
>  #include <public/sched.h>
> @@ -2290,6 +2291,7 @@ void hvm_vcpu_destroy(struct vcpu *v)
>  
>      hvm_all_ioreq_servers_remove_vcpu(d, v);
>  
> +    altp2mhvm_vcpu_destroy(v);
>      nestedhvm_vcpu_destroy(v);
>  
>      free_compat_arg_xlat(v);
> @@ -6377,6 +6379,25 @@ bool_t hvm_altp2m_supported()
>      return hvm_funcs.altp2m_supported;
>  }
>  
> +void ahvm_vcpu_update_eptp(struct vcpu *v)
> +{
> +    if (hvm_funcs.ahvm_vcpu_update_eptp)
> +        hvm_funcs.ahvm_vcpu_update_eptp(v);
> +}
> +
> +void ahvm_vcpu_update_vmfunc_ve(struct vcpu *v)
> +{
> +    if (hvm_funcs.ahvm_vcpu_update_vmfunc_ve)
> +        hvm_funcs.ahvm_vcpu_update_vmfunc_ve(v);
> +}
> +
> +bool_t ahvm_vcpu_emulate_ve(struct vcpu *v)
> +{
> +    if (hvm_funcs.ahvm_vcpu_emulate_ve)
> +        return hvm_funcs.ahvm_vcpu_emulate_ve(v);
> +    return 0;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/arch/x86/mm/hap/Makefile b/xen/arch/x86/mm/hap/Makefile
> index 68f2bb5..216cd90 100644
> --- a/xen/arch/x86/mm/hap/Makefile
> +++ b/xen/arch/x86/mm/hap/Makefile
> @@ -4,6 +4,7 @@ obj-y += guest_walk_3level.o
>  obj-$(x86_64) += guest_walk_4level.o
>  obj-y += nested_hap.o
>  obj-y += nested_ept.o
> +obj-y += altp2m_hap.o
>  
>  guest_walk_%level.o: guest_walk.c Makefile
>       $(CC) $(CFLAGS) -DGUEST_PAGING_LEVELS=$* -c $< -o $@
> diff --git a/xen/arch/x86/mm/hap/altp2m_hap.c 
> b/xen/arch/x86/mm/hap/altp2m_hap.c
> new file mode 100644
> index 0000000..c2cdc42
> --- /dev/null
> +++ b/xen/arch/x86/mm/hap/altp2m_hap.c
> @@ -0,0 +1,66 @@
> +/******************************************************************************
> + * arch/x86/mm/hap/altp2m_hap.c
> + *
> + * Copyright (c) 2014 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#include <xen/mem_event.h>
> +#include <xen/event.h>
> +#include <public/mem_event.h>
> +#include <asm/domain.h>
> +#include <asm/page.h>
> +#include <asm/paging.h>
> +#include <asm/p2m.h>
> +#include <asm/mem_sharing.h>
> +#include <asm/hap.h>
> +#include <asm/hvm/support.h>
> +
> +#include "private.h"
> +
> +/* Override macros from asm/page.h to make them work with mfn_t */
> +#undef mfn_valid
> +#define mfn_valid(_mfn) __mfn_valid(mfn_x(_mfn))
> +#undef page_to_mfn
> +#define page_to_mfn(_pg) _mfn(__page_to_mfn(_pg))
> +
> +void
> +altp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
> +    l1_pgentry_t *p, l1_pgentry_t new, unsigned int level)
> +{
> +    struct domain *d = p2m->domain;
> +    uint32_t old_flags;
> +
> +    paging_lock(d);
> +
> +    old_flags = l1e_get_flags(*p);
> +    safe_write_pte(p, new);
> +
> +    if (old_flags & _PAGE_PRESENT)
> +        flush_tlb_mask(p2m->dirty_cpumask);
> +
> +    paging_unlock(d);
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
> index abf3d7a..8fe0650 100644
> --- a/xen/arch/x86/mm/hap/hap.c
> +++ b/xen/arch/x86/mm/hap/hap.c
> @@ -439,7 +439,7 @@ void hap_domain_init(struct domain *d)
>  int hap_enable(struct domain *d, u32 mode)
>  {
>      unsigned int old_pages;
> -    uint8_t i;
> +    uint16_t i;
>      int rv = 0;
>  
>      domain_pause(d);
> @@ -485,6 +485,23 @@ int hap_enable(struct domain *d, u32 mode)
>             goto out;
>      }
>  
> +    /* Init alternate p2m data */
> +    if ( (d->arch.altp2m_eptp = alloc_xenheap_page()) == NULL )

This memory should be allocated from some domain-accounted pool,
probably the paging pool (d->->arch.paging.alloc_page()).  You can use
map_domain_page_global() to get a safe pointer to anchor in
d->arch.altp2m_eptp for hardware.

> +    {
> +        rv = -ENOMEM;
> +        goto out;
> +    }
> +    for (i = 0; i < 512; i++)
> +        d->arch.altp2m_eptp[i] = ~0ul;
> +
> +    for (i = 0; i < MAX_ALTP2M; i++) {
> +        rv = p2m_alloc_table(d->arch.altp2m_p2m[i]);
> +        if ( rv != 0 )
> +           goto out;
> +    }
> +
> +    d->arch.altp2m_active = 0;
> +
>      /* Now let other users see the new mode */
>      d->arch.paging.mode = mode | PG_HAP_enable;
>  
> @@ -497,6 +514,17 @@ void hap_final_teardown(struct domain *d)
>  {
>      uint8_t i;
>  
> +    d->arch.altp2m_active = 0;
> +
> +    if ( d->arch.altp2m_eptp ) {
> +        free_xenheap_page(d->arch.altp2m_eptp);
> +        d->arch.altp2m_eptp = NULL;
> +    }
> +
> +    for (i = 0; i < MAX_ALTP2M; i++) {
> +        p2m_teardown(d->arch.altp2m_p2m[i]);
> +    }
> +
>      /* Destroy nestedp2m's first */
>      for (i = 0; i < MAX_NESTEDP2M; i++) {
>          p2m_teardown(d->arch.nested_p2m[i]);
> diff --git a/xen/arch/x86/mm/mm-locks.h b/xen/arch/x86/mm/mm-locks.h
> index 769f7bc..a0faca3 100644
> --- a/xen/arch/x86/mm/mm-locks.h
> +++ b/xen/arch/x86/mm/mm-locks.h
> @@ -209,6 +209,10 @@ declare_mm_lock(nestedp2m)
>  #define nestedp2m_lock(d)   mm_lock(nestedp2m, &(d)->arch.nested_p2m_lock)
>  #define nestedp2m_unlock(d) mm_unlock(&(d)->arch.nested_p2m_lock)
>  
> +declare_mm_lock(altp2m)
> +#define altp2m_lock(d)   mm_lock(altp2m, &(d)->arch.altp2m_lock)
> +#define altp2m_unlock(d) mm_unlock(&(d)->arch.altp2m_lock)
> +
>  /* P2M lock (per-p2m-table)
>   *
>   * This protects all queries and updates to the p2m table.
> diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
> index 49b66fb..3c6049b 100644
> --- a/xen/arch/x86/mm/p2m.c
> +++ b/xen/arch/x86/mm/p2m.c
> @@ -35,6 +35,7 @@
>  #include <asm/hvm/vmx/vmx.h> /* ept_p2m_init() */
>  #include <asm/mem_sharing.h>
>  #include <asm/hvm/nestedhvm.h>
> +#include <asm/hvm/altp2mhvm.h>
>  #include <asm/hvm/svm/amd-iommu-proto.h>
>  #include <xsm/xsm.h>
>  
> @@ -182,6 +183,44 @@ static void p2m_teardown_nestedp2m(struct domain *d)
>      }
>  }
>  
> +static void p2m_teardown_altp2m(struct domain *d);
> +
> +static int p2m_init_altp2m(struct domain *d)
> +{
> +    uint8_t i;
> +    struct p2m_domain *p2m;
> +
> +    mm_lock_init(&d->arch.altp2m_lock);
> +    for (i = 0; i < MAX_ALTP2M; i++)
> +    {
> +        d->arch.altp2m_p2m[i] = p2m = p2m_init_one(d);
> +        if ( p2m == NULL )
> +        {
> +            p2m_teardown_altp2m(d);
> +            return -ENOMEM;
> +        }
> +        p2m->write_p2m_entry = altp2m_write_p2m_entry;
> +        p2m->alternate = 1;
> +    }
> +
> +    return 0;
> +}
> +
> +static void p2m_teardown_altp2m(struct domain *d)
> +{
> +    uint8_t i;
> +    struct p2m_domain *p2m;
> +
> +    for (i = 0; i < MAX_ALTP2M; i++)
> +    {
> +        if ( !d->arch.altp2m_p2m[i] )
> +            continue;
> +        p2m = d->arch.altp2m_p2m[i];
> +        p2m_free_one(p2m);
> +        d->arch.altp2m_p2m[i] = NULL;
> +    }
> +}
> +
>  int p2m_init(struct domain *d)
>  {
>      int rc;
> @@ -195,7 +234,14 @@ int p2m_init(struct domain *d)
>       * (p2m_init runs too early for HVM_PARAM_* options) */
>      rc = p2m_init_nestedp2m(d);
>      if ( rc )
> +    {
>          p2m_teardown_hostp2m(d);
> +        return rc;
> +    }
> +
> +    rc = p2m_init_altp2m(d);
> +    if ( rc )
> +        p2m_teardown_altp2m(d);
>  
>      return rc;
>  }
> @@ -1891,6 +1937,62 @@ int unmap_mmio_regions(struct domain *d,
>      return err;
>  }
>  
> +bool_t p2m_find_altp2m_by_eptp(struct domain *d, uint64_t eptp, unsigned 
> long *idx)
> +{
> +    struct p2m_domain *p2m;
> +    struct ept_data *ept;
> +    bool_t rc = 0;
> +    uint16_t i;
> +
> +    altp2m_lock(d);
> +
> +    for ( i = 0; i < MAX_ALTP2M; i++ )
> +    {
> +        if ( d->arch.altp2m_eptp[i] == ~0ul )
> +            continue;
> +
> +        p2m = d->arch.altp2m_p2m[i];
> +        ept = &p2m->ept;
> +
> +        if ( eptp != ept_get_eptp(ept) )
> +            continue;
> +
> +        *idx = i;
> +        rc = 1;
> +
> +        break;
> +    }
> +
> +    altp2m_unlock(d);
> +    return rc;
> +}
> +
> +bool_t p2m_switch_vcpu_altp2m_by_id(struct vcpu *v, uint16_t idx)
> +{
> +    struct domain *d = v->domain;
> +    bool_t rc = 0;
> +
> +    if ( idx > MAX_ALTP2M )
> +        return rc;
> +
> +    altp2m_lock(d);
> +
> +    if ( d->arch.altp2m_eptp[idx] != ~0ul )
> +    {
> +        if ( idx != vcpu_altp2mhvm(v).p2midx )
> +        {
> +            cpumask_clear_cpu(v->vcpu_id, p2m_get_altp2m(v)->dirty_cpumask);
> +            vcpu_altp2mhvm(v).p2midx = idx;
> +            cpumask_set_cpu(v->vcpu_id, p2m_get_altp2m(v)->dirty_cpumask);
> +            ahvm_vcpu_update_eptp(v);
> +        }
> +        rc = 1;
> +    }
> +
> +    altp2m_unlock(d);
> +    return rc;
> +}
> +
>  /*** Audit ***/
>  
>  #if P2M_AUDIT
> diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
> index 6a77a93..a0e9e90 100644
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -230,6 +230,7 @@ struct paging_vcpu {
>  typedef xen_domctl_cpuid_t cpuid_input_t;
>  
>  #define MAX_NESTEDP2M 10
> +#define MAX_ALTP2M    10
>  struct p2m_domain;
>  struct time_scale {
>      int shift;
> @@ -274,6 +275,12 @@ struct arch_domain
>      struct p2m_domain *nested_p2m[MAX_NESTEDP2M];
>      mm_lock_t nested_p2m_lock;
>  
> +    /* altp2m: allow multiple copies of host p2m */
> +    bool_t altp2m_active;
> +    struct p2m_domain *altp2m_p2m[MAX_ALTP2M];
> +    mm_lock_t altp2m_lock;
> +    uint64_t *altp2m_eptp;
> +
>      /* NB. protected by d->event_lock and by irq_desc[irq].lock */
>      struct radix_tree_root irq_pirq;
>  
> diff --git a/xen/include/asm-x86/hvm/altp2mhvm.h 
> b/xen/include/asm-x86/hvm/altp2mhvm.h
> new file mode 100644
> index 0000000..919986e
> --- /dev/null
> +++ b/xen/include/asm-x86/hvm/altp2mhvm.h
> @@ -0,0 +1,36 @@
> +/*
> + * Alternate p2m HVM
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program; if not, write to the Free Software Foundation, Inc., 59 
> Temple
> + * Place - Suite 330, Boston, MA 02111-1307 USA.
> + */
> +
> +#ifndef _HVM_ALTP2M_H
> +#define _HVM_ALTP2M_H
> +
> +#include <xen/types.h>         /* for uintNN_t */
> +#include <xen/sched.h>         /* for struct vcpu, struct domain */
> +#include <asm/hvm/vcpu.h>      /* for vcpu_altp2mhvm */
> +
> +/* Alternate p2m HVM on/off per domain */
> +#define altp2mhvm_active(d) \
> +    d->arch.altp2m_active

static inline bool_t altp2mhvm_active(const struct domain *d)
{
    return d->arch.altp2m_active;
}

Type systems are a nice.  We should use them where possible.

> +
> +/* Alternate p2m VCPU */
> +int altp2mhvm_vcpu_initialise(struct vcpu *v);
> +void altp2mhvm_vcpu_destroy(struct vcpu *v);
> +void altp2mhvm_vcpu_reset(struct vcpu *v);
> +
> +#endif /* _HVM_ALTP2M_H */
> +
> diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
> index 7115a68..32d1d02 100644
> --- a/xen/include/asm-x86/hvm/hvm.h
> +++ b/xen/include/asm-x86/hvm/hvm.h
> @@ -210,6 +210,14 @@ struct hvm_function_table {
>                                    uint32_t *ecx, uint32_t *edx);
>  
>      void (*enable_msr_exit_interception)(struct domain *d);
> +
> +    /* Alternate p2m */
> +    int (*ahvm_vcpu_initialise)(struct vcpu *v);
> +    void (*ahvm_vcpu_destroy)(struct vcpu *v);
> +    int (*ahvm_vcpu_reset)(struct vcpu *v);
> +    void (*ahvm_vcpu_update_eptp)(struct vcpu *v);
> +    void (*ahvm_vcpu_update_vmfunc_ve)(struct vcpu *v);
> +    bool_t (*ahvm_vcpu_emulate_ve)(struct vcpu *v);
>  };
>  
>  extern struct hvm_function_table hvm_funcs;
> @@ -531,6 +539,15 @@ extern bool_t opt_hvm_fep;
>  #define opt_hvm_fep 0
>  #endif
>  
> +/* updates the current EPTP in VMCS */
> +void ahvm_vcpu_update_eptp(struct vcpu *v);
> +
> +/* updates VMCS fields related to VMFUNC and #VE */
> +void ahvm_vcpu_update_vmfunc_ve(struct vcpu *v);
> +
> +/* emulates #VE */
> +bool_t ahvm_vcpu_emulate_ve(struct vcpu *v);

These should be added in the patch which introduces them.

> +
>  #endif /* __ASM_X86_HVM_HVM_H__ */
>  
>  /*
> diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h
> index 01e0665..9302d40 100644
> --- a/xen/include/asm-x86/hvm/vcpu.h
> +++ b/xen/include/asm-x86/hvm/vcpu.h
> @@ -118,6 +118,13 @@ struct nestedvcpu {
>  
>  #define vcpu_nestedhvm(v) ((v)->arch.hvm_vcpu.nvcpu)
>  
> +struct altp2mvcpu {
> +    uint16_t    p2midx ;        /* alternate p2m index */

Stray space.

> +    uint64_t    veinfo;         /* #VE information page guest pfn */
> +};
> +
> +#define vcpu_altp2mhvm(v) ((v)->arch.hvm_vcpu.avcpu)

static inline as well please.

~Andrew

> +
>  struct hvm_vcpu {
>      /* Guest control-register and EFER values, just as the guest sees them. 
> */
>      unsigned long       guest_cr[5];
> @@ -163,6 +170,8 @@ struct hvm_vcpu {
>  
>      struct nestedvcpu   nvcpu;
>  
> +    struct altp2mvcpu   avcpu;
> +
>      struct mtrr_state   mtrr;
>      u64                 pat_cr;
>  
> diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
> index 8193901..9fb5ba0 100644
> --- a/xen/include/asm-x86/p2m.h
> +++ b/xen/include/asm-x86/p2m.h
> @@ -688,6 +688,28 @@ void nestedp2m_write_p2m_entry(struct p2m_domain *p2m, 
> unsigned long gfn,
>      l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);
>  
>  /*
> + * Alternate p2m: shadow p2m tables used for alternate memory views
> + */
> +
> +void altp2m_write_p2m_entry(struct p2m_domain *p2m, unsigned long gfn,
> +    l1_pgentry_t *p, l1_pgentry_t new, unsigned int level);
> +
> +/* get current alternate p2m table */
> +static inline struct p2m_domain *p2m_get_altp2m(struct vcpu *v)
> +{
> +    struct domain *d = v->domain;
> +    uint16_t index = vcpu_altp2mhvm(v).p2midx;
> +
> +    return d->arch.altp2m_p2m[index];
> +}
> +
> +/* Locate an alternate p2m by its EPTP */
> +bool_t p2m_find_altp2m_by_eptp(struct domain *d, uint64_t eptp, unsigned 
> long *idx);
> +
> +/* Switch alternate p2m for a single vcpu */
> +bool_t p2m_switch_vcpu_altp2m_by_id(struct vcpu *v, uint16_t idx);
> +
> +/*
>   * p2m type to IOMMU flags
>   */
>  static inline unsigned int p2m_get_iommu_flags(p2m_type_t p2mt)



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.