Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'xenpvh5-tag' of https://gitlab.com/sstabellini/qemu into s…
…taging

xenpvh5

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEE0E4zq6UfZ7oH0wrqiU+PSHDhrpAFAmSLo0QACgkQiU+PSHDh
# rpB1Gw/9H5Cx7wQZVyKfFwnyOoP2QTedCISxC0HL5qFmUGcJY21gXaJZ10JaU/HM
# zHEJj2M17EgVCTkZVqZeKuj+nzyjbRKatT3YmFqKqFNNt5M1yQxC9BfVgso4PND/
# SY0/8BvqumgJEqD3sf76KbQAILKwahPtA42LTM7S7r2ZsmQpvmOpdOhCVugpnqs/
# FheP8N6hdlZ7GnRGtXv9QnKxMVThuE3mRCUWCyYsV/Roz6uvPsvskrdSeC3LzzBd
# Ewq56vB+qQg+WbNTgK2BcVOzV/89k9tjWsUnamfhjD2lUxfHrne1FBclhKMcHhUv
# T53zjhxjlRfmzUxC4917Krt4Tw/AaDW7v1pn6RokUq5U059Wb8q0IjzL75FOeD3o
# e9DNp+RR8py44ejfi2WHR7jqayMPVIO86uJ3usshiZ9YgK5efFAtlwN/KNR5JX8k
# Y1BR9O8BebtRymljtiLWUFXlu3xywGSA23KotT7XtzXKEaTZkIHdI395YKksYPkG
# pil0C0bh5ZW3ZWd4M/CNcVOb69R53p15O77mjmKtjnkQYJAPD6Kbc9thZ1zdWwPR
# ivFPdiTJb0FElS0ywZwezKYRKXje6E9ejXgAzgFuZI/rFdeO0HfkifiNoro1NAxK
# g4V+LE5oPt09GpL2nuHrh/y9g9MnLlXyNBhPV0CRelU6fPKIk1w=
# =543t
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 16 Jun 2023 01:48:20 AM CEST
# gpg:                using RSA key D04E33ABA51F67BA07D30AEA894F8F4870E1AE90
# gpg: Good signature from "Stefano Stabellini <sstabellini@kernel.org>" [unknown]
# gpg:                 aka "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: D04E 33AB A51F 67BA 07D3  0AEA 894F 8F48 70E1 AE90

* tag 'xenpvh5-tag' of https://gitlab.com/sstabellini/qemu:
  test/qtest: add xepvh to skip list for qtest
  meson.build: enable xenpv machine build for ARM
  hw/arm: introduce xenpvh machine
  meson.build: do not set have_xen_pci_passthrough for aarch64 targets
  hw/xen/xen-hvm-common: Use g_new and error_report
  hw/xen/xen-hvm-common: skip ioreq creation on ioreq registration failure
  include/hw/xen/xen_common: return error from xen_create_ioreq_server
  xen-hvm: reorganize xen-hvm and move common function to xen-hvm-common
  hw/i386/xen/xen-hvm: move x86-specific fields out of XenIOState
  hw/i386/xen: rearrange xen_hvm_init_pc
  hw/i386/xen/: move xen-mapcache.c to hw/xen/

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Jun 16, 2023
2 parents 5692a39 + d8a714e commit 0d7c8da
Show file tree
Hide file tree
Showing 19 changed files with 1,349 additions and 1,009 deletions.
34 changes: 34 additions & 0 deletions docs/system/arm/xenpvh.rst
@@ -0,0 +1,34 @@
XENPVH (``xenpvh``)
=========================================
This machine creates a IOREQ server to register/connect with Xen Hypervisor.

When TPM is enabled, this machine also creates a tpm-tis-device at a user input
tpm base address, adds a TPM emulator and connects to a swtpm application
running on host machine via chardev socket. This enables xenpvh to support TPM
functionalities for a guest domain.

More information about TPM use and installing swtpm linux application can be
found at: docs/specs/tpm.rst.

Example for starting swtpm on host machine:
.. code-block:: console
mkdir /tmp/vtpm2
swtpm socket --tpmstate dir=/tmp/vtpm2 \
--ctrl type=unixio,path=/tmp/vtpm2/swtpm-sock &
Sample QEMU xenpvh commands for running and connecting with Xen:
.. code-block:: console
qemu-system-aarch64 -xen-domid 1 \
-chardev socket,id=libxl-cmd,path=qmp-libxl-1,server=on,wait=off \
-mon chardev=libxl-cmd,mode=control \
-chardev socket,id=libxenstat-cmd,path=qmp-libxenstat-1,server=on,wait=off \
-mon chardev=libxenstat-cmd,mode=control \
-xen-attach -name guest0 -vnc none -display none -nographic \
-machine xenpvh -m 1301 \
-chardev socket,id=chrtpm,path=tmp/vtpm2/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm -machine tpm-base-addr=0x0C000000
In above QEMU command, last two lines are for connecting xenpvh QEMU to swtpm
via chardev socket.
1 change: 1 addition & 0 deletions docs/system/target-arm.rst
Expand Up @@ -107,6 +107,7 @@ undocumented; you can get a complete list by running
arm/stm32
arm/virt
arm/xlnx-versal-virt
arm/xenpvh
Emulated CPU architecture support
=================================
Expand Down
2 changes: 2 additions & 0 deletions hw/arm/meson.build
Expand Up @@ -63,6 +63,8 @@ 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('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)

softmmu_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c'))
softmmu_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c'))
Expand Down
181 changes: 181 additions & 0 deletions hw/arm/xen_arm.c
@@ -0,0 +1,181 @@
/*
* QEMU ARM Xen PVH 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 "qapi/visitor.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-hvm-common.h"
#include "sysemu/tpm.h"
#include "hw/xen/arch_hvm.h"

#define TYPE_XEN_ARM MACHINE_TYPE_NAME("xenpvh")
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;

struct {
uint64_t tpm_base_addr;
} cfg;
};

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)
{
}

#ifdef CONFIG_TPM
static void xen_enable_tpm(XenArmState *xam)
{
Error *errp = NULL;
DeviceState *dev;
SysBusDevice *busdev;

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, xam->cfg.tpm_base_addr);

DPRINTF("Connected tpmdev at address 0x%lx\n", xam->cfg.tpm_base_addr);
}
#endif

static void xen_arm_init(MachineState *machine)
{
XenArmState *xam = XEN_ARM(machine);

xam->state = g_new0(XenIOState, 1);

xen_register_ioreq(xam->state, machine->smp.cpus, xen_memory_listener);

#ifdef CONFIG_TPM
if (xam->cfg.tpm_base_addr) {
xen_enable_tpm(xam);
} else {
DPRINTF("tpm-base-addr is not provided. TPM will not be enabled\n");
}
#endif
}

#ifdef CONFIG_TPM
static void xen_arm_get_tpm_base_addr(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
XenArmState *xam = XEN_ARM(obj);
uint64_t value = xam->cfg.tpm_base_addr;

visit_type_uint64(v, name, &value, errp);
}

static void xen_arm_set_tpm_base_addr(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
XenArmState *xam = XEN_ARM(obj);
uint64_t value;

if (!visit_type_uint64(v, name, &value, errp)) {
return;
}

xam->cfg.tpm_base_addr = value;
}
#endif

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;
mc->default_machine_opts = "accel=xen";

#ifdef CONFIG_TPM
object_class_property_add(oc, "tpm-base-addr", "uint64_t",
xen_arm_get_tpm_base_addr,
xen_arm_set_tpm_base_addr,
NULL, NULL);
object_class_property_set_description(oc, "tpm-base-addr",
"Set Base address for TPM device.");

machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
}

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)
1 change: 1 addition & 0 deletions hw/i386/meson.build
Expand Up @@ -33,5 +33,6 @@ subdir('kvm')
subdir('xen')

i386_ss.add_all(xenpv_ss)
i386_ss.add_all(xen_ss)

hw_arch += {'i386': i386_ss}
1 change: 0 additions & 1 deletion hw/i386/xen/meson.build
@@ -1,6 +1,5 @@
i386_ss.add(when: 'CONFIG_XEN', if_true: files(
'xen-hvm.c',
'xen-mapcache.c',
'xen_apic.c',
'xen_pvdevice.c',
))
Expand Down
19 changes: 0 additions & 19 deletions hw/i386/xen/trace-events
Expand Up @@ -7,22 +7,3 @@ xen_platform_log(char *s) "xen platform: %s"
xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address 0x%"PRIx64")"
xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address 0x%"PRIx64")"

# xen-hvm.c
xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: 0x%lx, size 0x%lx"
xen_client_set_memory(uint64_t start_addr, unsigned long size, bool log_dirty) "0x%"PRIx64" size 0x%lx, log_dirty %i"
handle_ioreq(void *req, uint32_t type, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p type=%d dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
handle_ioreq_read(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p read type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
handle_ioreq_write(void *req, uint32_t type, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p write type=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
cpu_ioreq_pio(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p pio dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
cpu_ioreq_pio_read_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio read reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
cpu_ioreq_pio_write_reg(void *req, uint64_t data, uint64_t addr, uint32_t size) "I/O=%p pio write reg data=0x%"PRIx64" port=0x%"PRIx64" size=%d"
cpu_ioreq_move(void *req, uint32_t dir, uint32_t df, uint32_t data_is_ptr, uint64_t addr, uint64_t data, uint32_t count, uint32_t size) "I/O=%p copy dir=%d df=%d ptr=%d port=0x%"PRIx64" data=0x%"PRIx64" count=%d size=%d"
xen_map_resource_ioreq(uint32_t id, void *addr) "id: %u addr: %p"
cpu_ioreq_config_read(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"
cpu_ioreq_config_write(void *req, uint32_t sbdf, uint32_t reg, uint32_t size, uint32_t data) "I/O=%p sbdf=0x%x reg=%u size=%u data=0x%x"

# xen-mapcache.c
xen_map_cache(uint64_t phys_addr) "want 0x%"PRIx64
xen_remap_bucket(uint64_t index) "index 0x%"PRIx64
xen_map_cache_return(void* ptr) "%p"

0 comments on commit 0d7c8da

Please sign in to comment.