vfio: add display support
v8 cover vfio: add display support
This series adds support for a vgpu display to the qemu vfio code.
v8:
- codestyle fixes, this time for real ...
v7:
- rebase to latest master.
- dmabuf: update cursor hotspot properly (Tina).
- dmabuf: track whenever cursor hotspot + position changes.
- codestyle fixes.
v6:
- add support for hotplugging QemuConsoles.
- drop vfio-pci-display device, re-add OnOffAuto display property.
- add proper cleanup in finalize.
v5:
- rebase to latest master
- drop DeviceState->hotpluggable patch, use separate vfio-pci-display device instead so we can use DeviceClass->hotpluggable.
- add vfio dma-buf patch. Right now this can be tested with '-display egl-headless' only. gtk and spice support is almost ready for merge and should follow soon.
cheers,
Gerd
Gerd Hoffmann (9):
linux-headers: update to 4.16-rc1
standard-headers: add drm/drm_fourcc.h ui/pixman: add qemu_drm_format_to_pixman()
console: minimal hotplug suport
secondary-vga: properly close QemuConsole on unplug vfio/common: cleanup in vfio_region_finalize vfio/display: core & wireup
vfio/display: adding region support vfio/display: adding dmabuf support
hw/vfio/pci.h | 5 + include/hw/vfio/vfio-common.h | 22 ++ include/standard-headers/drm/drm_fourcc.h | 411 +++++++++++++++++++++ include/standard-headers/linux/input-event-codes.h | 1 + include/standard-headers/linux/input.h | 11 + include/standard-headers/linux/pci_regs.h | 30 +- include/standard-headers/linux/virtio_net.h | 13 + include/ui/console.h | 2 + include/ui/qemu-pixman.h | 5 + linux-headers/asm-powerpc/kvm.h | 2 + linux-headers/asm-powerpc/unistd.h | 3 + linux-headers/asm-s390/unistd.h | 401 +------------------- linux-headers/asm-s390/unistd_32.h | 364 ++++++++++++++++++ linux-headers/asm-s390/unistd_64.h | 331 +++++++++++++++++ linux-headers/asm-x86/kvm_para.h | 4 + linux-headers/linux/kvm.h | 90 +++++ linux-headers/linux/psci.h | 3 + linux-headers/linux/vfio.h | 72 ++++ hw/display/vga-pci.c | 9 + hw/vfio/common.c | 7 + hw/vfio/display.c | 347 +++++++++++++++++ hw/vfio/pci.c | 10 + ui/console.c | 79 +++- ui/qemu-pixman.c | 22 ++ hw/vfio/Makefile.objs | 2 +- scripts/update-linux-headers.sh | 8 + ui/trace-events | 2 + 27 files changed, 1839 insertions(+), 417 deletions(-) create mode 100644 include/standard-headers/drm/drm_fourcc.h create mode 100644 linux-headers/asm-s390/unistd_32.h create mode 100644 linux-headers/asm-s390/unistd_64.h create mode 100644 hw/vfio/display.c
Signature · 1 line
2.9.3
PATCH v8 1/9 linux-headers: update to 4.16-rc1
s390 has splitted syscall numbers into unistd_{32,64}.h files, so update scripts/update-linux-headers.sh accordingly.
Also add a rewrite from __BITS_PER_LONG to HOST_LONG_BITS for linux/input.h
--- include/standard-headers/linux/input-event-codes.h | 1 + include/standard-headers/linux/input.h | 11 + include/standard-headers/linux/pci_regs.h | 30 +- include/standard-headers/linux/virtio_net.h | 13 + linux-headers/asm-powerpc/kvm.h | 2 + linux-headers/asm-powerpc/unistd.h | 3 + linux-headers/asm-s390/unistd.h | 401 +-------------------- linux-headers/asm-s390/unistd_32.h | 364 +++++++++++++++++++ linux-headers/asm-s390/unistd_64.h | 331 +++++++++++++++++ linux-headers/asm-x86/kvm_para.h | 4 + linux-headers/linux/kvm.h | 90 +++++ linux-headers/linux/psci.h | 3 + linux-headers/linux/vfio.h | 72 ++++ scripts/update-linux-headers.sh | 3 + 14 files changed, 918 insertions(+), 410 deletions(-) create mode 100644 linux-headers/asm-s390/unistd_32.h create mode 100644 linux-headers/asm-s390/unistd_64.h
include/standard-headers/linux/input-event-codes.h +1 -0
@@ -594,6 +594,7 @@#define BTN_DPAD_RIGHT 0x223#define KEY_ALS_TOGGLE 0x230/* Ambient light sensor */ +#define KEY_ROTATE_LOCK_TOGGLE 0x231/* Display rotation lock */ #define KEY_BUTTONCONFIG 0x240/* AL Button Configuration */ #define KEY_TASKMANAGER 0x241/* AL Task/Project Manager */
include/standard-headers/linux/input.h +11 -0
@@ -18,10 +18,21 @@/* * The event structure itself +* Note that __USE_TIME_BITS64 is defined by libc based on +* application's request to use 64 bit time_t. */ struct input_event { +#if (HOST_LONG_BITS !=32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL)struct timeval time; +#define input_event_sec time.tv_sec +#define input_event_usec time.tv_usec +#else +__kernel_ulong_t __sec; +__kernel_ulong_t __usec; +#define input_event_sec __sec +#define input_event_usec __usec +#endif uint16_t type;uint16_t code;int32_t value;
include/standard-headers/linux/pci_regs.h +18 -12
@@ -622,15 +622,19 @@* safely. */ #define PCI_EXP_DEVCAP2 36/* Device Capabilities 2 */ +#define PCI_EXP_DEVCAP2_COMP_TMOUT_DIS 0x00000010/* Completion Timeout Disable supported */ #define PCI_EXP_DEVCAP2_ARI 0x00000020/* Alternative Routing-ID */ #define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040/* Atomic Op routing */ -#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100/* Atomic 64-bit compare */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP32 0x00000080/* 32b AtomicOp completion */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100/* 64b AtomicOp completion */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200/* 128b AtomicOp completion */ #define PCI_EXP_DEVCAP2_LTR 0x00000800/* Latency tolerance reporting */ #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000/* OBFF support mechanism */ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000/* New message signaling */ #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000/* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCTL2 40/* Device Control 2 */ #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f/* Completion Timeout Value */ +#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010/* Completion Timeout Disable */ #define PCI_EXP_DEVCTL2_ARI 0x0020/* Alternative Routing-ID */ #define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040/* Set Atomic requests */ #define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080/* Block atomic egress */
@@ -966,26 +970,28 @@/* Downstream Port Containment */ #define PCI_EXP_DPC_CAP 4/* DPC Capability */ -#define PCI_EXP_DPC_IRQ 0x1f/* DPC Interrupt Message Number */ -#define PCI_EXP_DPC_CAP_RP_EXT 0x20/* Root Port Extensions for DPC */ -#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40/* Poisoned TLP Egress Blocking Supported */ -#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80/* Software Triggering Supported */ -#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00/* RP PIO log size */ +#define PCI_EXP_DPC_IRQ 0x001F/* Interrupt Message Number */ +#define PCI_EXP_DPC_CAP_RP_EXT 0x0020/* Root Port Extensions */ +#define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040/* Poisoned TLP Egress Blocking Supported */ +#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080/* Software Triggering Supported */ +#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00/* RP PIO Log Size */ #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000/* ERR_COR signal on DL_Active supported */ #define PCI_EXP_DPC_CTL 6/* DPC control */ -#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02/* Enable trigger on ERR_NONFATAL message */ -#define PCI_EXP_DPC_CTL_INT_EN 0x08/* DPC Interrupt Enable */ +#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x0002/* Enable trigger on ERR_NONFATAL message */ +#define PCI_EXP_DPC_CTL_INT_EN 0x0008/* DPC Interrupt Enable */ #define PCI_EXP_DPC_STATUS 8/* DPC Status */ -#define PCI_EXP_DPC_STATUS_TRIGGER 0x01/* Trigger Status */ -#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08/* Interrupt Status */ -#define PCI_EXP_DPC_RP_BUSY 0x10/* Root Port Busy */ +#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001/* Trigger Status */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006/* Trigger Reason */ +#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008/* Interrupt Status */ +#define PCI_EXP_DPC_RP_BUSY 0x0010/* Root Port Busy */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060/* Trig Reason Extension */ #define PCI_EXP_DPC_SOURCE_ID 10/* DPC Source Identifier */ #define PCI_EXP_DPC_RP_PIO_STATUS 0x0C/* RP PIO Status */ -#define PCI_EXP_DPC_RP_PIO_MASK 0x10/* RP PIO MASK */ +#define PCI_EXP_DPC_RP_PIO_MASK 0x10/* RP PIO Mask */ #define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14/* RP PIO Severity */ #define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18/* RP PIO SysError */ #define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C/* RP PIO Exception */
include/standard-headers/linux/virtio_net.h +13 -0
@@ -57,6 +57,8 @@* Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23/* Set MAC address */ +#define VIRTIO_NET_F_SPEED_DUPLEX 63/* Device set linkspeed and duplex */ +#ifndef VIRTIO_NET_NO_LEGACY #define VIRTIO_NET_F_GSO 6/* Host handles pkts w/ any GSO type */ #endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,17 @@ struct virtio_net_config {uint16_t max_virtqueue_pairs;/* Default maximum transmit unit advice */ uint16_t mtu; +/* +* speed, in units of 1Mb. All values 0 to INT_MAX are legal. +* Any other value stands for unknown. +*/ +uint32_t speed; +/* +* 0x00 - half duplex +* 0x01 - full duplex +* Any other value stands for unknown. +*/ +uint8_t duplex; }QEMU_PACKED ;/*
linux-headers/asm-powerpc/kvm.h +2 -0
@@ -632,6 +632,8 @@ struct kvm_ppc_cpu_char {#define KVM_REG_PPC_TIDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbc)#define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd) +#define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe) +/* Transactional Memory checkpointed state: * This is all GPRs, all VSX regs and a subset of SPRs */
linux-headers/asm-powerpc/unistd.h +3 -0
@@ -395,5 +395,8 @@#define __NR_pwritev2 381#define __NR_kexec_file_load 382#define __NR_statx 383 +#define __NR_pkey_alloc 384 +#define __NR_pkey_free 385 +#define __NR_pkey_mprotect 386#endif /* _ASM_POWERPC_UNISTD_H_ */
linux-headers/asm-s390/unistd.h +3 -398
408 lines not on this page · raw message
linux-headers/asm-s390/unistd_32.h new file +364 -0
364 lines not on this page · raw message
linux-headers/asm-s390/unistd_64.h new file +331 -0
331 lines not on this page · raw message
linux-headers/asm-x86/kvm_para.h +4 -0
@@ -25,6 +25,7 @@#define KVM_FEATURE_STEAL_TIME 5#define KVM_FEATURE_PV_EOI 6#define KVM_FEATURE_PV_UNHALT 7 +#define KVM_FEATURE_PV_TLB_FLUSH 9/* The last 8 bits are used to indicate how to interpret the flags field * in pvclock structure. If no bits are set, all flags are ignored.
@@ -51,6 +52,9 @@ struct kvm_steal_time {__u32 pad[11 ]; }; +#define KVM_VCPU_PREEMPTED (1 << 0) +#define KVM_VCPU_FLUSH_TLB (1 << 1) +#define KVM_CLOCK_PAIRING_WALLCLOCK 0struct kvm_clock_pairing {__s64 sec;
linux-headers/linux/kvm.h +90 -0
96 lines not on this page · raw message
linux-headers/linux/psci.h +3 -0
@@ -88,6 +88,9 @@ (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)#define PSCI_VERSION_MINOR (ver) \ ((ver) & PSCI_VERSION_MINOR_MASK) +#define PSCI_VERSION (maj, min) \ + ((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \ + ((min) & PSCI_VERSION_MINOR_MASK))/* PSCI features decoding (>=1.0) */ #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT 1
linux-headers/linux/vfio.h +72 -0
84 lines not on this page · raw message
scripts/update-linux-headers.sh +3 -0
@@ -56,6 +56,7 @@ cp_portable() { -e 's/__bitwise//' \ -e 's/__attribute__((packed))/QEMU_PACKED/' \ -e 's/__inline__/inline/' \ + -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \ -e '/sys\/ioctl.h/d' \ -e 's/SW_MAX/SW_MAX_/' \ -e 's/atomic_t/int/' \
@@ -99,6 +100,8 @@ for arch in $ARCHLIST; do mkdir -p "$output/include/standard-headers/asm-$arch" if [ $arch = s390 ]; then cp_portable "$tmpdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" + cp "$tmpdir/include/asm/unistd_32.h" "$output/linux-headers/asm-s390/" + cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-s390/" fi if [ $arch = arm ]; then cp "$tmpdir/include/asm/unistd-eabi.h" "$output/linux-headers/asm-arm/"
Signature · 1 line
2.9.3
PATCH v8 2/9 standard-headers: add drm/drm_fourcc.h
In reply to Gerd HoffmannSo we can use the drm fourcc codes without a dependency on libdrm-devel.
--- include/standard-headers/drm/drm_fourcc.h | 411 ++++++++++++++++++++++++++++++ scripts/update-linux-headers.sh | 5 + 2 files changed, 416 insertions(+) create mode 100644 include/standard-headers/drm/drm_fourcc.h
include/standard-headers/drm/drm_fourcc.h new file +411 -0
@@ -0,0 +1,411 @@ +/* +* Copyright 2011 Intel Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice (including the next +* paragraph) shall be included in all copies or substantial portions of the +* Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef DRM_FOURCC_H +#define DRM_FOURCC_H + + +#if defined(__cplusplus) +extern "C" { +#endif + +#define fourcc_code (a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ + ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) + +#define DRM_FORMAT_BIG_ENDIAN (1<<31)/* format is big endian instead of little endian */ + +/* color index */ +#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')/* [7:0] C */ + +/* 8 bpp Red */ +#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')/* [7:0] R */ + +/* 16 bpp Red */ +#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')/* [15:0] R little endian */ + +/* 16 bpp RG */ +#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')/* [15:0] R:G 8:8 little endian */ +#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')/* [15:0] G:R 8:8 little endian */ + +/* 32 bpp RG */ +#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2')/* [31:0] R:G 16:16 little endian */ +#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')/* [31:0] G:R 16:16 little endian */ + +/* 8 bpp RGB */ +#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8')/* [7:0] R:G:B 3:3:2 */ +#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8')/* [7:0] B:G:R 2:3:3 */ + +/* 16 bpp RGB */ +#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2')/* [15:0] x:R:G:B 4:4:4:4 little endian */ +#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2')/* [15:0] x:B:G:R 4:4:4:4 little endian */ +#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2')/* [15:0] R:G:B:x 4:4:4:4 little endian */ +#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2')/* [15:0] B:G:R:x 4:4:4:4 little endian */ + +#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2')/* [15:0] A:R:G:B 4:4:4:4 little endian */ +#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2')/* [15:0] A:B:G:R 4:4:4:4 little endian */ +#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2')/* [15:0] R:G:B:A 4:4:4:4 little endian */ +#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2')/* [15:0] B:G:R:A 4:4:4:4 little endian */ + +#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5')/* [15:0] x:R:G:B 1:5:5:5 little endian */ +#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5')/* [15:0] x:B:G:R 1:5:5:5 little endian */ +#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5')/* [15:0] R:G:B:x 5:5:5:1 little endian */ +#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5')/* [15:0] B:G:R:x 5:5:5:1 little endian */ + +#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5')/* [15:0] A:R:G:B 1:5:5:5 little endian */ +#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5')/* [15:0] A:B:G:R 1:5:5:5 little endian */ +#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5')/* [15:0] R:G:B:A 5:5:5:1 little endian */ +#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5')/* [15:0] B:G:R:A 5:5:5:1 little endian */ + +#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6')/* [15:0] R:G:B 5:6:5 little endian */ +#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6')/* [15:0] B:G:R 5:6:5 little endian */ + +/* 24 bpp RGB */ +#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')/* [23:0] R:G:B little endian */ +#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4')/* [23:0] B:G:R little endian */ + +/* 32 bpp RGB */ +#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')/* [31:0] x:R:G:B 8:8:8:8 little endian */ +#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4')/* [31:0] x:B:G:R 8:8:8:8 little endian */ +#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4')/* [31:0] R:G:B:x 8:8:8:8 little endian */ +#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4')/* [31:0] B:G:R:x 8:8:8:8 little endian */ + +#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')/* [31:0] A:R:G:B 8:8:8:8 little endian */ +#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')/* [31:0] A:B:G:R 8:8:8:8 little endian */ +#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4')/* [31:0] R:G:B:A 8:8:8:8 little endian */ +#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4')/* [31:0] B:G:R:A 8:8:8:8 little endian */ + +#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0')/* [31:0] x:R:G:B 2:10:10:10 little endian */ +#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0')/* [31:0] x:B:G:R 2:10:10:10 little endian */ +#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0')/* [31:0] R:G:B:x 10:10:10:2 little endian */ +#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0')/* [31:0] B:G:R:x 10:10:10:2 little endian */ + +#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0')/* [31:0] A:R:G:B 2:10:10:10 little endian */ +#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')/* [31:0] A:B:G:R 2:10:10:10 little endian */ +#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0')/* [31:0] R:G:B:A 10:10:10:2 little endian */ +#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')/* [31:0] B:G:R:A 10:10:10:2 little endian */ + +/* packed YCbCr */ +#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V')/* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ +#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U')/* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ +#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y')/* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ +#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y')/* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ + +#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V')/* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ + +/* +* 2 plane RGB + A +* index 0 = RGB plane, same format as the corresponding non _A8 format has +* index 1 = A plane, [7:0] A +*/ +#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8') +#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8') +#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8') +#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8') +#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8') +#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8') +#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8') +#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8') + +/* +* 2 plane YCbCr +* index 0 = Y plane, [7:0] Y +* index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian +* or +* index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian +*/ +#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2')/* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1')/* 2x2 subsampled Cb:Cr plane */ +#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6')/* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1')/* 2x1 subsampled Cb:Cr plane */ +#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4')/* non-subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2')/* non-subsampled Cb:Cr plane */ + +/* +* 3 plane YCbCr +* index 0: Y plane, [7:0] Y +* index 1: Cb plane, [7:0] Cb +* index 2: Cr plane, [7:0] Cr +* or +* index 1: Cr plane, [7:0] Cr +* index 2: Cb plane, [7:0] Cb +*/ +#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9')/* 4x4 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9')/* 4x4 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1')/* 4x1 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1')/* 4x1 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')/* 2x2 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2')/* 2x2 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6')/* 2x1 subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6')/* 2x1 subsampled Cr (1) and Cb (2) planes */ +#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4')/* non-subsampled Cb (1) and Cr (2) planes */ +#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4')/* non-subsampled Cr (1) and Cb (2) planes */ + + +/* +* Format Modifiers: +* +* Format modifiers describe, typically, a re-ordering or modification +* of the data in a plane of an FB. This can be used to express tiled/ +* swizzled formats, or compression, or a combination of the two. +* +* The upper 8 bits of the format modifier are a vendor-id as assigned +* below. The lower 56 bits are assigned as vendor sees fit. +*/ + +/* Vendor Ids: */ +#define DRM_FORMAT_MOD_NONE 0 +#define DRM_FORMAT_MOD_VENDOR_NONE 0 +#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 +#define DRM_FORMAT_MOD_VENDOR_AMD 0x02 +#define DRM_FORMAT_MOD_VENDOR_NVIDIA 0x03 +#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 +#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 +#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06 +#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 +/* add more to the end as needed */ + +#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) + +#define fourcc_mod_code (vendor, val) \ + ((((uint64_t)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL)) + +/* +* Format Modifier tokens: +* +* When adding a new token please document the layout with a code comment, +* similar to the fourcc codes above. drm_fourcc.h is considered the +* authoritative source for all of these. +*/ + +/* +* Invalid Modifier +* +* This modifier can be used as a sentinel to terminate the format modifiers +* list, or to initialize a variable with an invalid modifier. It might also be +* used to report an error back to userspace for certain APIs. +*/ +#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) + +/* +* Linear Layout +* +* Just plain linear layout. Note that this is different from no specifying any +* modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl), +* which tells the driver to also take driver-internal information into account +* and so might actually result in a tiled framebuffer. +*/ +#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) + +/* Intel framebuffer modifiers */ + +/* +* Intel X-tiling layout +* +* This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) +* in row-major layout. Within the tile bytes are laid out row-major, with +* a platform-dependent stride. On top of that the memory can apply +* platform-depending swizzling of some higher address bits into bit6. +* +* This format is highly platforms specific and not useful for cross-driver +* sharing. It exists since on a given platform it does uniquely identify the +* layout in a simple way for i915-specific userspace. +*/ +#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1) + +/* +* Intel Y-tiling layout +* +* This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) +* in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes) +* chunks column-major, with a platform-dependent height. On top of that the +* memory can apply platform-depending swizzling of some higher address bits +* into bit6. +* +* This format is highly platforms specific and not useful for cross-driver +* sharing. It exists since on a given platform it does uniquely identify the +* layout in a simple way for i915-specific userspace. +*/ +#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2) + +/* +* Intel Yf-tiling layout +* +* This is a tiled layout using 4Kb tiles in row-major layout. +* Within the tile pixels are laid out in 16 256 byte units / sub-tiles which +* are arranged in four groups (two wide, two high) with column-major layout. +* Each group therefore consits out of four 256 byte units, which are also laid +* out as 2x2 column-major. +* 256 byte units are made out of four 64 byte blocks of pixels, producing +* either a square block or a 2:1 unit. +* 64 byte blocks of pixels contain four pixel rows of 16 bytes, where the width +* in pixel depends on the pixel depth. +*/ +#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) + +/* +* Intel color control surface (CCS) for render compression +* +* The framebuffer format must be one of the 8:8:8:8 RGB formats. +* The main surface will be plane index 0 and must be Y/Yf-tiled, +* the CCS will be plane index 1. +* +* Each CCS tile matches a 1024x512 pixel area of the main surface. +* To match certain aspects of the 3D hardware the CCS is +* considered to be made up of normal 128Bx32 Y tiles, Thus +* the CCS pitch must be specified in multiples of 128 bytes. +* +* In reality the CCS tile appears to be a 64Bx64 Y tile, composed +* of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks. +* But that fact is not relevant unless the memory is accessed +* directly. +*/ +#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4) +#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5) + +/* +* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks +* +* Macroblocks are laid in a Z-shape, and each pixel data is following the +* standard NV12 style. +* As for NV12, an image is the result of two frame buffers: one for Y, +* one for the interleaved Cb/Cr components (1/2 the height of the Y buffer). +* Alignment requirements are (for each buffer): +* - multiple of 128 pixels for the width +* - multiple of 32 pixels for the height +* +* For more information: see https://linuxtv.org/downloads/v4l-dvb-apis/re32.html +*/ +#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1) + +/* Vivante framebuffer modifiers */ + +/* +* Vivante 4x4 tiling layout +* +* This is a simple tiled layout using tiles of 4x4 pixels in a row-major +* layout. +*/ +#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1) + +/* +* Vivante 64x64 super-tiling layout +* +* This is a tiled layout using 64x64 pixel super-tiles, where each super-tile +* contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row- +* major layout. +* +* For more information: see +* https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling +*/ +#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2) + +/* +* Vivante 4x4 tiling layout for dual-pipe +* +* Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a +* different base address. Offsets from the base addresses are therefore halved +* compared to the non-split tiled layout. +*/ +#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3) + +/* +* Vivante 64x64 super-tiling layout for dual-pipe +* +* Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile +* starts at a different base address. Offsets from the base addresses are +* therefore halved compared to the non-split super-tiled layout. +*/ +#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4) + +/* NVIDIA frame buffer modifiers */ + +/* +* Tegra Tiled Layout, used by Tegra 2, 3 and 4. +* +* Pixels are arranged in simple tiles of 16 x 16 bytes. +*/ +#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1) + +/* +* 16Bx2 Block Linear layout, used by desktop GPUs, and Tegra K1 and later +* +* Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked +* vertically by a power of 2 (1 to 32 GOBs) to form a block. +* +* Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape. +* +* Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically. +* Valid values are: +* +* 0 == ONE_GOB +* 1 == TWO_GOBS +* 2 == FOUR_GOBS +* 3 == EIGHT_GOBS +* 4 == SIXTEEN_GOBS +* 5 == THIRTYTWO_GOBS +* +* Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format +* in full detail. +*/ +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK (v) \ + fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf)) + +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \ + fourcc_mod_code(NVIDIA, 0x10) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \ + fourcc_mod_code(NVIDIA, 0x11) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \ + fourcc_mod_code(NVIDIA, 0x12) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \ + fourcc_mod_code(NVIDIA, 0x13) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \ + fourcc_mod_code(NVIDIA, 0x14) +#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \ + fourcc_mod_code(NVIDIA, 0x15) + +/* +* Broadcom VC4 "T" format +* +* This is the primary layout that the V3D GPU can texture from (it +* can't do linear). The T format has: +* +* - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4 +* pixels at 32 bit depth. +* +* - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually +* 16x16 pixels). +* +* - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On +* even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows +* they're (TR, BR, BL, TL), where bottom left is start of memory. +* +* - an image made of 4k tiles in rows either left-to-right (even rows of 4k +* tiles) or right-to-left (odd rows of 4k tiles). +*/ +#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1) + +#if defined(__cplusplus) +} +#endif + +#endif /* DRM_FOURCC_H */
scripts/update-linux-headers.sh +5 -0
@@ -39,6 +39,7 @@ cp_portable() { -e 'input-event-codes' \ -e 'sys/' \ -e 'pvrdma_verbs' \ + -e 'drm.h' \ > /dev/null then echo "Unexpected #include in input file $f".
@@ -57,6 +58,7 @@ cp_portable() { -e 's/__attribute__((packed))/QEMU_PACKED/' \ -e 's/__inline__/inline/' \ -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \ + -e '/\"drm.h\"/d' \ -e '/sys\/ioctl.h/d' \ -e 's/SW_MAX/SW_MAX_/' \ -e 's/atomic_t/int/' \
@@ -152,6 +154,9 @@ for i in "$tmpdir"/include/linux/*virtio*.h "$tmpdir/include/linux/input.h" \ "$tmpdir/include/linux/pci_regs.h"; do cp_portable "$i" "$output/include/standard-headers/linux" done +mkdir -p "$output/include/standard-headers/drm" +cp_portable "$tmpdir/include/drm/drm_fourcc.h" \ + "$output/include/standard-headers/drm" rm -rf "$output/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma" mkdir -p "$output/include/standard-headers/drivers/infiniband/hw/vmw_pvrdma"
Signature · 1 line
2.9.3
PATCH v8 3/9 ui/pixman: add qemu_drm_format_to_pixman()
In reply to Gerd HoffmannMap drm fourcc codes to pixman formats.
--- include/ui/qemu-pixman.h | 5 +++++ ui/qemu-pixman.c | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+)
include/ui/qemu-pixman.h +5 -0
@@ -33,6 +33,8 @@# define PIXMAN_BE_r8g8b8a8 PIXMAN_r8g8b8a8# define PIXMAN_BE_x8b8g8r8 PIXMAN_x8b8g8r8# define PIXMAN_BE_a8b8g8r8 PIXMAN_a8b8g8r8 +# define PIXMAN_LE_r8g8b8 PIXMAN_b8g8r8 +# define PIXMAN_LE_a8r8g8b8 PIXMAN_b8g8r8a8# define PIXMAN_LE_x8r8g8b8 PIXMAN_b8g8r8x8#else # define PIXMAN_BE_r8g8b8 PIXMAN_b8g8r8
@@ -44,6 +46,8 @@# define PIXMAN_BE_r8g8b8a8 PIXMAN_a8b8g8r8# define PIXMAN_BE_x8b8g8r8 PIXMAN_r8g8b8x8# define PIXMAN_BE_a8b8g8r8 PIXMAN_r8g8b8a8 +# define PIXMAN_LE_r8g8b8 PIXMAN_r8g8b8 +# define PIXMAN_LE_a8r8g8b8 PIXMAN_a8r8g8b8# define PIXMAN_LE_x8r8g8b8 PIXMAN_x8r8g8b8#endif
@@ -51,6 +55,7 @@PixelFormat qemu_pixelformat_from_pixman (pixman_format_code_t format);pixman_format_code_t qemu_default_pixman_format (int bpp,bool native_endian); +pixman_format_code_t qemu_drm_format_to_pixman (uint32_t drm_format);int qemu_pixman_get_type (int rshift,int gshift,int bshift);pixman_format_code_t qemu_pixman_get_format (PixelFormat *pf); bool qemu_pixman_check_format(DisplayChangeListener *dcl,
ui/qemu-pixman.c +22 -0
@@ -6,6 +6,7 @@#include "qemu/osdep.h" #include "qemu-common.h" #include "ui/console.h" +#include "standard-headers/drm/drm_fourcc.h" PixelFormat qemu_pixelformat_from_pixman (pixman_format_code_t format) {
@@ -88,6 +89,27 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)return 0 ; } +/* Note: drm is little endian, pixman is native endian */ +pixman_format_code_t qemu_drm_format_to_pixman (uint32_t drm_format) +{ +static const struct { +uint32_t drm_format; +pixman_format_code_t pixman; + } map[] = { + {DRM_FORMAT_RGB888 , PIXMAN_LE_r8g8b8 }, + {DRM_FORMAT_ARGB8888 , PIXMAN_LE_a8r8g8b8 }, + {DRM_FORMAT_XRGB8888 , PIXMAN_LE_x8r8g8b8 } + }; +int i; + +for (i =0 ; i <ARRAY_SIZE (map); i++) { +if (drm_format == map[i].drm_format) { +return map[i].pixman; + } + } +return 0 ; +} +int qemu_pixman_get_type (int rshift,int gshift,int bshift) {int type =PIXMAN_TYPE_OTHER ;
Signature · 1 line
2.9.3
Re: [Qemu-devel] [PATCH v8 3/9] ui/pixman: add qemu_drm_format_to_pixman()
Looks good.
Reviewed by: Kirti Wankhede <[email protected]>
Thanks,
Kirti
Quoted 79 lines · Gerd Hoffmann
Map drm fourcc codes to pixman formats.
Signed-off-by Gerd Hoffmann <[email protected]>--- include/ui/qemu-pixman.h | 5 +++++ ui/qemu-pixman.c | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+)include/ui/qemu-pixman.h +5
-0@@ -33,6 +33,8 @@# define PIXMAN_BE_r8g8b8a8 PIXMAN_r8g8b8a8# define PIXMAN_BE_x8b8g8r8 PIXMAN_x8b8g8r8# define PIXMAN_BE_a8b8g8r8 PIXMAN_a8b8g8r8 +# define PIXMAN_LE_r8g8b8 PIXMAN_b8g8r8 +# define PIXMAN_LE_a8r8g8b8 PIXMAN_b8g8r8a8# define PIXMAN_LE_x8r8g8b8 PIXMAN_b8g8r8x8#else # define PIXMAN_BE_r8g8b8 PIXMAN_b8g8r8@@ -44,6 +46,8 @@# define PIXMAN_BE_r8g8b8a8 PIXMAN_a8b8g8r8# define PIXMAN_BE_x8b8g8r8 PIXMAN_r8g8b8x8# define PIXMAN_BE_a8b8g8r8 PIXMAN_r8g8b8a8 +# define PIXMAN_LE_r8g8b8 PIXMAN_r8g8b8 +# define PIXMAN_LE_a8r8g8b8 PIXMAN_a8r8g8b8# define PIXMAN_LE_x8r8g8b8 PIXMAN_x8r8g8b8#endif @@ -51,6 +55,7 @@PixelFormat qemu_pixelformat_from_pixman (pixman_format_code_t format);pixman_format_code_t qemu_default_pixman_format (int bpp,bool native_endian); +pixman_format_code_t qemu_drm_format_to_pixman (uint32_t drm_format);int qemu_pixman_get_type (int rshift,int gshift,int bshift);pixman_format_code_t qemu_pixman_get_format (PixelFormat *pf); bool qemu_pixman_check_format(DisplayChangeListener *dcl,ui/qemu-pixman.c +22
-0@@ -6,6 +6,7 @@#include "qemu/osdep.h" #include "qemu-common.h" #include "ui/console.h" +#include "standard-headers/drm/drm_fourcc.h" PixelFormat qemu_pixelformat_from_pixman (pixman_format_code_t format) {@@ -88,6 +89,27 @@ pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)return 0 ; } +/* Note: drm is little endian, pixman is native endian */ +pixman_format_code_t qemu_drm_format_to_pixman (uint32_t drm_format) +{ +static const struct { +uint32_t drm_format; +pixman_format_code_t pixman; + } map[] = { + {DRM_FORMAT_RGB888 , PIXMAN_LE_r8g8b8 }, + {DRM_FORMAT_ARGB8888 , PIXMAN_LE_a8r8g8b8 }, + {DRM_FORMAT_XRGB8888 , PIXMAN_LE_x8r8g8b8 } + }; +int i; + +for (i =0 ; i <ARRAY_SIZE (map); i++) { +if (drm_format == map[i].drm_format) { +return map[i].pixman; + } + } +return 0 ; +} +int qemu_pixman_get_type (int rshift,int gshift,int bshift) {int type =PIXMAN_TYPE_OTHER ;
PATCH v8 4/9 console: minimal hotplug suport
In reply to Gerd HoffmannThis patch allows to unbind devices from QemuConsoles, using the new graphic_console_close() function. The QemuConsole will show a static display then, saying the device was unplugged. When re-plugging a display later on the QemuConsole will be reused.
Eventually we will allocate and release QemuConsoles dynamically at some point in the future, that'll need more infrastructure though to notify user interfaces (gtk, sdl, spice, ...) about QemuConsoles coming and going.
--- include/ui/console.h | 2 ++ ui/console.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++---- ui/trace-events | 2 ++ 3 files changed, 77 insertions(+), 6 deletions(-)
include/ui/console.h +2 -0
@@ -384,6 +384,7 @@ QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head,void graphic_console_set_hwops (QemuConsole *con,const GraphicHwOps *hw_ops,void *opaque); +void graphic_console_close (QemuConsole *con);void graphic_hw_update (QemuConsole *con);void graphic_hw_invalidate (QemuConsole *con);
@@ -396,6 +397,7 @@ QemuConsole *qemu_console_lookup_by_index(unsigned int index);QemuConsole *qemu_console_lookup_by_device (DeviceState *dev,uint32_t head);QemuConsole *qemu_console_lookup_by_device_name (const char *device_id,uint32_t head,Error **errp); +QemuConsole *qemu_console_lookup_unused (void );bool qemu_console_is_visible (QemuConsole *con);bool qemu_console_is_graphic (QemuConsole *con);bool qemu_console_is_fixedsize (QemuConsole *con);
ui/console.c +73 -6
111 lines not on this page · raw message
ui/trace-events +2 -0
@@ -2,6 +2,8 @@ # ui/console.c console_gfx_new(void) "" +console_gfx_reuse(int index) "%d" +console_gfx_close(int index) "%d" console_putchar_csi(int esc_param0, int esc_param1, int ch, int nb_esc_params) "escape sequence CSI%d;%d%c, %d parameters" console_putchar_unhandled(int ch) "unhandled escape character '%c'" console_txt_new(int w, int h) "%dx%d"
Signature · 1 line
2.9.3
PATCH v8 5/9 secondary-vga: properly close QemuConsole on unplug
In reply to Gerd HoffmannUsing the new graphic_console_close() function.
--- hw/display/vga-pci.c | 9 +++++++++ 1 file changed, 9 insertions(+)
hw/display/vga-pci.c +9 -0
@@ -292,6 +292,14 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)pci_register_bar (&d->dev,2 ,PCI_BASE_ADDRESS_SPACE_MEMORY , &d->mmio); } +static void pci_secondary_vga_exit (PCIDevice *dev) +{ +PCIVGAState *d =PCI_VGA (dev); +VGACommonState *s = &d->vga; + +graphic_console_close (s->con); +} +static void pci_secondary_vga_init (Object *obj) {/* Expose framebuffer byteorder via QOM */
@@ -361,6 +369,7 @@ static void secondary_class_init(ObjectClass *klass, void *data)PCIDeviceClass *k =PCI_DEVICE_CLASS (klass); k->realize = pci_secondary_vga_realize; + k->exit = pci_secondary_vga_exit; k->class_id =PCI_CLASS_DISPLAY_OTHER ; dc->props = secondary_pci_properties; dc->reset = pci_secondary_vga_reset;
Signature · 1 line
2.9.3
[Qemu-devel] Memory corruption with secondary-vga (was: [PATCH v8 5/9] secondary-vga: properly close QemuConsole on unplug)
Quoted 27 lines · Gerd Hoffmann
Using the new
graphic_console_close()function.Signed-off-by Gerd Hoffmann <[email protected]>--- hw/display/vga-pci.c | 9 +++++++++ 1 file changed, 9 insertions(+)hw/display/vga-pci.c +8
-0@@ -292,6 +292,14 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)pci_register_bar (&d->dev,2 ,PCI_BASE_ADDRESS_SPACE_MEMORY , &d->mmio); } +static void pci_secondary_vga_exit (PCIDevice *dev) +{ +PCIVGAState *d =PCI_VGA (dev); +VGACommonState *s = &d->vga; + +graphic_console_close (s->con); +} +static void pci_secondary_vga_init (Object *obj) {/* Expose framebuffer byteorder via QOM */
hw/display/vga-pci.c static void secondary_class_init(ObjectClass *klass, void *data) · line 372
Quoted 4 lines
hw/display/vga-pci.c +1
-0@@ -361,6 +369,7 @@ static void secondary_class_init(ObjectClass *klass, void *data)PCIDeviceClass *k =PCI_DEVICE_CLASS (klass); k->realize = pci_secondary_vga_realize; + k->exit = pci_secondary_vga_exit;
Hi Gerd,
not sure what is exactly happening here, but this patch introduced a memory corruption problem. I can trigger it like this:
$ valgrind mips-softmmu/qemu-system-mips -accel qtest -monitor stdio ==12739== Memcheck, a memory error detector ==12739== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==12739== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==12739== Command: mips-softmmu/qemu-system-mips -accel qtest -monitor stdio ==12739== QEMU 2.12.50 monitor - type 'help' for more information (qemu) device_add secondary-vga Unsupported bus. Bus doesn't have property 'acpi-pcihp-bsel' set (qemu) dump-guest-memory /dev/null 0 4096 ==12739== Invalid read of size 8 ==12739== at 0x6AFCD5: object_dynamic_cast (object.c:613) ==12739== by 0x6AFCD5: object_resolve_abs_path (object.c:1721) ==12739== by 0x6AFD30: object_resolve_partial_path (object.c:1745) ==12739== by 0x6AFD92: object_resolve_partial_path (object.c:1755) ==12739== by 0x6AFD92: object_resolve_partial_path (object.c:1755) ==12739== by 0x6AFD92: object_resolve_partial_path (object.c:1755) ==12739== by 0x6AFE61: object_resolve_path_type (object.c:1784) ==12739== by 0x42992F: vmcoreinfo_find (vmcoreinfo.h:41) ==12739== by 0x42992F: dump_init (dump.c:1643) ==12739== by 0x42992F: qmp_dump_guest_memory (dump.c:1998) ==12739== by 0x50B6EC: hmp_dump_guest_memory (hmp.c:2051) ==12739== by 0x4153AA: handle_hmp_command (monitor.c:3455) ==12739== by 0x4166BB: monitor_command_cb (monitor.c:4347) ==12739== by 0x7A35C7: readline_handle_byte (readline.c:393) ==12739== by 0x4154E6: monitor_read (monitor.c:4330) ==12739== Address 0x231faf40 is 16 bytes inside a block of size 256 free'd ==12739== at 0x4C2ACBD: free (vg_replace_malloc.c:530) ==12739== by 0x89F26B6: pixman_image_unref (in /usr/lib64/libpixman-1.so.0.34.0) ==12739== by 0x689154: qemu_pixman_glyph_render (qemu-pixman.c:266) ==12739== by 0x683FFE: vga_putcharxy.isra.7 (console.c:469) ==12739== by 0x68551C: console_refresh (console.c:601) ==12739== by 0x684841: text_console_update_cursor (console.c:2160) ==12739== by 0x78F8C0: timerlist_run_timers (qemu-timer.c:536) ==12739== by 0x78FBA5: qemu_clock_run_timers (qemu-timer.c:547) ==12739== by 0x78FBA5: qemu_clock_run_all_timers (qemu-timer.c:674) ==12739== by 0x790099: main_loop_wait (main-loop.c:503) ==12739== by 0x4F2BF1: main_loop (vl.c:1848) ==12739== by 0x3C6C69: main (vl.c:4600) ==12739== Block was alloc'd at ==12739== at 0x4C29BC3: malloc (vg_replace_malloc.c:299) ==12739== by 0x89F267A: ??? (in /usr/lib64/libpixman-1.so.0.34.0) ==12739== by 0x89FF2FD: pixman_image_create_solid_fill (in /usr/lib64/libpixman-1.so.0.34.0) ==12739== by 0x68909A: qemu_pixman_glyph_render (qemu-pixman.c:255) ==12739== by 0x683FFE: vga_putcharxy.isra.7 (console.c:469) ==12739== by 0x68551C: console_refresh (console.c:601) ==12739== by 0x684841: text_console_update_cursor (console.c:2160) ==12739== by 0x78F8C0: timerlist_run_timers (qemu-timer.c:536) ==12739== by 0x78FBA5: qemu_clock_run_timers (qemu-timer.c:547) ==12739== by 0x78FBA5: qemu_clock_run_all_timers (qemu-timer.c:674) ==12739== by 0x790099: main_loop_wait (main-loop.c:503) ==12739== by 0x4F2BF1: main_loop (vl.c:1848) ==12739== by 0x3C6C69: main (vl.c:4600) ...
Thomas
PATCH v8 6/9 vfio/common: cleanup in vfio_region_finalize
In reply to Gerd Hoffmann--- hw/vfio/common.c | 7 +++++++ 1 file changed, 7 insertions(+)
hw/vfio/common.c +7 -0
@@ -858,6 +858,13 @@ void vfio_region_finalize(VFIORegion *region)g_free (region->mmaps);trace_vfio_region_finalize (region->vbasedev->name, region->nr); + + region->mem =NULL ; + region->mmaps =NULL ; + region->nr_mmaps =0 ; + region->size =0 ; + region->flags =0 ; + region->nr =0 ; }void vfio_region_mmaps_set_enabled (VFIORegion *region,bool enabled)
Signature · 1 line
2.9.3
Re: [Qemu-devel] [PATCH v8 6/9] vfio/common: cleanup in vfio_region_finalize
Looks good.
Reviewed by: Kirti Wankhede <[email protected]>
Thanks,
Kirti
Quoted 24 lines · Gerd Hoffmann
Signed-off-by Gerd Hoffmann <[email protected]>--- hw/vfio/common.c | 7 +++++++ 1 file changed, 7 insertions(+)hw/vfio/common.c +7
-0@@ -858,6 +858,13 @@ void vfio_region_finalize(VFIORegion *region)g_free (region->mmaps);trace_vfio_region_finalize (region->vbasedev->name, region->nr); + + region->mem =NULL ; + region->mmaps =NULL ; + region->nr_mmaps =0 ; + region->size =0 ; + region->flags =0 ; + region->nr =0 ; }void vfio_region_mmaps_set_enabled (VFIORegion *region,bool enabled)
PATCH v8 7/9 vfio/display: core & wireup
In reply to Gerd HoffmannInfrastructure for display support. Must be enabled using 'display' property.
--- hw/vfio/pci.h | 4 ++++ hw/vfio/display.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/pci.c | 10 +++++++++ hw/vfio/Makefile.objs | 2 +- 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 hw/vfio/display.c
hw/vfio/pci.h +4 -0
@@ -133,6 +133,7 @@ typedef struct VFIOPCIDevice {#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2#define VFIO_FEATURE_ENABLE_IGD_OPREGION \ (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT) +OnOffAuto display;int32_t bootindex;uint32_t igd_gms;OffAutoPCIBAR msix_relo;
@@ -174,4 +175,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,struct vfio_region_info *info, Error **errp); +int vfio_display_probe (VFIOPCIDevice *vdev,Error **errp); +void vfio_display_finalize (VFIOPCIDevice *vdev); +#endif /* HW_VFIO_VFIO_PCI_H */
hw/vfio/display.c new file +56 -0
56 lines not on this page · raw message
hw/vfio/pci.c +10 -0
@@ -3015,6 +3015,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) } } +if (vdev->display !=ON_OFF_AUTO_OFF ) { + ret =vfio_display_probe (vdev, errp); +if (ret) { + goto out_teardown; + } + } +vfio_register_err_notifier (vdev);vfio_register_req_notifier (vdev);vfio_setup_resetfn_quirk (vdev);
@@ -3035,6 +3042,7 @@ static void vfio_instance_finalize(Object *obj)VFIOPCIDevice *vdev =DO_UPCAST (VFIOPCIDevice, pdev, pci_dev);VFIOGroup *group = vdev->vbasedev.group; +vfio_display_finalize (vdev);vfio_bars_finalize (vdev);g_free (vdev->emulated_config_bits);g_free (vdev->rom);
@@ -3123,6 +3131,8 @@ static void vfio_instance_init(Object *obj)static Property vfio_pci_dev_properties[] = {DEFINE_PROP_PCI_HOST_DEVADDR ("host" , VFIOPCIDevice, host),DEFINE_PROP_STRING ("sysfsdev" , VFIOPCIDevice, vbasedev.sysfsdev), +DEFINE_PROP_ON_OFF_AUTO ("display" , VFIOPCIDevice, + display,ON_OFF_AUTO_AUTO ),DEFINE_PROP_UINT32 ("x-intx-mmap-timeout-ms" , VFIOPCIDevice, intx.mmap_timeout,1100 ), DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,
hw/vfio/Makefile.objs +1 -1
@@ -1,6 +1,6 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o -obj-$(CONFIG_PCI) += pci.o pci-quirks.o +obj-$(CONFIG_PCI) += pci.o pci-quirks.o display.o obj-$(CONFIG_VFIO_CCW) += ccw.o obj-$(CONFIG_SOFTMMU) += platform.o obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
Signature · 1 line
2.9.3
Re: [Qemu-devel] [PATCH v8 7/9] vfio/display: core & wireup
Reviewed By: Kirti Wankhede <[email protected]>
Thanks,
Kirti
Quoted 142 lines · Gerd Hoffmann
Infrastructure for display support. Must be enabled using 'display' property.
Signed-off-by Gerd Hoffmann <[email protected]>--- hw/vfio/pci.h | 4 ++++ hw/vfio/display.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/pci.c | 10 +++++++++ hw/vfio/Makefile.objs | 2 +- 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 hw/vfio/display.chw/vfio/pci.h +4
-0@@ -133,6 +133,7 @@ typedef struct VFIOPCIDevice {#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2#define VFIO_FEATURE_ENABLE_IGD_OPREGION \ (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT) +OnOffAuto display;int32_t bootindex;uint32_t igd_gms;OffAutoPCIBAR msix_relo;@@ -174,4 +175,7 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,struct vfio_region_info *info, Error **errp); +int vfio_display_probe (VFIOPCIDevice *vdev,Error **errp); +void vfio_display_finalize (VFIOPCIDevice *vdev); +#endif /* HW_VFIO_VFIO_PCI_H */ hw/vfio/display.c new file +56
-0@@ -0,0 +1,56 @@ +/* +* display support for mdev based vgpu devices +* +* Copyright Red Hat, Inc. 2017 +* +* Authors: +* Gerd Hoffmann +* +* This work is licensed under the terms of the GNU GPL, version 2. See +* the COPYING file in the top-level directory. +*/ + +#include "qemu/osdep.h" +#include <linux/vfio.h> +#include <sys/ioctl.h> + +#include "sysemu/sysemu.h" +#include "ui/console.h" +#include "qapi/error.h" +#include "pci.h" + +int vfio_display_probe (VFIOPCIDevice *vdev,Error **errp) +{ +struct vfio_device_gfx_plane_info probe; +int ret; + +memset (&probe,0 ,sizeof (probe)); + probe.argsz =sizeof (probe); + probe.flags =VFIO_GFX_PLANE_TYPE_PROBE |VFIO_GFX_PLANE_TYPE_DMABUF ; + ret =ioctl (vdev->vbasedev.fd,VFIO_DEVICE_QUERY_GFX_PLANE , &probe); +if (ret ==0 ) { +error_setg (errp,"vfio-display: dmabuf support not implemented yet" ); +return -1 ; + } + +memset (&probe,0 ,sizeof (probe)); + probe.argsz =sizeof (probe); + probe.flags =VFIO_GFX_PLANE_TYPE_PROBE |VFIO_GFX_PLANE_TYPE_REGION ; + ret =ioctl (vdev->vbasedev.fd,VFIO_DEVICE_QUERY_GFX_PLANE , &probe); +if (ret ==0 ) { +error_setg (errp,"vfio-display: region support not implemented yet" ); +return -1 ; + } + +if (vdev->display ==ON_OFF_AUTO_AUTO ) { +/* not an error in automatic mode */ +return 0 ; + } + +error_setg (errp,"vfio: device doesn't support any (known) display method" ); +return -1 ; +} + +void vfio_display_finalize (VFIOPCIDevice *vdev) +{ +}hw/vfio/pci.c +10
-0@@ -3015,6 +3015,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) } } +if (vdev->display !=ON_OFF_AUTO_OFF ) { + ret =vfio_display_probe (vdev, errp); +if (ret) { + goto out_teardown; + } + } +vfio_register_err_notifier (vdev);vfio_register_req_notifier (vdev);vfio_setup_resetfn_quirk (vdev);@@ -3035,6 +3042,7 @@ static void vfio_instance_finalize(Object *obj)VFIOPCIDevice *vdev =DO_UPCAST (VFIOPCIDevice, pdev, pci_dev);VFIOGroup *group = vdev->vbasedev.group; +vfio_display_finalize (vdev);vfio_bars_finalize (vdev);g_free (vdev->emulated_config_bits);g_free (vdev->rom);@@ -3123,6 +3131,8 @@ static void vfio_instance_init(Object *obj)static Property vfio_pci_dev_properties[] = {DEFINE_PROP_PCI_HOST_DEVADDR ("host" , VFIOPCIDevice, host),DEFINE_PROP_STRING ("sysfsdev" , VFIOPCIDevice, vbasedev.sysfsdev), +DEFINE_PROP_ON_OFF_AUTO ("display" , VFIOPCIDevice, + display,ON_OFF_AUTO_AUTO ),DEFINE_PROP_UINT32 ("x-intx-mmap-timeout-ms" , VFIOPCIDevice, intx.mmap_timeout,1100 ), DEFINE_PROP_BIT("x-vga", VFIOPCIDevice, features,hw/vfio/Makefile.objs +1
-1@@ -1,6 +1,6 @@ ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o -obj-$(CONFIG_PCI) += pci.o pci-quirks.o +obj-$(CONFIG_PCI) += pci.o pci-quirks.o display.o obj-$(CONFIG_VFIO_CCW) += ccw.o obj-$(CONFIG_SOFTMMU) += platform.o obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o
PATCH v8 8/9 vfio/display: adding region support
In reply to Gerd HoffmannWire up region-based display.
--- hw/vfio/pci.h | 1 + include/hw/vfio/vfio-common.h | 8 +++ hw/vfio/display.c | 117 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 124 insertions(+), 2 deletions(-)
hw/vfio/pci.h +1 -0
@@ -148,6 +148,7 @@ typedef struct VFIOPCIDevice {bool no_kvm_msi;bool no_kvm_msix;bool no_geforce_quirks; +VFIODisplay *dpy; } VFIOPCIDevice;uint32_t vfio_pci_read_config (PCIDevice *pdev,uint32_t addr,int len);
include/hw/vfio/vfio-common.h +8 -0
@@ -142,6 +142,14 @@ typedef struct VFIOGroup {QLIST_ENTRY (VFIOGroup) container_next; } VFIOGroup; +typedef struct VFIODisplay { +QemuConsole *con; +struct { +VFIORegion buffer; +DisplaySurface *surface; + } region; +}VFIODisplay ; +void vfio_put_base_device (VFIODevice *vbasedev);void vfio_disable_irqindex (VFIODevice *vbasedev,int index);void vfio_unmask_single_irqindex (VFIODevice *vbasedev,int index);
hw/vfio/display.c +115 -2
133 lines not on this page · raw message
Signature · 1 line
2.9.3
Re: [Qemu-devel] [PATCH v8 8/9] vfio/display: adding region support
Reviewed By: Kirti Wankhede <[email protected]>
Thanks,
Kirti
Quoted 181 lines · Gerd Hoffmann
Wire up region-based display.
Signed-off-by Gerd Hoffmann <[email protected]>--- hw/vfio/pci.h | 1 + include/hw/vfio/vfio-common.h | 8 +++ hw/vfio/display.c | 117 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 124 insertions(+), 2 deletions(-)hw/vfio/pci.h +1
-0@@ -148,6 +148,7 @@ typedef struct VFIOPCIDevice {bool no_kvm_msi;bool no_kvm_msix;bool no_geforce_quirks; +VFIODisplay *dpy; } VFIOPCIDevice;uint32_t vfio_pci_read_config (PCIDevice *pdev,uint32_t addr,int len);include/hw/vfio/vfio-common.h +8
-0@@ -142,6 +142,14 @@ typedef struct VFIOGroup {QLIST_ENTRY (VFIOGroup) container_next; } VFIOGroup; +typedef struct VFIODisplay { +QemuConsole *con; +struct { +VFIORegion buffer; +DisplaySurface *surface; + } region; +}VFIODisplay ; +void vfio_put_base_device (VFIODevice *vbasedev);void vfio_disable_irqindex (VFIODevice *vbasedev,int index);void vfio_unmask_single_irqindex (VFIODevice *vbasedev,int index);hw/vfio/display.c +115
-2@@ -19,6 +19,113 @@#include "qapi/error.h" #include "pci.h" +/* ---------------------------------------------------------------------- */ + +static void vfio_display_region_update (void *opaque) +{ +VFIOPCIDevice *vdev = opaque; +VFIODisplay *dpy = vdev->dpy; +struct vfio_device_gfx_plane_info plane = { + .argsz =sizeof (plane), + .flags =VFIO_GFX_PLANE_TYPE_REGION + }; +pixman_format_code_t format; +int ret; + + ret =ioctl (vdev->vbasedev.fd,VFIO_DEVICE_QUERY_GFX_PLANE , &plane); +if (ret <0 ) { +error_report ("ioctl VFIO_DEVICE_QUERY_GFX_PLANE: %s" , +strerror (errno)); +return ; + } +if (!plane.drm_format || !plane.size) { +return ; + } + format =qemu_drm_format_to_pixman (plane.drm_format); +if (!format) { +return ; + } + +if (dpy->region.buffer.size && + dpy->region.buffer.nr != plane.region_index) { +/* region changed */ +vfio_region_exit (&dpy->region.buffer); +vfio_region_finalize (&dpy->region.buffer); + dpy->region.surface =NULL ; + } + +if (dpy->region.surface && + (surface_width (dpy->region.surface) != plane.width || +surface_height (dpy->region.surface) != plane.height || +surface_format (dpy->region.surface) != format)) { +/* size changed */ + dpy->region.surface =NULL ; + } + +if (!dpy->region.buffer.size) { +/* mmap region */ + ret =vfio_region_setup (OBJECT (vdev), &vdev->vbasedev, + &dpy->region.buffer, + plane.region_index, +"display" ); +if (ret !=0 ) { +error_report ("%s: vfio_region_setup(%d): %s" , + __func__, plane.region_index,strerror (-ret)); + goto err; + } + ret =vfio_region_mmap (&dpy->region.buffer); +if (ret !=0 ) { +error_report ("%s: vfio_region_mmap(%d): %s" , __func__, + plane.region_index,strerror (-ret)); + goto err; + } +assert (dpy->region.buffer.mmaps[0 ].mmap !=NULL ); + } + +if (dpy->region.surface ==NULL ) { +/* create surface */ + dpy->region.surface =qemu_create_displaysurface_from + (plane.width, plane.height, format, + plane.stride, dpy->region.buffer.mmaps[0 ].mmap); +dpy_gfx_replace_surface (dpy->con, dpy->region.surface); + } + +/* full screen update */ +dpy_gfx_update (dpy->con,0 ,0 , +surface_width (dpy->region.surface), +surface_height (dpy->region.surface)); +return ; + +err: +vfio_region_exit (&dpy->region.buffer); +vfio_region_finalize (&dpy->region.buffer); +} + +static const GraphicHwOps vfio_display_region_ops = { + .gfx_update = vfio_display_region_update, +}; + +static int vfio_display_region_init (VFIOPCIDevice *vdev,Error **errp) +{ + vdev->dpy =g_new0 (VFIODisplay,1 ); + vdev->dpy->con =graphic_console_init (DEVICE (vdev),0 , + &vfio_display_region_ops, + vdev); +return 0 ; +} + +static void vfio_display_region_exit (VFIODisplay *dpy) +{ +if (!dpy->region.buffer.size) { +return ; + } + +vfio_region_exit (&dpy->region.buffer); +vfio_region_finalize (&dpy->region.buffer); +} + +/* ---------------------------------------------------------------------- */ +int vfio_display_probe (VFIOPCIDevice *vdev,Error **errp) {struct vfio_device_gfx_plane_info probe;@@ -38,8 +145,7 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp) probe.flags =VFIO_GFX_PLANE_TYPE_PROBE |VFIO_GFX_PLANE_TYPE_REGION ; ret =ioctl (vdev->vbasedev.fd,VFIO_DEVICE_QUERY_GFX_PLANE , &probe);if (ret ==0 ) { -error_setg (errp,"vfio-display: region support not implemented yet" ); -return -1 ; +return vfio_display_region_init (vdev, errp); }if (vdev->display ==ON_OFF_AUTO_AUTO ) {@@ -53,4 +159,11 @@ int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp)void vfio_display_finalize (VFIOPCIDevice *vdev) { +if (!vdev->dpy) { +return ; + } + +graphic_console_close (vdev->dpy->con); +vfio_display_region_exit (vdev->dpy); +g_free (vdev->dpy); }
PATCH v8 9/9 vfio/display: adding dmabuf support
In reply to Gerd HoffmannWire up dmabuf-based display.
--- include/hw/vfio/vfio-common.h | 14 ++++ hw/vfio/display.c | 182 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 194 insertions(+), 2 deletions(-)
include/hw/vfio/vfio-common.h +14 -0
@@ -26,6 +26,7 @@#include "exec/memory.h" #include "qemu/queue.h" #include "qemu/notify.h" +#include "ui/console.h" #ifdef CONFIG_LINUX #include <linux/vfio.h> #endif
@@ -142,12 +143,25 @@ typedef struct VFIOGroup {QLIST_ENTRY (VFIOGroup) container_next; } VFIOGroup; +typedef struct VFIODMABuf { +QemuDmaBuf buf; +uint32_t pos_x, pos_y, pos_updates; +uint32_t hot_x, hot_y, hot_updates; +int dmabuf_id; +QTAILQ_ENTRY (VFIODMABuf) next; +}VFIODMABuf ; +typedef struct VFIODisplay {QemuConsole *con;struct {VFIORegion buffer;DisplaySurface *surface; } region; +struct { + QTAILQ_HEAD(, VFIODMABuf) bufs; +VFIODMABuf *primary; +VFIODMABuf *cursor; + } dmabuf; }VFIODisplay ;void vfio_put_base_device (VFIODevice *vbasedev);
hw/vfio/display.c +180 -2
200 lines not on this page · raw message
Signature · 1 line
2.9.3
Quoted 1 line · Gerd Hoffmann
This series adds support for a vgpu display to the qemu vfio code.
Ok, for anyone who wants play with this, the requirements:
qemu
====
The repo at git://git.kraxel.org/qemu has a sirius/dmabufs-merge branch with this series and spice patches and gtk patches merged.
The traditional work/intel-vgpu branch has been updated too (it is the same as sirius/dmabufs-merge plus some work-in-progress patches).
host kernel
===========
You need a 4.16-rc kernel. The intel graphics driver comes with mdev support. Needs gen5+ hardware (broadwell, skylake, kaby-lake). Not sure about nvidia.
Pure software drivers are available from
git://git.kraxel.org/cgit/linux vfio-sample-display
There are three kernel modules in samples/vfio-mdev:
(1) mdpy.ko. Very simple display device. Fixed framebuffer and resolution. Uses the region-based vfio display interface.
(2) mbochs.ko. Mimics qemu vga with bochs dispi vbe interface. Doesn't emulate any legacy vga. But good enough to make the bochs-drm.ko driver happy. Uses the dmabuf-based vfio display interface. Zero-copy display updates.
(3) mdpy-fb.ko. Guest framebuffer driver for (1).
guest kernel
============
intel-gvt: 4.9+ I think. nvidia: dunno. mbochs: 3.14+ should work. mdpy: The vfio-sample-display branch above if you want see guest
display updates. Without that you'll see a static test pattern.
booting the guest
=================
Create mdev devices and use "-device vfio-pci,..." as usual, see
https://www.kernel.org/doc/Documentation/vfio-mediated-device.txt
For mdev devices using dmabufs you need opengl support. So start qemu with spice or gtk ui and opengl enabled:
qemu -display gtk,gl=on
qemu -spice gl=on,$otherargs
When using a display without opengl support you can use egl-headless to handle the opengl rendering and texture readout (which of course adds some overhead):
qemu -display egl-headless -vga $display qemu -display egl-headless -spice gl=off,$otherargs
enjoy,
Gerd