From nobody Tue Feb 10 10:07:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1670580044286617.2925277172088; Fri, 9 Dec 2022 02:00:44 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p3a8J-0002gY-29; Fri, 09 Dec 2022 04:57:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p3a7U-0002TB-Hk for qemu-devel@nongnu.org; Fri, 09 Dec 2022 04:56:41 -0500 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p3a7Q-0006qg-K5 for qemu-devel@nongnu.org; Fri, 09 Dec 2022 04:56:40 -0500 Received: from i7.infradead.org ([2001:8b0:10b:1:21e:67ff:fecb:7a92]) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1p3a7G-007tiL-5g; Fri, 09 Dec 2022 09:56:26 +0000 Received: from dwoodhou by i7.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1p3a77-002tYM-Pq; Fri, 09 Dec 2022 09:56:17 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=oV/8182zcImY/7Qa/FeC8p0iV5FEIwdb+SCiT7V3HWk=; b=HNi0YFdmTaTIQJ8EiTX9es+uS7 GYT6VlEl3WMjbG/m4GvtfrJXbVx/nxN1ueAPWioAtNBbuKQAngGo1UHUheommQgmBIeZgUOs31lHt z+S0e8PFBBmomYgp1WZeiIlyTmUF8RCd7LVhA+fPVwC75dHxv4LrLytmiRU8pV6fIxLPCAUCwp7E5 HAbsxI/Bu3/O4F9QGZ70K0r3PAljzNji73f+ukfabQ2Pfa/9lEFZUwNJuvk9TATMSR2+V3zzURyId OyBBeHoaSuBixRfuUgdBqfKa9c3EqpdnadbSUhgnvAy8F700VRzoH3PYp9RKye9hZpIVuttCMT0xz JBCnUohQ==; From: David Woodhouse To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Paul Durrant , Joao Martins , Ankur Arora , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Thomas Huth , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Juan Quintela , "Dr . David Alan Gilbert" , Claudio Fontana Subject: [RFC PATCH v2 03/22] i386/xen: Add xen-version machine property and init KVM Xen support Date: Fri, 9 Dec 2022 09:55:53 +0000 Message-Id: <20221209095612.689243-4-dwmw2@infradead.org> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221209095612.689243-1-dwmw2@infradead.org> References: <20221209095612.689243-1-dwmw2@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=2001:8b0:10b:1236::1; envelope-from=BATV+00235e7d7be18c3eb674+7047+infradead.org+dwmw2@casper.srs.infradead.org; helo=casper.infradead.org X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1670580045723100003 From: David Woodhouse This is a machine property for two main reasons. One is that it allows us to set it in default_machine_opts for the xenfv platform when not running on actual Xen. The other is that theoretically we *could* do this with TCG too; we'd just have to implement a bunch of the stuff that KVM already does for us. Signed-off-by: David Woodhouse --- hw/i386/pc.c | 32 +++++++++++++++++++++++++++ hw/i386/pc_piix.c | 10 +++++++-- include/hw/i386/pc.h | 3 +++ target/i386/kvm/kvm.c | 26 ++++++++++++++++++++++ target/i386/meson.build | 1 + target/i386/xen.c | 49 +++++++++++++++++++++++++++++++++++++++++ target/i386/xen.h | 19 ++++++++++++++++ 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 target/i386/xen.c create mode 100644 target/i386/xen.h diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 546b703cb4..9bada1a8ff 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1811,6 +1811,32 @@ static void pc_machine_set_max_fw_size(Object *obj, = Visitor *v, pcms->max_fw_size =3D value; } =20 +static void pc_machine_get_xen_version(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCMachineState *pcms =3D PC_MACHINE(obj); + uint32_t value =3D pcms->xen_version; + + visit_type_uint32(v, name, &value, errp); +} + +static void pc_machine_set_xen_version(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCMachineState *pcms =3D PC_MACHINE(obj); + Error *error =3D NULL; + uint32_t value; + + visit_type_uint32(v, name, &value, &error); + if (error) { + error_propagate(errp, error); + return; + } + + pcms->xen_version =3D value; +} =20 static void pc_machine_initfn(Object *obj) { @@ -1978,6 +2004,12 @@ static void pc_machine_class_init(ObjectClass *oc, v= oid *data) NULL, NULL); object_class_property_set_description(oc, PC_MACHINE_SMBIOS_EP, "SMBIOS Entry Point type [32, 64]"); + + object_class_property_add(oc, "xen-version", "uint32", + pc_machine_get_xen_version, pc_machine_set_xen_version, + NULL, NULL); + object_class_property_set_description(oc, "xen-version", + "Xen version to be emulated (in XENVER_version form e.g. 0x4000a f= or 4.10)"); } =20 static const TypeInfo pc_machine_info =3D { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0ad0ed1603..13286d0739 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -876,7 +876,10 @@ static void xenfv_4_2_machine_options(MachineClass *m) pc_i440fx_4_2_machine_options(m); m->desc =3D "Xen Fully-virtualized PC"; m->max_cpus =3D HVM_MAX_VCPUS; - m->default_machine_opts =3D "accel=3Dxen,suppress-vmdesc=3Don"; + if (xen_enabled()) + m->default_machine_opts =3D "accel=3Dxen,suppress-vmdesc=3Don"; + else + m->default_machine_opts =3D "accel=3Dkvm,xen-version=3D0x40002= "; } =20 DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init, @@ -888,7 +891,10 @@ static void xenfv_3_1_machine_options(MachineClass *m) m->desc =3D "Xen Fully-virtualized PC"; m->alias =3D "xenfv"; m->max_cpus =3D HVM_MAX_VCPUS; - m->default_machine_opts =3D "accel=3Dxen,suppress-vmdesc=3Don"; + if (xen_enabled()) + m->default_machine_opts =3D "accel=3Dxen,suppress-vmdesc=3Don"; + else + m->default_machine_opts =3D "accel=3Dkvm,xen-version=3D0x30001= "; } =20 DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init, diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c95333514e..9b14b18836 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -52,6 +52,9 @@ typedef struct PCMachineState { bool default_bus_bypass_iommu; uint64_t max_fw_size; =20 + /* Xen HVM emulation */ + uint32_t xen_version; + /* ACPI Memory hotplug IO base address */ hwaddr memhp_io_base; =20 diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index a213209379..0a2069b117 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -31,6 +31,7 @@ #include "sysemu/runstate.h" #include "kvm_i386.h" #include "sev.h" +#include "xen.h" #include "hyperv.h" #include "hyperv-proto.h" =20 @@ -774,6 +775,17 @@ static inline bool freq_within_bounds(int freq, int ta= rget_freq) return false; } =20 +static uint32_t kvm_arch_xen_version(MachineState *ms) +{ + uint32_t v =3D object_property_get_int(OBJECT(ms), "xen-version", NULL= ); + + /* If it was unset, return zero */ + if (v =3D=3D (uint32_t) -1) + return 0; + + return v; +} + static int kvm_arch_set_tsc_khz(CPUState *cs) { X86CPU *cpu =3D X86_CPU(cs); @@ -2459,6 +2471,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) { uint64_t identity_base =3D 0xfffbc000; uint64_t shadow_mem; + uint32_t xen_version; int ret; struct utsname utsname; Error *local_err =3D NULL; @@ -2513,6 +2526,19 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } =20 + xen_version =3D kvm_arch_xen_version(ms); + if (xen_version) { +#ifdef CONFIG_XEN_EMU + ret =3D kvm_xen_init(s, xen_version); + if (ret < 0) { + return ret; + } +#else + error_report("kvm: Xen support not enabled in qemu"); + return -ENOTSUP; +#endif + } + ret =3D kvm_get_supported_msrs(s); if (ret < 0) { return ret; diff --git a/target/i386/meson.build b/target/i386/meson.build index ae38dc9563..9f3ef246b8 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -7,6 +7,7 @@ i386_ss.add(files( 'cpu-dump.c', )) i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c')) +i386_ss.add(when: 'CONFIG_XEN_EMU', if_true: files('xen.c')) =20 # x86 cpu type i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c')) diff --git a/target/i386/xen.c b/target/i386/xen.c new file mode 100644 index 0000000000..bc183dce4e --- /dev/null +++ b/target/i386/xen.c @@ -0,0 +1,49 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "kvm/kvm_i386.h" +#include "xen.h" + +int kvm_xen_init(KVMState *s, uint32_t xen_version) +{ + const int required_caps =3D KVM_XEN_HVM_CONFIG_HYPERCALL_MSR | + KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL | KVM_XEN_HVM_CONFIG_SHARED_INF= O; + struct kvm_xen_hvm_config cfg =3D { + .msr =3D XEN_HYPERCALL_MSR, + .flags =3D KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL, + }; + int xen_caps, ret; + + xen_caps =3D kvm_check_extension(s, KVM_CAP_XEN_HVM); + if (required_caps & ~xen_caps) { + error_report("kvm: Xen HVM guest support not present or insufficie= nt"); + return -ENOSYS; + } + + if (xen_caps & KVM_XEN_HVM_CONFIG_EVTCHN_SEND) { + struct kvm_xen_hvm_attr ha =3D { + .type =3D KVM_XEN_ATTR_TYPE_XEN_VERSION, + .u.xen_version =3D xen_version, + }; + (void)kvm_vm_ioctl(s, KVM_XEN_HVM_SET_ATTR, &ha); + + cfg.flags |=3D KVM_XEN_HVM_CONFIG_EVTCHN_SEND; + } + + ret =3D kvm_vm_ioctl(s, KVM_XEN_HVM_CONFIG, &cfg); + if (ret < 0) { + error_report("kvm: Failed to enable Xen HVM support: %s", strerror= (-ret)); + return ret; + } + + return 0; +} diff --git a/target/i386/xen.h b/target/i386/xen.h new file mode 100644 index 0000000000..6c4f3b7822 --- /dev/null +++ b/target/i386/xen.h @@ -0,0 +1,19 @@ +/* + * Xen HVM emulation support in KVM + * + * Copyright =C2=A9 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright =C2=A9 2022 Amazon.com, Inc. or its affiliates. All Rights Re= served. + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_I386_XEN_H +#define QEMU_I386_XEN_H + +#define XEN_HYPERCALL_MSR 0x40000000 + +int kvm_xen_init(KVMState *s, uint32_t xen_version); + +#endif /* QEMU_I386_XEN_H */ --=20 2.35.3