[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 54/62] i386/xen: Implement HYPERVISOR_physdev_op
From: |
Paolo Bonzini |
Subject: |
[PULL 54/62] i386/xen: Implement HYPERVISOR_physdev_op |
Date: |
Thu, 2 Mar 2023 13:30:21 +0100 |
From: David Woodhouse <dwmw@amazon.co.uk>
Just hook up the basic hypercalls to stubs in xen_evtchn.c for now.
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
---
hw/i386/kvm/xen_evtchn.c | 25 ++++++++
hw/i386/kvm/xen_evtchn.h | 11 ++++
target/i386/kvm/xen-compat.h | 19 ++++++
target/i386/kvm/xen-emu.c | 118 +++++++++++++++++++++++++++++++++++
4 files changed, 173 insertions(+)
diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 6c396270b75d..b95ee9ba913e 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -1349,6 +1349,31 @@ int xen_evtchn_set_port(uint16_t port)
return ret;
}
+int xen_physdev_map_pirq(struct physdev_map_pirq *map)
+{
+ return -ENOTSUP;
+}
+
+int xen_physdev_unmap_pirq(struct physdev_unmap_pirq *unmap)
+{
+ return -ENOTSUP;
+}
+
+int xen_physdev_eoi_pirq(struct physdev_eoi *eoi)
+{
+ return -ENOTSUP;
+}
+
+int xen_physdev_query_pirq(struct physdev_irq_status_query *query)
+{
+ return -ENOTSUP;
+}
+
+int xen_physdev_get_free_pirq(struct physdev_get_free_pirq *get)
+{
+ return -ENOTSUP;
+}
+
struct xenevtchn_handle *xen_be_evtchn_open(void)
{
struct xenevtchn_handle *xc = g_new0(struct xenevtchn_handle, 1);
diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h
index 5a71ffb75311..352c87597643 100644
--- a/hw/i386/kvm/xen_evtchn.h
+++ b/hw/i386/kvm/xen_evtchn.h
@@ -62,4 +62,15 @@ int xen_evtchn_bind_interdomain_op(struct
evtchn_bind_interdomain *interdomain);
int xen_evtchn_bind_vcpu_op(struct evtchn_bind_vcpu *vcpu);
int xen_evtchn_reset_op(struct evtchn_reset *reset);
+struct physdev_map_pirq;
+struct physdev_unmap_pirq;
+struct physdev_eoi;
+struct physdev_irq_status_query;
+struct physdev_get_free_pirq;
+int xen_physdev_map_pirq(struct physdev_map_pirq *map);
+int xen_physdev_unmap_pirq(struct physdev_unmap_pirq *unmap);
+int xen_physdev_eoi_pirq(struct physdev_eoi *eoi);
+int xen_physdev_query_pirq(struct physdev_irq_status_query *query);
+int xen_physdev_get_free_pirq(struct physdev_get_free_pirq *get);
+
#endif /* QEMU_XEN_EVTCHN_H */
diff --git a/target/i386/kvm/xen-compat.h b/target/i386/kvm/xen-compat.h
index 448336de9236..7f30180cc2c5 100644
--- a/target/i386/kvm/xen-compat.h
+++ b/target/i386/kvm/xen-compat.h
@@ -48,4 +48,23 @@ struct compat_xen_add_to_physmap_batch {
COMPAT_HANDLE(int) errs;
};
+struct compat_physdev_map_pirq {
+ domid_t domid;
+ uint16_t pad;
+ /* IN */
+ int type;
+ /* IN (ignored for ..._MULTI_MSI) */
+ int index;
+ /* IN or OUT */
+ int pirq;
+ /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */
+ int bus;
+ /* IN */
+ int devfn;
+ /* IN (also OUT for ..._MULTI_MSI) */
+ int entry_nr;
+ /* IN */
+ uint64_t table_base;
+} __attribute__((packed));
+
#endif /* QEMU_I386_XEN_COMPAT_H */
diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c
index 50965b56f3c9..fe15696cc9a9 100644
--- a/target/i386/kvm/xen-emu.c
+++ b/target/i386/kvm/xen-emu.c
@@ -1539,6 +1539,121 @@ static bool kvm_xen_hcall_gnttab_op(struct kvm_xen_exit
*exit, X86CPU *cpu,
return true;
}
+static bool kvm_xen_hcall_physdev_op(struct kvm_xen_exit *exit, X86CPU *cpu,
+ int cmd, uint64_t arg)
+{
+ CPUState *cs = CPU(cpu);
+ int err;
+
+ switch (cmd) {
+ case PHYSDEVOP_map_pirq: {
+ struct physdev_map_pirq map;
+
+ if (hypercall_compat32(exit->u.hcall.longmode)) {
+ struct compat_physdev_map_pirq *map32 = (void *)↦
+
+ if (kvm_copy_from_gva(cs, arg, map32, sizeof(*map32))) {
+ return -EFAULT;
+ }
+
+ /*
+ * The only thing that's different is the alignment of the
+ * uint64_t table_base at the end, which gets padding to make
+ * it 64-bit aligned in the 64-bit version.
+ */
+ qemu_build_assert(sizeof(*map32) == 36);
+ qemu_build_assert(offsetof(struct physdev_map_pirq, entry_nr) ==
+ offsetof(struct compat_physdev_map_pirq,
entry_nr));
+ memmove(&map.table_base, &map32->table_base,
sizeof(map.table_base));
+ } else {
+ if (kvm_copy_from_gva(cs, arg, &map, sizeof(map))) {
+ err = -EFAULT;
+ break;
+ }
+ }
+ err = xen_physdev_map_pirq(&map);
+ /*
+ * Since table_base is an IN parameter and won't be changed, just
+ * copy the size of the compat structure back to the guest.
+ */
+ if (!err && kvm_copy_to_gva(cs, arg, &map,
+ sizeof(struct compat_physdev_map_pirq))) {
+ err = -EFAULT;
+ }
+ break;
+ }
+ case PHYSDEVOP_unmap_pirq: {
+ struct physdev_unmap_pirq unmap;
+
+ qemu_build_assert(sizeof(unmap) == 8);
+ if (kvm_copy_from_gva(cs, arg, &unmap, sizeof(unmap))) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = xen_physdev_unmap_pirq(&unmap);
+ if (!err && kvm_copy_to_gva(cs, arg, &unmap, sizeof(unmap))) {
+ err = -EFAULT;
+ }
+ break;
+ }
+ case PHYSDEVOP_eoi: {
+ struct physdev_eoi eoi;
+
+ qemu_build_assert(sizeof(eoi) == 4);
+ if (kvm_copy_from_gva(cs, arg, &eoi, sizeof(eoi))) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = xen_physdev_eoi_pirq(&eoi);
+ if (!err && kvm_copy_to_gva(cs, arg, &eoi, sizeof(eoi))) {
+ err = -EFAULT;
+ }
+ break;
+ }
+ case PHYSDEVOP_irq_status_query: {
+ struct physdev_irq_status_query query;
+
+ qemu_build_assert(sizeof(query) == 8);
+ if (kvm_copy_from_gva(cs, arg, &query, sizeof(query))) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = xen_physdev_query_pirq(&query);
+ if (!err && kvm_copy_to_gva(cs, arg, &query, sizeof(query))) {
+ err = -EFAULT;
+ }
+ break;
+ }
+ case PHYSDEVOP_get_free_pirq: {
+ struct physdev_get_free_pirq get;
+
+ qemu_build_assert(sizeof(get) == 8);
+ if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = xen_physdev_get_free_pirq(&get);
+ if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) {
+ err = -EFAULT;
+ }
+ break;
+ }
+ case PHYSDEVOP_pirq_eoi_gmfn_v2: /* FreeBSD 13 makes this hypercall */
+ err = -ENOSYS;
+ break;
+
+ default:
+ return false;
+ }
+
+ exit->u.hcall.result = err;
+ return true;
+}
+
static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct kvm_xen_exit *exit)
{
uint16_t code = exit->u.hcall.input;
@@ -1580,6 +1695,9 @@ static bool do_kvm_xen_handle_exit(X86CPU *cpu, struct
kvm_xen_exit *exit)
case __HYPERVISOR_memory_op:
return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0],
exit->u.hcall.params[1]);
+ case __HYPERVISOR_physdev_op:
+ return kvm_xen_hcall_physdev_op(exit, cpu, exit->u.hcall.params[0],
+ exit->u.hcall.params[1]);
case __HYPERVISOR_xen_version:
return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0],
exit->u.hcall.params[1]);
--
2.39.1
- [PULL 40/62] hw/xen: Support HVM_PARAM_CALLBACK_TYPE_GSI callback, (continued)
- [PULL 40/62] hw/xen: Support HVM_PARAM_CALLBACK_TYPE_GSI callback, Paolo Bonzini, 2023/03/02
- [PULL 44/62] hw/xen: Support mapping grant frames, Paolo Bonzini, 2023/03/02
- [PULL 51/62] hw/xen: Add xen_xenstore device for xenstore emulation, Paolo Bonzini, 2023/03/02
- [PULL 47/62] i386/xen: handle PV timer hypercalls, Paolo Bonzini, 2023/03/02
- [PULL 48/62] i386/xen: Reserve Xen special pages for console, xenstore rings, Paolo Bonzini, 2023/03/02
- [PULL 50/62] hw/xen: Add backend implementation of interdomain event channel support, Paolo Bonzini, 2023/03/02
- [PULL 46/62] hw/xen: Implement GNTTABOP_query_size, Paolo Bonzini, 2023/03/02
- [PULL 43/62] hw/xen: Add xen_gnttab device for grant table emulation, Paolo Bonzini, 2023/03/02
- [PULL 56/62] hw/xen: Support GSI mapping to PIRQ, Paolo Bonzini, 2023/03/02
- [PULL 55/62] hw/xen: Implement emulated PIRQ hypercall support, Paolo Bonzini, 2023/03/02
- [PULL 54/62] i386/xen: Implement HYPERVISOR_physdev_op,
Paolo Bonzini <=
- [PULL 57/62] hw/xen: Support MSI mapping to PIRQ, Paolo Bonzini, 2023/03/02
- [PULL 53/62] hw/xen: Automatically add xen-platform PCI device for emulated Xen guests, Paolo Bonzini, 2023/03/02
- [PULL 61/62] qapi: Add 'acpi' field to 'query-machines' output, Paolo Bonzini, 2023/03/02
- [PULL 59/62] i386/xen: Document Xen HVM emulation, Paolo Bonzini, 2023/03/02
- [PULL 60/62] hw/xen: Subsume xen_be_register_common() into xen_be_init(), Paolo Bonzini, 2023/03/02
- [PULL 34/62] hw/xen: Implement EVTCHNOP_send, Paolo Bonzini, 2023/03/02
- [PULL 52/62] hw/xen: Add basic ring handling to xenstore, Paolo Bonzini, 2023/03/02
- Re: [PULL 00/62] i386, misc changes for QEMU 8.0 soft freeze, Peter Maydell, 2023/03/03