mirror of https://github.com/xemu-project/xemu.git
Bugfixes for emulated Xen support
Selected bugfixes for mainline and stable, especially to the per-vCPU local APIC vector delivery mode for event channel notifications, which was broken in a number of ways. The xen-block driver has been defaulting to the wrong protocol for x86 guest, and this fixes that — which is technically an incompatible change but I'm fairly sure nobody relies on the broken behaviour (and in production I *have* seen guests which rely on the correct behaviour, which now matches the blkback driver in the Linux kernel). A handful of other simple fixes for issues which came to light as new features (qv) were being developed. -----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEvgfZ/VSAmrLEsP9fY3Ys2mfi81kFAmVIvv4UHGR3bXcyQGlu ZnJhZGVhZC5vcmcACgkQY3Ys2mfi81nFmRAAvK3VNuGDV56TJqFdtEWD+3jzSZU0 CoL1mxggvwnlFn1SdHvbC5jl+UscknErcNbqlxMTTg9jQiiQqzFuaWujJnL0dEOY RJiS2scKln/1gv9NRbLE31FjPwoNz+zJI/iMvdutjT7Ll//v34jY0vd1Y5Wo53ay MBschuuxD1sUUTHNj5f9afrgZaetJfgBSNZraiLR5T2HEadJVJuhItdGxW1+KaPI zBIcflIeZmJl9b/L1a2bP3KJmRo8QzHB56X3uzwkPhYhYSU2dnCaJTLCkiNfK+Qh SgCBMlzsvJbIZqDA9YPOGdKK1ArfTJRmRDwAkqH0YQknQGoIkpN+7eQiiSv6PMS5 U/93V7r6MfaftIs6YdWSnFozWeBuyKZL9H2nAXqZgL5t6uEMVR8Un/kFnGfslTFY 9gQ1o4IM6ECLiXhIP/sPNOprrbFb0HU7QPtEDJOxrJzBM+IfLbldRHn4p9CccqQA LHvJF98VhX1d0nA0iZBT3qqfKPbmUhRV9Jrm+WamqNrRXhiGdF8EidsUf8RWX+JD xZWJiqhTwShxdLE6TC/JgFz4cQCVHG8QiZstZUbdq59gtz9YO5PGByMgI3ds7iNQ lGXAPFm+1wU85W4dZOH7qyim6d9ytFm2Fm110BKM8l9B6UKEuKHpsxXMqdo65JXI 7uBKbVpdPKul0DY= =dQ7h -----END PGP SIGNATURE----- Merge tag 'pull-xenfv-stable-20231106' of git://git.infradead.org/users/dwmw2/qemu into staging Bugfixes for emulated Xen support Selected bugfixes for mainline and stable, especially to the per-vCPU local APIC vector delivery mode for event channel notifications, which was broken in a number of ways. The xen-block driver has been defaulting to the wrong protocol for x86 guest, and this fixes that — which is technically an incompatible change but I'm fairly sure nobody relies on the broken behaviour (and in production I *have* seen guests which rely on the correct behaviour, which now matches the blkback driver in the Linux kernel). A handful of other simple fixes for issues which came to light as new features (qv) were being developed. # -----BEGIN PGP SIGNATURE----- # # iQJIBAABCAAyFiEEvgfZ/VSAmrLEsP9fY3Ys2mfi81kFAmVIvv4UHGR3bXcyQGlu # ZnJhZGVhZC5vcmcACgkQY3Ys2mfi81nFmRAAvK3VNuGDV56TJqFdtEWD+3jzSZU0 # CoL1mxggvwnlFn1SdHvbC5jl+UscknErcNbqlxMTTg9jQiiQqzFuaWujJnL0dEOY # RJiS2scKln/1gv9NRbLE31FjPwoNz+zJI/iMvdutjT7Ll//v34jY0vd1Y5Wo53ay # MBschuuxD1sUUTHNj5f9afrgZaetJfgBSNZraiLR5T2HEadJVJuhItdGxW1+KaPI # zBIcflIeZmJl9b/L1a2bP3KJmRo8QzHB56X3uzwkPhYhYSU2dnCaJTLCkiNfK+Qh # SgCBMlzsvJbIZqDA9YPOGdKK1ArfTJRmRDwAkqH0YQknQGoIkpN+7eQiiSv6PMS5 # U/93V7r6MfaftIs6YdWSnFozWeBuyKZL9H2nAXqZgL5t6uEMVR8Un/kFnGfslTFY # 9gQ1o4IM6ECLiXhIP/sPNOprrbFb0HU7QPtEDJOxrJzBM+IfLbldRHn4p9CccqQA # LHvJF98VhX1d0nA0iZBT3qqfKPbmUhRV9Jrm+WamqNrRXhiGdF8EidsUf8RWX+JD # xZWJiqhTwShxdLE6TC/JgFz4cQCVHG8QiZstZUbdq59gtz9YO5PGByMgI3ds7iNQ # lGXAPFm+1wU85W4dZOH7qyim6d9ytFm2Fm110BKM8l9B6UKEuKHpsxXMqdo65JXI # 7uBKbVpdPKul0DY= # =dQ7h # -----END PGP SIGNATURE----- # gpg: Signature made Mon 06 Nov 2023 18:25:02 HKT # gpg: using RSA key BE07D9FD54809AB2C4B0FF5F63762CDA67E2F359 # gpg: issuer "dwmw2@infradead.org" # gpg: Good signature from "David Woodhouse <dwmw2@infradead.org>" [unknown] # gpg: aka "David Woodhouse <dwmw2@exim.org>" [unknown] # gpg: aka "David Woodhouse <david@woodhou.se>" [unknown] # gpg: aka "David Woodhouse <dwmw2@kernel.org>" [unknown] # gpg: WARNING: The key's User ID is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: BE07 D9FD 5480 9AB2 C4B0 FF5F 6376 2CDA 67E2 F359 * tag 'pull-xenfv-stable-20231106' of git://git.infradead.org/users/dwmw2/qemu: hw/xen: use correct default protocol for xen-block on x86 hw/xen: take iothread mutex in xen_evtchn_reset_op() hw/xen: fix XenStore watch delivery to guest hw/xen: don't clear map_track[] in xen_gnttab_reset() hw/xen: select kernel mode for per-vCPU event channel upcall vector i386/xen: fix per-vCPU upcall vector for Xen emulation i386/xen: Don't advertise XENFEAT_supervisor_mode_kernel Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
54e97162db
|
@ -115,9 +115,13 @@ static void xen_block_connect(XenDevice *xendev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
if (xen_device_frontend_scanf(xendev, "protocol", "%ms",
|
||||
&str) != 1) {
|
||||
protocol = BLKIF_PROTOCOL_NATIVE;
|
||||
if (xen_device_frontend_scanf(xendev, "protocol", "%ms", &str) != 1) {
|
||||
/* x86 defaults to the 32-bit protocol even for 64-bit guests. */
|
||||
if (object_dynamic_cast(OBJECT(qdev_get_machine()), "x86-machine")) {
|
||||
protocol = BLKIF_PROTOCOL_X86_32;
|
||||
} else {
|
||||
protocol = BLKIF_PROTOCOL_NATIVE;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(str, XEN_IO_PROTO_ABI_X86_32) == 0) {
|
||||
protocol = BLKIF_PROTOCOL_X86_32;
|
||||
|
|
|
@ -490,6 +490,12 @@ int xen_evtchn_set_callback_param(uint64_t param)
|
|||
break;
|
||||
}
|
||||
|
||||
/* If the guest has set a per-vCPU callback vector, prefer that. */
|
||||
if (gsi && kvm_xen_has_vcpu_callback_vector()) {
|
||||
in_kernel = kvm_xen_has_cap(EVTCHN_SEND);
|
||||
gsi = 0;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
/* If vector delivery was turned *off* then tell the kernel */
|
||||
if ((s->callback_param >> CALLBACK_VIA_TYPE_SHIFT) ==
|
||||
|
@ -1129,6 +1135,7 @@ int xen_evtchn_reset_op(struct evtchn_reset *reset)
|
|||
return -ESRCH;
|
||||
}
|
||||
|
||||
QEMU_IOTHREAD_LOCK_GUARD();
|
||||
return xen_evtchn_soft_reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -541,7 +541,5 @@ int xen_gnttab_reset(void)
|
|||
s->entries.v1[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
|
||||
s->entries.v1[GNTTAB_RESERVED_XENSTORE].frame = XEN_SPECIAL_PFN(XENSTORE);
|
||||
|
||||
memset(s->map_track, 0, s->max_frames * ENTRIES_PER_FRAME_V1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1357,10 +1357,12 @@ static void fire_watch_cb(void *opaque, const char *path, const char *token)
|
|||
} else {
|
||||
deliver_watch(s, path, token);
|
||||
/*
|
||||
* If the message was queued because there was already ring activity,
|
||||
* no need to wake the guest. But if not, we need to send the evtchn.
|
||||
* Attempt to queue the message into the actual ring, and send
|
||||
* the event channel notification if any bytes are copied.
|
||||
*/
|
||||
xen_be_evtchn_notify(s->eh, s->be_port);
|
||||
if (s->rsp_pending && put_rsp(s) > 0) {
|
||||
xen_be_evtchn_notify(s->eh, s->be_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
int kvm_xen_soft_reset(void);
|
||||
uint32_t kvm_xen_get_caps(void);
|
||||
void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id);
|
||||
bool kvm_xen_has_vcpu_callback_vector(void);
|
||||
void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
|
||||
void kvm_xen_set_callback_asserted(void);
|
||||
int kvm_xen_set_vcpu_virq(uint32_t vcpu_id, uint16_t virq, uint16_t port);
|
||||
|
|
|
@ -267,7 +267,6 @@ static bool kvm_xen_hcall_xen_version(struct kvm_xen_exit *exit, X86CPU *cpu,
|
|||
fi.submap |= 1 << XENFEAT_writable_page_tables |
|
||||
1 << XENFEAT_writable_descriptor_tables |
|
||||
1 << XENFEAT_auto_translated_physmap |
|
||||
1 << XENFEAT_supervisor_mode_kernel |
|
||||
1 << XENFEAT_hvm_callback_vector |
|
||||
1 << XENFEAT_hvm_safe_pvclock |
|
||||
1 << XENFEAT_hvm_pirqs;
|
||||
|
@ -307,7 +306,7 @@ static int kvm_xen_set_vcpu_callback_vector(CPUState *cs)
|
|||
|
||||
trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector);
|
||||
|
||||
return kvm_vcpu_ioctl(cs, KVM_XEN_HVM_SET_ATTR, &xva);
|
||||
return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xva);
|
||||
}
|
||||
|
||||
static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data)
|
||||
|
@ -425,6 +424,13 @@ void kvm_xen_set_callback_asserted(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool kvm_xen_has_vcpu_callback_vector(void)
|
||||
{
|
||||
CPUState *cs = qemu_get_cpu(0);
|
||||
|
||||
return cs && !!X86_CPU(cs)->env.xen_vcpu_callback_vector;
|
||||
}
|
||||
|
||||
void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type)
|
||||
{
|
||||
CPUState *cs = qemu_get_cpu(vcpu_id);
|
||||
|
@ -441,7 +447,8 @@ void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type)
|
|||
* deliver it as an MSI.
|
||||
*/
|
||||
MSIMessage msg = {
|
||||
.address = APIC_DEFAULT_ADDRESS | X86_CPU(cs)->apic_id,
|
||||
.address = APIC_DEFAULT_ADDRESS |
|
||||
(X86_CPU(cs)->apic_id << MSI_ADDR_DEST_ID_SHIFT),
|
||||
.data = vector | (1UL << MSI_DATA_LEVEL_SHIFT),
|
||||
};
|
||||
kvm_irqchip_send_msi(kvm_state, msg);
|
||||
|
@ -850,8 +857,7 @@ static bool kvm_xen_hcall_hvm_op(struct kvm_xen_exit *exit, X86CPU *cpu,
|
|||
int ret = -ENOSYS;
|
||||
switch (cmd) {
|
||||
case HVMOP_set_evtchn_upcall_vector:
|
||||
ret = kvm_xen_hcall_evtchn_upcall_vector(exit, cpu,
|
||||
exit->u.hcall.params[0]);
|
||||
ret = kvm_xen_hcall_evtchn_upcall_vector(exit, cpu, arg);
|
||||
break;
|
||||
|
||||
case HVMOP_pagetable_dying:
|
||||
|
|
Loading…
Reference in New Issue