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

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



> From: Roger Pau Monne [mailto:roger.pau@xxxxxxxxxx]
> Sent: Wednesday, April 08, 2015 8:57 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.
> 
> Also add the IO ports of the serial console used by Xen to the list of not
> accessible IO ports.
> 
> 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>
> ---
>  xen/arch/x86/domain_build.c      | 10 ++++++++++
>  xen/arch/x86/hvm/hvm.c           | 11 +++++++++++
>  xen/arch/x86/hvm/svm/vmcb.c      |  3 ++-
>  xen/arch/x86/hvm/vmx/vmcs.c      |  6 ++++--
>  xen/arch/x86/hvm/vmx/vmx.c       |  1 +
>  xen/drivers/char/ns16550.c       | 10 ++++++++++
>  xen/include/asm-x86/hvm/domain.h |  2 ++
>  xen/include/asm-x86/hvm/hvm.h    |  1 +
>  xen/include/xen/serial.h         |  4 ++++
>  9 files changed, 45 insertions(+), 3 deletions(-)
> 
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index e5c845c..d0365fe 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -22,6 +22,7 @@
>  #include <xen/compat.h>
>  #include <xen/libelf.h>
>  #include <xen/pfn.h>
> +#include <xen/serial.h>
>  #include <asm/regs.h>
>  #include <asm/system.h>
>  #include <asm/io.h>
> @@ -1541,6 +1542,11 @@ int __init construct_dom0(
>      rc |= ioports_deny_access(d, 0x40, 0x43);
>      /* PIT Channel 2 / PC Speaker Control. */
>      rc |= ioports_deny_access(d, 0x61, 0x61);
> +    /* Serial console. */
> +    if ( uart_ioport1 != 0 )
> +        rc |= ioports_deny_access(d, uart_ioport1, uart_ioport1 + 7);
> +    if ( uart_ioport2 != 0 )
> +        rc |= ioports_deny_access(d, uart_ioport2, uart_ioport2 + 7);

would this be better in actual serial driver?

>      /* ACPI PM Timer. */
>      if ( pmtmr_ioport )
>          rc |= ioports_deny_access(d, pmtmr_ioport, pmtmr_ioport + 3);
> @@ -1618,6 +1624,10 @@ int __init construct_dom0(
> 
>          pvh_map_all_iomem(d, nr_pages);
>          pvh_setup_e820(d, nr_pages);
> +
> +        for ( i = 0; i < 0x10000; i++ )
> +            if ( ioports_access_permitted(d, i, i) )
> +                __clear_bit(i, hvm_hw_io_bitmap);
>      }
> 
>      if ( d->domain_id == hardware_domid )
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index 3ff87c6..6de89b2 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -82,6 +82,10 @@ struct hvm_function_table hvm_funcs __read_mostly;
>  unsigned long __attribute__ ((__section__ (".bss.page_aligned")))
>      hvm_io_bitmap[3*PAGE_SIZE/BYTES_PER_LONG];
> 
> +/* I/O permission bitmap for HVM hardware domain */
> +unsigned long __attribute__ ((__section__ (".bss.page_aligned")))
> +    hvm_hw_io_bitmap[3*PAGE_SIZE/BYTES_PER_LONG];
> +
>  /* Xen command-line option to enable HAP */
>  static bool_t __initdata opt_hap_enabled = 1;
>  boolean_param("hap", opt_hap_enabled);
> @@ -162,6 +166,7 @@ static int __init hvm_enable(void)
>       * often used for I/O delays, but the vmexits simply slow things down).
>       */
>      memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
> +    memset(hvm_hw_io_bitmap, ~0, sizeof(hvm_hw_io_bitmap));
>      if ( hvm_port80_allowed )
>          __clear_bit(0x80, hvm_io_bitmap);
>      __clear_bit(0xed, hvm_io_bitmap);
> @@ -1484,6 +1489,12 @@ 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 = hvm_hw_io_bitmap;
> +    else
> +        d->arch.hvm_domain.io_bitmap = hvm_io_bitmap;
> +

if we want to support multiple PVH hardware domains w/ different
permissions, using global array is not correct here.

>      if ( is_pvh_domain(d) )
>      {
>          register_portio_handler(d, 0, 0x10003, handle_pvh_io);
> diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c
> index 21292bb..eb2176b 100644
> --- a/xen/arch/x86/hvm/svm/vmcb.c
> +++ b/xen/arch/x86/hvm/svm/vmcb.c
> @@ -72,6 +72,7 @@ static int construct_vmcb(struct vcpu *v)
>  {
>      struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
>      struct vmcb_struct *vmcb = arch_svm->vmcb;
> +    struct domain *d = v->domain;
> 
>      vmcb->_general1_intercepts =
>          GENERAL1_INTERCEPT_INTR        |
> GENERAL1_INTERCEPT_NMI         |
> @@ -118,7 +119,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  =
> (u64)virt_to_maddr(d->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 d614638..3080979 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -986,8 +986,10 @@ 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((char *)d->arch.hvm_domain.io_bitmap +
> 0));
> +    __vmwrite(IO_BITMAP_B,
> +              virt_to_maddr((char *)d->arch.hvm_domain.io_bitmap +
> PAGE_SIZE));
> 
>      if ( cpu_has_vmx_virtual_intr_delivery )
>      {
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index 2ac1492..d5ccdce 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -3118,6 +3118,7 @@ void vmx_vmexit_handler(struct cpu_user_regs
> *regs)
>              uint16_t port = (exit_qualification >> 16) & 0xFFFF;
>              int bytes = (exit_qualification & 0x07) + 1;
>              int dir = (exit_qualification & 0x08) ? IOREQ_READ :
> IOREQ_WRITE;
> +
>              if ( handle_pio(port, bytes, dir) )
>                  update_guest_eip(); /* Safe: IN, OUT */
>          }
> diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
> index d443880..b382e72 100644
> --- a/xen/drivers/char/ns16550.c
> +++ b/xen/drivers/char/ns16550.c
> @@ -44,6 +44,9 @@ static char __initdata opt_com2[30] = "";
>  string_param("com1", opt_com1);
>  string_param("com2", opt_com2);
> 
> +unsigned int uart_ioport1 = 0;
> +unsigned int uart_ioport2 = 0;
> +
>  static struct ns16550 {
>      int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
>      u64 io_base;   /* I/O port or memory-mapped I/O address. */
> @@ -1121,6 +1124,13 @@ void __init ns16550_init(int index, struct
> ns16550_defaults *defaults)
>      uart->reg_shift = 0;
> 
>      ns16550_parse_port_config(uart, (index == 0) ? opt_com1 : opt_com2);
> +    if ( uart->baud != 0 && uart->io_base < 0x10000 )
> +    {
> +        if ( index == 0 )
> +            uart_ioport1 = uart->io_base;
> +        else
> +            uart_ioport2 = uart->io_base;
> +    }
>  }
> 
>  #ifdef HAS_DEVICE_TREE
> diff --git a/xen/include/asm-x86/hvm/domain.h
> b/xen/include/asm-x86/hvm/domain.h
> index 0702bf5..d002954 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -143,6 +143,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/hvm/hvm.h
> b/xen/include/asm-x86/hvm/hvm.h
> index 0dc909b..55e432e 100644
> --- a/xen/include/asm-x86/hvm/hvm.h
> +++ b/xen/include/asm-x86/hvm/hvm.h
> @@ -213,6 +213,7 @@ extern struct hvm_function_table hvm_funcs;
>  extern bool_t hvm_enabled;
>  extern bool_t cpu_has_lmsl;
>  extern s8 hvm_port80_allowed;
> +extern unsigned long hvm_hw_io_bitmap[];
> 
>  extern const struct hvm_function_table *start_svm(void);
>  extern const struct hvm_function_table *start_vmx(void);
> diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h
> index 71e6ade..bc5fb06 100644
> --- a/xen/include/xen/serial.h
> +++ b/xen/include/xen/serial.h
> @@ -24,6 +24,10 @@ void serial_set_rx_handler(int handle, serial_rx_fn fn);
>  /* Number of characters we buffer for an interrupt-driven transmitter. */
>  extern unsigned int serial_txbufsz;
> 
> +/* UART IO port */
> +extern unsigned int uart_ioport1;
> +extern unsigned int uart_ioport2;
> +
>  struct uart_driver;
> 
>  enum serial_port_state {
> --
> 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®.