On Tue, 20 Aug 2024, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.igles...@amd.com>
> 
> Add a Xen PVH x86 machine based on the abstract PVH Machine.
> 
> Signed-off-by: Edgar E. Iglesias <edgar.igles...@amd.com>


Reviewed-by: Stefano Stabellini <sstabell...@kernel.org>


> ---
>  hw/i386/xen/meson.build |   1 +
>  hw/i386/xen/xen-pvh.c   | 121 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 122 insertions(+)
>  create mode 100644 hw/i386/xen/xen-pvh.c
> 
> diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build
> index 3f0df8bc07..c73c62b8e3 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-pvh.c b/hw/i386/xen/xen-pvh.c
> new file mode 100644
> index 0000000000..45645667e9
> --- /dev/null
> +++ b/hw/i386/xen/xen-pvh.c
> @@ -0,0 +1,121 @@
> +/*
> + * QEMU Xen PVH x86 Machine
> + *
> + * Copyright (c) 2024 Advanced Micro Devices, Inc.
> + * Written by Edgar E. Iglesias <edgar.igles...@amd.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "hw/boards.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/xen/arch_hvm.h"
> +#include <xen/hvm/hvm_info_table.h>
> +#include "hw/xen/xen-pvh-common.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, 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;
> +
> +    /*
> +     * 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)
> -- 
> 2.43.0
> 

Reply via email to