diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h index 86e23ee..ebc77ac 100644 --- a/tools/libxc/xc_dom.h +++ b/tools/libxc/xc_dom.h @@ -136,6 +136,7 @@ struct xc_dom_image { int8_t vhpt_size_log2; /* for IA64 */ int8_t superpages; int claim_enabled; /* 0 by default, 1 enables it */ + int fix; int shadow_enabled; int xen_version; diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c index 126c0f8..57291ab 100644 --- a/tools/libxc/xc_dom_x86.c +++ b/tools/libxc/xc_dom_x86.c @@ -360,13 +360,14 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom) l3_pgentry_64_t *l3tab = NULL; l2_pgentry_64_t *l2tab = NULL; l1_pgentry_64_t *l1tab = NULL; - uint64_t l4off, l3off, l2off, l1off; + uint64_t l4off = 0, l3off = 0, l2off = 0, l1off = 0; uint64_t addr; xen_pfn_t pgpfn; if ( l4tab == NULL ) goto pfn_error; - + + DOMPRINTF("%s: fix %s", __FUNCTION__, dom->fix ? "enabled" : "disabled"); for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end; addr += PAGE_SIZE_X86 ) { @@ -391,8 +392,10 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom) l3off = l3_table_offset_x86_64(addr); l3tab[l3off] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT; - if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) ) - l3tab = NULL; + if (!dom->fix) { + if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) ) + l3tab = NULL; + } l2pfn++; } @@ -405,8 +408,10 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom) l2off = l2_table_offset_x86_64(addr); l2tab[l2off] = pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT; - if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) ) - l2tab = NULL; + if (!dom->fix) { + if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) ) + l2tab = NULL; + } l1pfn++; } @@ -418,8 +423,17 @@ static int setup_pgtables_x86_64(struct xc_dom_image *dom) if ( (addr >= dom->pgtables_seg.vstart) && (addr < dom->pgtables_seg.vend) ) l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */ - if ( l1off == (L1_PAGETABLE_ENTRIES_X86_64 - 1) ) - l1tab = NULL; + + if (dom->fix) { + if ( l1off == (L1_PAGETABLE_ENTRIES_X86_64 - 1) ) { + l1tab = NULL; + if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) ) { + l2tab = NULL; + if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) ) + l3tab = NULL; + } + } + } } return 0; diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 6e2252a..8ec8bab 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -375,6 +375,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, dom->xenstore_evtchn = state->store_port; dom->xenstore_domid = state->store_domid; dom->claim_enabled = libxl_defbool_val(info->claim_mode); + dom->fix = libxl_defbool_val(info->u.pv.fix); if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) { LOGE(ERROR, "xc_dom_boot_xen_init failed"); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 85341a0..fdda8a9 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -347,6 +347,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("features", string, {'const': True}), # Use host's E820 for PCI passthrough. ("e820_host", libxl_defbool), + ("fix", libxl_defbool), ])), ("invalid", Struct(None, [])), ], keyvar_init_val = "LIBXL_DOMAIN_TYPE_INVALID")), diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 884f050..834ff74 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -1279,7 +1279,8 @@ skip_vfb: if (!xlu_cfg_get_long (config, "pci_permissive", &l, 0)) pci_permissive = l; - + + xlu_cfg_get_defbool(config, "fix", &b_info->u.pv.fix, 0); /* 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) {