 
	
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 5/5] tools: add example application to initialize dom0less PV drivers
 Hi, On 28/01/2022 21:33, 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. 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 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 --- tools/helpers/Makefile | 13 ++ tools/helpers/init-dom0less.c | 269 ++++++++++++++++++++++++++++++++++ Should we document how this is meant to be used? 2 files changed, 282 insertions(+) create mode 100644 tools/helpers/init-dom0less.c diff --git a/tools/helpers/Makefile b/tools/helpers/Makefile index 7f6c422440..8e42997052 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 > endifXEN_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) Why are we allocating 4 pages when only 2 (maybe 1) is necessary? Please don't rely on the fact the page size will be 4KB in Xen. Instead, use XC_PAGE_*. + if (rc < 0) + return rc; + + for (i = 0; i < NR_MAGIC_PAGES; i++) + p2m[i] = base + i; + + rc = xc_domain_populate_physmap_exact(dom->xch, dom->guest_domid, + NR_MAGIC_PAGES, 0, 0, p2m); + if (rc < 0) + return rc; + + dom->xenstore_pfn = base + XENSTORE_PFN_OFFSET; + + xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn); So you allocate 4 pages, use 2, but only clear 1. Can you explain why? Also, should not you check the error return here and ... + + xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_STORE_PFN, + dom->xenstore_pfn); here...?Also, in theory, as soon as you set xc_hvm_param_set(), the guest may be able to start using Xenstore. So wouldn't it be better to set it once you know everything is in place (i.e. just before calling xs_introduce_domain())? From my understanding, xs_write() will create a node that will only be readable/writable by the domain executing this binary (i.e. dom0). IOW, the guest will not see the nodes. So shouldn't you also set the permissions? Please use %u when you refer to unsigned value. Also, I think it would be a good practice to check the return value of snprintf(). This would avoid any future surprise of value truncated by mistake. The same is valid for all the other use below. As I wrote in v1, I think "restore" is misleading because the domain was never in Xenstore. So how about "create"? (Which BTW you agreed on back then). This is used as an iterator for a uint32_t value. So I think it should at least be unsigned int. + 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 cpu_str[STR_MAX_LENGTH]; + char xenstore_port_str[STR_MAX_LENGTH]; + char ring_ref_str[STR_MAX_LENGTH]; + xs_transaction_t t; + + domid = info->domid; + snprintf(id_str, STR_MAX_LENGTH, "%d", domid); + snprintf(dom_name_str, STR_MAX_LENGTH, "dom0less-%d", domid); + snprintf(uuid_str, STR_MAX_LENGTH, LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid)); + snprintf(vm_val_str, STR_MAX_LENGTH, + "vm/" LIBXL_UUID_FMT, LIBXL_UUID_BYTES(uuid)); + snprintf(max_memkb_str, STR_MAX_LENGTH, "%lu", info->max_memkb); + snprintf(ring_ref_str, STR_MAX_LENGTH, "%lld", + (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + XENSTORE_PFN_OFFSET); + snprintf(xenstore_port_str, STR_MAX_LENGTH, "%d", xenstore_port); > + +retry_transaction: + t = xs_transaction_start(xsh); + if (t == XBT_NULL) + return -errno; + + /* /vm */ + if (!do_xs_write_vm(xsh, t, uuid, "name", dom_name_str)) return -EIO; You should terminate the transaction in case of an error. + if (!do_xs_write_vm(xsh, t, uuid, "uuid", uuid_str)) return -EIO; + if (!do_xs_write_vm(xsh, t, uuid, "start_time", "0")) return -EIO; Wouldn't it be better to create based on the time now? I am a bit confused. You created 0 above, so why do you need to create it here again? + if (!do_xs_write_dom(xsh, t, domid, "cpu/availability", "online")) return -EIO; I can't seem to find this node in xenstore and libxl. + + if (!do_xs_write_dom(xsh, t, domid, "memory", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "memory/static-max", max_memkb_str)) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "memory/videoram", "-1")) return -EIO; How about "memory/target"? + + if (!do_xs_write_dom(xsh, t, domid, "device", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "device/suspend", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "device/suspend/event-channel", "")) return -EIO; + + if (!do_xs_write_dom(xsh, t, domid, "control", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/shutdown", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/feature-poweroff", "1")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/feature-reboot", "1")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/feature-suspend", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/sysrq", "")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control/platform-feature-multiprocessor-suspend", "1")) return -EIO; + if (!do_xs_write_dom(xsh, t, domid, "control", "platform-feature-xs_reset_watches")) return -EIO; It sounds like this wants to be "control/platform-feature...". If this hasn't been done, I would diff the libxl version and your version to check if all are the same (names, values, permissions). I would initialize dom to 0 to avoid any undef behavior. I find a bit odd you set the domid but not the event channel, page. Can you explain? Actually, can you explain why only half of the structure is initialized? This call as the risk to break the guest if the dom0 Linux doesn't support the acquire interface. This is because it will punch a hole in the domain memory where the grant-table may have already been mapped. Also, this function could fails. + + libxl_uuid_generate(&uuid); + xc_domain_sethandle(dom.xch, info->domid, libxl_uuid_bytearray(&uuid)); + + rc = gen_stub_json_config(info->domid, &uuid); + if (rc) + err(1, "gen_stub_json_config"); + + rc = restore_xenstore(xsh, info, uuid, dom.xenstore_evtchn); + if (rc) + err(1, "writing to xenstore"); + + xs_introduce_domain(xsh, info->domid, + (GUEST_MAGIC_BASE >> XC_PAGE_SHIFT) + XENSTORE_PFN_OFFSET, + dom.xenstore_evtchn); xs_introduce_domain() can technically fails. Would not this lead to initialize a domain with PV driver disabled?In addition to that, I think we should warn the users (maybe in some documentation) that this should not be called in parallel of scripts that may create new domain. Otherwise they may be picked up here as well... From my understanding xs_daemon_open() is deprecated. Instead, you want to use xs_open(0). However, libxl_ctx_alloc() is already opening a xenstore connection. So I think it would be better to rely on libxl and other the provided helpers (introduce new one if necessary) or just completely drop libxl from the equations. init_domain() could return an error. So shouldn't you check it?If yes, then the question is whether you want to continue to handle the other domain or abort? If the former, then what's the next steps if the domain is half initialized? So we try again? Cheers, -- Julien Grall 
 
 | 
|  | Lists.xenproject.org is hosted with RackSpace, monitoring our |