From 25b287345b4979b28b8c968f5e04023e85270120 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Fri, 3 Nov 2023 17:26:01 +0000 Subject: xen/pt: Emulate multifunction bit in header type The intention of the code appears to have been to unconditionally set the multifunction bit but since the emulation mask is 0x00 it has no effect. Instead, emulate the bit and set it based on the multifunction property of the PCIDevice (which can be set using QAPI). This allows making passthrough devices appear as functions in a Xen guest. Signed-off-by: Ross Lagerwall Reviewed-by: Paul Durrant Message-Id: <20231103172601.1319375-1-ross.lagerwall@citrix.com> Signed-off-by: Anthony PERARD --- hw/xen/xen_pt_config_init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'hw/xen') diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index ba4cd78..3edaeab 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -292,7 +292,10 @@ static int xen_pt_header_type_reg_init(XenPCIPassthroughState *s, uint32_t *data) { /* read PCI_HEADER_TYPE */ - *data = reg->init_val | 0x80; + *data = reg->init_val; + if ((PCI_DEVICE(s)->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) { + *data |= PCI_HEADER_TYPE_MULTI_FUNCTION; + } return 0; } @@ -677,7 +680,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = { .size = 1, .init_val = 0x00, .ro_mask = 0xFF, - .emu_mask = 0x00, + .emu_mask = PCI_HEADER_TYPE_MULTI_FUNCTION, .init = xen_pt_header_type_reg_init, .u.b.read = xen_pt_byte_reg_read, .u.b.write = xen_pt_byte_reg_write, -- cgit v1.1 From 9253d83062268209533df4b29859e5b51a2dc324 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 24 Jan 2024 10:14:50 +0800 Subject: xen: Drop out of coroutine context xen_invalidate_map_cache_entry xen_invalidate_map_cache_entry is not expected to run in a coroutine. Without this, there is crash: signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 threadid=) at pthread_kill.c:78 at /usr/src/debug/glibc/2.38+git-r0/sysdeps/posix/raise.c:26 fmt=0xffff9e1ca8a8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0xaaaae0d25740 "!qemu_in_coroutine()", file=file@entry=0xaaaae0d301a8 "../qemu-xen-dir-remote/block/graph-lock.c", line=line@entry=260, function=function@entry=0xaaaae0e522c0 <__PRETTY_FUNCTION__.3> "bdrv_graph_rdlock_main_loop") at assert.c:92 assertion=assertion@entry=0xaaaae0d25740 "!qemu_in_coroutine()", file=file@entry=0xaaaae0d301a8 "../qemu-xen-dir-remote/block/graph-lock.c", line=line@entry=260, function=function@entry=0xaaaae0e522c0 <__PRETTY_FUNCTION__.3> "bdrv_graph_rdlock_main_loop") at assert.c:101 at ../qemu-xen-dir-remote/block/graph-lock.c:260 at /home/Freenix/work/sw-stash/xen/upstream/tools/qemu-xen-dir-remote/include/block/graph-lock.h:259 host=host@entry=0xffff742c8000, size=size@entry=2097152) at ../qemu-xen-dir-remote/block/io.c:3362 host=0xffff742c8000, size=2097152) at ../qemu-xen-dir-remote/block/block-backend.c:2859 host=, size=, max_size=) at ../qemu-xen-dir-remote/block/block-ram-registrar.c:33 size=2097152, max_size=2097152) at ../qemu-xen-dir-remote/hw/core/numa.c:883 buffer=buffer@entry=0xffff743c5000 "") at ../qemu-xen-dir-remote/hw/xen/xen-mapcache.c:475 buffer=buffer@entry=0xffff743c5000 "") at ../qemu-xen-dir-remote/hw/xen/xen-mapcache.c:487 as=as@entry=0xaaaae1ca3ae8 , buffer=0xffff743c5000, len=, is_write=is_write@entry=true, access_len=access_len@entry=32768) at ../qemu-xen-dir-remote/system/physmem.c:3199 dir=DMA_DIRECTION_FROM_DEVICE, len=, buffer=, as=0xaaaae1ca3ae8 ) at /home/Freenix/work/sw-stash/xen/upstream/tools/qemu-xen-dir-remote/include/sysemu/dma.h:236 elem=elem@entry=0xaaaaf620aa30, len=len@entry=32769) at ../qemu-xen-dir-remote/hw/virtio/virtio.c:758 elem=elem@entry=0xaaaaf620aa30, len=len@entry=32769, idx=idx@entry=0) at ../qemu-xen-dir-remote/hw/virtio/virtio.c:919 elem=elem@entry=0xaaaaf620aa30, len=32769) at ../qemu-xen-dir-remote/hw/virtio/virtio.c:994 req=req@entry=0xaaaaf620aa30, status=status@entry=0 '\000') at ../qemu-xen-dir-remote/hw/block/virtio-blk.c:67 ret=0) at ../qemu-xen-dir-remote/hw/block/virtio-blk.c:136 at ../qemu-xen-dir-remote/block/block-backend.c:1559 --Type for more, q to quit, c to continue without paging-- at ../qemu-xen-dir-remote/block/block-backend.c:1614 i1=) at ../qemu-xen-dir-remote/util/coroutine-ucontext.c:177 at ../sysdeps/unix/sysv/linux/aarch64/setcontext.S:123 Signed-off-by: Peng Fan Reviewed-by: Stefano Stabellini Message-Id: <20240124021450.21656-1-peng.fan@oss.nxp.com> Signed-off-by: Anthony PERARD --- hw/xen/xen-mapcache.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'hw/xen') diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c index 4f956d0..7f59080 100644 --- a/hw/xen/xen-mapcache.c +++ b/hw/xen/xen-mapcache.c @@ -476,11 +476,37 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer) g_free(entry); } -void xen_invalidate_map_cache_entry(uint8_t *buffer) +typedef struct XenMapCacheData { + Coroutine *co; + uint8_t *buffer; +} XenMapCacheData; + +static void xen_invalidate_map_cache_entry_bh(void *opaque) { + XenMapCacheData *data = opaque; + mapcache_lock(); - xen_invalidate_map_cache_entry_unlocked(buffer); + xen_invalidate_map_cache_entry_unlocked(data->buffer); mapcache_unlock(); + + aio_co_wake(data->co); +} + +void coroutine_mixed_fn xen_invalidate_map_cache_entry(uint8_t *buffer) +{ + if (qemu_in_coroutine()) { + XenMapCacheData data = { + .co = qemu_coroutine_self(), + .buffer = buffer, + }; + aio_bh_schedule_oneshot(qemu_get_current_aio_context(), + xen_invalidate_map_cache_entry_bh, &data); + qemu_coroutine_yield(); + } else { + mapcache_lock(); + xen_invalidate_map_cache_entry_unlocked(buffer); + mapcache_unlock(); + } } void xen_invalidate_map_cache(void) -- cgit v1.1