From: David Woodhouse Date: Thu, 12 Oct 2023 13:39:35 +0000 (+0100) Subject: WIP Xen console hacks X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fxenfv-console;p=users%2Fdwmw2%2Fqemu.git WIP Xen console hacks Signed-off-by: David Woodhouse --- diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 810dae3f44..4760d58acc 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -256,7 +256,7 @@ out: g_free(type); return ret; } - +void *conshack; static int con_initialise(struct XenLegacyDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); @@ -268,12 +268,14 @@ static int con_initialise(struct XenLegacyDevice *xendev) return -1; if (xenstore_read_int(con->console, "limit", &limit) == 0) con->buffer.max_capacity = limit; - + printf("ref %x port %d\n", con->ring_ref, con->xendev.remote_port); if (!xendev->dev) { xen_pfn_t mfn = con->ring_ref; con->sring = qemu_xen_foreignmem_map(con->xendev.dom, NULL, PROT_READ | PROT_WRITE, 1, &mfn, NULL); + con->sring = conshack; + printf("sring %p\n", con->sring); } else { con->sring = xen_be_map_grant_ref(xendev, con->ring_ref, PROT_READ | PROT_WRITE); diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c index 3300e0614a..df91b37430 100644 --- a/hw/i386/kvm/xen_xenstore.c +++ b/hw/i386/kvm/xen_xenstore.c @@ -54,6 +54,7 @@ struct XenXenstoreState { XenstoreImplState *impl; GList *watch_events; /* for the guest */ + MemoryRegion console_page; MemoryRegion xenstore_page; struct xenstore_domain_interface *xs; uint8_t req_data[XENSTORE_HEADER_SIZE + XENSTORE_PAYLOAD_MAX]; @@ -63,6 +64,8 @@ struct XenXenstoreState { bool rsp_pending; bool fatal_error; + evtchn_port_t cons_guest_port; + evtchn_port_t guest_port; evtchn_port_t be_port; struct xenevtchn_handle *eh; @@ -80,8 +83,9 @@ static void xen_xenstore_event(void *opaque); static void fire_watch_cb(void *opaque, const char *path, const char *token); static struct xenstore_backend_ops emu_xenstore_backend_ops; - -static void G_GNUC_PRINTF (4, 5) relpath_printf(XenXenstoreState *s, +extern void *conshack; +static void G_GNUC_PRINTF (5, 6) relpath_printf(XenXenstoreState *s, + unsigned int domid, GList *perms, const char *relpath, const char *fmt, ...) @@ -92,7 +96,7 @@ static void G_GNUC_PRINTF (4, 5) relpath_printf(XenXenstoreState *s, GByteArray *data; int err; - abspath = g_strdup_printf("/local/domain/%u/%s", xen_domid, relpath); + abspath = g_strdup_printf("/local/domain/%u/%s", domid, relpath); va_start(args, fmt); value = g_strdup_vprintf(fmt, args); va_end(args); @@ -125,6 +129,11 @@ static void xen_xenstore_realize(DeviceState *dev, Error **errp) s->xs = memory_region_get_ram_ptr(&s->xenstore_page); memset(s->xs, 0, XEN_PAGE_SIZE); + memory_region_init_ram(&s->console_page, OBJECT(dev), "xen:console_page", + XEN_PAGE_SIZE, &error_abort); + memory_region_set_enabled(&s->console_page, true); + memset(memory_region_get_ram_ptr(&s->console_page), 0, XEN_PAGE_SIZE); + conshack = memory_region_get_ram_ptr(&s->console_page); /* We can't map it this early as KVM isn't ready */ xen_xenstore_singleton = s; @@ -144,37 +153,37 @@ static void xen_xenstore_realize(DeviceState *dev, Error **errp) perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, DOMID_QEMU)); perms = g_list_append(perms, xs_perm_as_string(XS_PERM_READ, xen_domid)); - relpath_printf(s, perms, "", "%s", ""); + relpath_printf(s, xen_domid, perms, "", "%s", ""); - relpath_printf(s, perms, "domid", "%u", xen_domid); + relpath_printf(s, xen_domid, perms, "domid", "%u", xen_domid); - relpath_printf(s, perms, "control/platform-feature-xs_reset_watches", "%u", 1); - relpath_printf(s, perms, "control/platform-feature-multiprocessor-suspend", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/platform-feature-xs_reset_watches", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/platform-feature-multiprocessor-suspend", "%u", 1); - relpath_printf(s, perms, "platform/acpi", "%u", 1); - relpath_printf(s, perms, "platform/acpi_s3", "%u", 1); - relpath_printf(s, perms, "platform/acpi_s4", "%u", 1); - relpath_printf(s, perms, "platform/acpi_laptop_slate", "%u", 0); + relpath_printf(s, xen_domid, perms, "platform/acpi", "%u", 1); + relpath_printf(s, xen_domid, perms, "platform/acpi_s3", "%u", 1); + relpath_printf(s, xen_domid, perms, "platform/acpi_s4", "%u", 1); + relpath_printf(s, xen_domid, perms, "platform/acpi_laptop_slate", "%u", 0); g_list_free_full(perms, g_free); /* Nodes owned by the guest */ perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, xen_domid)); - relpath_printf(s, perms, "attr", "%s", ""); + relpath_printf(s, xen_domid, perms, "attr", "%s", ""); - relpath_printf(s, perms, "control/shutdown", "%s", ""); - relpath_printf(s, perms, "control/feature-poweroff", "%u", 1); - relpath_printf(s, perms, "control/feature-reboot", "%u", 1); - relpath_printf(s, perms, "control/feature-suspend", "%u", 1); - relpath_printf(s, perms, "control/feature-s3", "%u", 1); - relpath_printf(s, perms, "control/feature-s4", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/shutdown", "%s", ""); + relpath_printf(s, xen_domid, perms, "control/feature-poweroff", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/feature-reboot", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/feature-suspend", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/feature-s3", "%u", 1); + relpath_printf(s, xen_domid, perms, "control/feature-s4", "%u", 1); - relpath_printf(s, perms, "data", "%s", ""); - relpath_printf(s, perms, "device", "%s", ""); - relpath_printf(s, perms, "drivers", "%s", ""); - relpath_printf(s, perms, "error", "%s", ""); - relpath_printf(s, perms, "feature", "%s", ""); + relpath_printf(s, xen_domid, perms, "data", "%s", ""); + relpath_printf(s, xen_domid, perms, "device", "%s", ""); + relpath_printf(s, xen_domid, perms, "drivers", "%s", ""); + relpath_printf(s, xen_domid, perms, "error", "%s", ""); + relpath_printf(s, xen_domid, perms, "feature", "%s", ""); g_list_free_full(perms, g_free); @@ -1427,6 +1436,9 @@ static void alloc_guest_port(XenXenstoreState *s) if (!xen_evtchn_alloc_unbound_op(&alloc)) { s->guest_port = alloc.port; } + if (!xen_evtchn_alloc_unbound_op(&alloc)) { + s->cons_guest_port = alloc.port; + } } int xen_xenstore_reset(void) @@ -1446,6 +1458,10 @@ int xen_xenstore_reset(void) uint64_t gpa = XEN_SPECIAL_PFN(XENSTORE) << TARGET_PAGE_BITS; xen_overlay_do_map_page(&s->xenstore_page, gpa); } + if (!memory_region_is_mapped(&s->console_page)) { + uint64_t gpa = XEN_SPECIAL_PFN(CONSOLE) << TARGET_PAGE_BITS; + xen_overlay_do_map_page(&s->console_page, gpa); + } alloc_guest_port(s); @@ -1464,8 +1480,26 @@ int xen_xenstore_reset(void) perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, DOMID_QEMU)); perms = g_list_append(perms, xs_perm_as_string(XS_PERM_READ, xen_domid)); - relpath_printf(s, perms, "store/ring-ref", "%lu", XEN_SPECIAL_PFN(XENSTORE)); - relpath_printf(s, perms, "store/port", "%u", s->be_port); + relpath_printf(s, xen_domid, perms, "store/ring-ref", "%lu", XEN_SPECIAL_PFN(XENSTORE)); + relpath_printf(s, xen_domid, perms, "store/port", "%u", s->be_port); + + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0", "%s", ""); + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0/frontend", "/local/domain/%u/console", xen_domid); + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0/frontend-id", "%u", xen_domid); + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0/online", "1"); + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0/state", "%u", XenbusStateInitialising); + relpath_printf(s, DOMID_QEMU, perms, "backend/console/1/0/protocol", "vt100"); + + g_list_free_full(perms, g_free); + + perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, xen_domid)); + perms = g_list_append(perms, xs_perm_as_string(XS_PERM_READ|XS_PERM_WRITE, DOMID_QEMU)); + + relpath_printf(s, xen_domid, perms, "console/ring-ref", "%lu", XEN_SPECIAL_PFN(CONSOLE)); + relpath_printf(s, xen_domid, perms, "console/port", "%u", s->cons_guest_port); + relpath_printf(s, xen_domid, perms, "console/type", "ioemu"); + relpath_printf(s, xen_domid, perms, "console/output", "mon:stdio"); + relpath_printf(s, xen_domid, perms, "console/backend", "/local/domain/0/backend/console/%u/0", xen_domid); g_list_free_full(perms, g_free); diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c index 477e93cd92..f48a4270ca 100644 --- a/target/i386/kvm/xen-emu.c +++ b/target/i386/kvm/xen-emu.c @@ -811,6 +811,12 @@ static bool handle_get_param(struct kvm_xen_exit *exit, X86CPU *cpu, case HVM_PARAM_STORE_EVTCHN: hp.value = xen_xenstore_get_port(); break; + case HVM_PARAM_CONSOLE_PFN: + hp.value = XEN_SPECIAL_PFN(CONSOLE); + break; + case HVM_PARAM_CONSOLE_EVTCHN: + hp.value = xen_xenstore_get_port() + 1; + break; default: return false; }