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

Re: [Xen-devel] [PATCH v5 1/3] xen/pvh: use a custom IO bitmap for PVH hardware domains



> From: Roger Pau Monne [mailto:roger.pau@xxxxxxxxxx]
> Sent: Thursday, May 07, 2015 10:54 PM
> 
> Since a PVH hardware domain has access to the physical hardware create a
> custom more permissive IO bitmap. The permissions set on the bitmap are
> populated based on the contents of the ioports rangeset.
> 
> Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx>
> Cc: Jan Beulich <jbeulich@xxxxxxxx>
> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> Cc: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
> Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@xxxxxxx>
> Cc: Jun Nakajima <jun.nakajima@xxxxxxxxx>
> Cc: Eddie Dong <eddie.dong@xxxxxxxxx>
> Cc: Kevin Tian <kevin.tian@xxxxxxxxx>

Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>

Thanks
Kevin

> ---
> Changes since v4:
>  - Split changes also affecting PV to a separate patch.
>  - Use int with __clear_bit.
>  - Drop pointless cast in vmcb.c.
>  - Make HVM_IOBITMAP_SIZE contain the size of the io bitmap pages in bytes.
>  - Make setup_io_bitmap a hardware domain specific function, and allow it to
>    work with late hw domain init.
> 
> Changes since v3:
>  - Add the RTC IO ports to the list of blocked ports.
>  - Remove admin_io_okay since it's just a wrapper around
>    ioports_access_permitted.
> 
> Changes since v2:
>  - Add 0xcf8-0xcfb to the range of blocked (trapped) IO ports.
>  - Use rangeset_report_ranges in order to iterate over the range of not
>    trapped IO ports.
>  - Allocate the Dom0 PVH IO bitmap with _xmalloc_array, which allows
> setting
>    the alignment to PAGE_SIZE.
>  - Tested with Linux PV/PVH using 3.18 and FreeBSD PVH HEAD.
> 
> Changes since v1:
>  - Dynamically allocate PVH Dom0 IO bitmap if needed.
>  - Drop cast from construct_vmcs when writing the IO bitmap.
>  - Create a new function that sets up the bitmap before launching Dom0. This
>    is needed because ns16550_endboot is called after construct_dom0.
> ---
>  xen/arch/x86/hvm/hvm.c           | 24 ++++++++++++++++++++++--
>  xen/arch/x86/hvm/svm/vmcb.c      |  2 +-
>  xen/arch/x86/hvm/vmx/vmcs.c      |  5 +++--
>  xen/arch/x86/setup.c             | 29
> +++++++++++++++++++++++++++++
>  xen/common/domain.c              |  2 ++
>  xen/include/asm-x86/hvm/domain.h |  2 ++
>  xen/include/asm-x86/setup.h      |  1 +
>  7 files changed, 60 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 3a09439..ea052c4 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -77,9 +77,13 @@ integer_param("hvm_debug", opt_hvm_debug_level);
> 
>  struct hvm_function_table hvm_funcs __read_mostly;
> 
> -/* I/O permission bitmap is globally shared by all HVM guests. */
> +#define HVM_IOBITMAP_SIZE   (3*PAGE_SIZE)
> +/*
> + * The I/O permission bitmap is globally shared by all HVM guests except
> + * the hardware domain that has a more permissive IO bitmap.
> + */
>  unsigned long __attribute__ ((__section__ (".bss.page_aligned")))
> -    hvm_io_bitmap[3*PAGE_SIZE/BYTES_PER_LONG];
> +    hvm_io_bitmap[HVM_IOBITMAP_SIZE/BYTES_PER_LONG];
> 
>  /* Xen command-line option to enable HAP */
>  static bool_t __initdata opt_hap_enabled = 1;
> @@ -1461,6 +1465,20 @@ int hvm_domain_initialise(struct domain *d)
>          goto fail1;
>      d->arch.hvm_domain.io_handler->num_slot = 0;
> 
> +    /* Set the default IO Bitmap */
> +    if ( is_hardware_domain(d) )
> +    {
> +        d->arch.hvm_domain.io_bitmap = _xmalloc(HVM_IOBITMAP_SIZE,
> PAGE_SIZE);
> +        if ( d->arch.hvm_domain.io_bitmap == NULL )
> +        {
> +            rc = -ENOMEM;
> +            goto fail1;
> +        }
> +        memset(d->arch.hvm_domain.io_bitmap, ~0,
> HVM_IOBITMAP_SIZE);
> +    }
> +    else
> +        d->arch.hvm_domain.io_bitmap = hvm_io_bitmap;
> +
>      if ( is_pvh_domain(d) )
>      {
>          register_portio_handler(d, 0, 0x10003, handle_pvh_io);
> @@ -1496,6 +1514,8 @@ int hvm_domain_initialise(struct domain *d)
>      stdvga_deinit(d);
>      vioapic_deinit(d);
>   fail1:
> +    if ( is_hardware_domain(d) )
> +        xfree(d->arch.hvm_domain.io_bitmap);
>      xfree(d->arch.hvm_domain.io_handler);
>      xfree(d->arch.hvm_domain.params);
>   fail0:
> diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
> index 21292bb..10afd44 100644
> --- a/xen/arch/x86/hvm/svm/vmcb.c
> +++ b/xen/arch/x86/hvm/svm/vmcb.c
> @@ -118,7 +118,7 @@ static int construct_vmcb(struct vcpu *v)
>          svm_disable_intercept_for_msr(v, MSR_AMD64_LWP_CBADDR);
> 
>      vmcb->_msrpm_base_pa = (u64)virt_to_maddr(arch_svm->msrpm);
> -    vmcb->_iopm_base_pa  = (u64)virt_to_maddr(hvm_io_bitmap);
> +    vmcb->_iopm_base_pa =
> virt_to_maddr(v->domain->arch.hvm_domain.io_bitmap);
> 
>      /* Virtualise EFLAGS.IF and LAPIC TPR (CR8). */
>      vmcb->_vintr.fields.intr_masking = 1;
> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
> index 3123706..f62aa90 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1032,8 +1032,9 @@ static int construct_vmcs(struct vcpu *v)
>      }
> 
>      /* I/O access bitmap. */
> -    __vmwrite(IO_BITMAP_A, virt_to_maddr((char *)hvm_io_bitmap + 0));
> -    __vmwrite(IO_BITMAP_B, virt_to_maddr((char *)hvm_io_bitmap +
> PAGE_SIZE));
> +    __vmwrite(IO_BITMAP_A,
> virt_to_maddr(d->arch.hvm_domain.io_bitmap));
> +    __vmwrite(IO_BITMAP_B,
> virt_to_maddr(d->arch.hvm_domain.io_bitmap +
> +                                         PAGE_SIZE /
> BYTES_PER_LONG));
> 
>      if ( cpu_has_vmx_virtual_intr_delivery )
>      {
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 2b9787a..3b9aee5 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -1446,6 +1446,9 @@ void __init noreturn __start_xen(unsigned long
> mbi_p)
> 
>      dmi_end_boot();
> 
> +    if ( is_hardware_domain(dom0) )
> +        setup_io_bitmap(dom0);
> +
>      system_state = SYS_STATE_active;
> 
>      domain_unpause_by_systemcontroller(dom0);
> @@ -1509,6 +1512,32 @@ int __hwdom_init xen_in_range(unsigned long
> mfn)
>      return 0;
>  }
> 
> +static int __hwdom_init io_bitmap_cb(unsigned long s, unsigned long e,
> +                                     void *ctx)
> +{
> +    struct domain *d = ctx;
> +    int i;
> +
> +    ASSERT(s <= INT_MAX && e <= INT_MAX);
> +    for ( i = s; i <= e; i++ )
> +        __clear_bit(i, d->arch.hvm_domain.io_bitmap);
> +
> +    return 0;
> +}
> +
> +void __hwdom_init setup_io_bitmap(struct domain *d)
> +{
> +    int rc;
> +
> +    ASSERT(is_hardware_domain(d));
> +    if ( has_hvm_container_domain(d) )
> +    {
> +        rc = rangeset_report_ranges(d->arch.ioport_caps, 0, 0x10000,
> +                                    io_bitmap_cb, d);
> +        BUG_ON(rc);
> +    }
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index 6803c4d..8e0a7cd 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -225,6 +225,8 @@ static int late_hwdom_init(struct domain *d)
> 
>      iommu_hwdom_init(d);
> 
> +    setup_io_bitmap(d);
> +
>      return rv;
>  #else
>      return 0;
> diff --git a/xen/include/asm-x86/hvm/domain.h
> b/xen/include/asm-x86/hvm/domain.h
> index 0f8b19a..e250791 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -141,6 +141,8 @@ struct hvm_domain {
>       */
>      uint64_t sync_tsc;
> 
> +    unsigned long         *io_bitmap;
> +
>      union {
>          struct vmx_domain vmx;
>          struct svm_domain svm;
> diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
> index 08bc23a..381d9f8 100644
> --- a/xen/include/asm-x86/setup.h
> +++ b/xen/include/asm-x86/setup.h
> @@ -32,6 +32,7 @@ int construct_dom0(
>      module_t *initrd,
>      void *(*bootstrap_map)(const module_t *),
>      char *cmdline);
> +void setup_io_bitmap(struct domain *d);
> 
>  unsigned long initial_images_nrpages(nodeid_t node);
>  void discard_initial_images(void);
> --
> 1.9.5 (Apple Git-50.3)

_______________________________________________
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®.