Mukesh Rathor
2013-Jan-12 01:53 UTC
[RFC PATCH 7/16]: PVH xen: User space changes to create a PVH domain
In this patch, I introduce xl/xc changes to create a PVH domain. For now, only one mode is supported/testd: > losetup /dev/loop1 guest.img > In vm.cfg file: disk = [''phy:/dev/loop1,xvda,w''] Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com> diff -r 5af39353f3f9 -r 956e77de73e4 tools/debugger/gdbsx/xg/xg_main.c --- a/tools/debugger/gdbsx/xg/xg_main.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/debugger/gdbsx/xg/xg_main.c Fri Jan 11 16:29:49 2013 -0800 @@ -80,6 +80,7 @@ int xgtrc_on = 0; struct xen_domctl domctl; /* just use a global domctl */ static int _hvm_guest; /* hvm guest? 32bit HVMs have 64bit context */ +static int _pvh_guest; /* PV guest in HVM container */ static domid_t _dom_id; /* guest domid */ static int _max_vcpu_id; /* thus max_vcpu_id+1 VCPUs */ static int _dom0_fd; /* fd of /dev/privcmd */ @@ -308,6 +309,7 @@ xg_attach(int domid, int guest_bitness) _max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id; _hvm_guest = (domctl.u.getdomaininfo.flags & XEN_DOMINF_hvm_guest); + _pvh_guest = (domctl.u.getdomaininfo.flags & XEN_DOMINF_pvh_guest); return _max_vcpu_id; } @@ -368,7 +370,7 @@ _change_TF(vcpuid_t which_vcpu, int gues int sz = sizeof(anyc); /* first try the MTF for hvm guest. otherwise do manually */ - if (_hvm_guest) { + if (_hvm_guest || _pvh_guest) { domctl.u.debug_op.vcpu = which_vcpu; domctl.u.debug_op.op = setit ? XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON : XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF; diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxc/xc_dom.h --- a/tools/libxc/xc_dom.h Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxc/xc_dom.h Fri Jan 11 16:29:49 2013 -0800 @@ -130,6 +130,7 @@ struct xc_dom_image { domid_t console_domid; domid_t xenstore_domid; xen_pfn_t shared_info_mfn; + int domcr_is_pvh; xc_interface *xch; domid_t guest_domid; diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxc/xc_dom_x86.c --- a/tools/libxc/xc_dom_x86.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxc/xc_dom_x86.c Fri Jan 11 16:29:49 2013 -0800 @@ -386,7 +386,8 @@ static int setup_pgtables_x86_64(struct pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86; l1tab[l1off] pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT; - if ( (addr >= dom->pgtables_seg.vstart) && + if ( (!dom->domcr_is_pvh) && + (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) ) @@ -716,7 +717,7 @@ int arch_setup_meminit(struct xc_dom_ima rc = x86_compat(dom->xch, dom->guest_domid, dom->guest_type); if ( rc ) return rc; - if ( xc_dom_feature_translated(dom) ) + if ( xc_dom_feature_translated(dom) && !dom->domcr_is_pvh ) { dom->shadow_enabled = 1; rc = x86_shadow(dom->xch, dom->guest_domid); @@ -830,7 +831,7 @@ int arch_setup_bootlate(struct xc_dom_im } /* Map grant table frames into guest physmap. */ - for ( i = 0; ; i++ ) + for ( i = 0; !dom->domcr_is_pvh; i++ ) { rc = xc_domain_add_to_physmap(dom->xch, dom->guest_domid, XENMAPSPACE_grant_table, diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxl/libxl_create.c Fri Jan 11 16:29:49 2013 -0800 @@ -409,6 +409,8 @@ int libxl__domain_make(libxl__gc *gc, li flags |= XEN_DOMCTL_CDF_hvm_guest; flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0; flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off; + } else if ( libxl_defbool_val(info->ci_pvh) ) { + flags |= XEN_DOMCTL_CDF_hap; } *domid = -1; diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxl/libxl_dom.c Fri Jan 11 16:29:49 2013 -0800 @@ -270,7 +270,8 @@ int libxl__build_pre(libxl__gc *gc, uint if (rtc_timeoffset) xc_domain_set_time_offset(ctx->xch, domid, rtc_timeoffset); - if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + if (info->type == LIBXL_DOMAIN_TYPE_HVM || + libxl_defbool_val(info->bi_pvh) ) { unsigned long shadow; shadow = (info->shadow_memkb + 1023) / 1024; xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); @@ -368,9 +369,23 @@ int libxl__build_pv(libxl__gc *gc, uint3 struct xc_dom_image *dom; int ret; int flags = 0; + int is_pvh = libxl_defbool_val(info->bi_pvh); xc_dom_loginit(ctx->xch); + if (is_pvh) { + char *pv_feats = "writable_descriptor_tables|auto_translated_physmap" + "|supervisor_mode_kernel|hvm_callback_vector"; + + if (info->u.pv.features && info->u.pv.features[0] != ''\0'') + { + LOG(ERROR, "Didn''t expect info->u.pv.features to contain string\n"); + LOG(ERROR, "String: %s\n", info->u.pv.features); + return ERROR_FAIL; + } + info->u.pv.features = strdup(pv_feats); + } + dom = xc_dom_allocate(ctx->xch, state->pv_cmdline, info->u.pv.features); if (!dom) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_allocate failed"); @@ -409,6 +424,7 @@ int libxl__build_pv(libxl__gc *gc, uint3 } dom->flags = flags; + dom->domcr_is_pvh = is_pvh; dom->console_evtchn = state->console_port; dom->console_domid = state->console_domid; dom->xenstore_evtchn = state->store_port; @@ -438,7 +454,8 @@ int libxl__build_pv(libxl__gc *gc, uint3 LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_image failed"); goto out; } - if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) { + /* PVH sets up its own grant during boot via hvm mechanisms */ + if ( !is_pvh && (ret = xc_dom_gnttab_init(dom)) != 0 ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_gnttab_init failed"); goto out; } diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxl/libxl_types.idl Fri Jan 11 16:29:49 2013 -0800 @@ -243,6 +243,7 @@ libxl_domain_create_info = Struct("domai ("platformdata", libxl_key_value_list), ("poolid", uint32), ("run_hotplug_scripts",libxl_defbool), + ("ci_pvh", libxl_defbool), ], dir=DIR_IN) MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT") @@ -339,6 +340,7 @@ libxl_domain_build_info = Struct("domain ])), ("invalid", Struct(None, [])), ], keyvar_init_val = "LIBXL_DOMAIN_TYPE_INVALID")), + ("bi_pvh", libxl_defbool), ], dir=DIR_IN ) diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/libxl/xl_cmdimpl.c Fri Jan 11 16:29:49 2013 -0800 @@ -615,8 +615,18 @@ static void parse_config_data(const char !strncmp(buf, "hvm", strlen(buf))) c_info->type = LIBXL_DOMAIN_TYPE_HVM; + libxl_defbool_setdefault(&c_info->ci_pvh, false); + libxl_defbool_setdefault(&c_info->hap, false); + xlu_cfg_get_defbool(config, "pvh", &c_info->ci_pvh, 0); xlu_cfg_get_defbool(config, "hap", &c_info->hap, 0); + if (libxl_defbool_val(c_info->ci_pvh) && + !libxl_defbool_val(c_info->hap)) { + + fprintf(stderr, "hap is required for PVH domain\n"); + exit(1); + } + if (xlu_cfg_replace_string (config, "name", &c_info->name, 0)) { fprintf(stderr, "Domain name must be specified.\n"); exit(1); @@ -916,6 +926,7 @@ static void parse_config_data(const char b_info->u.pv.cmdline = cmdline; xlu_cfg_replace_string (config, "ramdisk", &b_info->u.pv.ramdisk, 0); + libxl_defbool_set(&b_info->bi_pvh, libxl_defbool_val(c_info->ci_pvh)); break; } default: diff -r 5af39353f3f9 -r 956e77de73e4 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Fri Jan 11 16:27:46 2013 -0800 +++ b/tools/xenstore/xenstored_domain.c Fri Jan 11 16:29:49 2013 -0800 @@ -168,13 +168,15 @@ static int readchn(struct connection *co static void *map_interface(domid_t domid, unsigned long mfn) { if (*xcg_handle != NULL) { - /* this is the preferred method */ - return xc_gnttab_map_grant_ref(*xcg_handle, domid, + void *addr; + /* this is the preferred method */ + addr = xc_gnttab_map_grant_ref(*xcg_handle, domid, GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); - } else { - return xc_map_foreign_range(*xc_handle, domid, - getpagesize(), PROT_READ|PROT_WRITE, mfn); - } + if (addr) + return addr; + } + return xc_map_foreign_range(*xc_handle, domid, + getpagesize(), PROT_READ|PROT_WRITE, mfn); } static void unmap_interface(void *interface)
Stefano Stabellini
2013-Jan-14 16:26 UTC
Re: [RFC PATCH 7/16]: PVH xen: User space changes to create a PVH domain
On Sat, 12 Jan 2013, Mukesh Rathor wrote:> In this patch, I introduce xl/xc changes to create a PVH domain. For > now, only one mode is supported/testd: > > losetup /dev/loop1 guest.img > > In vm.cfg file: disk = [''phy:/dev/loop1,xvda,w''] > > Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com> > > diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/libxl_dom.c > --- a/tools/libxl/libxl_dom.c Fri Jan 11 16:27:46 2013 -0800 > +++ b/tools/libxl/libxl_dom.c Fri Jan 11 16:29:49 2013 -0800 > @@ -270,7 +270,8 @@ int libxl__build_pre(libxl__gc *gc, uint > if (rtc_timeoffset) > xc_domain_set_time_offset(ctx->xch, domid, rtc_timeoffset); > > - if (info->type == LIBXL_DOMAIN_TYPE_HVM) { > + if (info->type == LIBXL_DOMAIN_TYPE_HVM || > + libxl_defbool_val(info->bi_pvh) ) { > unsigned long shadow; > shadow = (info->shadow_memkb + 1023) / 1024; > xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL); > @@ -368,9 +369,23 @@ int libxl__build_pv(libxl__gc *gc, uint3 > struct xc_dom_image *dom; > int ret; > int flags = 0; > + int is_pvh = libxl_defbool_val(info->bi_pvh); > > xc_dom_loginit(ctx->xch); > > + if (is_pvh) { > + char *pv_feats = "writable_descriptor_tables|auto_translated_physmap" > + "|supervisor_mode_kernel|hvm_callback_vector"; > + > + if (info->u.pv.features && info->u.pv.features[0] != ''\0'') > + { > + LOG(ERROR, "Didn''t expect info->u.pv.features to contain string\n"); > + LOG(ERROR, "String: %s\n", info->u.pv.features); > + return ERROR_FAIL; > + } > + info->u.pv.features = strdup(pv_feats); > + } > + > dom = xc_dom_allocate(ctx->xch, state->pv_cmdline, info->u.pv.features); > if (!dom) { > LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_allocate failed"); > @@ -409,6 +424,7 @@ int libxl__build_pv(libxl__gc *gc, uint3 > } > > dom->flags = flags; > + dom->domcr_is_pvh = is_pvh; > dom->console_evtchn = state->console_port; > dom->console_domid = state->console_domid; > dom->xenstore_evtchn = state->store_port; > @@ -438,7 +454,8 @@ int libxl__build_pv(libxl__gc *gc, uint3 > LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_image failed"); > goto out; > } > - if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) { > + /* PVH sets up its own grant during boot via hvm mechanisms */ > + if ( !is_pvh && (ret = xc_dom_gnttab_init(dom)) != 0 ) { > LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_gnttab_init failed"); > goto out; > }I have the same problem on ARM and I have just managed to fix it. Provided that gnttab_create_shared_page and gnttab_shared_gmfn are implemented correctly for PVH guests, I think that you just need to call xc_dom_gnttab_hvm_seed instead of xc_dom_gnttab_init. Keep an eye on the ARM patch series that I am about to send: it is going to conflict with this patch, but it should sort out this issue for PVH too.> diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/libxl_types.idl > --- a/tools/libxl/libxl_types.idl Fri Jan 11 16:27:46 2013 -0800 > +++ b/tools/libxl/libxl_types.idl Fri Jan 11 16:29:49 2013 -0800 > @@ -243,6 +243,7 @@ libxl_domain_create_info = Struct("domai > ("platformdata", libxl_key_value_list), > ("poolid", uint32), > ("run_hotplug_scripts",libxl_defbool), > + ("ci_pvh", libxl_defbool), > ], dir=DIR_IN) > > MemKB = UInt(64, init_val = "LIBXL_MEMKB_DEFAULT") > @@ -339,6 +340,7 @@ libxl_domain_build_info = Struct("domain > ])), > ("invalid", Struct(None, [])), > ], keyvar_init_val = "LIBXL_DOMAIN_TYPE_INVALID")), > + ("bi_pvh", libxl_defbool), > ], dir=DIR_IN > ) > > diff -r 5af39353f3f9 -r 956e77de73e4 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Fri Jan 11 16:27:46 2013 -0800 > +++ b/tools/libxl/xl_cmdimpl.c Fri Jan 11 16:29:49 2013 -0800 > @@ -615,8 +615,18 @@ static void parse_config_data(const char > !strncmp(buf, "hvm", strlen(buf))) > c_info->type = LIBXL_DOMAIN_TYPE_HVM; > > + libxl_defbool_setdefault(&c_info->ci_pvh, false); > + libxl_defbool_setdefault(&c_info->hap, false); > + xlu_cfg_get_defbool(config, "pvh", &c_info->ci_pvh, 0); > xlu_cfg_get_defbool(config, "hap", &c_info->hap, 0); > > + if (libxl_defbool_val(c_info->ci_pvh) && > + !libxl_defbool_val(c_info->hap)) { > + > + fprintf(stderr, "hap is required for PVH domain\n"); > + exit(1); > + } > + > if (xlu_cfg_replace_string (config, "name", &c_info->name, 0)) { > fprintf(stderr, "Domain name must be specified.\n"); > exit(1); > @@ -916,6 +926,7 @@ static void parse_config_data(const char > > b_info->u.pv.cmdline = cmdline; > xlu_cfg_replace_string (config, "ramdisk", &b_info->u.pv.ramdisk, 0); > + libxl_defbool_set(&b_info->bi_pvh, libxl_defbool_val(c_info->ci_pvh)); > break; > } > default:I think that it is time to add a set of arch-specific options in the IDL and in the config file, so that we don''t have to parse PVH and HAP on ARM, where they are meaningless.> diff -r 5af39353f3f9 -r 956e77de73e4 tools/xenstore/xenstored_domain.c > --- a/tools/xenstore/xenstored_domain.c Fri Jan 11 16:27:46 2013 -0800 > +++ b/tools/xenstore/xenstored_domain.c Fri Jan 11 16:29:49 2013 -0800 > @@ -168,13 +168,15 @@ static int readchn(struct connection *co > static void *map_interface(domid_t domid, unsigned long mfn) > { > if (*xcg_handle != NULL) { > - /* this is the preferred method */ > - return xc_gnttab_map_grant_ref(*xcg_handle, domid, > + void *addr; > + /* this is the preferred method */ > + addr = xc_gnttab_map_grant_ref(*xcg_handle, domid, > GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); > - } else { > - return xc_map_foreign_range(*xc_handle, domid, > - getpagesize(), PROT_READ|PROT_WRITE, mfn); > - } > + if (addr) > + return addr; > + } > + return xc_map_foreign_range(*xc_handle, domid, > + getpagesize(), PROT_READ|PROT_WRITE, mfn); > } > > static void unmap_interface(void *interface)Even though I think I managed to fix this problem for ARM and PVH, I still welcome this change.