[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |