From 5618a18b1f12d567a8ef85240d55b841e18ef472 Mon Sep 17 00:00:00 2001 From: Vikram Garhwal Date: Fri, 1 Jul 2022 17:28:16 -0700 Subject: [PATCH 10/16] hw/arm: introduce xenpv machine Create a new machine xenpv which creates a IOREQ server to connect with Xen. It also creates a tpm-tis-device which connects to swtpm to support TPM functionalities. Xen IOREQ connection expect the TARGET_PAGE_SIZE to 4096, and the xenpv machine on ARM will have no CPU definitions. We need to define TARGET_PAGE_SIZE appropriately ourselves. Signed-off-by: Vikram Garhwal Signed-off-by: Stefano Stabellini Reviewed-by: Stefano Stabellini --- hw/arm/meson.build | 1 + hw/arm/xen_arm.c | 156 ++++++++++++++++++++++++++++++++++ include/hw/arm/xen_arch_hvm.h | 12 +++ include/hw/xen/arch_hvm.h | 2 + 4 files changed, 171 insertions(+) create mode 100644 hw/arm/xen_arm.c create mode 100644 include/hw/arm/xen_arch_hvm.h diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 3aac913bfd..0cae024374 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -62,6 +62,7 @@ arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre. arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c', 'smmuv3.c')) arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c')) arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c')) +arm_ss.add(when: 'CONFIG_XEN', if_true: files('xen_arm.c')) arm_ss.add_all(xen_ss) hw_arch += {'arm': arm_ss} diff --git a/hw/arm/xen_arm.c b/hw/arm/xen_arm.c new file mode 100644 index 0000000000..0922e3db84 --- /dev/null +++ b/hw/arm/xen_arm.c @@ -0,0 +1,156 @@ +/* + * QEMU ARM Xen PV Machine + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/qapi-commands-migration.h" +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "sysemu/block-backend.h" +#include "sysemu/tpm_backend.h" +#include "sysemu/sysemu.h" +#include "hw/xen/xen-legacy-backend.h" +#include "hw/xen/xen-hvm-common.h" +#include "sysemu/tpm.h" +#include "hw/xen/arch_hvm.h" + +#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpv") +OBJECT_DECLARE_SIMPLE_TYPE(XenArmState, XEN_ARM) + +static MemoryListener xen_memory_listener = { + .region_add = xen_region_add, + .region_del = xen_region_del, + .log_start = NULL, + .log_stop = NULL, + .log_sync = NULL, + .log_global_start = NULL, + .log_global_stop = NULL, + .priority = 10, +}; + +struct XenArmState { + /*< private >*/ + MachineState parent; + + XenIOState *state; +}; + +void arch_handle_ioreq(XenIOState *state, ioreq_t *req) +{ + hw_error("Invalid ioreq type 0x%x\n", req->type); + + return; +} + +void arch_xen_set_memory(XenIOState *state,MemoryRegionSection *section, + bool add) +{ +} + +void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length) +{ +} + +void qmp_xen_set_global_dirty_log(bool enable, Error **errp) +{ +} + +static int xen_init_ioreq(XenIOState *state, unsigned int max_cpus) +{ + xen_dmod = xendevicemodel_open(0, 0); + xen_xc = xc_interface_open(0, 0, 0); + + if (xen_xc == NULL) { + perror("xen: can't open xen interface\n"); + return -1; + } + + xen_fmem = xenforeignmemory_open(0, 0); + if (xen_fmem == NULL) { + perror("xen: can't open xen fmem interface\n"); + xc_interface_close(xen_xc); + return -1; + } + + xen_register_ioreq(state, max_cpus, xen_memory_listener); + + xenstore_record_dm_state(xenstore, "running"); + + return 0; +} + + +static void xen_arm_init(MachineState *machine) +{ + DeviceState *dev; + SysBusDevice *busdev; + Error *errp = NULL; + XenArmState *xam = XEN_ARM(machine); + + xam->state = g_new0(XenIOState, 1); + + if (xen_init_ioreq(xam->state, machine->smp.cpus)) { + return; + } + + TPMBackend *be = qemu_find_tpm_be("tpm0"); + if (be == NULL) { + DPRINTF("Couldn't fine the backend for tpm0\n"); + return; + } + + dev = qdev_new(TYPE_TPM_TIS_SYSBUS); + object_property_set_link(OBJECT(dev), "tpmdev", OBJECT(be), &errp); + object_property_set_str(OBJECT(dev), "tpmdev", be->id, &errp); + busdev = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(busdev, &error_fatal); + sysbus_mmio_map(busdev, 0, GUEST_TPM_BASE); + + DPRINTF("Connected tpmdev at address 0x%lx\n", GUEST_TPM_BASE); + + return; +} + +static void xen_arm_machine_class_init(ObjectClass *oc, void *data) +{ + + MachineClass *mc = MACHINE_CLASS(oc); + mc->desc = "Xen Para-virtualized PC"; + mc->init = xen_arm_init; + mc->max_cpus = 1; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); +} + +static const TypeInfo xen_arm_machine_type = { + .name = TYPE_XEN_ARM, + .parent = TYPE_MACHINE, + .class_init = xen_arm_machine_class_init, + .instance_size = sizeof(XenArmState), +}; + +static void xen_arm_machine_register_types(void) +{ + type_register_static(&xen_arm_machine_type); +} + +type_init(xen_arm_machine_register_types) diff --git a/include/hw/arm/xen_arch_hvm.h b/include/hw/arm/xen_arch_hvm.h new file mode 100644 index 0000000000..f645dfec28 --- /dev/null +++ b/include/hw/arm/xen_arch_hvm.h @@ -0,0 +1,12 @@ +#ifndef HW_XEN_ARCH_ARM_HVM_H +#define HW_XEN_ARCH_ARM_HVM_H + +#include +void arch_handle_ioreq(XenIOState *state, ioreq_t *req); +void arch_xen_set_memory(XenIOState *state, + MemoryRegionSection *section, + bool add); + +#undef TARGET_PAGE_SIZE +#define TARGET_PAGE_SIZE 4096 +#endif diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h index 26674648d8..c7c515220d 100644 --- a/include/hw/xen/arch_hvm.h +++ b/include/hw/xen/arch_hvm.h @@ -1,3 +1,5 @@ #if defined(TARGET_I386) || defined(TARGET_X86_64) #include "hw/i386/xen_arch_hvm.h" +#elif defined(TARGET_ARM) || defined(TARGET_ARM_64) +#include "hw/arm/xen_arch_hvm.h" #endif -- 2.17.1