4.20-rc6: WARNING: CPU: 30 PID: 197360 at net/core/flow_dissector.c:764 __skb_flow_dissect
Folks, I got this warning today. I cant tell when and why this happened, so I do not know yet how to reproduce. Maybe someone has a quick idea. [85109.572032] WARNING: CPU: 30 PID: 197360 at net/core/flow_dissector.c:764 __skb_flow_dissect+0x1f0/0x1318 [85109.572036] Modules linked in: vhost_net vhost macvtap macvlan tap vfio_ap vfio_mdev mdev vfio_iommu_type1 vfio kvm xt_CHECKSUM ipt_MASQUERADE tun bridge stp llc xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip6table_nat nf_nat_ipv6 ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat_ipv4 nf_nat iptable_mangle iptable_raw iptable_security nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nfnetlink ip6table_filter ip6_tables iptable_filter dm_service_time rpcrdma sunrpc rdma_ucm rdma_cm configfs iw_cm ib_cm mlx4_ib ib_uverbs ib_core pkey ghash_s390 prng aes_s390 des_s390 des_generic sha512_s390 sha1_s390 zcrypt_cex4 zcrypt rng_core eadm_sch sch_fq_codel ip_tables x_tables mlx4_en mlx4_core sha256_s390 sha_common dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua dm_mirror dm_region_hash dm_log dm_mod autofs4 [85109.572072] CPU: 30 PID: 197360 Comm: vhost-197330 Not tainted 4.20.0-20181213.rc6.git0.407d079170c1.300.fc29.s390x #1 [85109.572074] Hardware name: IBM 2964 NC9 712 (LPAR) [85109.572075] Krnl PSW : 0704c0018000 0092e320 (__skb_flow_dissect+0x1f0/0x1318) [85109.572078]R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3 [85109.572080] Krnl GPRS: 002a 03e0385bfc84 00d91e30 [85109.572081]03e0385bfc84 00d91e30 [85109.572083]03e0385bfc84 000e 007e3eb88100 007ff3561e00 [85109.572084]0806 00b4f288 03e0385bfbb8 03e0385bfab0 [85109.572115] Krnl Code: 0092e312: e310b0180002ltg %r1,24(%r11) 0092e318: a7740271brc 7,92e7fa #0092e31c: a7f40001brc 15,92e31e >0092e320: 91407003tm 3(%r7),64 0092e324: a7740257brc 7,92e7d2 0092e328: 5810f0b4l %r1,180(%r15) 0092e32c: e54cf0c8mvhi 200(%r15),0 0092e332: c01b0008nilf%r1,8 [85109.572129] Call Trace: [85109.572130] ([<>] (null)) [85109.572134] [<03ff800c81e4>] tap_sendmsg+0x384/0x430 [tap] [85109.572137] [<03ff801acdee>] vhost_tx_batch.isra.10+0x66/0xe0 [vhost_net] [85109.572138] [<03ff801ad61c>] handle_tx_copy+0x18c/0x568 [vhost_net] [85109.572140] [<03ff801adab4>] handle_tx+0xbc/0x100 [vhost_net] [85109.572145] [<03ff8019bbe8>] vhost_worker+0xc8/0x128 [vhost] [85109.572148] [<001690b8>] kthread+0x140/0x160 [85109.572152] [<00a84266>] kernel_thread_starter+0x6/0x10 [85109.572154] [<00a84260>] kernel_thread_starter+0x0/0x10 [85109.572155] Last Breaking-Event-Address: [85109.572156] [<0092e31c>] __skb_flow_dissect+0x1ec/0x1318 [85109.572158] ---[ end trace 97c040a6691bc000 ]--- ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH v2] drm/bochs: add edid present check
Check first two header bytes before trying to read the edid blob, to avoid the log being spammed in case qemu has no edid support (old qemu or edid turned off). Fixes: 01f23459cf drm/bochs: add edid support. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_hw.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index c90a0d492f..e1f8ffce00 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -89,6 +89,14 @@ int bochs_hw_load_edid(struct bochs_device *bochs) if (!bochs->mmio) return -1; + /* +* Check first two EDID blob header bytes to figure whenever +* edid support is enabled in qemu. +*/ + if (readb(bochs->mmio + 0) != 0x00 || + readb(bochs->mmio + 1) != 0xff) + return -1; + kfree(bochs->edid); bochs->edid = drm_do_get_edid(&bochs->connector, bochs_get_edid_block, bochs); -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH] virtio: fix test build after uio.h change
Fixes: d38499530e5 ("fs: decouple READ and WRITE from the block layer ops") Signed-off-by: Michael S. Tsirkin --- tools/virtio/linux/kernel.h | 4 1 file changed, 4 insertions(+) diff --git a/tools/virtio/linux/kernel.h b/tools/virtio/linux/kernel.h index fb22bccfbc8a..7ef45a4a3cba 100644 --- a/tools/virtio/linux/kernel.h +++ b/tools/virtio/linux/kernel.h @@ -23,6 +23,10 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #define PAGE_ALIGN(x) ((x + PAGE_SIZE - 1) & PAGE_MASK) +/* generic data direction definitions */ +#define READ0 +#define WRITE 1 + typedef unsigned long long phys_addr_t; typedef unsigned long long dma_addr_t; typedef size_t __kernel_size_t; -- MST ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PULL] virtio fix
Sorry about the last-minute pull req. But it does seem very very safe and also the tests aren't automatically built right now so the 0 day infrastructure won't help anyway. The following changes since commit 7566ec393f4161572ba6f11ad5171fd5d59b0fbd: Linux 4.20-rc7 (2018-12-16 15:46:55 -0800) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git tags/for_linus for you to fetch changes up to c5c08bed843c2b2c048c16d1296d7631d7c1620e: virtio: fix test build after uio.h change (2018-12-19 18:23:49 -0500) virtio fix A last-minute fix for a test build. Signed-off-by: Michael S. Tsirkin Michael S. Tsirkin (1): virtio: fix test build after uio.h change tools/virtio/linux/kernel.h | 4 1 file changed, 4 insertions(+) ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v6 0/7] Add virtio-iommu driver
On Thu, Dec 13, 2018 at 12:50:29PM +, Jean-Philippe Brucker wrote: > >> [3] git://linux-arm.org/linux-jpb.git virtio-iommu/v0.9.1 > >> git://linux-arm.org/kvmtool-jpb.git virtio-iommu/v0.9 > > > > Unfortunatly gitweb seems to be broken on linux-arm.org. What is missing > > in this patch-set to make this work on x86? > > You should be able to access it here: > http://www.linux-arm.org/git?p=linux-jpb.git;a=shortlog;h=refs/heads/virtio-iommu/devel > > That branch contains missing bits for x86 support: > > * ACPI support. We have the code but it's waiting for an IORT spec > update, to reserve the IORT node ID. I expect it to take a while, given > that I'm alone requesting a change for something that's not upstream or > in hardware. Frankly I think you should take a hard look at just getting the data needed from the PCI device itself. You don't need to depend on virtio, it can be a small driver that gets you that data from the device config space and then just goes away. If you want help with writing such a small driver let me know. If there's an advantage to virtio-iommu then that would be its portability, and it all goes out of the window because of dependencies on ACPI and DT and OF and the rest of the zoo. > * DMA ops for x86 (see "HACK" commit). I'd like to use dma-iommu but I'm > not sure how to implement the glue that sets dma_ops properly. > > Thanks, > Jean OK so IIUC you are looking into Christoph's suggestions to fix that up? There's still a bit of time left before the merge window, maybe you can make above changes. -- MST ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net 4/4] vhost: log dirty page correctly
Hi Jason, I love your patch! Perhaps something to improve: [auto build test WARNING on net/master] url: https://github.com/0day-ci/linux/commits/Jason-Wang/Fix-various-issue-of-vhost/20181210-223236 config: x86_64-allmodconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): include/linux/slab.h:332:43: warning: dubious: x & !y include/linux/slab.h:332:43: warning: dubious: x & !y include/linux/slab.h:332:43: warning: dubious: x & !y drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * include/linux/slab.h:332:43: warning: dubious: x & !y drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * >> drivers/vhost/vhost.c:1771:35: warning: cast removes address space '' >> of expression drivers/vhost/vhost.c:1776:42: warning: cast removes address space '' of expression drivers/vhost/vhost.c:1788:48: warning: cast removes address space '' of expression drivers/vhost/vhost.c:1819:13: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:1819:13:expected void *addr drivers/vhost/vhost.c:1819:13:got restricted __virtio16 [noderef] * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:851:42: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:851:42:expected void [noderef] *addr drivers/vhost/vhost.c:851:42:got void *addr drivers/vhost/vhost.c:1837:13: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:1837:13:expected void *addr drivers/vhost/vhost.c:1837:13:got restricted __virtio16 [noderef] [usertype] * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:851:42: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:851:42:expected void [noderef] *addr drivers/vhost/vhost.c:851:42:got void *addr drivers/vhost/vhost.c:1874:13: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:1874:13:expected void *addr drivers/vhost/vhost.c:1874:13:got restricted __virtio16 [noderef] * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:851:42: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:851:42:expected void [noderef] *addr drivers/vhost/vhost.c:851:42:got void *addr drivers/vhost/vhost.c:2073:21: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:2073:21:expected void *addr drivers/vhost/vhost.c:2073:21:got restricted __virtio16 [noderef] * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:851:42: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:851:42:expected void [noderef] *addr drivers/vhost/vhost.c:851:42:got void *addr drivers/vhost/vhost.c:2100:13: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:2100:13:expected void *addr drivers/vhost/vhost.c:2100:13:got restricted __virtio16 [noderef] * drivers/vhost/vhost.c:704:17: warning: incorrect type in return expression (different address spaces) drivers/vhost/vhost.c:704:17:expected void [noderef] * drivers/vhost/vhost.c:704:17:got void * drivers/vhost/vhost.c:851:42: warning: incorrect type in argument 2 (different address spaces) drivers/vhost/vhost.c:851:42:expected void [noderef] *addr drivers/vhost/vhost.c:851:42:got void *addr drivers/vhost/vhost.c:2231:21: warning: incorrect type in argument 2 (differ
Re: [PATCH] drm/bochs: add edid present check
Hi, > You could probably have a comment here explaining the magic below > (just like in the commit message to ease the task of understanding > while reading the code why 2 of 8 bytes of the EDID header is checked > and why it is all needed). Of course one can use git blame... Up to you Makes sense. > > + if (readb(bochs->mmio + 0) != 0x00 || > > + readb(bochs->mmio + 1) != 0xff) > > bochs->mmio is defined as "void __iomem *mmio;". Can we please avoid > void pointer arithmetic here? Why is that a problem? gcc uses bytes when doing pointer arithmetic with void pointers (even though it is undefined in the C standard), and as far I know the linux kernel depends on that behavior anyway. Also the driver already does it everywhere. cheers, Gerd ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v3 00/12] x86, kbuild: revert macrofying inline assembly code
On Wed, Dec 19, 2018 at 9:44 PM Ingo Molnar wrote: > > > * Masahiro Yamada wrote: > > > This series reverts the in-kernel workarounds for inlining issues. > > > > The commit description of 77b0bf55bc67 mentioned > > "We also hope that GCC will eventually get fixed,..." > > > > Now, GCC provides a solution. > > > > https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html > > explains the new "asm inline" syntax. > > > > The performance issue will be eventually solved. > > > > [About Code cleanups] > > > > I know Nadam Amit is opposed to the full revert. > > He also claims his motivation for macrofying was not only > > performance, but also cleanups. > > > > IIUC, the criticism addresses the code duplication between C and ASM. > > > > If so, I'd like to suggest a different approach for cleanups. > > Please see the last 3 patches. > > IMHO, preprocessor approach is more straight-forward, and readable. > > Basically, this idea should work because it is what we already do for > > __ASM_FORM() etc. > > > > [Quick Test of "asm inline" of GCC 9] > > > > If you want to try "asm inline" feature, the patch is available: > > https://lore.kernel.org/patchwork/patch/1024590/ > > > > The number of symbols for arch/x86/configs/x86_64_defconfig: > > > > nr_symbols > > [1]v4.20-rc7 : 96502 > > [2][1]+full revert : 96705 (+203) > > [3][2]+"asm inline": 96568 (-137) > > > > [3]: apply my patch, then replace "asm" -> "asm_inline" > > for _BUG_FLAGS(), refcount_add(), refcount_inc(), refcount_dec(), > > annotate_reachable(), annotate_unreachable() > > > > > > Changes in v3: > > - Split into per-commit revert (per Nadav Amit) > > - Add some cleanups with preprocessor approach > > > > Changes in v2: > > - Revive clean-ups made by 5bdcd510c2ac (per Peter Zijlstra) > > - Fix commit quoting style (per Peter Zijlstra) > > > > Masahiro Yamada (12): > > Revert "x86/jump-labels: Macrofy inline assembly code to work around > > GCC inlining bugs" > > Revert "x86/cpufeature: Macrofy inline assembly code to work around > > GCC inlining bugs" > > Revert "x86/extable: Macrofy inline assembly code to work around GCC > > inlining bugs" > > Revert "x86/paravirt: Work around GCC inlining bugs when compiling > > paravirt ops" > > Revert "x86/bug: Macrofy the BUG table section handling, to work > > around GCC inlining bugs" > > Revert "x86/alternatives: Macrofy lock prefixes to work around GCC > > inlining bugs" > > Revert "x86/refcount: Work around GCC inlining bug" > > Revert "x86/objtool: Use asm macros to work around GCC inlining bugs" > > Revert "kbuild/Makefile: Prepare for using macros in inline assembly > > code to work around asm() related GCC inlining bugs" > > linux/linkage: add ASM() macro to reduce duplication between C/ASM > > code > > x86/alternatives: consolidate LOCK_PREFIX macro > > x86/asm: consolidate ASM_EXTABLE_* macros > > > > Makefile | 9 +-- > > arch/x86/Makefile | 7 --- > > arch/x86/include/asm/alternative-asm.h| 22 +-- > > arch/x86/include/asm/alternative-common.h | 47 +++ > > arch/x86/include/asm/alternative.h| 30 +- > > arch/x86/include/asm/asm.h| 46 +-- > > arch/x86/include/asm/bug.h| 98 > > +-- > > arch/x86/include/asm/cpufeature.h | 82 +++--- > > arch/x86/include/asm/jump_label.h | 22 +-- > > arch/x86/include/asm/paravirt_types.h | 56 +- > > arch/x86/include/asm/refcount.h | 81 +++-- > > arch/x86/kernel/macros.S | 16 - > > include/asm-generic/bug.h | 8 +-- > > include/linux/compiler.h | 56 -- > > include/linux/linkage.h | 8 +++ > > scripts/Kbuild.include| 4 +- > > scripts/mod/Makefile | 2 - > > 17 files changed, 249 insertions(+), 345 deletions(-) > > create mode 100644 arch/x86/include/asm/alternative-common.h > > delete mode 100644 arch/x86/kernel/macros.S > > I absolutely agree that this needs to be resolved in v4.20. > > So I did the 1-9 reverts manually myself as well, because I think the > first commit should be reverted fully to get as close to the starting > point as possible (we are late in the cycle) - and came to the attached > interdiff between your series and mine. > > Does this approach look OK to you, or did I miss something? It looks OK to me. I thought the diff was a good cleanup part, but we can deal with it later on, so I do not mind it. Thanks! > Thanks, > > Ingo > > => > > entry/calling.h |2 - > include/asm/jump_label.h | 50 > ++- > 2 files changed, 38 insertions(+), 14 d
[PATCH 08/10] drm/virtio: drop fencing in virtio_gpu_resource_create_ioctl
There is no need to wait for completion here. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 51 +- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 52d6ec2dde..65ac61f86a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -279,10 +279,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, struct virtio_gpu_object *qobj; struct drm_gem_object *obj; uint32_t handle = 0; - struct list_head validate_list; - struct ttm_validate_buffer mainbuf; - struct virtio_gpu_fence *fence = NULL; - struct ww_acquire_ctx ticket; struct virtio_gpu_object_params params = { .pinned = false, }; @@ -300,9 +296,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - INIT_LIST_HEAD(&validate_list); - memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer)); - params.format = rc->format; params.width = rc->width; params.height = rc->height; @@ -330,62 +323,20 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, ret = virtio_gpu_object_attach(vgdev, qobj, NULL); } else { - /* use a gem reference since unref list undoes them */ - drm_gem_object_get(&qobj->gem_base); - mainbuf.bo = &qobj->tbo; - list_add(&mainbuf.head, &validate_list); - - ret = virtio_gpu_object_list_validate(&ticket, &validate_list); - if (ret) { - DRM_DEBUG("failed to validate\n"); - goto fail_unref; - } - - fence = virtio_gpu_fence_alloc(vgdev); - if (!fence) { - ret = -ENOMEM; - goto fail_backoff; - } - virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms); - ret = virtio_gpu_object_attach(vgdev, qobj, fence); - if (ret) { - dma_fence_put(&fence->f); - goto fail_backoff; - } - ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); + ret = virtio_gpu_object_attach(vgdev, qobj, NULL); } ret = drm_gem_handle_create(file_priv, obj, &handle); if (ret) { - drm_gem_object_release(obj); - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } return ret; } drm_gem_object_put_unlocked(obj); rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */ rc->bo_handle = handle; - - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } return 0; -fail_backoff: - ttm_eu_backoff_reservation(&ticket, &validate_list); -fail_unref: - if (vgdev->has_virgl_3d) { - virtio_gpu_unref_list(&validate_list); - dma_fence_put(&fence->f); - } -//fail_obj: -// drm_gem_object_handle_unreference_unlocked(obj); - return ret; } static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 05/10] drm/virtio: use struct to pass params to virtio_gpu_object_create()
Create virtio_gpu_object_params, use that to pass object parameters to virtio_gpu_object_create. Also drop unused "kernel" parameter (unused, always false). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h| 15 ++- drivers/gpu/drm/virtio/virtgpu_gem.c| 18 +++--- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 12 +++- drivers/gpu/drm/virtio/virtgpu_object.c | 22 +- 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bfb31fc3d0..8cff8a3f7c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -53,6 +53,11 @@ /* virtgpu_drm_bus.c */ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); +struct virtio_gpu_object_params { + unsigned long size; + bool pinned; +}; + struct virtio_gpu_object { struct drm_gem_object gem_base; uint32_t hw_res_handle; @@ -220,16 +225,16 @@ int virtio_gpu_gem_init(struct virtio_gpu_device *vgdev); void virtio_gpu_gem_fini(struct virtio_gpu_device *vgdev); int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev, - uint64_t size, + struct virtio_gpu_object_params *params, struct drm_gem_object **obj_p, uint32_t *handle_p); int virtio_gpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file); void virtio_gpu_gem_object_close(struct drm_gem_object *obj, struct drm_file *file); -struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, - size_t size, bool kernel, - bool pinned); +struct virtio_gpu_object* +virtio_gpu_alloc_object(struct drm_device *dev, + struct virtio_gpu_object_params *params); int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args); @@ -345,7 +350,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, /* virtio_gpu_object */ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, -unsigned long size, bool kernel, bool pinned, +struct virtio_gpu_object_params *params, struct virtio_gpu_object **bo_ptr); void virtio_gpu_object_kunmap(struct virtio_gpu_object *bo); int virtio_gpu_object_kmap(struct virtio_gpu_object *bo); diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index f065863939..384cd80bf3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -34,15 +34,15 @@ void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj) virtio_gpu_object_unref(&obj); } -struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, - size_t size, bool kernel, - bool pinned) +struct virtio_gpu_object* +virtio_gpu_alloc_object(struct drm_device *dev, + struct virtio_gpu_object_params *params) { struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_object *obj; int ret; - ret = virtio_gpu_object_create(vgdev, size, kernel, pinned, &obj); + ret = virtio_gpu_object_create(vgdev, params, &obj); if (ret) return ERR_PTR(ret); @@ -51,7 +51,7 @@ struct virtio_gpu_object *virtio_gpu_alloc_object(struct drm_device *dev, int virtio_gpu_gem_create(struct drm_file *file, struct drm_device *dev, - uint64_t size, + struct virtio_gpu_object_params *params, struct drm_gem_object **obj_p, uint32_t *handle_p) { @@ -59,7 +59,7 @@ int virtio_gpu_gem_create(struct drm_file *file, int ret; u32 handle; - obj = virtio_gpu_alloc_object(dev, size, false, false); + obj = virtio_gpu_alloc_object(dev, params); if (IS_ERR(obj)) return PTR_ERR(obj); @@ -85,6 +85,9 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_gem_object *gobj; struct virtio_gpu_object *obj; + struct virtio_gpu_object_params params = { + .pinned = false, + }; int ret; uint32_t pitch; uint32_t format; @@ -96,7 +99,8 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, args->size = pitch * args->height; args->size = ALIGN(
[PATCH 07/10] drm/virtio: params struct for virtio_gpu_cmd_create_resource_3d()
Add 3d resource parameters to virtio_gpu_object_params struct and use it for virtio_gpu_cmd_resource_create_3d() calls. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 10 +- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 25 ++--- drivers/gpu/drm/virtio/virtgpu_vq.c| 16 +--- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 8c65deadd0..f9959306ae 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -59,6 +59,14 @@ struct virtio_gpu_object_params { uint32_t height; unsigned long size; bool pinned; + /* 3d */ + uint32_t target; + uint32_t bind; + uint32_t depth; + uint32_t array_size; + uint32_t last_level; + uint32_t nr_samples; + uint32_t flags; }; struct virtio_gpu_object { @@ -313,7 +321,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - struct virtio_gpu_resource_create_3d *rc_3d); + struct virtio_gpu_object_params *params); void virtio_gpu_ctrl_ack(struct virtqueue *vq); void virtio_gpu_cursor_ack(struct virtqueue *vq); void virtio_gpu_fence_ack(struct virtqueue *vq); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 33112c8495..52d6ec2dde 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -283,7 +283,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, struct ttm_validate_buffer mainbuf; struct virtio_gpu_fence *fence = NULL; struct ww_acquire_ctx ticket; - struct virtio_gpu_resource_create_3d rc_3d; struct virtio_gpu_object_params params = { .pinned = false, }; @@ -308,7 +307,15 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, params.width = rc->width; params.height = rc->height; params.size = rc->size; - + if (vgdev->has_virgl_3d) { + params.target = rc->target; + params.bind = rc->bind; + params.depth = rc->depth; + params.array_size = rc->array_size; + params.last_level = rc->last_level; + params.nr_samples = rc->nr_samples; + params.flags = rc->flags; + } /* allocate a single page size object */ if (params.size == 0) params.size = PAGE_SIZE; @@ -334,25 +341,13 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, goto fail_unref; } - rc_3d.resource_id = cpu_to_le32(qobj->hw_res_handle); - rc_3d.target = cpu_to_le32(rc->target); - rc_3d.format = cpu_to_le32(rc->format); - rc_3d.bind = cpu_to_le32(rc->bind); - rc_3d.width = cpu_to_le32(rc->width); - rc_3d.height = cpu_to_le32(rc->height); - rc_3d.depth = cpu_to_le32(rc->depth); - rc_3d.array_size = cpu_to_le32(rc->array_size); - rc_3d.last_level = cpu_to_le32(rc->last_level); - rc_3d.nr_samples = cpu_to_le32(rc->nr_samples); - rc_3d.flags = cpu_to_le32(rc->flags); - fence = virtio_gpu_fence_alloc(vgdev); if (!fence) { ret = -ENOMEM; goto fail_backoff; } - virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); + virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms); ret = virtio_gpu_object_attach(vgdev, qobj, fence); if (ret) { dma_fence_put(&fence->f); diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 363b8b8577..ca93ec6ca3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -826,7 +826,7 @@ void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, void virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - struct virtio_gpu_resource_create_3d *rc_3d) + struct virtio_gpu_object_params *params) { struct virtio_gpu_resource_create_3d *cmd_p; struct virtio_gpu_vbuffer *vbuf; @@ -834,9 +834,19 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); memset(cmd_p, 0, sizeof(*cmd_p)); - *cmd_p = *rc
[PATCH 02/10] drm/virtio: fix pageflip flush
Sending the flush command only makes sense if we actually have a framebuffer attached to the scanout (handle != 0). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_plane.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index ead5c53d4e..548265b8e8 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -130,11 +130,12 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); - virtio_gpu_cmd_resource_flush(vgdev, handle, - plane->state->src_x >> 16, - plane->state->src_y >> 16, - plane->state->src_w >> 16, - plane->state->src_h >> 16); + if (handle) + virtio_gpu_cmd_resource_flush(vgdev, handle, + plane->state->src_x >> 16, + plane->state->src_y >> 16, + plane->state->src_w >> 16, + plane->state->src_h >> 16); } static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 09/10] drm/virtio: move virtio_gpu_cmd_create_resource call into virtio_gpu_object_create
Specifically call virtio_gpu_object_create() before ttm_bo_init(). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h| 2 ++ drivers/gpu/drm/virtio/virtgpu_gem.c| 3 +-- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 10 ++ drivers/gpu/drm/virtio/virtgpu_object.c | 10 -- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index f9959306ae..f50ca81132 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -59,7 +59,9 @@ struct virtio_gpu_object_params { uint32_t height; unsigned long size; bool pinned; + bool dumb; /* 3d */ + bool virgl; uint32_t target; uint32_t bind; uint32_t depth; diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index eea6c6e8db..ca84990382 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -102,20 +102,19 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, params.width = args->width; params.height = args->height; params.size = args->size; + params.dumb = true; ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj, &args->handle); if (ret) goto fail; obj = gem_to_virtio_gpu_obj(gobj); - virtio_gpu_cmd_create_resource(vgdev, obj, ¶ms); /* attach the object to the resource */ ret = virtio_gpu_object_attach(vgdev, obj, NULL); if (ret) goto fail; - obj->dumb = true; args->pitch = pitch; return ret; diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 65ac61f86a..e5bd1fed56 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -301,6 +301,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, params.height = rc->height; params.size = rc->size; if (vgdev->has_virgl_3d) { + params.virgl = true; params.target = rc->target; params.bind = rc->bind; params.depth = rc->depth; @@ -318,14 +319,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, return PTR_ERR(qobj); obj = &qobj->gem_base; - if (!vgdev->has_virgl_3d) { - virtio_gpu_cmd_create_resource(vgdev, qobj, ¶ms); - - ret = virtio_gpu_object_attach(vgdev, qobj, NULL); - } else { - virtio_gpu_cmd_resource_create_3d(vgdev, qobj, ¶ms); - ret = virtio_gpu_object_attach(vgdev, qobj, NULL); - } + ret = virtio_gpu_object_attach(vgdev, qobj, NULL); ret = drm_gem_handle_create(file_priv, obj, &handle); if (ret) { diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 62367e3f80..94da9e68d2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -106,9 +106,15 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, kfree(bo); return ret; } - bo->dumb = false; + bo->dumb = params->dumb; + + if (params->virgl) { + virtio_gpu_cmd_resource_create_3d(vgdev, bo, params); + } else { + virtio_gpu_cmd_create_resource(vgdev, bo, params); + } + virtio_gpu_init_ttm_placement(bo, params->pinned); - ret = ttm_bo_init(&vgdev->mman.bdev, &bo->tbo, params->size, ttm_bo_type_device, &bo->placement, 0, true, acc_size, NULL, NULL, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 04/10] drm/virtio: move virtio_gpu_object_{attach, detach} calls.
Drop the dummy ttm backend implementation, add a real one for TTM_PL_FLAG_TT objects. The bin/unbind callbacks will call virtio_gpu_object_{attach,detach}, to update the object state on the host side, instead of invoking those calls from the move_notify() callback. With that in place the move and move_notify callbacks are not needed any more, so drop them. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_ttm.c | 92 ++-- 1 file changed, 24 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c b/drivers/gpu/drm/virtio/virtgpu_ttm.c index 4bfbf25fab..77407976c7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ttm.c +++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c @@ -194,42 +194,45 @@ static void virtio_gpu_ttm_io_mem_free(struct ttm_bo_device *bdev, */ struct virtio_gpu_ttm_tt { struct ttm_dma_tt ttm; - struct virtio_gpu_device*vgdev; - u64 offset; + struct virtio_gpu_object*obj; }; -static int virtio_gpu_ttm_backend_bind(struct ttm_tt *ttm, - struct ttm_mem_reg *bo_mem) +static int virtio_gpu_ttm_tt_bind(struct ttm_tt *ttm, + struct ttm_mem_reg *bo_mem) { - struct virtio_gpu_ttm_tt *gtt = (void *)ttm; + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); + struct virtio_gpu_device *vgdev = + virtio_gpu_get_vgdev(gtt->obj->tbo.bdev); - gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); - if (!ttm->num_pages) - WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", -ttm->num_pages, bo_mem, ttm); - - /* Not implemented */ + virtio_gpu_object_attach(vgdev, gtt->obj, NULL); return 0; } -static int virtio_gpu_ttm_backend_unbind(struct ttm_tt *ttm) +static int virtio_gpu_ttm_tt_unbind(struct ttm_tt *ttm) { - /* Not implemented */ + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); + struct virtio_gpu_device *vgdev = + virtio_gpu_get_vgdev(gtt->obj->tbo.bdev); + + virtio_gpu_object_detach(vgdev, gtt->obj); return 0; } -static void virtio_gpu_ttm_backend_destroy(struct ttm_tt *ttm) +static void virtio_gpu_ttm_tt_destroy(struct ttm_tt *ttm) { - struct virtio_gpu_ttm_tt *gtt = (void *)ttm; + struct virtio_gpu_ttm_tt *gtt = + container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm); ttm_dma_tt_fini(>t->ttm); kfree(gtt); } -static struct ttm_backend_func virtio_gpu_backend_func = { - .bind = &virtio_gpu_ttm_backend_bind, - .unbind = &virtio_gpu_ttm_backend_unbind, - .destroy = &virtio_gpu_ttm_backend_destroy, +static struct ttm_backend_func virtio_gpu_tt_func = { + .bind = &virtio_gpu_ttm_tt_bind, + .unbind = &virtio_gpu_ttm_tt_unbind, + .destroy = &virtio_gpu_ttm_tt_destroy, }; static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, @@ -242,8 +245,8 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, gtt = kzalloc(sizeof(struct virtio_gpu_ttm_tt), GFP_KERNEL); if (gtt == NULL) return NULL; - gtt->ttm.ttm.func = &virtio_gpu_backend_func; - gtt->vgdev = vgdev; + gtt->ttm.ttm.func = &virtio_gpu_tt_func; + gtt->obj = container_of(bo, struct virtio_gpu_object, tbo); if (ttm_dma_tt_init(>t->ttm, bo, page_flags)) { kfree(gtt); return NULL; @@ -251,51 +254,6 @@ static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo, return >t->ttm.ttm; } -static void virtio_gpu_move_null(struct ttm_buffer_object *bo, -struct ttm_mem_reg *new_mem) -{ - struct ttm_mem_reg *old_mem = &bo->mem; - - BUG_ON(old_mem->mm_node != NULL); - *old_mem = *new_mem; - new_mem->mm_node = NULL; -} - -static int virtio_gpu_bo_move(struct ttm_buffer_object *bo, bool evict, - struct ttm_operation_ctx *ctx, - struct ttm_mem_reg *new_mem) -{ - int ret; - - ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu); - if (ret) - return ret; - - virtio_gpu_move_null(bo, new_mem); - return 0; -} - -static void virtio_gpu_bo_move_notify(struct ttm_buffer_object *tbo, - bool evict, - struct ttm_mem_reg *new_mem) -{ - struct virtio_gpu_object *bo; - struct virtio_gpu_device *vgdev; - - bo = container_of(tbo, struct virtio_gpu_object, tbo); - vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; - - if (!new_mem || (new_mem->placement & TTM_PL_FLAG_SYSTEM))
[PATCH 10/10] drm/virtio: ditch virtio_gpu_object_attach() calls
With virtio_gpu_object_create() being called earlier ttm_bo_init() will handle the virtio_gpu_object_attach() (via backend binding), so we can drop the extra calls now. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_gem.c | 9 - drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 -- 2 files changed, 11 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index ca84990382..4b01e5655c 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -82,9 +82,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) { - struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_gem_object *gobj; - struct virtio_gpu_object *obj; struct virtio_gpu_object_params params = { .pinned = false, }; @@ -108,13 +106,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, if (ret) goto fail; - obj = gem_to_virtio_gpu_obj(gobj); - - /* attach the object to the resource */ - ret = virtio_gpu_object_attach(vgdev, obj, NULL); - if (ret) - goto fail; - args->pitch = pitch; return ret; diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index e5bd1fed56..90b3955b6f 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -319,8 +319,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, return PTR_ERR(qobj); obj = &qobj->gem_base; - ret = virtio_gpu_object_attach(vgdev, qobj, NULL); - ret = drm_gem_handle_create(file_priv, obj, &handle); if (ret) { drm_gem_object_release(obj); -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 01/10] drm/virtio: log error responses
If we got an error response code from the host, print it to the log. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_vq.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index e27c4aedb8..6bc2008b0d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -192,8 +192,16 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work) list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf; - if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) - DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); + if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) { + if (resp->type >= cpu_to_le32(VIRTIO_GPU_RESP_ERR_UNSPEC)) { + struct virtio_gpu_ctrl_hdr *cmd; + cmd = (struct virtio_gpu_ctrl_hdr *)entry->buf; + DRM_ERROR("response 0x%x (command 0x%x)\n", + le32_to_cpu(resp->type), + le32_to_cpu(cmd->type)); + } else + DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); + } if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) { u64 f = le64_to_cpu(resp->fence_id); -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 03/10] drm/virtio: drop virtio_gpu_fence_cleanup()
Just call drm_fence_put directly instead. Also set vgfb->fence to NULL after dropping the reference. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_fence.c | 8 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 6 -- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 63704915f8..bfb31fc3d0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -337,7 +337,6 @@ int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma); /* virtio_gpu_fence.c */ struct virtio_gpu_fence *virtio_gpu_fence_alloc( struct virtio_gpu_device *vgdev); -void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence); int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, struct virtio_gpu_ctrl_hdr *cmd_hdr, struct virtio_gpu_fence *fence); diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 4d6826b278..21bd4c4a32 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -81,14 +81,6 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) return fence; } -void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence) -{ - if (!fence) - return; - - dma_fence_put(&fence->f); -} - int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, struct virtio_gpu_ctrl_hdr *cmd_hdr, struct virtio_gpu_fence *fence) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 161b80fee4..14ce8188c0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -351,7 +351,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); ret = virtio_gpu_object_attach(vgdev, qobj, fence); if (ret) { - virtio_gpu_fence_cleanup(fence); + dma_fence_put(&fence->f); goto fail_backoff; } ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 548265b8e8..024c2aa0c9 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -169,8 +169,10 @@ static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane, return; vgfb = to_virtio_gpu_framebuffer(plane->state->fb); - if (vgfb->fence) - virtio_gpu_fence_cleanup(vgfb->fence); + if (vgfb->fence) { + dma_fence_put(&vgfb->fence->f); + vgfb->fence = NULL; + } } static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 06/10] drm/virtio: params struct for virtio_gpu_cmd_create_resource()
Add format, width and height to the virtio_gpu_object_params struct and use the struct for virtio_gpu_cmd_create_resource(). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/virtgpu_drv.h | 7 --- drivers/gpu/drm/virtio/virtgpu_gem.c | 8 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 6 -- drivers/gpu/drm/virtio/virtgpu_vq.c| 10 -- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 8cff8a3f7c..8c65deadd0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -54,6 +54,9 @@ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); struct virtio_gpu_object_params { + uint32_t format; + uint32_t width; + uint32_t height; unsigned long size; bool pinned; }; @@ -251,9 +254,7 @@ int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev); void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev); void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - uint32_t format, - uint32_t width, - uint32_t height); + struct virtio_gpu_object_params *params); void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, uint32_t resource_id); void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 384cd80bf3..eea6c6e8db 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -90,7 +90,6 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, }; int ret; uint32_t pitch; - uint32_t format; if (args->bpp != 32) return -EINVAL; @@ -99,16 +98,17 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, args->size = pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); + params.format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB); + params.width = args->width; + params.height = args->height; params.size = args->size; ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj, &args->handle); if (ret) goto fail; - format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB); obj = gem_to_virtio_gpu_obj(gobj); - virtio_gpu_cmd_create_resource(vgdev, obj, format, - args->width, args->height); + virtio_gpu_cmd_create_resource(vgdev, obj, ¶ms); /* attach the object to the resource */ ret = virtio_gpu_object_attach(vgdev, obj, NULL); diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 65b4a54f10..33112c8495 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -304,6 +304,9 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, INIT_LIST_HEAD(&validate_list); memset(&mainbuf, 0, sizeof(struct ttm_validate_buffer)); + params.format = rc->format; + params.width = rc->width; + params.height = rc->height; params.size = rc->size; /* allocate a single page size object */ @@ -316,8 +319,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, obj = &qobj->gem_base; if (!vgdev->has_virgl_3d) { - virtio_gpu_cmd_create_resource(vgdev, qobj, rc->format, - rc->width, rc->height); + virtio_gpu_cmd_create_resource(vgdev, qobj, ¶ms); ret = virtio_gpu_object_attach(vgdev, qobj, NULL); } else { diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 6bc2008b0d..363b8b8577 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -376,9 +376,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev, /* create a basic resource */ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, - uint32_t format, - uint32_t width, - uint32_t height) + struct virtio_gpu_object_params *params) { struct virtio_gpu_resource_create_2d *cmd_p; struct virtio_gpu_vbuffer *vbuf; @@ -388,9 +386,9 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD
[PATCH 13/14] drm/bochs: drop old fbdev emulation code
Not needed any more, bochs uses the generic emulation now. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs.h | 9 --- drivers/gpu/drm/bochs/bochs_drv.c | 6 -- drivers/gpu/drm/bochs/bochs_fbdev.c | 137 3 files changed, 152 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 4236d5d811..42a587e71e 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -80,12 +80,6 @@ struct bochs_device { struct ttm_bo_device bdev; bool initialized; } ttm; - - /* fbdev */ - struct { - struct drm_framebuffer *fb; - struct drm_fb_helper helper; - } fb; }; struct bochs_bo { @@ -161,7 +155,4 @@ int bochs_kms_init(struct bochs_device *bochs); void bochs_kms_fini(struct bochs_device *bochs); /* bochs_fbdev.c */ -int bochs_fbdev_init(struct bochs_device *bochs); -void bochs_fbdev_fini(struct bochs_device *bochs); - extern const struct drm_mode_config_funcs bochs_mode_funcs; diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index f1f65324bb..ad1290ca7b 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -110,12 +110,9 @@ static int bochs_pm_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct bochs_device *bochs = drm_dev->dev_private; drm_kms_helper_poll_disable(drm_dev); - drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 1); - return 0; } @@ -123,12 +120,9 @@ static int bochs_pm_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - struct bochs_device *bochs = drm_dev->dev_private; drm_helper_resume_force_mode(drm_dev); - drm_fb_helper_set_suspend_unlocked(&bochs->fb.helper, 0); - drm_kms_helper_poll_enable(drm_dev); return 0; } diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 92feb817ff..7cac3f5253 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -11,132 +11,6 @@ /* -- */ -static int bochsfb_mmap(struct fb_info *info, - struct vm_area_struct *vma) -{ - struct drm_fb_helper *fb_helper = info->par; - struct bochs_bo *bo = gem_to_bochs_bo(fb_helper->fb->obj[0]); - - return ttm_fbdev_mmap(vma, &bo->bo); -} - -static struct fb_ops bochsfb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_fillrect = drm_fb_helper_cfb_fillrect, - .fb_copyarea = drm_fb_helper_cfb_copyarea, - .fb_imageblit = drm_fb_helper_cfb_imageblit, - .fb_mmap = bochsfb_mmap, -}; - -static int bochsfb_create_object(struct bochs_device *bochs, -const struct drm_mode_fb_cmd2 *mode_cmd, -struct drm_gem_object **gobj_p) -{ - struct drm_device *dev = bochs->dev; - struct drm_gem_object *gobj; - u32 size; - int ret = 0; - - size = mode_cmd->pitches[0] * mode_cmd->height; - ret = bochs_gem_create(dev, size, true, &gobj); - if (ret) - return ret; - - *gobj_p = gobj; - return ret; -} - -static int bochsfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct bochs_device *bochs = - container_of(helper, struct bochs_device, fb.helper); - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd; - struct drm_gem_object *gobj = NULL; - struct bochs_bo *bo = NULL; - int size, ret; - - if (sizes->surface_bpp != 32) - return -EINVAL; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = sizes->surface_width * 4; - mode_cmd.pixel_format = DRM_FORMAT_HOST_XRGB; - size = mode_cmd.pitches[0] * mode_cmd.height; - - /* alloc, pin & map bo */ - ret = bochsfb_create_object(bochs, &mode_cmd, &gobj); - if (ret) { - DRM_ERROR("failed to create fbcon backing object %d\n", ret); - return ret; - } - - bo = gem_to_bochs_bo(gobj); - - ret = ttm_bo_reserve(&bo->bo, true, false, NULL); - if (ret) - return ret; - - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); - if (ret) { - DRM_ERROR("failed to pin fbcon\n"); - ttm_bo_unreserve(&bo->bo); - return ret; - } - - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, - &bo->kmap); - if (ret) { -
[PATCH 08/14] drm/bochs: atomic: set DRIVER_ATOMIC
Conversion to atomic modesetting, final step. Set the DRIVER_ATOMIC flag. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index f3dd66ae99..278f9d2e7f 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -81,7 +81,7 @@ static const struct file_operations bochs_fops = { }; static struct drm_driver bochs_driver = { - .driver_features= DRIVER_GEM | DRIVER_MODESET, + .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &bochs_fops, .name = "bochs-drm", .desc = "bochs dispi vga interface (qemu stdvga)", -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 07/14] drm/bochs: atomic: use atomic page_flip helper
Conversion to atomic modesetting, step five. Use atomic page_flip helper for crtc. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 23 +-- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index dcc8b864fc..9e836386e9 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -104,27 +104,6 @@ static void bochs_crtc_commit(struct drm_crtc *crtc) { } -static int bochs_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, - uint32_t page_flip_flags, - struct drm_modeset_acquire_ctx *ctx) -{ - struct bochs_device *bochs = - container_of(crtc, struct bochs_device, crtc); - struct drm_framebuffer *old_fb = crtc->primary->fb; - unsigned long irqflags; - - drm_atomic_set_fb_for_plane(crtc->primary->state, fb); - bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); - if (event) { - spin_lock_irqsave(&bochs->dev->event_lock, irqflags); - drm_crtc_send_vblank_event(crtc, event); - spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags); - } - return 0; -} - static void bochs_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { @@ -152,7 +131,7 @@ static void bochs_crtc_atomic_flush(struct drm_crtc *crtc, static const struct drm_crtc_funcs bochs_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, - .page_flip = bochs_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 11/14] drm/bochs: add basic prime support
Generic framebuffer emulation needs this. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs.h | 11 +++ drivers/gpu/drm/bochs/bochs_drv.c | 15 +- drivers/gpu/drm/bochs/bochs_mm.c | 63 +++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index d0d474e06f..4236d5d811 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -145,6 +145,17 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag); int bochs_bo_unpin(struct bochs_bo *bo); +int bochs_gem_prime_pin(struct drm_gem_object *obj); +void bochs_gem_prime_unpin(struct drm_gem_object *obj); +struct sg_table *bochs_gem_prime_get_sg_table(struct drm_gem_object *obj); +struct drm_gem_object *bochs_gem_prime_import_sg_table( +struct drm_device *dev, struct dma_buf_attachment *attach, +struct sg_table *sgt); +void *bochs_gem_prime_vmap(struct drm_gem_object *obj); +void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); +int bochs_gem_prime_mmap(struct drm_gem_object *obj, +struct vm_area_struct *vma); + /* bochs_kms.c */ int bochs_kms_init(struct bochs_device *bochs); void bochs_kms_fini(struct bochs_device *bochs); diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 278f9d2e7f..a9c7140e3b 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -81,7 +81,8 @@ static const struct file_operations bochs_fops = { }; static struct drm_driver bochs_driver = { - .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .driver_features= DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | + DRIVER_PRIME, .fops = &bochs_fops, .name = "bochs-drm", .desc = "bochs dispi vga interface (qemu stdvga)", @@ -91,6 +92,18 @@ static struct drm_driver bochs_driver = { .gem_free_object_unlocked = bochs_gem_free_object, .dumb_create= bochs_dumb_create, .dumb_map_offset= bochs_dumb_mmap_offset, + + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_pin = bochs_gem_prime_pin, + .gem_prime_unpin = bochs_gem_prime_unpin, + .gem_prime_get_sg_table = bochs_gem_prime_get_sg_table, + .gem_prime_import_sg_table = bochs_gem_prime_import_sg_table, + .gem_prime_vmap = bochs_gem_prime_vmap, + .gem_prime_vunmap = bochs_gem_prime_vunmap, + .gem_prime_mmap = bochs_gem_prime_mmap, }; /* -- */ diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 5a0e092847..cfe061c25f 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -387,3 +387,66 @@ int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, drm_gem_object_put_unlocked(obj); return 0; } + +/* -- */ + +int bochs_gem_prime_pin(struct drm_gem_object *obj) +{ + struct bochs_bo *bo = gem_to_bochs_bo(obj); + + return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); +} + +void bochs_gem_prime_unpin(struct drm_gem_object *obj) +{ + struct bochs_bo *bo = gem_to_bochs_bo(obj); + + bochs_bo_unpin(bo); +} + +struct sg_table *bochs_gem_prime_get_sg_table(struct drm_gem_object *obj) +{ + WARN_ONCE(1, "not implemented"); + return ERR_PTR(-ENODEV); +} + +struct drm_gem_object *bochs_gem_prime_import_sg_table( + struct drm_device *dev, struct dma_buf_attachment *attach, + struct sg_table *table) +{ + WARN_ONCE(1, "not implemented"); + return ERR_PTR(-ENODEV); +} + +void *bochs_gem_prime_vmap(struct drm_gem_object *obj) +{ + struct bochs_bo *bo = gem_to_bochs_bo(obj); + bool is_iomem; + int ret; + + ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); + if (ret) + return NULL; + ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); + if (ret) { + bochs_bo_unpin(bo); + return NULL; + } + return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); +} + +void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) +{ + struct bochs_bo *bo = gem_to_bochs_bo(obj); + + ttm_bo_kunmap(&bo->kmap); + bochs_bo_unpin(bo); +} + +int bochs_gem_prime_mmap(struct drm_gem_object *obj, +struct vm_area_struct *vma) +{ + struct bochs_bo *bo = gem_to_bochs_bo(obj); + + return ttm_fbdev_mmap(vma
[PATCH 14/14] drm/bochs: move remaining fb bits to kms
bochs_fbdev.c is almost empty now. Move the remaining framebuffer bits over to bochs_kms.c. Pure code motion. No functional change. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_fbdev.c | 29 - drivers/gpu/drm/bochs/bochs_kms.c | 17 + drivers/gpu/drm/bochs/Makefile | 2 +- 3 files changed, 18 insertions(+), 30 deletions(-) delete mode 100644 drivers/gpu/drm/bochs/bochs_fbdev.c diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c deleted file mode 100644 index 7cac3f5253..00 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include "bochs.h" -#include -#include - -/* -- */ - -static struct drm_framebuffer * -bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - if (mode_cmd->pixel_format != DRM_FORMAT_XRGB && - mode_cmd->pixel_format != DRM_FORMAT_BGRX) - return ERR_PTR(-EINVAL); - - return drm_gem_fb_create(dev, file, mode_cmd); -} - -const struct drm_mode_config_funcs bochs_mode_funcs = { - .fb_create = bochs_gem_fb_create, - .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, -}; diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index a1a0129f3e..3688d0b616 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -9,6 +9,7 @@ #include #include #include +#include static int defx = 1024; static int defy = 768; @@ -256,6 +257,22 @@ static void bochs_connector_init(struct drm_device *dev) } } +static struct drm_framebuffer * +bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + if (mode_cmd->pixel_format != DRM_FORMAT_XRGB && + mode_cmd->pixel_format != DRM_FORMAT_BGRX) + return ERR_PTR(-EINVAL); + + return drm_gem_fb_create(dev, file, mode_cmd); +} + +const struct drm_mode_config_funcs bochs_mode_funcs = { + .fb_create = bochs_gem_fb_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; int bochs_kms_init(struct bochs_device *bochs) { diff --git a/drivers/gpu/drm/bochs/Makefile b/drivers/gpu/drm/bochs/Makefile index 98ef60a19e..e9e0f8f5eb 100644 --- a/drivers/gpu/drm/bochs/Makefile +++ b/drivers/gpu/drm/bochs/Makefile @@ -1,3 +1,3 @@ -bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_fbdev.o bochs_hw.o +bochs-drm-y := bochs_drv.o bochs_mm.o bochs_kms.o bochs_hw.o obj-$(CONFIG_DRM_BOCHS)+= bochs-drm.o -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 09/14] drm/bochs: remove old bochs_crtc_* functions
Remove the old, now unused crtc callbacks. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 81 --- 1 file changed, 81 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 9e836386e9..85dd268fa1 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -20,74 +20,6 @@ MODULE_PARM_DESC(defy, "default y resolution"); /* -- */ -static void bochs_crtc_dpms(struct drm_crtc *crtc, int mode) -{ - switch (mode) { - case DRM_MODE_DPMS_ON: - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - default: - return; - } -} - -static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct bochs_device *bochs = - container_of(crtc, struct bochs_device, crtc); - struct bochs_bo *bo; - u64 gpu_addr = 0; - int ret; - - if (old_fb) { - bo = gem_to_bochs_bo(old_fb->obj[0]); - ret = ttm_bo_reserve(&bo->bo, true, false, NULL); - if (ret) { - DRM_ERROR("failed to reserve old_fb bo\n"); - } else { - bochs_bo_unpin(bo); - ttm_bo_unreserve(&bo->bo); - } - } - - if (WARN_ON(crtc->primary->fb == NULL)) - return -EINVAL; - - bo = gem_to_bochs_bo(crtc->primary->fb->obj[0]); - ret = ttm_bo_reserve(&bo->bo, true, false, NULL); - if (ret) - return ret; - - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - ttm_bo_unreserve(&bo->bo); - return ret; - } - - ttm_bo_unreserve(&bo->bo); - bochs_hw_setbase(bochs, x, y, gpu_addr); - return 0; -} - -static int bochs_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) -{ - struct bochs_device *bochs = - container_of(crtc, struct bochs_device, crtc); - - if (WARN_ON(crtc->primary->fb == NULL)) - return -EINVAL; - - bochs_hw_setmode(bochs, mode); - bochs_hw_setformat(bochs, crtc->primary->fb->format); - bochs_crtc_mode_set_base(crtc, x, y, old_fb); - return 0; -} - static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct bochs_device *bochs = @@ -96,14 +28,6 @@ static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc) bochs_hw_setmode(bochs, &crtc->mode); } -static void bochs_crtc_prepare(struct drm_crtc *crtc) -{ -} - -static void bochs_crtc_commit(struct drm_crtc *crtc) -{ -} - static void bochs_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { @@ -138,12 +62,7 @@ static const struct drm_crtc_funcs bochs_crtc_funcs = { }; static const struct drm_crtc_helper_funcs bochs_helper_funcs = { - .dpms = bochs_crtc_dpms, - .mode_set = bochs_crtc_mode_set, - .mode_set_base = bochs_crtc_mode_set_base, .mode_set_nofb = bochs_crtc_mode_set_nofb, - .prepare = bochs_crtc_prepare, - .commit = bochs_crtc_commit, .atomic_enable = bochs_crtc_atomic_enable, .atomic_flush = bochs_crtc_atomic_flush, }; -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 10/14] drm/bochs: drop unused gpu_addr arg from bochs_bo_pin()
It's always NULL, so just remove it. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs.h | 2 +- drivers/gpu/drm/bochs/bochs_fbdev.c | 2 +- drivers/gpu/drm/bochs/bochs_kms.c | 2 +- drivers/gpu/drm/bochs/bochs_mm.c| 11 +-- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 4dc1b6384e..d0d474e06f 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -142,7 +142,7 @@ int bochs_dumb_create(struct drm_file *file, struct drm_device *dev, int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, uint32_t handle, uint64_t *offset); -int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr); +int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag); int bochs_bo_unpin(struct bochs_bo *bo); /* bochs_kms.c */ diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index d9f3d42999..92feb817ff 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -81,7 +81,7 @@ static int bochsfb_create(struct drm_fb_helper *helper, if (ret) return ret; - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); + ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); if (ret) { DRM_ERROR("failed to pin fbcon\n"); ttm_bo_unreserve(&bo->bo); diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 85dd268fa1..a1a0129f3e 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -96,7 +96,7 @@ static int bochs_plane_prepare_fb(struct drm_plane *plane, if (!new_state->fb) return 0; bo = gem_to_bochs_bo(new_state->fb->obj[0]); - return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); + return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); } static void bochs_plane_cleanup_fb(struct drm_plane *plane, diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 0980411e41..5a0e092847 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -210,20 +210,13 @@ static void bochs_ttm_placement(struct bochs_bo *bo, int domain) bo->placement.num_busy_placement = c; } -static inline u64 bochs_bo_gpu_offset(struct bochs_bo *bo) -{ - return bo->bo.offset; -} - -int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr) +int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag) { struct ttm_operation_ctx ctx = { false, false }; int i, ret; if (bo->pin_count) { bo->pin_count++; - if (gpu_addr) - *gpu_addr = bochs_bo_gpu_offset(bo); return 0; } @@ -235,8 +228,6 @@ int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag, u64 *gpu_addr) return ret; bo->pin_count = 1; - if (gpu_addr) - *gpu_addr = bochs_bo_gpu_offset(bo); return 0; } -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 05/14] drm/bochs: atomic: switch planes to atomic, wire up helpers.
Conversion to atomic modesetting, step three. Wire up atomic helpers. Switch planes to atomic. We are late to the party, the transitional helpers are gone, so this can't be splitted into smaller steps any more. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_fbdev.c | 3 ++ drivers/gpu/drm/bochs/bochs_kms.c | 70 +++-- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index dd3c7df267..d9f3d42999 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -6,6 +6,7 @@ */ #include "bochs.h" +#include #include /* -- */ @@ -149,6 +150,8 @@ bochs_gem_fb_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_config_funcs bochs_mode_funcs = { .fb_create = bochs_gem_fb_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, }; int bochs_fbdev_init(struct bochs_device *bochs) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 18b705fb0b..aa3ba0377a 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -6,7 +6,9 @@ */ #include "bochs.h" +#include #include +#include static int defx = 1024; static int defy = 768; @@ -113,7 +115,7 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *old_fb = crtc->primary->fb; unsigned long irqflags; - crtc->primary->fb = fb; + drm_atomic_set_fb_for_plane(crtc->primary->state, fb); bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); if (event) { spin_lock_irqsave(&bochs->dev->event_lock, irqflags); @@ -151,6 +153,9 @@ static const struct drm_crtc_funcs bochs_crtc_funcs = { .set_config = drm_crtc_helper_set_config, .destroy = drm_crtc_cleanup, .page_flip = bochs_crtc_page_flip, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; static const struct drm_crtc_helper_funcs bochs_helper_funcs = { @@ -169,6 +174,59 @@ static const uint32_t bochs_formats[] = { DRM_FORMAT_BGRX, }; +static void bochs_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct bochs_device *bochs = plane->dev->dev_private; + struct bochs_bo *bo; + + if (!plane->state->fb) + return; + bo = gem_to_bochs_bo(plane->state->fb->obj[0]); + bochs_hw_setbase(bochs, +plane->state->crtc_x, +plane->state->crtc_y, +bo->bo.offset); + bochs_hw_setformat(bochs, plane->state->fb->format); +} + +static int bochs_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + struct bochs_bo *bo; + + if (!new_state->fb) + return 0; + bo = gem_to_bochs_bo(new_state->fb->obj[0]); + return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); +} + +static void bochs_plane_cleanup_fb(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct bochs_bo *bo; + + if (!old_state->fb) + return; + bo = gem_to_bochs_bo(old_state->fb->obj[0]); + bochs_bo_unpin(bo); +} + +static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = { + .atomic_update = bochs_plane_atomic_update, + .prepare_fb = bochs_plane_prepare_fb, + .cleanup_fb = bochs_plane_cleanup_fb, +}; + +static const struct drm_plane_funcs bochs_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy= drm_primary_helper_destroy, + .reset = drm_atomic_helper_plane_reset, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + static struct drm_plane *bochs_primary_plane(struct drm_device *dev) { struct drm_plane *primary; @@ -181,16 +239,17 @@ static struct drm_plane *bochs_primary_plane(struct drm_device *dev) } ret = drm_universal_plane_init(dev, primary, 0, - &drm_primary_helper_funcs, + &bochs_plane_funcs, bochs_formats, ARRAY_SIZE(bochs_formats), NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { kfree(primary); - primar
[PATCH 12/14] drm/bochs: switch to generic drm fbdev emulation
Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_drv.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index a9c7140e3b..f1f65324bb 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -27,7 +27,6 @@ static void bochs_unload(struct drm_device *dev) { struct bochs_device *bochs = dev->dev_private; - bochs_fbdev_fini(bochs); bochs_kms_fini(bochs); bochs_mm_fini(bochs); bochs_hw_fini(dev); @@ -58,9 +57,6 @@ static int bochs_load(struct drm_device *dev) if (ret) goto err; - if (enable_fbdev) - bochs_fbdev_init(bochs); - return 0; err: @@ -178,6 +174,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, if (ret) goto err_unload; + drm_fbdev_generic_setup(dev, 32); return ret; err_unload: -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 04/14] drm/bochs: atomic: add mode_set_nofb callback.
Conversion to atomic modesetting, step two. Add mode_set_nofb crtc helper callback. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 59d469f343..18b705fb0b 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -86,6 +86,14 @@ static int bochs_crtc_mode_set(struct drm_crtc *crtc, return 0; } +static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc) +{ + struct bochs_device *bochs = + container_of(crtc, struct bochs_device, crtc); + + bochs_hw_setmode(bochs, &crtc->mode); +} + static void bochs_crtc_prepare(struct drm_crtc *crtc) { } @@ -149,6 +157,7 @@ static const struct drm_crtc_helper_funcs bochs_helper_funcs = { .dpms = bochs_crtc_dpms, .mode_set = bochs_crtc_mode_set, .mode_set_base = bochs_crtc_mode_set_base, + .mode_set_nofb = bochs_crtc_mode_set_nofb, .prepare = bochs_crtc_prepare, .commit = bochs_crtc_commit, .atomic_enable = bochs_crtc_atomic_enable, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PULL 1/1] virtio-ccw: diag 500 may return a negative cookie
If something goes wrong in the kvm io bus handling, the virtio-ccw diagnose may return a negative error value in the cookie gpr. Document this. Reviewed-by: Halil Pasic Signed-off-by: Cornelia Huck --- Documentation/virtual/kvm/s390-diag.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/virtual/kvm/s390-diag.txt b/Documentation/virtual/kvm/s390-diag.txt index 48c4921794ed..7c52e5f8b210 100644 --- a/Documentation/virtual/kvm/s390-diag.txt +++ b/Documentation/virtual/kvm/s390-diag.txt @@ -68,7 +68,8 @@ Subcode 3 - virtio-ccw notification identifier, it is ignored. After completion of the DIAGNOSE call, general register 2 may contain -a 64bit identifier (in the kvm_io_bus cookie case). +a 64bit identifier (in the kvm_io_bus cookie case), or a negative +error value, if an internal error occurred. See also the virtio standard for a discussion of this hypercall. -- 2.17.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 06/14] drm/bochs: atomic: use atomic set_config helper
Conversion to atomic modesetting, step four. Use atomic set_config helper for crtc. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index aa3ba0377a..dcc8b864fc 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -150,7 +150,7 @@ static void bochs_crtc_atomic_flush(struct drm_crtc *crtc, /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs bochs_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, .page_flip = bochs_crtc_page_flip, .reset = drm_atomic_helper_crtc_reset, -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 01/14] drm/bochs: encoder cleanup
Most unused callbacks can be NULL pointers these days. Drop a bunch of empty encoder callbacks. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 26 -- 1 file changed, 26 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index f87c284dd9..c8ce54498d 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -170,31 +170,6 @@ static void bochs_crtc_init(struct drm_device *dev) drm_crtc_helper_add(crtc, &bochs_helper_funcs); } -static void bochs_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ -} - -static void bochs_encoder_dpms(struct drm_encoder *encoder, int state) -{ -} - -static void bochs_encoder_prepare(struct drm_encoder *encoder) -{ -} - -static void bochs_encoder_commit(struct drm_encoder *encoder) -{ -} - -static const struct drm_encoder_helper_funcs bochs_encoder_helper_funcs = { - .dpms = bochs_encoder_dpms, - .mode_set = bochs_encoder_mode_set, - .prepare = bochs_encoder_prepare, - .commit = bochs_encoder_commit, -}; - static const struct drm_encoder_funcs bochs_encoder_encoder_funcs = { .destroy = drm_encoder_cleanup, }; @@ -207,7 +182,6 @@ static void bochs_encoder_init(struct drm_device *dev) encoder->possible_crtcs = 0x1; drm_encoder_init(dev, encoder, &bochs_encoder_encoder_funcs, DRM_MODE_ENCODER_DAC, NULL); - drm_encoder_helper_add(encoder, &bochs_encoder_helper_funcs); } -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 02/14] drm/bochs: split bochs_hw_setmode
Create a separate bochs_hw_setformat function to configure the framebuffer format (actually just the byteorder). Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs.h | 5 +++-- drivers/gpu/drm/bochs/bochs_hw.c | 19 --- drivers/gpu/drm/bochs/bochs_kms.c | 3 ++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index fb38c8b857..4dc1b6384e 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -121,8 +121,9 @@ int bochs_hw_init(struct drm_device *dev); void bochs_hw_fini(struct drm_device *dev); void bochs_hw_setmode(struct bochs_device *bochs, - struct drm_display_mode *mode, - const struct drm_format_info *format); + struct drm_display_mode *mode); +void bochs_hw_setformat(struct bochs_device *bochs, + const struct drm_format_info *format); void bochs_hw_setbase(struct bochs_device *bochs, int x, int y, u64 addr); int bochs_hw_load_edid(struct bochs_device *bochs); diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index c90a0d492f..bbb251fc78 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -197,8 +197,7 @@ void bochs_hw_fini(struct drm_device *dev) } void bochs_hw_setmode(struct bochs_device *bochs, - struct drm_display_mode *mode, - const struct drm_format_info *format) + struct drm_display_mode *mode) { bochs->xres = mode->hdisplay; bochs->yres = mode->vdisplay; @@ -206,12 +205,8 @@ void bochs_hw_setmode(struct bochs_device *bochs, bochs->stride = mode->hdisplay * (bochs->bpp / 8); bochs->yres_virtual = bochs->fb_size / bochs->stride; - DRM_DEBUG_DRIVER("%dx%d @ %d bpp, format %c%c%c%c, vy %d\n", + DRM_DEBUG_DRIVER("%dx%d @ %d bpp, vy %d\n", bochs->xres, bochs->yres, bochs->bpp, -(format->format >> 0) & 0xff, -(format->format >> 8) & 0xff, -(format->format >> 16) & 0xff, -(format->format >> 24) & 0xff, bochs->yres_virtual); bochs_vga_writeb(bochs, 0x3c0, 0x20); /* unblank */ @@ -229,6 +224,16 @@ void bochs_hw_setmode(struct bochs_device *bochs, bochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED); +} + +void bochs_hw_setformat(struct bochs_device *bochs, + const struct drm_format_info *format) +{ + DRM_DEBUG_DRIVER("format %c%c%c%c\n", +(format->format >> 0) & 0xff, +(format->format >> 8) & 0xff, +(format->format >> 16) & 0xff, +(format->format >> 24) & 0xff); switch (format->format) { case DRM_FORMAT_XRGB: diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index c8ce54498d..f7e6d1a9b3 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -80,7 +80,8 @@ static int bochs_crtc_mode_set(struct drm_crtc *crtc, if (WARN_ON(crtc->primary->fb == NULL)) return -EINVAL; - bochs_hw_setmode(bochs, mode, crtc->primary->fb->format); + bochs_hw_setmode(bochs, mode); + bochs_hw_setformat(bochs, crtc->primary->fb->format); bochs_crtc_mode_set_base(crtc, x, y, old_fb); return 0; } -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v3 00/12] x86, kbuild: revert macrofying inline assembly code
On Wed, Dec 19, 2018 at 5:26 AM Nadav Amit wrote: > > > On Dec 17, 2018, at 8:03 AM, Masahiro Yamada > > wrote: > > > > This series reverts the in-kernel workarounds for inlining issues. > > > > The commit description of 77b0bf55bc67 mentioned > > "We also hope that GCC will eventually get fixed,..." > > > > Now, GCC provides a solution. > > > > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FExtended-Asm.html&data=02%7C01%7Cnamit%40vmware.com%7Cc43f433d8c6244de15f108d6643a49e4%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636806598899962669&sdata=88UJ25RoiHik9vTCJKZV6%2F7xpzCGsvKb9LFg1kfEYL0%3D&reserved=0 > > explains the new "asm inline" syntax. > > > > The performance issue will be eventually solved. > > > > [About Code cleanups] > > > > I know Nadam Amit is opposed to the full revert. > > My name is Nadav. Sorry about that. (I relied on a spell checker. I should be careful about typos in people's name.) > > He also claims his motivation for macrofying was not only > > performance, but also cleanups. > > Masahiro, I understand your concerns and criticism, and indeed various > alternative solutions exist. I do have my reservations about the one you > propose, since it makes coding more complicated to simplify the Make system. > Yet, more important, starting this discussion suddenly now after RC7 is > strange. I did not think this was so sudden. When I suggested the revert a few weeks ago, Borislav was for it. I did not hear from the other x86 maintainers. Anyway, it is true we are running out of time for the release. > Anyhow, since it’s obviously not my call, please don’t make it > sound as if I am a side in the decision. > Not my call, either. That's why I put the x86 maintainers in the TO list, and other people in CC. The original patch set went in via x86 tree. So, its revert set, if we want, should go in the same path. Anyway, we have to do something for v4.20. Maybe, discussing short-term / long-term solutions separately could move things forward. [1] Solution for v4.20 [2] Solution for future kernel If we do not want to see the revert for [1], the best I can suggest is to copy arch/x86/kernel/macros.s to include/generated/macros.h so that it is kept for the external module build. (It is not literally included by anyone, but should work at least.) For [2], what do we want to see? -- Best Regards Masahiro Yamada ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v2] VSOCK: Send reset control packet when socket is partially bound
From: Jorgen Hansen Date: Tue, 18 Dec 2018 00:34:06 -0800 > If a server side socket is bound to an address, but not in the listening > state yet, incoming connection requests should receive a reset control > packet in response. However, the function used to send the reset > silently drops the reset packet if the sending socket isn't bound > to a remote address (as is the case for a bound socket not yet in > the listening state). This change fixes this by using the src > of the incoming packet as destination for the reset packet in > this case. > > Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") > Reviewed-by: Adit Ranadive > Reviewed-by: Vishnu Dasa > Signed-off-by: Jorgen Hansen Applied and queued up for -stable, thanks. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH v2] VSOCK: Send reset control packet when socket is partially bound
If a server side socket is bound to an address, but not in the listening state yet, incoming connection requests should receive a reset control packet in response. However, the function used to send the reset silently drops the reset packet if the sending socket isn't bound to a remote address (as is the case for a bound socket not yet in the listening state). This change fixes this by using the src of the incoming packet as destination for the reset packet in this case. Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reviewed-by: Adit Ranadive Reviewed-by: Vishnu Dasa Signed-off-by: Jorgen Hansen --- v1 -> v2: - Changed order of local variables net/vmw_vsock/vmci_transport.c | 67 +++--- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 0ae3614..5cf8935 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -264,6 +264,31 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src, } static int +vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src, + struct sockaddr_vm *dst, + enum vmci_transport_packet_type type, + u64 size, + u64 mode, + struct vmci_transport_waiting_info *wait, + u16 proto, + struct vmci_handle handle) +{ + struct vmci_transport_packet *pkt; + int err; + + pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + if (!pkt) + return -ENOMEM; + + err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size, + mode, wait, proto, handle, + true); + kfree(pkt); + + return err; +} + +static int vmci_transport_send_control_pkt(struct sock *sk, enum vmci_transport_packet_type type, u64 size, @@ -272,9 +297,7 @@ vmci_transport_send_control_pkt(struct sock *sk, u16 proto, struct vmci_handle handle) { - struct vmci_transport_packet *pkt; struct vsock_sock *vsk; - int err; vsk = vsock_sk(sk); @@ -284,17 +307,10 @@ vmci_transport_send_control_pkt(struct sock *sk, if (!vsock_addr_bound(&vsk->remote_addr)) return -EINVAL; - pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); - if (!pkt) - return -ENOMEM; - - err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr, - &vsk->remote_addr, type, size, - mode, wait, proto, handle, - true); - kfree(pkt); - - return err; + return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, +&vsk->remote_addr, +type, size, mode, +wait, proto, handle); } static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, @@ -312,12 +328,29 @@ static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, static int vmci_transport_send_reset(struct sock *sk, struct vmci_transport_packet *pkt) { + struct sockaddr_vm *dst_ptr; + struct sockaddr_vm dst; + struct vsock_sock *vsk; + if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST) return 0; - return vmci_transport_send_control_pkt(sk, - VMCI_TRANSPORT_PACKET_TYPE_RST, - 0, 0, NULL, VSOCK_PROTO_INVALID, - VMCI_INVALID_HANDLE); + + vsk = vsock_sk(sk); + + if (!vsock_addr_bound(&vsk->local_addr)) + return -EINVAL; + + if (vsock_addr_bound(&vsk->remote_addr)) { + dst_ptr = &vsk->remote_addr; + } else { + vsock_addr_init(&dst, pkt->dg.src.context, + pkt->src_port); + dst_ptr = &dst; + } + return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, dst_ptr, +VMCI_TRANSPORT_PACKET_TYPE_RST, +0, 0, NULL, VSOCK_PROTO_INVALID, +VMCI_INVALID_HANDLE); } static int vmci_transport_send_negotiate(struct sock *sk, size_t size) -- 2.6.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtu
[PATCH] drm/bochs: add edid present check
Check first two header bytes before trying to read the edid blob, to avoid the log being spammed in case qemu has no edid support (old qemu or edid turned off). Fixes: 01f23459cf drm/bochs: add edid support. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_hw.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index c90a0d492f..f91e049625 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -89,6 +89,10 @@ int bochs_hw_load_edid(struct bochs_device *bochs) if (!bochs->mmio) return -1; + if (readb(bochs->mmio + 0) != 0x00 || + readb(bochs->mmio + 1) != 0xff) + return -1; + kfree(bochs->edid); bochs->edid = drm_do_get_edid(&bochs->connector, bochs_get_edid_block, bochs); -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH] virtio-ccw: diag 500 may return a negative cookie
If something goes wrong in the kvm io bus handling, the virtio-ccw diagnose may return a negative error value in the cookie gpr. Document this. Signed-off-by: Cornelia Huck --- Even if the virtio spec is the correct place to specify what diag 500 subcode 3 does, we also should mention here that the cookie may be an error. --- Documentation/virtual/kvm/s390-diag.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/virtual/kvm/s390-diag.txt b/Documentation/virtual/kvm/s390-diag.txt index 48c4921794ed..7c52e5f8b210 100644 --- a/Documentation/virtual/kvm/s390-diag.txt +++ b/Documentation/virtual/kvm/s390-diag.txt @@ -68,7 +68,8 @@ Subcode 3 - virtio-ccw notification identifier, it is ignored. After completion of the DIAGNOSE call, general register 2 may contain -a 64bit identifier (in the kvm_io_bus cookie case). +a 64bit identifier (in the kvm_io_bus cookie case), or a negative +error value, if an internal error occurred. See also the virtio standard for a discussion of this hypercall. -- 2.17.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH] Export mm_update_next_owner function for vhost-net
On Tue, Dec 18, 2018 at 09:39:16AM +0800, gchen chen wrote: > Yes, I think so. > and i think the point is that unuse_mm() can't directly set tsk->mm=NULL. So why can't unuse_mm call mm_update_next_owner? -- MST ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: kernel vhost demands an interrupt from guest when the ring is full in order to enable guest to submit new packets to the queue
On 12/17/18, 2:55 PM, "Michael S. Tsirkin" wrote: On Thu, Dec 13, 2018 at 11:24:28PM +, Steven Luong (sluong) via Virtualization wrote: > Folks, > > > > We came across a memory race condition between VPP vhost driver and the kernel > vhost. VPP is running a tap interface over vhost backend. In this case, VPP is > acting as the vhost driver mode and the kernel vhost is acting as the vhost > device mode. > > > > In the kernel vhost’s TX traffic direction which is VPP’s RX traffic direction, > kernel vhost is the producer and VPP is the consumer. Looking at vhost net kernel code, it seems to use the same terminology as virtio net. Can you pls clarify which ring number do you use 0 or 1? 0. I will assume ring 0 below. > Kernel vhost places > traffic in kernel vhost’s TX vring. VPP removes traffic in VPP’s RX vring. So VPP makes buffers available and vhost kernel uses them? Correct. > It > is inevitable that the vring may become full under heavy traffic and the kernel > vhost may have to stop and wait for the guest (VPP) to empty the vring and to > refill the vring with descriptors. When that case happens, kernel vhost clears > the bit in the vring’s used flag to request an interrupt/notification. Due to > shared memory race condition, VPP may miss the clearing of the vring’s used > flag from kernel vhost and didn’t send kernel vhost an interrupt after VPP > empties and refills the vring with new descriptors. So kernel vhost's wakeups are signalled through eventfd - I assume this is what you mean by an interrupt? To prevent the race that you describe, vhost has this code: /* OK, now we need to know about added descriptors. */ if (!headcount) { if (unlikely(busyloop_intr)) { vhost_poll_queue(&vq->poll); } else if (unlikely(vhost_enable_notify(&net->dev, vq))) { /* They have slipped one in as we were * doing that: check again. */ vhost_disable_notify(&net->dev, vq); continue; } /* Nothing new? Wait for eventfd to tell us So ring should be re-checked after notifications are enabled. If ring is no longer empty, vhost will proceed to handle the ring. This code has been around for many years. Thus if VPP doesn't work with it then I suspect it does something differently, e.g. is it possible that it is missing a memory barrier after writing out the available buffers and before checking the flags? Can the race condition be avoided totally? Here is the scenario. t0: VPP refills the vring with new descriptors, not yet sets avail->idx to make it available to kernel vhost. t1: kernel vhost checks the vring, still sees no space available, but does not yet execute the line of code to clear the used->flags t2: vpp executes sfence, and sets avail->idx to make it available to kernel vhost t3: vpp checks used->flags, it is still 1, vpp skips sending the interrupt t4: kernel vhost clears used->flags to indicate interrupt is required. But VPP just missed it. The result is kernel vhost got stuck even though the vring is filled with new descriptors. Steven > Unfortunately, this missed > notification causes the kernel vhost to be stuck because once the kernel vhost > is waiting for an interrupt/notification from the guest, only an interrupt/ > notification from the guest can resume/re-enable the guest from submitting new > packets to the vring. This design seems vulnerable. The protocol right now relies on notifications never being lost. I can imagine an alternative where device also re-checks the rings periodically, but that would involve running timers host side which is only possible if there's a free processor that can handle them. Further, it will still lead to stalls and packet drops, which will be harder to debug. That's just my $.02, pls feel free to take it with the virtio tc maybe others will feel differently. > Should the kernel vhost > totally depend on the notification from the guest? Quoting the text from > > > > http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html > > > > /* The device uses this in used->flags to advise the driver: don’t kick me > * when you add a buffer. It’s unreliable, so it’s simply an > * optimization. */ > #define VIRTQ_USED_F_NO_NOTIFY 1 > > > > I interpret that the notification is simply an optimization
Re: kernel vhost demands an interrupt from guest when the ring is full in order to enable guest to submit new packets to the queue
On Mon, Dec 17, 2018 at 11:56:59PM +, Steven Luong (sluong) wrote: > > > On 12/17/18, 2:55 PM, "Michael S. Tsirkin" wrote: > > On Thu, Dec 13, 2018 at 11:24:28PM +, Steven Luong (sluong) via > Virtualization wrote: > > Folks, > > > > > > > > We came across a memory race condition between VPP vhost driver and the > kernel > > vhost. VPP is running a tap interface over vhost backend. In this case, > VPP is > > acting as the vhost driver mode and the kernel vhost is acting as the > vhost > > device mode. > > > > > > > > In the kernel vhost’s TX traffic direction which is VPP’s RX traffic > direction, > > kernel vhost is the producer and VPP is the consumer. > > Looking at vhost net kernel code, it seems to use the > same terminology as virtio net. > Can you pls clarify which ring number do you use 0 or 1? > > 0. > > I will assume ring 0 below. > > > > > Kernel vhost places > > traffic in kernel vhost’s TX vring. VPP removes traffic in VPP’s RX > vring. > > > So VPP makes buffers available and vhost kernel uses them? > > Correct. > > > It > > is inevitable that the vring may become full under heavy traffic and > the kernel > > vhost may have to stop and wait for the guest (VPP) to empty the vring > and to > > refill the vring with descriptors. When that case happens, kernel vhost > clears > > the bit in the vring’s used flag to request an interrupt/notification. > Due to > > shared memory race condition, VPP may miss the clearing of the vring’s > used > > flag from kernel vhost and didn’t send kernel vhost an interrupt after > VPP > > empties and refills the vring with new descriptors. > > So kernel vhost's wakeups are signalled through eventfd - I assume > this is what you mean by an interrupt? > > > To prevent the race that you describe, vhost has this code: > > /* OK, now we need to know about added descriptors. */ > if (!headcount) { > if (unlikely(busyloop_intr)) { > vhost_poll_queue(&vq->poll); > } else if > (unlikely(vhost_enable_notify(&net->dev, vq))) { > /* They have slipped one in as we were > * doing that: check again. */ > vhost_disable_notify(&net->dev, vq); > continue; > } > /* Nothing new? Wait for eventfd to tell us > > So ring should be re-checked after notifications are enabled. > If ring is no longer empty, vhost will proceed to handle the ring. > This code has been around for many years. > > Thus if VPP doesn't work with it then I suspect it does something > differently, e.g. is it possible that it is missing a memory > barrier after writing out the available buffers and before > checking the flags? > > Can the race condition be avoided totally? Here is the scenario. > > t0: VPP refills the vring with new descriptors, not yet sets avail->idx to > make it available to kernel vhost. > t1: kernel vhost checks the vring, still sees no space available, but does > not yet execute the line of code to clear the used->flags > t2: vpp executes sfence, and sets avail->idx to make it available to kernel > vhost At this point you need a full memory barrier. E.g. mfence, or xor. Otherwise the read can get re-ordered before the write. > t3: vpp checks used->flags, it is still 1, vpp skips sending the interrupt > t4: kernel vhost clears used->flags to indicate interrupt is required. But > VPP just missed it. fine but at this point kernel vhost will recheck using vhost_get_avail and process the buffers. So the lack of notification isn't a problem: bool vhost_enable_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq) { __virtio16 avail_idx; int r; if (!(vq->used_flags & VRING_USED_F_NO_NOTIFY)) return false; vq->used_flags &= ~VRING_USED_F_NO_NOTIFY; if (!vhost_has_feature(vq, VIRTIO_RING_F_EVENT_IDX)) { r = vhost_update_used_flags(vq); if (r) { vq_err(vq, "Failed to enable notification at %p: %d\n", &vq->used->flags, r); return false; } } else { r = vhost_update_avail_event(vq, vq->avail_idx); if (r) { vq_err(vq, "Failed to update avail event index at %p: %d\n", vhost_avail_event(vq), r); return false; } } /* They could have slipped one in as we were doing
Re: kernel vhost demands an interrupt from guest when the ring is full in order to enable guest to submit new packets to the queue
On Thu, Dec 13, 2018 at 11:24:28PM +, Steven Luong (sluong) via Virtualization wrote: > Folks, > > > > We came across a memory race condition between VPP vhost driver and the kernel > vhost. VPP is running a tap interface over vhost backend. In this case, VPP is > acting as the vhost driver mode and the kernel vhost is acting as the vhost > device mode. > > > > In the kernel vhost’s TX traffic direction which is VPP’s RX traffic > direction, > kernel vhost is the producer and VPP is the consumer. Looking at vhost net kernel code, it seems to use the same terminology as virtio net. Can you pls clarify which ring number do you use 0 or 1? I will assume ring 0 below. > Kernel vhost places > traffic in kernel vhost’s TX vring. VPP removes traffic in VPP’s RX vring. So VPP makes buffers available and vhost kernel uses them? > It > is inevitable that the vring may become full under heavy traffic and the > kernel > vhost may have to stop and wait for the guest (VPP) to empty the vring and to > refill the vring with descriptors. When that case happens, kernel vhost clears > the bit in the vring’s used flag to request an interrupt/notification. Due to > shared memory race condition, VPP may miss the clearing of the vring’s used > flag from kernel vhost and didn’t send kernel vhost an interrupt after VPP > empties and refills the vring with new descriptors. So kernel vhost's wakeups are signalled through eventfd - I assume this is what you mean by an interrupt? To prevent the race that you describe, vhost has this code: /* OK, now we need to know about added descriptors. */ if (!headcount) { if (unlikely(busyloop_intr)) { vhost_poll_queue(&vq->poll); } else if (unlikely(vhost_enable_notify(&net->dev, vq))) { /* They have slipped one in as we were * doing that: check again. */ vhost_disable_notify(&net->dev, vq); continue; } /* Nothing new? Wait for eventfd to tell us So ring should be re-checked after notifications are enabled. If ring is no longer empty, vhost will proceed to handle the ring. This code has been around for many years. Thus if VPP doesn't work with it then I suspect it does something differently, e.g. is it possible that it is missing a memory barrier after writing out the available buffers and before checking the flags? > Unfortunately, this missed > notification causes the kernel vhost to be stuck because once the kernel vhost > is waiting for an interrupt/notification from the guest, only an interrupt/ > notification from the guest can resume/re-enable the guest from submitting new > packets to the vring. This design seems vulnerable. The protocol right now relies on notifications never being lost. I can imagine an alternative where device also re-checks the rings periodically, but that would involve running timers host side which is only possible if there's a free processor that can handle them. Further, it will still lead to stalls and packet drops, which will be harder to debug. That's just my $.02, pls feel free to take it with the virtio tc maybe others will feel differently. > Should the kernel vhost > totally depend on the notification from the guest? Quoting the text from > > > > http://docs.oasis-open.org/virtio/virtio/v1.0/virtio-v1.0.html > > > > /* The device uses this in used->flags to advise the driver: don’t kick me > * when you add a buffer. It’s unreliable, so it’s simply an > * optimization. */ > #define VIRTQ_USED_F_NO_NOTIFY 1 > > > > I interpret that the notification is simply an optimization, not a reliable > notification mechanism. What was meant I think is that suppression is unreliable. >So the kernel vhost should not bet the farm on it. > > > > We encounter the same race condition in kernel vhost’s RX traffic direction > which causes the kernel vhost to be stuck due to missed interrupt/notification > although it is less frequent. For the reverse direction the spec actually has some pseudo-code and a suggestion about handling that race: For optimal performance, a driver MAY disable used buffer notifications while processing the used ring, but beware the problem of missing notifications between emptying the ring and reenabling no- tifications. This is usually handled by re-checking for more used buffers after notifications are re- enabled: virtq_disable_used_buffer_notifications(vq); for (;;) { if (vq->last_seen_used != le16_to_cpu(virtq->used.idx)) { virtq_enable_used_buffer_notifications(vq); mb(); if (vq->last_seen_used != le16_to_cpu(virtq->used.idx))
Re: [PATCH] VSOCK: Send reset control packet when socket is partially bound
From: Jorgen Hansen Date: Wed, 12 Dec 2018 01:38:59 -0800 > static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, > @@ -312,12 +328,29 @@ static int vmci_transport_send_reset_bh(struct > sockaddr_vm *dst, > static int vmci_transport_send_reset(struct sock *sk, >struct vmci_transport_packet *pkt) > { > + struct sockaddr_vm dst; > + struct sockaddr_vm *dst_ptr; > + struct vsock_sock *vsk; > + Please order local variables from longest to shortest line. Thank you. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH v3 00/12] x86, kbuild: revert macrofying inline assembly code
This series reverts the in-kernel workarounds for inlining issues. The commit description of 77b0bf55bc67 mentioned "We also hope that GCC will eventually get fixed,..." Now, GCC provides a solution. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html explains the new "asm inline" syntax. The performance issue will be eventually solved. [About Code cleanups] I know Nadam Amit is opposed to the full revert. He also claims his motivation for macrofying was not only performance, but also cleanups. IIUC, the criticism addresses the code duplication between C and ASM. If so, I'd like to suggest a different approach for cleanups. Please see the last 3 patches. IMHO, preprocessor approach is more straight-forward, and readable. Basically, this idea should work because it is what we already do for __ASM_FORM() etc. [Quick Test of "asm inline" of GCC 9] If you want to try "asm inline" feature, the patch is available: https://lore.kernel.org/patchwork/patch/1024590/ The number of symbols for arch/x86/configs/x86_64_defconfig: nr_symbols [1]v4.20-rc7 : 96502 [2][1]+full revert : 96705 (+203) [3][2]+"asm inline": 96568 (-137) [3]: apply my patch, then replace "asm" -> "asm_inline" for _BUG_FLAGS(), refcount_add(), refcount_inc(), refcount_dec(), annotate_reachable(), annotate_unreachable() Changes in v3: - Split into per-commit revert (per Nadav Amit) - Add some cleanups with preprocessor approach Changes in v2: - Revive clean-ups made by 5bdcd510c2ac (per Peter Zijlstra) - Fix commit quoting style (per Peter Zijlstra) Masahiro Yamada (12): Revert "x86/jump-labels: Macrofy inline assembly code to work around GCC inlining bugs" Revert "x86/cpufeature: Macrofy inline assembly code to work around GCC inlining bugs" Revert "x86/extable: Macrofy inline assembly code to work around GCC inlining bugs" Revert "x86/paravirt: Work around GCC inlining bugs when compiling paravirt ops" Revert "x86/bug: Macrofy the BUG table section handling, to work around GCC inlining bugs" Revert "x86/alternatives: Macrofy lock prefixes to work around GCC inlining bugs" Revert "x86/refcount: Work around GCC inlining bug" Revert "x86/objtool: Use asm macros to work around GCC inlining bugs" Revert "kbuild/Makefile: Prepare for using macros in inline assembly code to work around asm() related GCC inlining bugs" linux/linkage: add ASM() macro to reduce duplication between C/ASM code x86/alternatives: consolidate LOCK_PREFIX macro x86/asm: consolidate ASM_EXTABLE_* macros Makefile | 9 +-- arch/x86/Makefile | 7 --- arch/x86/include/asm/alternative-asm.h| 22 +-- arch/x86/include/asm/alternative-common.h | 47 +++ arch/x86/include/asm/alternative.h| 30 +- arch/x86/include/asm/asm.h| 46 +-- arch/x86/include/asm/bug.h| 98 +-- arch/x86/include/asm/cpufeature.h | 82 +++--- arch/x86/include/asm/jump_label.h | 22 +-- arch/x86/include/asm/paravirt_types.h | 56 +- arch/x86/include/asm/refcount.h | 81 +++-- arch/x86/kernel/macros.S | 16 - include/asm-generic/bug.h | 8 +-- include/linux/compiler.h | 56 -- include/linux/linkage.h | 8 +++ scripts/Kbuild.include| 4 +- scripts/mod/Makefile | 2 - 17 files changed, 249 insertions(+), 345 deletions(-) create mode 100644 arch/x86/include/asm/alternative-common.h delete mode 100644 arch/x86/kernel/macros.S -- 2.7.4 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH v3 04/12] Revert "x86/paravirt: Work around GCC inlining bugs when compiling paravirt ops"
This reverts commit 494b5168f2de009eb80f198f668da374295098dd. The in-kernel workarounds will be replaced with GCC's new "asm inline" syntax. Signed-off-by: Masahiro Yamada --- arch/x86/include/asm/paravirt_types.h | 56 ++- arch/x86/kernel/macros.S | 1 - 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 26942ad..488c596 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -348,11 +348,23 @@ extern struct paravirt_patch_template pv_ops; #define paravirt_clobber(clobber) \ [paravirt_clobber] "i" (clobber) +/* + * Generate some code, and mark it as patchable by the + * apply_paravirt() alternate instruction patcher. + */ +#define _paravirt_alt(insn_string, type, clobber) \ + "771:\n\t" insn_string "\n" "772:\n"\ + ".pushsection .parainstructions,\"a\"\n"\ + _ASM_ALIGN "\n" \ + _ASM_PTR " 771b\n" \ + " .byte " type "\n"\ + " .byte 772b-771b\n" \ + " .short " clobber "\n"\ + ".popsection\n" + /* Generate patchable code, with the default asm parameters. */ -#define paravirt_call \ - "PARAVIRT_CALL type=\"%c[paravirt_typenum]\"" \ - " clobber=\"%c[paravirt_clobber]\"" \ - " pv_opptr=\"%c[paravirt_opptr]\";" +#define paravirt_alt(insn_string) \ + _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") /* Simple instruction patching code. */ #define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t" @@ -373,6 +385,16 @@ unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len); int paravirt_disable_iospace(void); /* + * This generates an indirect call based on the operation type number. + * The type number, computed in PARAVIRT_PATCH, is derived from the + * offset into the paravirt_patch_template structure, and can therefore be + * freely converted back into a structure offset. + */ +#define PARAVIRT_CALL \ + ANNOTATE_RETPOLINE_SAFE \ + "call *%c[paravirt_opptr];" + +/* * These macros are intended to wrap calls through one of the paravirt * ops structs, so that they can be later identified and patched at * runtime. @@ -509,7 +531,7 @@ int paravirt_disable_iospace(void); /* since this condition will never hold */ \ if (sizeof(rettype) > sizeof(unsigned long)) { \ asm volatile(pre\ -paravirt_call \ +paravirt_alt(PARAVIRT_CALL)\ post \ : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ @@ -519,7 +541,7 @@ int paravirt_disable_iospace(void); __ret = (rettype)u64)__edx) << 32) | __eax); \ } else {\ asm volatile(pre\ -paravirt_call \ +paravirt_alt(PARAVIRT_CALL)\ post \ : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ @@ -546,7 +568,7 @@ int paravirt_disable_iospace(void); PVOP_VCALL_ARGS;\ PVOP_TEST_NULL(op); \ asm volatile(pre\ -paravirt_call \ +paravirt_alt(PARAVIRT_CALL)\ post \ : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ @@ -664,26 +686,6 @@ struct paravirt_patch_site { extern struct paravirt_patch_site __parainstructions[], __parainstructions_end[]; -#else /* __ASSEMBLY__ */ - -/* - * This generates an indirect call based on the operation type number. - * The type number, computed in PARAVIRT_PATCH, is derived from the - * offset into the paravirt_patch_template structure, and c
Re: [PATCH] Export mm_update_next_owner function for vhost-net
This seems like an issue all the unuse_mm users (at least those outside of swapfile.c) have, so it should be solved in the core. Bonus points for moving the set_fs magic into use_mm().. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
[PATCH 03/14] drm/bochs: atomic: add atomic_flush+atomic_enable callbacks.
Conversion to atomic modesetting, step one. Add atomic crtc helper callbacks. Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/bochs/bochs_kms.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index f7e6d1a9b3..59d469f343 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -115,6 +115,29 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc, return 0; } +static void bochs_crtc_atomic_enable(struct drm_crtc *crtc, +struct drm_crtc_state *old_crtc_state) +{ +} + +static void bochs_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state) +{ + struct drm_device *dev = crtc->dev; + struct drm_pending_vblank_event *event; + unsigned long irqflags; + + if (crtc->state && crtc->state->event) { + event = crtc->state->event; + crtc->state->event = NULL; + + spin_lock_irqsave(&dev->event_lock, irqflags); + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irqrestore(&dev->event_lock, irqflags); + } +} + + /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs bochs_crtc_funcs = { .set_config = drm_crtc_helper_set_config, @@ -128,6 +151,8 @@ static const struct drm_crtc_helper_funcs bochs_helper_funcs = { .mode_set_base = bochs_crtc_mode_set_base, .prepare = bochs_crtc_prepare, .commit = bochs_crtc_commit, + .atomic_enable = bochs_crtc_atomic_enable, + .atomic_flush = bochs_crtc_atomic_flush, }; static const uint32_t bochs_formats[] = { -- 2.9.3 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v3 00/12] x86, kbuild: revert macrofying inline assembly code
* Masahiro Yamada wrote: > This series reverts the in-kernel workarounds for inlining issues. > > The commit description of 77b0bf55bc67 mentioned > "We also hope that GCC will eventually get fixed,..." > > Now, GCC provides a solution. > > https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html > explains the new "asm inline" syntax. > > The performance issue will be eventually solved. > > [About Code cleanups] > > I know Nadam Amit is opposed to the full revert. > He also claims his motivation for macrofying was not only > performance, but also cleanups. > > IIUC, the criticism addresses the code duplication between C and ASM. > > If so, I'd like to suggest a different approach for cleanups. > Please see the last 3 patches. > IMHO, preprocessor approach is more straight-forward, and readable. > Basically, this idea should work because it is what we already do for > __ASM_FORM() etc. > > [Quick Test of "asm inline" of GCC 9] > > If you want to try "asm inline" feature, the patch is available: > https://lore.kernel.org/patchwork/patch/1024590/ > > The number of symbols for arch/x86/configs/x86_64_defconfig: > > nr_symbols > [1]v4.20-rc7 : 96502 > [2][1]+full revert : 96705 (+203) > [3][2]+"asm inline": 96568 (-137) > > [3]: apply my patch, then replace "asm" -> "asm_inline" > for _BUG_FLAGS(), refcount_add(), refcount_inc(), refcount_dec(), > annotate_reachable(), annotate_unreachable() > > > Changes in v3: > - Split into per-commit revert (per Nadav Amit) > - Add some cleanups with preprocessor approach > > Changes in v2: > - Revive clean-ups made by 5bdcd510c2ac (per Peter Zijlstra) > - Fix commit quoting style (per Peter Zijlstra) > > Masahiro Yamada (12): > Revert "x86/jump-labels: Macrofy inline assembly code to work around > GCC inlining bugs" > Revert "x86/cpufeature: Macrofy inline assembly code to work around > GCC inlining bugs" > Revert "x86/extable: Macrofy inline assembly code to work around GCC > inlining bugs" > Revert "x86/paravirt: Work around GCC inlining bugs when compiling > paravirt ops" > Revert "x86/bug: Macrofy the BUG table section handling, to work > around GCC inlining bugs" > Revert "x86/alternatives: Macrofy lock prefixes to work around GCC > inlining bugs" > Revert "x86/refcount: Work around GCC inlining bug" > Revert "x86/objtool: Use asm macros to work around GCC inlining bugs" > Revert "kbuild/Makefile: Prepare for using macros in inline assembly > code to work around asm() related GCC inlining bugs" > linux/linkage: add ASM() macro to reduce duplication between C/ASM > code > x86/alternatives: consolidate LOCK_PREFIX macro > x86/asm: consolidate ASM_EXTABLE_* macros > > Makefile | 9 +-- > arch/x86/Makefile | 7 --- > arch/x86/include/asm/alternative-asm.h| 22 +-- > arch/x86/include/asm/alternative-common.h | 47 +++ > arch/x86/include/asm/alternative.h| 30 +- > arch/x86/include/asm/asm.h| 46 +-- > arch/x86/include/asm/bug.h| 98 > +-- > arch/x86/include/asm/cpufeature.h | 82 +++--- > arch/x86/include/asm/jump_label.h | 22 +-- > arch/x86/include/asm/paravirt_types.h | 56 +- > arch/x86/include/asm/refcount.h | 81 +++-- > arch/x86/kernel/macros.S | 16 - > include/asm-generic/bug.h | 8 +-- > include/linux/compiler.h | 56 -- > include/linux/linkage.h | 8 +++ > scripts/Kbuild.include| 4 +- > scripts/mod/Makefile | 2 - > 17 files changed, 249 insertions(+), 345 deletions(-) > create mode 100644 arch/x86/include/asm/alternative-common.h > delete mode 100644 arch/x86/kernel/macros.S I absolutely agree that this needs to be resolved in v4.20. So I did the 1-9 reverts manually myself as well, because I think the first commit should be reverted fully to get as close to the starting point as possible (we are late in the cycle) - and came to the attached interdiff between your series and mine. Does this approach look OK to you, or did I miss something? Thanks, Ingo => entry/calling.h |2 - include/asm/jump_label.h | 50 ++- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 25e5a6bda8c3..20d0885b00fb 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -352,7 +352,7 @@ For 32-bit we have the following conventions - kernel is built with .macro CALL_enter_from_user_mode #ifdef CONFIG_CONTEXT_TRACKING #ifdef HAVE_JUMP_LABEL - STATIC_BRANCH_JMP l_ye
[PULL 0/1] virtio-ccw: one more patch for 4.21
The following changes since commit 37d1246af2d530710cf5822d2845774f01c03b22: virtio_net: bulk free tx skbs (2018-12-06 14:28:39 -0500) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git tags/virtio-ccw-20181219 for you to fetch changes up to 6fb95ef30707f1b2fcaea8d6dc873055e0460b1a: virtio-ccw: diag 500 may return a negative cookie (2018-12-19 11:01:57 +0100) One small documentation fix for 4.21. Cornelia Huck (1): virtio-ccw: diag 500 may return a negative cookie Documentation/virtual/kvm/s390-diag.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.17.2 ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH v2] x86, kbuild: revert macrofying inline assembly code
On Sun, Dec 16, 2018 at 12:29 PM Nadav Amit wrote: > > > On Dec 15, 2018, at 6:50 PM, Masahiro Yamada > > wrote: > > > > Revert the following 9 commits: > > > > [1] 5bdcd510c2ac ("x86/jump-labels: Macrofy inline assembly code to > >work around GCC inlining bugs") > > > >This was partially reverted because it made good cleanups > >irrespective of the inlining issue; the error message is still > >unneeded, and the conversion to STATIC_BRANCH_{NOP,JUMP} should > >be kept. > > > > [2] d5a581d84ae6 ("x86/cpufeature: Macrofy inline assembly code to > >work around GCC inlining bugs") > > > > [3] 0474d5d9d2f7 ("x86/extable: Macrofy inline assembly code to work > >around GCC inlining bugs") > > > > [4] 494b5168f2de ("x86/paravirt: Work around GCC inlining bugs when > >compiling paravirt ops") > > > > [5] f81f8ad56fd1 ("x86/bug: Macrofy the BUG table section handling, > >to work around GCC inlining bugs") > > > > [6] 77f48ec28e4c ("x86/alternatives: Macrofy lock prefixes to work > > around GCC inlining bugs") > > > > [7] 9e1725b41059 ("x86/refcount: Work around GCC inlining bug") > > > >Resolved conflicts in arch/x86/include/asm/refcount.h caused by > >288e4521f0f6 ("x86/asm: 'Simplify' GEN_*_RMWcc() macros"). > > > > [8] c06c4d809051 ("x86/objtool: Use asm macros to work around GCC > >inlining bugs") > > > > [9] 77b0bf55bc67 ("kbuild/Makefile: Prepare for using macros in inline > >assembly code to work around asm() related GCC inlining bugs") > > > > A few days after those commits applied, discussion started to solve > > the issue more elegantly with the help of compiler: > > > > > > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.org%2Flkml%2F2018%2F10%2F7%2F92&data=02%7C01%7Cnamit%40vmware.com%7Ce893ce88065e4c59236308d663019424%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C636805255787607178&sdata=miiUndmPfGNKvrzD5mttC1%2Bn6rNaoIFebjZOAkBr24Y%3D&reserved=0 > > > > The new syntax "asm inline" was implemented by Segher Boessenkool, and > > now queued up for GCC 9. (People were positive even for back-porting it > > to older compilers). > > > > Since the in-kernel workarounds merged, some issues have been reported: > > breakage of building with distcc/icecc, breakage of distro packages for > > module building. (More fundamentally, we cannot build external modules > > after 'make clean'.) > > > > I do not want to mess up the build system any more. > > > > Given that this issue will be solved in a cleaner way sooner or later, > > let's revert the in-kernel workarounds, and wait for GCC 9. > > > > Reported-by: Logan Gunthorpe # distcc > > Reported-by: Sedat Dilek # deb/rpm package > > It is customary to cc those who report an issue. OK. > The distcc issue has already been resolved both in distcc Precisely, the fix-up was submitted, but not pulled yet as of writing. https://github.com/distcc/distcc/pull/313 > and in the patches > I’ve sent: https://lkml.org/lkml/2018/11/15/467 . I was scared by this ugly fix-up, so I rejected it. > So I cannot understand why > it is mentioned as a motivation. > > It sounds that the external modules can easily be resolved. Can you please > provide a link for the bug report? https://www.spinics.net/lists/linux-kbuild/msg20037.html We can fix it under circumstances "we can do anything" although I am scared by endless Makefile hacks. > Please regard my comments regarding v1. I will try my best, although I felt some of your requests were too much. I am not an x86 developer. I posted this so people can play with 'asm inline' https://lore.kernel.org/patchwork/patch/1024590/ You can confirm vmlinux size is increased, and some symbols disappears. > I must admit that I’m very surprised > that you don’t like the patches since you ack’d the original patch-set I think ack and "I like it" are different. There are situations where we had to accept something reluctantly. Without my ack, your patch series would not have been merged via x86 tree. There was no other solution at that time. Also, I could not predict potential problems, which turned out later. So I let it go. It would have been better if the following discussion had stared earlier. https://lkml.org/lkml/2018/10/7/92 Now, we got a much cleaner solution. I believe we should replace the workarounds with it. > (and > actually assisted me in changing the Makefile). You were clearly breaking the build system. So, I provided a less ugly solution. Again, the in-kernel hack was the only solution at that time, but the situation has changed then. -- Best Regards Masahiro Yamada ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH] virtio-ccw: diag 500 may return a negative cookie
On Tue, 18 Dec 2018 14:20:34 +0100 Cornelia Huck wrote: > If something goes wrong in the kvm io bus handling, the virtio-ccw > diagnose may return a negative error value in the cookie gpr. > > Document this. > > Signed-off-by: Cornelia Huck > --- > > Even if the virtio spec is the correct place to specify what diag 500 > subcode 3 does, we also should mention here that the cookie may be > an error. > > --- > Documentation/virtual/kvm/s390-diag.txt | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/Documentation/virtual/kvm/s390-diag.txt > b/Documentation/virtual/kvm/s390-diag.txt > index 48c4921794ed..7c52e5f8b210 100644 > --- a/Documentation/virtual/kvm/s390-diag.txt > +++ b/Documentation/virtual/kvm/s390-diag.txt > @@ -68,7 +68,8 @@ Subcode 3 - virtio-ccw notification > identifier, it is ignored. > > After completion of the DIAGNOSE call, general register 2 may contain > -a 64bit identifier (in the kvm_io_bus cookie case). > +a 64bit identifier (in the kvm_io_bus cookie case), or a negative > +error value, if an internal error occurred. > > See also the virtio standard for a discussion of this hypercall. > Queued. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization