[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v6 6/7] tools: add example application to initialize dom0less PV drivers
On Thu, 5 May 2022, Juergen Gross wrote: > On 05.05.22 02:16, Stefano Stabellini wrote: > > From: Luca Miccio <lucmiccio@xxxxxxxxx> > > > > Add an example application that can be run in dom0 to complete the > > dom0less domains initialization so that they can get access to xenstore > > and use PV drivers. > > > > The application sets "connection" to XENSTORE_RECONNECT on the xenstore > > page before calling xs_introduce_domain to signal that the connection is > > not ready yet to be used. XENSTORE_RECONNECT is reset soon after by > > xenstored. > > > > Signed-off-by: Luca Miccio <lucmiccio@xxxxxxxxx> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx> > > CC: Wei Liu <wl@xxxxxxx> > > CC: Anthony PERARD <anthony.perard@xxxxxxxxxx> > > CC: Juergen Gross <jgross@xxxxxxxx> > > --- > > Changes in v6: > > - include xs_wire.h and use its definitions > > > > Changes in v5: > > - set XS_CONNECTION_STATE_RECONNECTING before xs_introduce_domain > > > > Changes in v4: > > - only alloc xs page (no other magic pages) > > - add xenstore permissions > > - check all return values > > - rename restore_xenstore to create_xenstore > > - set target_memkb > > - set start_time properly > > - close xs transaction on error > > - call xc_dom_gnttab_seed instead of xc_dom_gnttab_init > > - xs_open instead of xs_daemon_open > > > > Changes in v3: > > - handle xenstore errors > > - add an in-code comment about xenstore entries > > - less verbose output > > - clean-up error path in main > > > > Changes in v2: > > - do not set HVM_PARAM_STORE_EVTCHN twice > > - rename restore_xenstore to create_xenstore > > - increase maxmem > > > > connection reconnecting > > --- > > tools/helpers/Makefile | 13 ++ > > tools/helpers/init-dom0less.c | 340 ++++++++++++++++++++++++++++++++++ > > 2 files changed, 353 insertions(+) > > create mode 100644 tools/helpers/init-dom0less.c > > > > diff --git a/tools/helpers/Makefile b/tools/helpers/Makefile > > index 7f6c422440..8d78ab1e90 100644 > > --- a/tools/helpers/Makefile > > +++ b/tools/helpers/Makefile > > @@ -10,6 +10,9 @@ ifeq ($(CONFIG_Linux),y) > > ifeq ($(CONFIG_X86),y) > > PROGS += init-xenstore-domain > > endif > > +ifeq ($(CONFIG_ARM),y) > > +PROGS += init-dom0less > > +endif > > endif > > XEN_INIT_DOM0_OBJS = xen-init-dom0.o init-dom-json.o > > @@ -26,6 +29,13 @@ $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS += > > $(CFLAGS_libxenstore) > > $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS += $(CFLAGS_libxenlight) > > $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS += -include > > $(XEN_ROOT)/tools/config.h > > +INIT_DOM0LESS_OBJS = init-dom0less.o init-dom-json.o > > +$(INIT_DOM0LESS_OBJS): CFLAGS += $(CFLAGS_libxentoollog) > > +$(INIT_DOM0LESS_OBJS): CFLAGS += $(CFLAGS_libxenstore) > > +$(INIT_DOM0LESS_OBJS): CFLAGS += $(CFLAGS_libxenlight) > > +$(INIT_DOM0LESS_OBJS): CFLAGS += $(CFLAGS_libxenctrl) > > +$(INIT_DOM0LESS_OBJS): CFLAGS += $(CFLAGS_libxenevtchn) > > + > > .PHONY: all > > all: $(PROGS) > > @@ -35,6 +45,9 @@ xen-init-dom0: $(XEN_INIT_DOM0_OBJS) > > init-xenstore-domain: $(INIT_XENSTORE_DOMAIN_OBJS) > > $(CC) $(LDFLAGS) -o $@ $(INIT_XENSTORE_DOMAIN_OBJS) > > $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) > > $(LDLIBS_libxenguest) $(LDLIBS_libxenlight) $(APPEND_LDFLAGS) > > +init-dom0less: $(INIT_DOM0LESS_OBJS) > > + $(CC) $(LDFLAGS) -o $@ $(INIT_DOM0LESS_OBJS) $(LDLIBS_libxenctrl) > > $(LDLIBS_libxenevtchn) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) > > $(LDLIBS_libxenlight) $(LDLIBS_libxenguest) $(LDLIBS_libxenforeignmemory) > > $(APPEND_LDFLAGS) > > + > > .PHONY: install > > install: all > > $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC_BIN) > > diff --git a/tools/helpers/init-dom0less.c b/tools/helpers/init-dom0less.c > > new file mode 100644 > > index 0000000000..bfd5ff0761 > > --- /dev/null > > +++ b/tools/helpers/init-dom0less.c > > @@ -0,0 +1,340 @@ > > +#include <stdbool.h> > > +#include <syslog.h> > > +#include <stdio.h> > > +#include <err.h> > > +#include <stdlib.h> > > +#include <sys/time.h> > > +#include <xenstore.h> > > +#include <xenctrl.h> > > +#include <xenguest.h> > > +#include <libxl.h> > > +#include <xenevtchn.h> > > +#include <xenforeignmemory.h> > > +#include <xen/io/xs_wire.h> > > + > > +#include "init-dom-json.h" > > + > > +#define XENSTORE_PFN_OFFSET 1 > > +#define STR_MAX_LENGTH 64 > > + > > +static int alloc_xs_page(struct xc_interface_core *xch, > > + libxl_dominfo *info, > > + uint64_t *xenstore_pfn) > > +{ > > + int rc; > > + const xen_pfn_t base = GUEST_MAGIC_BASE >> XC_PAGE_SHIFT; > > + xen_pfn_t p2m = (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + > > XENSTORE_PFN_OFFSET; > > + > > + rc = xc_domain_setmaxmem(xch, info->domid, > > + info->max_memkb + (XC_PAGE_SIZE/1024)); > > + if (rc < 0) > > + return rc; > > + > > + rc = xc_domain_populate_physmap_exact(xch, info->domid, 1, 0, 0, &p2m); > > + if (rc < 0) > > + return rc; > > + > > + *xenstore_pfn = base + XENSTORE_PFN_OFFSET; > > + rc = xc_clear_domain_page(xch, info->domid, *xenstore_pfn); > > + if (rc < 0) > > + return rc; > > + > > + return 0; > > +} > > + > > +static bool do_xs_write_dom(struct xs_handle *xsh, xs_transaction_t t, > > + domid_t domid, char *path, char *val) > > +{ > > + char full_path[STR_MAX_LENGTH]; > > + struct xs_permissions perms[2]; > > + > > + perms[0].id = domid; > > + perms[0].perms = XS_PERM_NONE; > > + perms[1].id = 0; > > + perms[1].perms = XS_PERM_READ; > > + > > + if (snprintf(full_path, STR_MAX_LENGTH, > > + "/local/domain/%u/%s", domid, path) < 0) > > + return false; > > + if (!xs_write(xsh, t, full_path, val, strlen(val))) > > + return false; > > + return xs_set_permissions(xsh, t, full_path, perms, 2); > > +} > > + > > +static bool do_xs_write_libxl(struct xs_handle *xsh, xs_transaction_t t, > > + domid_t domid, char *path, char *val) > > +{ > > + char full_path[STR_MAX_LENGTH]; > > + > > + if (snprintf(full_path, STR_MAX_LENGTH, > > + "/libxl/%u/%s", domid, path) < 0) > > + return false; > > + return xs_write(xsh, t, full_path, val, strlen(val)); > > +} > > + > > +static bool do_xs_write_vm(struct xs_handle *xsh, xs_transaction_t t, > > + libxl_uuid uuid, char *path, char *val) > > +{ > > + char full_path[STR_MAX_LENGTH]; > > + > > + if (snprintf(full_path, STR_MAX_LENGTH, > > + "/vm/" LIBXL_UUID_FMT "/%s", LIBXL_UUID_BYTES(uuid), path) > > < 0) > > + return false; > > + return xs_write(xsh, t, full_path, val, strlen(val)); > > +} > > + > > +/* > > + * The xenstore nodes are the xenstore nodes libxl writes at domain > > + * creation. > > + * > > + * The list was retrieved by running xenstore-ls on a corresponding > > + * domain started by xl/libxl. > > + */ > > +static int create_xenstore(struct xs_handle *xsh, > > + libxl_dominfo *info, libxl_uuid uuid, > > + evtchn_port_t xenstore_port) > > +{ > > + domid_t domid; > > + unsigned int i; > > + char uuid_str[STR_MAX_LENGTH]; > > + char dom_name_str[STR_MAX_LENGTH]; > > + char vm_val_str[STR_MAX_LENGTH]; > > + char id_str[STR_MAX_LENGTH]; > > + char max_memkb_str[STR_MAX_LENGTH]; > > + char target_memkb_str[STR_MAX_LENGTH]; > > + char cpu_str[STR_MAX_LENGTH]; > > + char xenstore_port_str[STR_MAX_LENGTH]; > > + char ring_ref_str[STR_MAX_LENGTH]; > > + xs_transaction_t t; > > + struct timeval start_time; > > + char start_time_str[STR_MAX_LENGTH]; > > + int rc; > > + > > + if (gettimeofday(&start_time, NULL) < 0) > > + return -errno; > > + rc = snprintf(start_time_str, STR_MAX_LENGTH, "%jd.%02d", > > + (intmax_t)start_time.tv_sec, (int)start_time.tv_usec / 10000); > > + if (rc < 0) > > + return rc; > > + > > + domid = info->domid; > > + rc = snprintf(id_str, STR_MAX_LENGTH, "%u", domid); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(dom_name_str, STR_MAX_LENGTH, "dom0less-%u", domid); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(uuid_str, STR_MAX_LENGTH, LIBXL_UUID_FMT, > > LIBXL_UUID_BYTES(uuid)); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(vm_val_str, STR_MAX_LENGTH, > > + "vm/" LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid)); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(max_memkb_str, STR_MAX_LENGTH, "%lu", info->max_memkb); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(target_memkb_str, STR_MAX_LENGTH, "%lu", > > info->current_memkb); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(ring_ref_str, STR_MAX_LENGTH, "%lld", > > + (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + > > XENSTORE_PFN_OFFSET); > > + if (rc < 0) > > + return rc; > > + rc = snprintf(xenstore_port_str, STR_MAX_LENGTH, "%u", xenstore_port); > > + if (rc < 0) > > + return rc; > > + > > +retry_transaction: > > + t = xs_transaction_start(xsh); > > + if (t == XBT_NULL) > > + return -errno; > > + > > + rc = -EIO; > > + /* /vm */ > > + if (!do_xs_write_vm(xsh, t, uuid, "name", dom_name_str)) goto err; > > + if (!do_xs_write_vm(xsh, t, uuid, "uuid", uuid_str)) goto err; > > + if (!do_xs_write_vm(xsh, t, uuid, "start_time", start_time_str)) goto > > err; > > + > > + /* /domain */ > > + if (!do_xs_write_dom(xsh, t, domid, "vm", vm_val_str)) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "name", dom_name_str)) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "cpu", "")) goto err; > > + for (i = 0; i < info->vcpu_max_id; i++) { > > + rc = snprintf(cpu_str, STR_MAX_LENGTH, "cpu/%u/availability/", i); > > + if (rc < 0) > > + goto err; > > + rc = -EIO; > > + if (!do_xs_write_dom(xsh, t, domid, cpu_str, > > + (info->cpupool & (1 << i)) ? "online" : > > "offline")) > > + goto err; > > + } > > + > > + if (!do_xs_write_dom(xsh, t, domid, "memory", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "memory/static-max", > > max_memkb_str)) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "memory/target", target_memkb_str)) > > goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "memory/videoram", "-1")) goto err; > > + > > + if (!do_xs_write_dom(xsh, t, domid, "device", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "device/suspend", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "device/suspend/event-channel", > > "")) goto err; > > + > > + if (!do_xs_write_dom(xsh, t, domid, "control", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "control/shutdown", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "control/feature-poweroff", "1")) > > goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "control/feature-reboot", "1")) > > goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "control/feature-suspend", "")) > > goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "control/sysrq", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, > > "control/platform-feature-multiprocessor-suspend", "1")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, > > "control/platform-feature-xs_reset_watches", "1")) goto err; > > + > > + if (!do_xs_write_dom(xsh, t, domid, "domid", id_str)) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "data", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "drivers", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "feature", "")) goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "attr", "")) goto err; > > + > > + if (!do_xs_write_dom(xsh, t, domid, "store/port", xenstore_port_str)) > > goto err; > > + if (!do_xs_write_dom(xsh, t, domid, "store/ring-ref", ring_ref_str)) > > goto err; > > + > > + if (!do_xs_write_libxl(xsh, t, domid, "type", "pvh")) goto err; > > + if (!do_xs_write_libxl(xsh, t, domid, "dm-version", "qemu_xen")) goto > > err; > > + > > + if (!xs_transaction_end(xsh, t, false)) { > > + if (errno == EAGAIN) > > + goto retry_transaction; > > + else > > + return -errno; > > + } > > + > > + return 0; > > + > > +err: > > + xs_transaction_end(xsh, t, true); > > + return rc; > > +} > > + > > +static int init_domain(struct xs_handle *xsh, > > + struct xc_interface_core *xch, > > + xenforeignmemory_handle *xfh, > > + libxl_dominfo *info) > > +{ > > + libxl_uuid uuid; > > + uint64_t xenstore_evtchn, xenstore_pfn; > > + int rc; > > + struct xenstore_domain_interface *intf; > > + > > + printf("Init dom0less domain: %u\n", info->domid); > > + > > + rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN, > > + &xenstore_evtchn); > > + if (rc != 0) { > > + printf("Failed to get HVM_PARAM_STORE_EVTCHN\n"); > > + return 1; > > + } > > + > > + /* Alloc xenstore page */ > > + if (alloc_xs_page(xch, info, &xenstore_pfn) != 0) { > > + printf("Error on alloc magic pages\n"); > > + return 1; > > + } > > + > > + intf = xenforeignmemory_map(xfh, info->domid, XS_READ | XS_WRITE, 1, > > I don't think you want to pass the xenstore wire commands here. Did you mean > PROT_READ | PROT_WRITE? Ops, you are right. I'll fix that. > > + &xenstore_pfn, NULL); > > + if (!intf) { > > + printf("Error mapping xenstore page\n"); > > + return 1; > > + } > > + intf->connection = XENSTORE_RECONNECT; > > + xenforeignmemory_unmap(xfh, intf, 1); > > + > > + rc = xc_dom_gnttab_seed(xch, info->domid, true, > > + (xen_pfn_t)-1, xenstore_pfn, 0, 0); > > So no support for Xenstore running in a stub-domain? We don't have stub-domains on ARM yet (unfortunately), so we cannot run xenstore in one. It would not be possible for me to test it at the moment.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |