[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [v8][PATCH 02/17] introduce XEN_DOMCTL_set_rdm
> From: Chen, Tiejun > Sent: Monday, December 01, 2014 5:24 PM > > This should be based on a new parameter globally, 'pci_rdmforce'. > > pci_rdmforce = 1 => Of course this should be 0 by default. > > '1' means we should force check to reserve all ranges. If failed > VM wouldn't be created successfully. This also can give user a > chance to work well with later hotplug, even if not a device > assignment while creating VM. > > But we can override that by one specific pci device: > > pci = ['AA:BB.CC,rdmforce=0/1] > > But this 'rdmforce' should be 1 by default since obviously any > passthrough device always need to do this. Actually no one really > want to set as '0' so it may be unnecessary but I'd like to leave > this as a potential approach. since no one requires it, why bother adding it? better to just keep global option. > > So this domctl provides an approach to control how to populate > reserved device memory by tools. > > Note we always post a message to user about this once we owns > RMRR. > > Signed-off-by: Tiejun Chen <tiejun.chen@xxxxxxxxx> > --- > docs/man/xl.cfg.pod.5 | 6 +++++ > docs/misc/vtd.txt | 15 ++++++++++++ > tools/libxc/include/xenctrl.h | 6 +++++ > tools/libxc/xc_domain.c | 28 +++++++++++++++++++++++ > tools/libxl/libxl_create.c | 3 +++ > tools/libxl/libxl_dm.c | 47 > ++++++++++++++++++++++++++++++++++++++ > tools/libxl/libxl_internal.h | 4 ++++ > tools/libxl/libxl_types.idl | 2 ++ > tools/libxl/libxlu_pci.c | 2 ++ > tools/libxl/xl_cmdimpl.c | 10 ++++++++ > xen/drivers/passthrough/pci.c | 39 > +++++++++++++++++++++++++++++++ > xen/drivers/passthrough/vtd/dmar.c | 8 +++++++ > xen/include/asm-x86/hvm/domain.h | 4 ++++ > xen/include/public/domctl.h | 21 +++++++++++++++++ > xen/xsm/flask/hooks.c | 1 + > 15 files changed, 196 insertions(+) > > diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5 > index 622ea53..9adc41e 100644 > --- a/docs/man/xl.cfg.pod.5 > +++ b/docs/man/xl.cfg.pod.5 > @@ -645,6 +645,12 @@ dom0 without confirmation. Please use with care. > D0-D3hot power management states for the PCI device. False (0) by > default. > > +=item B<rdmforce=BOOLEAN> > + > +(HVM/x86 only) Specifies that the VM would force to check and try to > +reserve all reserved device memory, like RMRR, associated to the PCI > +device. False (0) by default. > + > =back > > =back > diff --git a/docs/misc/vtd.txt b/docs/misc/vtd.txt > index 9af0e99..23544d5 100644 > --- a/docs/misc/vtd.txt > +++ b/docs/misc/vtd.txt > @@ -111,6 +111,21 @@ in the config file: > To override for a specific device: > pci = [ '01:00.0,msitranslate=0', '03:00.0' ] > > +RDM, 'reserved device memory', for PCI Device Passthrough > +--------------------------------------------------------- > + > +The BIOS controls some devices in terms of some reginos of memory used for > +these devices. This kind of region should be reserved before creating a VM > +to make sure they are not occupied by RAM/MMIO to conflict, and also we > can > +create necessary IOMMU table successfully. > + > +To enable this globally, add "pci_rdmforce" in the config file: > + > + pci_rdmforce = 1 (default is 0) > + > +Or just enable for a specific device: > + pci = [ '01:00.0,rdmforce=1', '03:00.0' ] > + > > Caveat on Conventional PCI Device Passthrough > --------------------------------------------- > diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h > index 0ad8b8d..84012fe 100644 > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -2038,6 +2038,12 @@ int xc_assign_device(xc_interface *xch, > uint32_t domid, > uint32_t machine_bdf); > > +int xc_domain_device_setrdm(xc_interface *xch, > + uint32_t domid, > + uint32_t num_pcidevs, > + uint32_t pci_rdmforce, > + struct xen_guest_pcidev_info *pcidevs); > + > int xc_get_device_group(xc_interface *xch, > uint32_t domid, > uint32_t machine_bdf, > diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c > index b864872..7fd43e9 100644 > --- a/tools/libxc/xc_domain.c > +++ b/tools/libxc/xc_domain.c > @@ -1633,6 +1633,34 @@ int xc_assign_device( > return do_domctl(xch, &domctl); > } > > +int xc_domain_device_setrdm(xc_interface *xch, > + uint32_t domid, > + uint32_t num_pcidevs, > + uint32_t pci_rdmforce, > + struct xen_guest_pcidev_info *pcidevs) > +{ > + int ret; > + DECLARE_DOMCTL; > + DECLARE_HYPERCALL_BOUNCE(pcidevs, > + > num_pcidevs*sizeof(xen_guest_pcidev_info_t), > + XC_HYPERCALL_BUFFER_BOUNCE_IN); > + > + if ( xc_hypercall_bounce_pre(xch, pcidevs) ) > + return -1; > + > + domctl.cmd = XEN_DOMCTL_set_rdm; > + domctl.domain = (domid_t)domid; > + domctl.u.set_rdm.flags = pci_rdmforce; > + domctl.u.set_rdm.num_pcidevs = num_pcidevs; > + set_xen_guest_handle(domctl.u.set_rdm.pcidevs, pcidevs); > + > + ret = do_domctl(xch, &domctl); > + > + xc_hypercall_bounce_post(xch, pcidevs); > + > + return ret; > +} > + > int xc_get_device_group( > xc_interface *xch, > uint32_t domid, > diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c > index 1198225..c615686 100644 > --- a/tools/libxl/libxl_create.c > +++ b/tools/libxl/libxl_create.c > @@ -862,6 +862,9 @@ static void initiate_domain_create(libxl__egc *egc, > ret = libxl__domain_build_info_setdefault(gc, &d_config->b_info); > if (ret) goto error_out; > > + ret = libxl__domain_device_setrdm(gc, d_config, domid); > + if (ret) goto error_out; > + > if (!sched_params_valid(gc, domid, &d_config->b_info.sched_params)) { > LOG(ERROR, "Invalid scheduling parameters\n"); > ret = ERROR_INVAL; > diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c > index 3e191c3..e50587d 100644 > --- a/tools/libxl/libxl_dm.c > +++ b/tools/libxl/libxl_dm.c > @@ -90,6 +90,53 @@ const char *libxl__domain_device_model(libxl__gc *gc, > return dm; > } > > +int libxl__domain_device_setrdm(libxl__gc *gc, > + libxl_domain_config *d_config, > + uint32_t dm_domid) > +{ > + int i, ret; > + libxl_ctx *ctx = libxl__gc_owner(gc); > + struct xen_guest_pcidev_info *pcidevs = NULL; > + uint32_t rdmforce = 0; > + > + if ( d_config->num_pcidevs ) > + { > + pcidevs = > malloc(d_config->num_pcidevs*sizeof(xen_guest_pcidev_info_t)); > + if ( pcidevs ) > + { > + for (i = 0; i < d_config->num_pcidevs; i++) > + { > + pcidevs[i].devfn = PCI_DEVFN(d_config->pcidevs[i].dev, > + > d_config->pcidevs[i].func); > + pcidevs[i].bus = d_config->pcidevs[i].bus; > + pcidevs[i].seg = d_config->pcidevs[i].domain; > + pcidevs[i].flags = d_config->pcidevs[i].rdmforce & > + PCI_DEV_RDM_CHECK; > + } > + } > + else > + { > + LIBXL__LOG(CTX, LIBXL__LOG_ERROR, > + "Can't allocate for pcidevs."); > + return -1; > + } > + } > + rdmforce = libxl_defbool_val(d_config->b_info.rdmforce) ? 1 : 0; > + > + /* Nothing to do. */ > + if ( !rdmforce && !d_config->num_pcidevs ) > + return 0; move check before creating pcidevs. > + > + ret = xc_domain_device_setrdm(ctx->xch, dm_domid, > + (uint32_t)d_config->num_pcidevs, > + rdmforce, > + pcidevs); > + if ( d_config->num_pcidevs ) > + free(pcidevs); > + > + return ret; > +} > + > const libxl_vnc_info *libxl__dm_vnc(const libxl_domain_config > *guest_config) > { > const libxl_vnc_info *vnc = NULL; > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index a38f695..be397a6 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -1477,6 +1477,10 @@ _hidden int libxl__need_xenpv_qemu(libxl__gc > *gc, > int nr_disks, libxl_device_disk *disks, > int nr_channels, libxl_device_channel *channels); > > +_hidden int libxl__domain_device_setrdm(libxl__gc *gc, > + libxl_domain_config *info, > + uint32_t domid); > + > /* > * This function will cause the whole libxl process to hang > * if the device model does not respond. It is deprecated. > diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl > index f7fc695..0076a32 100644 > --- a/tools/libxl/libxl_types.idl > +++ b/tools/libxl/libxl_types.idl > @@ -398,6 +398,7 @@ libxl_domain_build_info = > Struct("domain_build_info",[ > ("kernel", string), > ("cmdline", string), > ("ramdisk", string), > + ("rdmforce", libxl_defbool), > ("u", KeyedUnion(None, libxl_domain_type, "type", > [("hvm", Struct(None, [("firmware", string), > ("bios", > libxl_bios_type), > @@ -518,6 +519,7 @@ libxl_device_pci = Struct("device_pci", [ > ("power_mgmt", bool), > ("permissive", bool), > ("seize", bool), > + ("rdmforce", bool), > ]) > > libxl_device_vtpm = Struct("device_vtpm", [ > diff --git a/tools/libxl/libxlu_pci.c b/tools/libxl/libxlu_pci.c > index 26fb143..989eac8 100644 > --- a/tools/libxl/libxlu_pci.c > +++ b/tools/libxl/libxlu_pci.c > @@ -143,6 +143,8 @@ int xlu_pci_parse_bdf(XLU_Config *cfg, > libxl_device_pci *pcidev, const char *str > pcidev->permissive = atoi(tok); > }else if ( !strcmp(optkey, "seize") ) { > pcidev->seize = atoi(tok); > + }else if ( !strcmp(optkey, "rdmforce") ) { > + pcidev->rdmforce = atoi(tok); > }else{ > XLU__PCI_ERR(cfg, "Unknown PCI BDF option: %s", > optkey); > } > diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c > index 0e754e7..9c23733 100644 > --- a/tools/libxl/xl_cmdimpl.c > +++ b/tools/libxl/xl_cmdimpl.c > @@ -919,6 +919,7 @@ static void parse_config_data(const char > *config_source, > int pci_msitranslate = 0; > int pci_permissive = 0; > int pci_seize = 0; > + int pci_rdmforce = 0; > int i, e; > > libxl_domain_create_info *c_info = &d_config->c_info; > @@ -1699,6 +1700,9 @@ skip_vfb: > if (!xlu_cfg_get_long (config, "pci_seize", &l, 0)) > pci_seize = l; > > + if (!xlu_cfg_get_long (config, "pci_rdmforce", &l, 0)) > + pci_rdmforce = l; > + > /* To be reworked (automatically enabled) once the auto ballooning > * after guest starts is done (with PCI devices passed in). */ > if (c_info->type == LIBXL_DOMAIN_TYPE_PV) { > @@ -1719,6 +1723,7 @@ skip_vfb: > pcidev->power_mgmt = pci_power_mgmt; > pcidev->permissive = pci_permissive; > pcidev->seize = pci_seize; > + pcidev->rdmforce = pci_rdmforce; > if (!xlu_pci_parse_bdf(config, pcidev, buf)) > d_config->num_pcidevs++; > } > @@ -1726,6 +1731,11 @@ skip_vfb: > libxl_defbool_set(&b_info->u.pv.e820_host, true); > } > > + if ((c_info->type == LIBXL_DOMAIN_TYPE_HVM) && pci_rdmforce) > + libxl_defbool_set(&b_info->rdmforce, true); > + else > + libxl_defbool_set(&b_info->rdmforce, false); > + > switch (xlu_cfg_get_list(config, "cpuid", &cpuids, 0, 1)) { > case 0: > { > diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c > index 78c6977..ae924ad 100644 > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -34,6 +34,7 @@ > #include <xen/tasklet.h> > #include <xsm/xsm.h> > #include <asm/msi.h> > +#include <xen/stdbool.h> > > struct pci_seg { > struct list_head alldevs_list; > @@ -1553,6 +1554,44 @@ int iommu_do_pci_domctl( > } > break; > > + case XEN_DOMCTL_set_rdm: > + { > + struct xen_domctl_set_rdm *xdsr = &domctl->u.set_rdm; > + struct xen_guest_pcidev_info *pcidevs = NULL; > + struct domain *d = rcu_lock_domain_by_any_id(domctl->domain); > + > + if ( d == NULL ) > + return -ESRCH; > + > + d->arch.hvm_domain.pci_force = > + xdsr->flags & PCI_DEV_RDM_CHECK ? > true : false; > + d->arch.hvm_domain.num_pcidevs = xdsr->num_pcidevs; > + d->arch.hvm_domain.pcidevs = NULL; > + > + if ( xdsr->num_pcidevs ) > + { > + pcidevs = xmalloc_array(xen_guest_pcidev_info_t, > + xdsr->num_pcidevs); > + if ( pcidevs == NULL ) > + { > + rcu_unlock_domain(d); > + return -ENOMEM; > + } > + > + if ( copy_from_guest(pcidevs, xdsr->pcidevs, > + > xdsr->num_pcidevs*sizeof(*pcidevs)) ) > + { > + xfree(pcidevs); > + rcu_unlock_domain(d); > + return -EFAULT; > + } > + } > + > + d->arch.hvm_domain.pcidevs = pcidevs; > + rcu_unlock_domain(d); > + } > + break; > + > case XEN_DOMCTL_assign_device: > if ( unlikely(d->is_dying) ) > { > diff --git a/xen/drivers/passthrough/vtd/dmar.c > b/xen/drivers/passthrough/vtd/dmar.c > index 1152c3a..5e41e7a 100644 > --- a/xen/drivers/passthrough/vtd/dmar.c > +++ b/xen/drivers/passthrough/vtd/dmar.c > @@ -674,6 +674,14 @@ acpi_parse_one_rmrr(struct acpi_dmar_header > *header) > " RMRR region: base_addr %"PRIx64 > " end_address %"PRIx64"\n", > rmrru->base_address, rmrru->end_address); > + /* > + * TODO: we may provide a precise paramter just to reserve > + * RMRR range specific to one device. > + */ > + dprintk(XENLOG_WARNING VTDPREFIX, > + "So please set pci_rdmforce to reserve these ranges" > + " if you need such a device in hotplug case.\n"); > + > acpi_register_rmrr_unit(rmrru); > } > } > diff --git a/xen/include/asm-x86/hvm/domain.h > b/xen/include/asm-x86/hvm/domain.h > index 2757c7f..38530e5 100644 > --- a/xen/include/asm-x86/hvm/domain.h > +++ b/xen/include/asm-x86/hvm/domain.h > @@ -90,6 +90,10 @@ struct hvm_domain { > /* Cached CF8 for guest PCI config cycles */ > uint32_t pci_cf8; > > + bool_t pci_force; > + uint32_t num_pcidevs; > + struct xen_guest_pcidev_info *pcidevs; > + > struct pl_time pl_time; > > struct hvm_io_handler *io_handler; > diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > index 57e2ed7..ba8970d 100644 > --- a/xen/include/public/domctl.h > +++ b/xen/include/public/domctl.h > @@ -508,6 +508,25 @@ struct xen_domctl_get_device_group { > typedef struct xen_domctl_get_device_group > xen_domctl_get_device_group_t; > DEFINE_XEN_GUEST_HANDLE(xen_domctl_get_device_group_t); > > +/* Currently just one bit to indicate force to check Reserved Device Memory. > */ > +#define PCI_DEV_RDM_CHECK 0x1 > +struct xen_guest_pcidev_info { > + uint16_t seg; > + uint8_t bus; > + uint8_t devfn; > + uint32_t flags; > +}; > +typedef struct xen_guest_pcidev_info xen_guest_pcidev_info_t; > +DEFINE_XEN_GUEST_HANDLE(xen_guest_pcidev_info_t); > +/* Control whether/how we check and reserve device memory. */ > +struct xen_domctl_set_rdm { > + uint32_t flags; > + uint32_t num_pcidevs; > + XEN_GUEST_HANDLE_64(xen_guest_pcidev_info_t) pcidevs; > +}; > +typedef struct xen_domctl_set_rdm xen_domctl_set_rdm_t; > +DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_rdm_t); > + > /* Pass-through interrupts: bind real irq -> hvm devfn. */ > /* XEN_DOMCTL_bind_pt_irq */ > /* XEN_DOMCTL_unbind_pt_irq */ > @@ -1070,6 +1089,7 @@ struct xen_domctl { > #define XEN_DOMCTL_setvnumainfo 74 > #define XEN_DOMCTL_psr_cmt_op 75 > #define XEN_DOMCTL_arm_configure_domain 76 > +#define XEN_DOMCTL_set_rdm 77 > #define XEN_DOMCTL_gdbsx_guestmemio 1000 > #define XEN_DOMCTL_gdbsx_pausevcpu 1001 > #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 > @@ -1135,6 +1155,7 @@ struct xen_domctl { > struct xen_domctl_gdbsx_domstatus gdbsx_domstatus; > struct xen_domctl_vnuma vnuma; > struct xen_domctl_psr_cmt_op psr_cmt_op; > + struct xen_domctl_set_rdm set_rdm; > uint8_t pad[128]; > } u; > }; > diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c > index d48463f..5a760e2 100644 > --- a/xen/xsm/flask/hooks.c > +++ b/xen/xsm/flask/hooks.c > @@ -592,6 +592,7 @@ static int flask_domctl(struct domain *d, int cmd) > case XEN_DOMCTL_test_assign_device: > case XEN_DOMCTL_assign_device: > case XEN_DOMCTL_deassign_device: > + case XEN_DOMCTL_set_rdm: > #endif > return 0; > > -- > 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |