diff options
Diffstat (limited to 'hw/i386/xen')
-rw-r--r-- | hw/i386/xen/meson.build | 1 | ||||
-rw-r--r-- | hw/i386/xen/xen-hvm.c | 12 | ||||
-rw-r--r-- | hw/i386/xen/xen-pvh.c | 125 | ||||
-rw-r--r-- | hw/i386/xen/xen_apic.c | 4 | ||||
-rw-r--r-- | hw/i386/xen/xen_platform.c | 12 | ||||
-rw-r--r-- | hw/i386/xen/xen_pvdevice.c | 7 |
6 files changed, 146 insertions, 15 deletions
diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build index 3f0df8b..c73c62b 100644 --- a/hw/i386/xen/meson.build +++ b/hw/i386/xen/meson.build @@ -4,6 +4,7 @@ i386_ss.add(when: 'CONFIG_XEN', if_true: files( )) i386_ss.add(when: ['CONFIG_XEN', xen], if_true: files( 'xen-hvm.c', + 'xen-pvh.c', )) i386_ss.add(when: 'CONFIG_XEN_BUS', if_true: files( diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 4f64466..ceb2242 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -10,10 +10,12 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "qemu/error-report.h" #include "qapi/error.h" #include "qapi/qapi-commands-migration.h" #include "trace.h" +#include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/irq.h" #include "hw/i386/apic-msidef.h" @@ -24,6 +26,10 @@ #include "hw/xen/arch_hvm.h" #include <xen/hvm/e820.h> #include "exec/target_page.h" +#include "target/i386/cpu.h" +#include "system/runstate.h" +#include "system/xen-mapcache.h" +#include "system/xen.h" static MemoryRegion ram_640k, ram_lo, ram_hi; static MemoryRegion *framebuffer; @@ -614,7 +620,9 @@ void xen_hvm_init_pc(PCMachineState *pcms, MemoryRegion **ram_memory) state = g_new0(XenIOState, 1); - xen_register_ioreq(state, max_cpus, &xen_memory_listener); + xen_register_ioreq(state, max_cpus, + HVM_IOREQSRV_BUFIOREQ_ATOMIC, + &xen_memory_listener); xen_is_stubdomain = xen_check_stubdomain(state->xenstore); @@ -750,6 +758,4 @@ void arch_handle_ioreq(XenIOState *state, ioreq_t *req) default: hw_error("Invalid ioreq type 0x%x\n", req->type); } - - return; } diff --git a/hw/i386/xen/xen-pvh.c b/hw/i386/xen/xen-pvh.c new file mode 100644 index 0000000..067f73e --- /dev/null +++ b/hw/i386/xen/xen-pvh.c @@ -0,0 +1,125 @@ +/* + * QEMU Xen PVH x86 Machine + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * Written by Edgar E. Iglesias <edgar.iglesias@amd.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "hw/boards.h" +#include "system/system.h" +#include "hw/xen/arch_hvm.h" +#include <xen/hvm/hvm_info_table.h> +#include "hw/xen/xen-pvh-common.h" +#include "target/i386/cpu.h" + +#define TYPE_XEN_PVH_X86 MACHINE_TYPE_NAME("xenpvh") +OBJECT_DECLARE_SIMPLE_TYPE(XenPVHx86State, XEN_PVH_X86) + +struct XenPVHx86State { + /*< private >*/ + XenPVHMachineState parent; + + DeviceState **cpu; +}; + +static DeviceState *xen_pvh_cpu_new(MachineState *ms, + int64_t apic_id) +{ + Object *cpu = object_new(ms->cpu_type); + + object_property_add_child(OBJECT(ms), "cpu[*]", cpu); + object_property_set_uint(cpu, "apic-id", apic_id, &error_fatal); + qdev_realize(DEVICE(cpu), NULL, &error_fatal); + object_unref(cpu); + + return DEVICE(cpu); +} + +static void xen_pvh_init(MachineState *ms) +{ + XenPVHx86State *xp = XEN_PVH_X86(ms); + int i; + + /* Create dummy cores. This will indirectly create the APIC MSI window. */ + xp->cpu = g_malloc(sizeof xp->cpu[0] * ms->smp.max_cpus); + for (i = 0; i < ms->smp.max_cpus; i++) { + xp->cpu[i] = xen_pvh_cpu_new(ms, i); + } +} + +static void xen_pvh_instance_init(Object *obj) +{ + XenPVHMachineState *s = XEN_PVH_MACHINE(obj); + + /* Default values. */ + s->cfg.ram_low = (MemMapEntry) { 0x0, 0x80000000U }; + s->cfg.ram_high = (MemMapEntry) { 0xC000000000ULL, 0x4000000000ULL }; + s->cfg.pci_intx_irq_base = 16; +} + +/* + * Deliver INTX interrupts to Xen guest. + */ +static void xen_pvh_set_pci_intx_irq(void *opaque, int irq, int level) +{ + /* + * Since QEMU emulates all of the swizziling + * We don't want Xen to do any additional swizzling in + * xen_set_pci_intx_level() so we always set device to 0. + */ + if (xen_set_pci_intx_level(xen_domid, 0, 0, 0, irq, level)) { + error_report("xendevicemodel_set_pci_intx_level failed"); + } +} + +static void xen_pvh_machine_class_init(ObjectClass *oc, const void *data) +{ + XenPVHMachineClass *xpc = XEN_PVH_MACHINE_CLASS(oc); + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Xen PVH x86 machine"; + mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE; + + /* mc->max_cpus holds the MAX value allowed in the -smp cmd-line opts. */ + mc->max_cpus = HVM_MAX_VCPUS; + + /* We have an implementation specific init to create CPU objects. */ + xpc->init = xen_pvh_init; + + /* Enable buffered IOREQs. */ + xpc->handle_bufioreq = HVM_IOREQSRV_BUFIOREQ_ATOMIC; + + /* + * PCI INTX routing. + * + * We describe the mapping between the 4 INTX interrupt and GSIs + * using xen_set_pci_link_route(). xen_pvh_set_pci_intx_irq is + * used to deliver the interrupt. + */ + xpc->set_pci_intx_irq = xen_pvh_set_pci_intx_irq; + xpc->set_pci_link_route = xen_set_pci_link_route; + + /* List of supported features known to work on PVH x86. */ + xpc->has_pci = true; + + xen_pvh_class_setup_common_props(xpc); +} + +static const TypeInfo xen_pvh_x86_machine_type = { + .name = TYPE_XEN_PVH_X86, + .parent = TYPE_XEN_PVH_MACHINE, + .class_init = xen_pvh_machine_class_init, + .instance_init = xen_pvh_instance_init, + .instance_size = sizeof(XenPVHx86State), +}; + +static void xen_pvh_machine_register_types(void) +{ + type_register_static(&xen_pvh_x86_machine_type); +} + +type_init(xen_pvh_machine_register_types) diff --git a/hw/i386/xen/xen_apic.c b/hw/i386/xen/xen_apic.c index 101e16a..f30398f 100644 --- a/hw/i386/xen/xen_apic.c +++ b/hw/i386/xen/xen_apic.c @@ -36,7 +36,7 @@ static void xen_apic_mem_write(void *opaque, hwaddr addr, static const MemoryRegionOps xen_apic_io_ops = { .read = xen_apic_mem_read, .write = xen_apic_mem_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void xen_apic_realize(DeviceState *dev, Error **errp) @@ -76,7 +76,7 @@ static void xen_send_msi(MSIMessage *msi) xen_hvm_inject_msi(msi->address, msi->data); } -static void xen_apic_class_init(ObjectClass *klass, void *data) +static void xen_apic_class_init(ObjectClass *klass, const void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index 708488a..c8b852b 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -30,8 +30,8 @@ #include "migration/vmstate.h" #include "net/net.h" #include "trace.h" -#include "sysemu/xen.h" -#include "sysemu/block-backend.h" +#include "system/xen.h" +#include "system/block-backend.h" #include "qemu/error-report.h" #include "qemu/module.h" #include "qom/object.h" @@ -514,7 +514,7 @@ static void platform_mmio_write(void *opaque, hwaddr addr, static const MemoryRegionOps platform_mmio_handler = { .read = &platform_mmio_read, .write = &platform_mmio_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void platform_mmio_setup(PCIXenPlatformState *d) @@ -581,7 +581,7 @@ static void platform_reset(DeviceState *dev) platform_fixed_ioport_reset(s); } -static void xen_platform_class_init(ObjectClass *klass, void *data) +static void xen_platform_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -595,7 +595,7 @@ static void xen_platform_class_init(ObjectClass *klass, void *data) k->revision = 1; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->desc = "XEN platform pci device"; - dc->reset = platform_reset; + device_class_set_legacy_reset(dc, platform_reset); dc->vmsd = &vmstate_xen_platform; } @@ -604,7 +604,7 @@ static const TypeInfo xen_platform_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIXenPlatformState), .class_init = xen_platform_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c index ed62153..87a974a 100644 --- a/hw/i386/xen/xen_pvdevice.c +++ b/hw/i386/xen/xen_pvdevice.c @@ -115,15 +115,14 @@ static void xen_pv_realize(PCIDevice *pci_dev, Error **errp) &d->mmio); } -static Property xen_pv_props[] = { +static const Property xen_pv_props[] = { DEFINE_PROP_UINT16("vendor-id", XenPVDevice, vendor_id, PCI_VENDOR_ID_XEN), DEFINE_PROP_UINT16("device-id", XenPVDevice, device_id, 0xffff), DEFINE_PROP_UINT8("revision", XenPVDevice, revision, 0x01), DEFINE_PROP_UINT32("size", XenPVDevice, size, 0x400000), - DEFINE_PROP_END_OF_LIST() }; -static void xen_pv_class_init(ObjectClass *klass, void *data) +static void xen_pv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -140,7 +139,7 @@ static const TypeInfo xen_pv_type_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(XenPVDevice), .class_init = xen_pv_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, |