Why doesn't the guest punch its own hole, by relocating RAM above 4GB?
That's what all HVM guests do (in hvmloader).
-- Keir
On 12/11/2010 23:08, "Konrad Rzeszutek Wilk" <konrad.wilk@xxxxxxxxxx> wrote:
> Hey guys,
>
> Attached is an RFC patch for making a PCI hole in the PV guests. This allows
> PV guests(*) with 4GB or more to now properly work with or without
> PCI passthrough cards.
>
> Previously the Linux kernel would not be able to allocate the PCI region
> underneath the 4GB region as that region was all System RAM. And you would see
> this:
>
> [ 0.000000] PM: Registered nosave memory: 00000000000a0000 -
> 0000000000100000
> [ 0.000000] PCI: Warning: Cannot find a gap in the 32bit address range
> [ 0.000000] PCI: Unassigned devices with 32bit resource registers may
> break!
> [ 0.000000] Allocating PCI resources starting at 100100000 (gap:
> 100100000:400000)
>
>
> This patchset punches an PCI hole in the E820 region and as well fills the P2M
> properly,
> so that now you can see (*):
> [ 0.000000] Allocating PCI resources starting at a0000000 (gap:
> a0000000:60000000)
>
> It adds a new option to guest config file, which is "pci_hole". The user can
> specify the PFN number, such as '0xc0000' or in case of using the xl, '1'
> which
> will automatically figure out the start of the PCI address.
>
> *: This option requires support in the Linux kernel to actually deal with two
> entries in the E820 map and P2M space filled with ~0.
>
>
> The patches (draft, not ready for upstream) for the Linux kernel to support
> this are
> available at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git devel/e820-hole
>
> All of these patches make the E820 of the Linux guest with 4GB (or more)
> passed
> look like this (2.6.37-rc1+devel/e820-hole):
> [ 0.000000] Xen: 0000000000000000 - 00000000000a0000 (usable)
> [ 0.000000] Xen: 00000000000a0000 - 0000000000100000 (reserved)
> [ 0.000000] Xen: 0000000000100000 - 00000000a0000000 (usable)
> [ 0.000000] Xen: 0000000100000000 - 0000000160800000 (usable)
>
> compared to (2.6.36)
> [ 0.000000] Xen: 0000000000000000 - 00000000000a0000 (usable)
> [ 0.000000] Xen: 00000000000a0000 - 0000000000100000 (reserved)
> [ 0.000000] Xen: 0000000000100000 - 0000000100000000 (usable)
>
> and (2.6.37-rc1):
> [ 0.000000] Xen: 0000000000000000 - 00000000000a0000 (usable)
> [ 0.000000] Xen: 00000000000a0000 - 0000000000100000 (reserved)
> [ 0.000000] Xen: 0000000000100000 - 0000000100800000 (usable)
>
> In regards to the patches that I am attaching here, what is the magic
> incantention
> to make the indentation/StyleGuide proper for the tools/libxc directory? The
> tab spacing
> is off a bit (I think).
>
> I've tested this so far only on 64-bit guests, and I am quite sure the
> tool-stack
> needs some extra care for the 32-bit guests..
>
> But please take a look and give feedback.
>
> diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
> --- a/tools/libxc/xc_dom.h
> +++ b/tools/libxc/xc_dom.h
> @@ -91,6 +91,8 @@ struct xc_dom_image {
>
> /* physical memory */
> xen_pfn_t total_pages;
> + /* start of the pci_hole. goes up to 4gb */
> + xen_pfn_t pci_hole;
> struct xc_dom_phys *phys_pages;
> int realmodearea_log;
>
> diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
> --- a/tools/libxc/xc_dom_core.c
> +++ b/tools/libxc/xc_dom_core.c
> @@ -715,17 +715,22 @@ int xc_dom_update_guest_p2m(struct xc_do
> uint32_t *p2m_32;
> uint64_t *p2m_64;
> xen_pfn_t i;
> + size_t tot_pages;
>
> if ( !dom->p2m_guest )
> return 0;
>
> + tot_pages = dom->total_pages;
> + if (dom->pci_hole)
> + tot_pages += (0x100000 - dom->pci_hole);
> +
> switch ( dom->arch_hooks->sizeof_pfn )
> {
> case 4:
> DOMPRINTF("%s: dst 32bit, pages 0x%" PRIpfn "",
> - __FUNCTION__, dom->total_pages);
> + __FUNCTION__, tot_pages);
> p2m_32 = dom->p2m_guest;
> - for ( i = 0; i < dom->total_pages; i++ )
> + for ( i = 0; i < tot_pages; i++ )
> if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
> p2m_32[i] = dom->p2m_host[i];
> else
> @@ -733,9 +738,9 @@ int xc_dom_update_guest_p2m(struct xc_do
> break;
> case 8:
> DOMPRINTF("%s: dst 64bit, pages 0x%" PRIpfn "",
> - __FUNCTION__, dom->total_pages);
> + __FUNCTION__, tot_pages);
> p2m_64 = dom->p2m_guest;
> - for ( i = 0; i < dom->total_pages; i++ )
> + for ( i = 0; i < tot_pages; i++ )
> if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
> p2m_64[i] = dom->p2m_host[i];
> else
> diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
> --- a/tools/libxc/xc_dom_x86.c
> +++ b/tools/libxc/xc_dom_x86.c
> @@ -406,6 +406,15 @@ static int alloc_magic_pages(struct xc_d
> {
> size_t p2m_size = dom->total_pages * dom->arch_hooks->sizeof_pfn;
>
> + if (dom->pci_hole && (dom->total_pages > dom->pci_hole))
> + {
> + size_t p2m_pci_hole_size = (0x100000 - dom->pci_hole) *
> + dom->arch_hooks->sizeof_pfn;
> +
> + DOMPRINTF("%s: Expanding P2M to include PCI hole (%ld->%ld)\n",
> + __FUNCTION__, p2m_size, p2m_size + p2m_pci_hole_size);
> + p2m_size += p2m_pci_hole_size;
> + }
> /* allocate phys2mach table */
> if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size) )
> return -1;
> @@ -712,6 +721,7 @@ int arch_setup_meminit(struct xc_dom_ima
> {
> int rc;
> xen_pfn_t pfn, allocsz, i, j, mfn;
> + size_t p2m_size;
>
> rc = x86_compat(dom->xch, dom->guest_domid, dom->guest_type);
> if ( rc )
> @@ -723,8 +733,13 @@ int arch_setup_meminit(struct xc_dom_ima
> if ( rc )
> return rc;
> }
> + p2m_size = dom->total_pages;
>
> - dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
> + if (dom->pci_hole && (dom->total_pages > dom->pci_hole))
> + p2m_size += (0x100000 - dom->pci_hole);
> +
> + DOMPRINTF("Allocating %ld bytes for P2M", p2m_size * sizeof(xen_pfn_t));
> + dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * p2m_size);
> if ( dom->superpages )
> {
> int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
> @@ -750,21 +765,66 @@ int arch_setup_meminit(struct xc_dom_ima
> }
> else
> {
> - /* setup initial p2m */
> - for ( pfn = 0; pfn < dom->total_pages; pfn++ )
> - dom->p2m_host[pfn] = pfn;
> -
> - /* allocate guest memory */
> - for ( i = rc = allocsz = 0;
> - (i < dom->total_pages) && !rc;
> - i += allocsz )
> + /* for PCI mapping, stick INVALID_MFN in the PCI_HOLE */
> + if ( dom->pci_hole && (dom->total_pages > dom->pci_hole) )
> {
> - allocsz = dom->total_pages - i;
> - if ( allocsz > 1024*1024 )
> - allocsz = 1024*1024;
> - rc = xc_domain_populate_physmap_exact(
> - dom->xch, dom->guest_domid, allocsz,
> - 0, 0, &dom->p2m_host[i]);
> + /* setup initial p2m in three passes. */
> + for (pfn = 0; pfn < dom->pci_hole; pfn++)
> + dom->p2m_host[pfn] = pfn;
> +
> + xc_dom_printf (dom->xch, "%s: 0x0->0x%lx has PFNs.",
> __FUNCTION__, pfn);
> + xc_dom_printf (dom->xch, "%s: 0x%lx -> 0x%x has INVALID_MFN",
> + __FUNCTION__, pfn, 0x100000);
> + for (; pfn < 0x100000; pfn++)
> + dom->p2m_host[pfn] = INVALID_MFN;
> +
> + for (; pfn < 0x100000 + dom->total_pages - dom->pci_hole; pfn++)
> + dom->p2m_host[pfn] = pfn;
> + xc_dom_printf (dom->xch, "%s: 0x%x -> 0x%lx has PFNs.",
> __FUNCTION__,
> + 0x100000, pfn);
> +
> + /* allocate guest memory in two passes. */
> + for (i = rc = allocsz = 0; (i < dom->pci_hole) && !rc; i +=
> allocsz)
> + {
> + allocsz = dom->pci_hole - i;
> + xc_dom_printf (dom->xch, "%s: Populating M2P 0x%lx->0x%lx",
> + __FUNCTION__, i, i + allocsz);
> + rc = xc_domain_populate_physmap_exact (dom->xch,
> dom->guest_domid,
> + allocsz, 0, 0,
> + &dom->p2m_host[i]);
> + }
> + for (i = 0x100000, allocsz = rc = 0;
> + (i < (0x100000 + dom->total_pages - dom->pci_hole))
> + && !rc; i += allocsz)
> + {
> + allocsz = (dom->total_pages - dom->pci_hole) - (i - 0x100000);
> + if (allocsz > 1024 * 1024)
> + allocsz = 1024 * 1024;
> + xc_dom_printf (dom->xch, "%s: Populating M2P 0x%lx->0x%lx",
> + __FUNCTION__, i, i + allocsz);
> + rc = xc_domain_populate_physmap_exact (dom->xch,
> dom->guest_domid,
> + allocsz, 0, 0,
> + &dom->p2m_host[i]);
> + }
> + xc_dom_printf (dom->xch, "%s: Done with PCI populate physmap",
> + __FUNCTION__);
> + } else {
> + /* setup initial p2m */
> + for ( pfn = 0; pfn < dom->total_pages; pfn++ )
> + dom->p2m_host[pfn] = pfn;
> +
> + /* allocate guest memory */
> + for ( i = rc = allocsz = 0;
> + (i < dom->total_pages) && !rc;
> + i += allocsz )
> + {
> + allocsz = dom->total_pages - i;
> + if ( allocsz > 1024*1024 )
> + allocsz = 1024*1024;
> + rc = xc_domain_populate_physmap_exact(
> + dom->xch, dom->guest_domid, allocsz,
> + 0, 0, &dom->p2m_host[i]);
> + }
> }
> }
>
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -481,16 +481,25 @@ int xc_domain_pin_memory_cacheattr(xc_in
> #include "xc_e820.h"
> int xc_domain_set_memmap_limit(xc_interface *xch,
> uint32_t domid,
> - unsigned long map_limitkb)
> + unsigned long map_limitkb,
> + xen_pfn_t pci_hole_start)
> {
> int rc;
> + uint64_t delta_kb;
> + size_t e820_sz;
> struct xen_foreign_memory_map fmap = {
> .domid = domid,
> .map = { .nr_entries = 1 }
> };
> DECLARE_HYPERCALL_BUFFER(struct e820entry, e820);
>
> - e820 = xc_hypercall_buffer_alloc(xch, e820, sizeof(*e820));
> + delta_kb = map_limitkb - (uint64_t)(pci_hole_start << 2);
> + if (pci_hole_start && (delta_kb > 0))
> + e820_sz = sizeof(*e820);
> + else
> + e820_sz = sizeof(*e820)*2;
> +
> + e820 = xc_hypercall_buffer_alloc(xch, e820, e820_sz);
>
> if ( e820 == NULL )
> {
> @@ -502,6 +511,16 @@ int xc_domain_set_memmap_limit(xc_interf
> e820->size = (uint64_t)map_limitkb << 10;
> e820->type = E820_RAM;
>
> + if (pci_hole_start && (delta_kb > 0))
> + {
> + fmap.map.nr_entries ++;
> + e820[0].size = (uint64_t)pci_hole_start << 12;
> +
> + e820[1].type = E820_RAM;
> + e820[1].addr = (uint64_t)0x100000 << 12; /* val in pfn... */
> + e820[1].size = (uint64_t)delta_kb << 10; /* .. while here in in kB. */
> + }
> +
> set_xen_guest_handle(fmap.map.buffer, e820);
>
> rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap));
> @@ -513,7 +532,8 @@ int xc_domain_set_memmap_limit(xc_interf
> #else
> int xc_domain_set_memmap_limit(xc_interface *xch,
> uint32_t domid,
> - unsigned long map_limitkb)
> + unsigned long map_limitkb,
> + xen_pfn_t pci_hole_start)
> {
> PERROR("Function not implemented");
> errno = ENOSYS;
> diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
> --- a/tools/libxc/xenctrl.h
> +++ b/tools/libxc/xenctrl.h
> @@ -913,7 +913,8 @@ int xc_domain_setmaxmem(xc_interface *xc
>
> int xc_domain_set_memmap_limit(xc_interface *xch,
> uint32_t domid,
> - unsigned long map_limitkb);
> + unsigned long map_limitkb,
> + xen_pfn_t pci_hole_start);
>
> int xc_domain_set_time_offset(xc_interface *xch,
> uint32_t domid,
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -392,6 +392,7 @@ int libxl_device_disk_getinfo(libxl_ctx
> libxl_device_disk *disk, libxl_diskinfo
> *diskinfo);
> int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk
> *disk);
>
> +int libxl_find_pci_hole(uint32_t *start_pfn);
> /*
> * Make a disk available in this domain. Returns path to a device.
> */
> diff --git a/tools/libxl/libxl.idl b/tools/libxl/libxl.idl
> --- a/tools/libxl/libxl.idl
> +++ b/tools/libxl/libxl.idl
> @@ -110,6 +110,7 @@ libxl_domain_build_info = Struct("domain
> ])),
> ("pv", "!%s", Struct(None,
> [("slack_memkb", uint32),
> + ("pci_hole_start", uint32),
> ("bootloader", string),
> ("bootloader_args", string),
> ("cmdline", string),
> diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
> --- a/tools/libxl/libxl_dom.c
> +++ b/tools/libxl/libxl_dom.c
> @@ -71,7 +71,8 @@ int libxl__build_pre(libxl_ctx *ctx, uin
> xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb +
> LIBXL_MAXMEM_CONSTANT);
> xc_domain_set_memmap_limit(ctx->xch, domid,
> (info->hvm) ? info->max_memkb :
> - (info->max_memkb + info->u.pv.slack_memkb));
> + (info->max_memkb + info->u.pv.slack_memkb),
> + (info->hvm) ? 0 : info->u.pv.pci_hole_start);
> xc_domain_set_tsc_info(ctx->xch, domid, info->tsc_mode, 0, 0, 0);
> if ( info->disable_migrate )
> xc_domain_disable_migrate(ctx->xch, domid);
> @@ -181,6 +182,8 @@ int libxl__build_pv(libxl_ctx *ctx, uint
> }
> }
> }
> + if ( info->u.pv.pci_hole_start)
> + dom->pci_hole = info->u.pv.pci_hole_start;
>
> dom->flags = flags;
> dom->console_evtchn = state->console_port;
> diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
> --- a/tools/libxl/libxl_pci.c
> +++ b/tools/libxl/libxl_pci.c
> @@ -1066,3 +1066,51 @@ int libxl_device_pci_shutdown(libxl_ctx
> free(pcidevs);
> return 0;
> }
> +
> +#define MAX_LINE 300
> +int libxl_find_pci_hole(uint32_t *start_pfn)
> +{
> + FILE *fp;
> + char *s;
> + char buf[MAX_LINE];
> + int ret = -ENODEV;
> + long int pci_hole_phys;
> +
> + *start_pfn = 0;
> + fp = fopen("/proc/iomem", "r");
> + if (!fp)
> + return ret;
> +
> + while (1) {
> + s = fgets(buf, MAX_LINE, fp);
> + if (!s)
> + break;
> + if (strlen(buf) < 1)
> + continue;
> + if (buf[strlen(buf)-1] == '\n')
> + buf[strlen(buf)-1] = '\0';
> + s = strchr(buf,'P');
> + if (!s)
> + continue;
> + if (strncmp(s, "PCI", 3) == 0) {
> + if (buf[0] == ' ')
> + continue;
> + s = strchr(buf,'-');
> + if (!s)
> + break;
> + s[0]='\0';
> + pci_hole_phys = strtol(buf, NULL, 16);
> + if (!pci_hole_phys)
> + break;
> + /* We don't want to the holes below 16MB. */
> + if (pci_hole_phys <= 0x1000)
> + continue;
> + *start_pfn = pci_hole_phys >> 12;
> + fprintf(stderr,"The value is 0x%d\n", *start_pfn);
> + ret = 0;
> + break;
> + }
> + }
> + fclose(fp);
> + return ret;
> +}
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -1078,6 +1078,14 @@ skip_vfb:
> if (!xlu_cfg_get_long (config, "pci_power_mgmt", &l))
> pci_power_mgmt = l;
>
> + if (!xlu_cfg_get_long (config, "pci_hole", &l)) {
> + if (l == 1) {
> + uint32_t pfn_start = 0;
> + if (!libxl_find_pci_hole(&pfn_start))
> + b_info->u.pv.pci_hole_start = pfn_start;
> + } else
> + b_info->u.pv.pci_hole_start = l;
> + }
> if (!xlu_cfg_get_list (config, "pci", &pcis, 0, 0)) {
> int i;
> d_config->num_pcidevs = 0;
> diff --git a/tools/python/xen/lowlevel/xc/xc.c
> b/tools/python/xen/lowlevel/xc/xc.c
> --- a/tools/python/xen/lowlevel/xc/xc.c
> +++ b/tools/python/xen/lowlevel/xc/xc.c
> @@ -458,6 +458,7 @@ static PyObject *pyxc_linux_build(XcObje
> unsigned int mem_mb;
> unsigned long store_mfn = 0;
> unsigned long console_mfn = 0;
> + unsigned long pci_hole_start = 0;
> PyObject* elfnote_dict;
> PyObject* elfnote = NULL;
> PyObject* ret;
> @@ -467,14 +468,16 @@ static PyObject *pyxc_linux_build(XcObje
> "console_evtchn", "image",
> /* optional */
> "ramdisk", "cmdline", "flags",
> - "features", "vhpt", "superpages", NULL };
> -
> - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisii", kwd_list,
> + "features", "vhpt", "superpages",
> + "pci_hole", NULL };
> +
> + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssisiii", kwd_list,
> &domid, &store_evtchn, &mem_mb,
> &console_evtchn, &image,
> /* optional */
> &ramdisk, &cmdline, &flags,
> - &features, &vhpt, &superpages) )
> + &features, &vhpt, &superpages,
> + &pci_hole_start) )
> return NULL;
>
> xc_dom_loginit(self->xc_handle);
> @@ -486,6 +489,8 @@ static PyObject *pyxc_linux_build(XcObje
>
> dom->superpages = superpages;
>
> + dom->pci_hole = pci_hole_start;
> +
> if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
> ramdisk, flags, store_evtchn, &store_mfn,
> console_evtchn, &console_mfn) != 0 ) {
> @@ -1659,11 +1664,13 @@ static PyObject *pyxc_domain_set_memmap_
> {
> uint32_t dom;
> unsigned int maplimit_kb;
> -
> - if ( !PyArg_ParseTuple(args, "ii", &dom, &maplimit_kb) )
> + unsigned long pci_hole_start = 0;
> +
> + if ( !PyArg_ParseTuple(args, "ii|i", &dom, &maplimit_kb, &pci_hole_start)
> )
> return NULL;
>
> - if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
> + if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb,
> + pci_hole_start) != 0 )
> return pyxc_error_to_exception(self->xc_handle);
>
> Py_INCREF(zero);
> @@ -2661,6 +2668,7 @@ static PyMethodDef pyxc_methods[] = {
> "Set a domain's physical memory mappping limit\n"
> " dom [int]: Identifier of domain.\n"
> " map_limitkb [int]: .\n"
> + " pci_hole_start [int]: PFN for start of PCI hole (optional).\n"
> "Returns: [int] 0 on success; -1 on error.\n" },
>
> #ifdef __ia64__
> diff --git a/tools/python/xen/xend/XendConfig.py
> b/tools/python/xen/xend/XendConfig.py
> --- a/tools/python/xen/xend/XendConfig.py
> +++ b/tools/python/xen/xend/XendConfig.py
> @@ -241,6 +241,7 @@ XENAPI_CFG_TYPES = {
> 'suppress_spurious_page_faults': bool0,
> 's3_integrity' : int,
> 'superpages' : int,
> + 'pci_hole' : int,
> 'memory_sharing': int,
> 'pool_name' : str,
> 'Description': str,
> @@ -422,6 +423,7 @@ class XendConfig(dict):
> 'target': 0,
> 'pool_name' : 'Pool-0',
> 'superpages': 0,
> + 'pci_hole': 0,
> 'description': '',
> }
>
> @@ -2135,6 +2137,9 @@ class XendConfig(dict):
> image.append(['args', self['PV_args']])
> if self.has_key('superpages'):
> image.append(['superpages', self['superpages']])
> + if self.has_key('pci_hole'):
> + image.append(['pci_hole', self['pci_hole']])
> +
>
> for key in XENAPI_PLATFORM_CFG_TYPES.keys():
> if key in self['platform']:
> @@ -2179,6 +2184,10 @@ class XendConfig(dict):
> val = sxp.child_value(image_sxp, 'superpages')
> if val is not None:
> self['superpages'] = val
> +
> + val = sxp.child_value(image_sxp, 'pci_hole')
> + if val is not None:
> + self['pci_hole'] = val
>
> val = sxp.child_value(image_sxp, 'memory_sharing')
> if val is not None:
> diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py
> --- a/tools/python/xen/xend/image.py
> +++ b/tools/python/xen/xend/image.py
> @@ -84,6 +84,7 @@ class ImageHandler:
>
> ostype = None
> superpages = 0
> + pci_hole = 0
> memory_sharing = 0
>
> def __init__(self, vm, vmConfig):
> @@ -711,6 +712,7 @@ class LinuxImageHandler(ImageHandler):
> self.vramsize = int(vmConfig['platform'].get('videoram',4)) * 1024
> self.is_stubdom = (self.kernel.find('stubdom') >= 0)
> self.superpages = int(vmConfig['superpages'])
> + self.pci_hole = int(vmConfig['pci_hole'])
>
> def buildDomain(self):
> store_evtchn = self.vm.getStorePort()
> @@ -729,6 +731,7 @@ class LinuxImageHandler(ImageHandler):
> log.debug("features = %s", self.vm.getFeatures())
> log.debug("flags = %d", self.flags)
> log.debug("superpages = %d", self.superpages)
> + log.debug("pci_hole = %d", self.pci_hole)
> if arch.type == "ia64":
> log.debug("vhpt = %d", self.vhpt)
>
> @@ -742,7 +745,8 @@ class LinuxImageHandler(ImageHandler):
> features = self.vm.getFeatures(),
> flags = self.flags,
> vhpt = self.vhpt,
> - superpages = self.superpages)
> + superpages = self.superpages,
> + pci_hole = self.pci_hole)
>
> def getBitSize(self):
> return xc.getBitSize(image = self.kernel,
> @@ -774,7 +778,6 @@ class LinuxImageHandler(ImageHandler):
> args = args + ([ "-M", "xenpv"])
> return args
>
> -
> class HVMImageHandler(ImageHandler):
>
> ostype = "hvm"
> @@ -1065,7 +1068,7 @@ class X86_Linux_ImageHandler(LinuxImageH
> # set physical mapping limit
> # add an 8MB slack to balance backend allocations.
> mem_kb = self.getRequiredMaximumReservation() + (8 * 1024)
> - xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
> + xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb, self.pci_hole)
> rc = LinuxImageHandler.buildDomain(self)
> self.setCpuid()
> return rc
> diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py
> --- a/tools/python/xen/xm/create.py
> +++ b/tools/python/xen/xm/create.py
> @@ -680,6 +680,11 @@ gopts.var('superpages', val='0|1',
> fn=set_int, default=0,
> use="Create domain with superpages")
>
> +gopts.var('pci_hole', val='0x<XXX>|0',
> + fn=set_int, default=0,
> + use="""Create domain with a PCI hole. The value is the PFN of the
> + start of PCI hole. Usually that is 0xc0000.""")
> +
> def err(msg):
> """Print an error to stderr and exit.
> """
> @@ -770,6 +775,9 @@ def configure_image(vals):
> config_image.append(['args', vals.extra])
> if vals.superpages:
> config_image.append(['superpages', vals.superpages])
> + if vals.pci_hole:
> + config_image.append(['pci_hole', vals.pci_hole])
> +
>
> if vals.builder == 'hvm':
> configure_hvm(config_image, vals)
> diff --git a/tools/python/xen/xm/xenapi_create.py
> b/tools/python/xen/xm/xenapi_create.py
> --- a/tools/python/xen/xm/xenapi_create.py
> +++ b/tools/python/xen/xm/xenapi_create.py
> @@ -285,6 +285,8 @@ class xenapi_create:
> vm.attributes["s3_integrity"].value,
> "superpages":
> vm.attributes["superpages"].value,
> + "pci_hole":
> + vm.attributes["pci_hole"].value,
> "memory_static_max":
> get_child_node_attribute(vm, "memory", "static_max"),
> "memory_static_min":
> @@ -697,6 +699,8 @@ class sxp2xml:
> = str(get_child_by_name(config, "s3_integrity", 0))
> vm.attributes["superpages"] \
> = str(get_child_by_name(config, "superpages", 0))
> + vm.attributes["pci_hole"] \
> + = str(get_child_by_name(config, "pci_hole", 0))
> vm.attributes["pool_name"] \
> = str(get_child_by_name(config, "pool_name", "Pool-0"))
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|