All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support
@ 2016-08-30  3:06 Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4 Jason Wang
                   ` (12 more replies)
  0 siblings, 13 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

Hi all:

As the userspace vitio driver became popular, more and more request
were received for secure DMA environemt (DMAR). So this series tries
to makeDMAR works for virtio/vhost. The idea is let virtio/vhost
co-work with userspace iommu implememtation. This is done through:

- for virtio, when platform supports IOMMU (VIRTIO_F_IOMMU_PLATFORM),
  virtio will not assume address_space_memory, instead a transport
  specific method were introduced for querying the dma address space
  and dma helpers were used in device emulation codes.
- for vhost, implement a device IOTLB by using device IOTLB API
  supported by recent kernel. With this API, vhost kernel can query
  IOTLB entry for a specified iova from qemu, qemu can invalidate an
  arbitrary range of iova in vhost kernel.

The device IOTLB API is totaly architecture independent, an example
implementation was done with intel iommu by:

- implement basic ATS (Address Translation Service) for virtio-pci,
  this will make device IOTLB visible for iommu driver in guest.
- implement device IOTLB descriptor processing in intel iommu (enabled
  through device-iotlb=on), and trigger the device IOTLB invalidation
  in vhost through iommu notifier.

It could be easily ported to other IOMMU or architecture even if it
doesn't support device IOTLB. (e.g just invalidate the vhost IOTLB
during IOMMU IOTLB invalidation).

Test was done by:

- intel_iommu=on/strict in guest.
- vfio l2fwd in guest.

This main use case is the programs that use fixed mapping in guest
(e.g dpdk). If 1G hugepage were used in guest, thanks to the SLLPS
support, we can get 100% TLB hit rate for l2fwd in guest.

For the normal kernel driver which uses lots of dynamic mapping and
unmapping, we may see performance penalty, this could be optimized in
the future.

TODO:
- non ATS support (userspace IOTLB snooping)
- more platforms and IOMMU support
- performance optimizations

Changes from RFC:
- rebase to HEAD
- switch to use new vhost device IOTLB API
- use the new feature bit VIRITO_F_IOMMU_PLATFORM
- finalize basic ATS implementation
- add ATSR for Root port ATS transaction
- fix the iommu notifier handling during unregistering
- use snprintf() in patch 3
- correc the loop in address_space_get_iotlb_entry()
- small tweak on the address calculation during device iotlb
  descriptor processing.

Please reivew.

Jason Wang (10):
  linux-headers: update to 4.8-rc4
  virtio: convert to use DMA api
  intel_iommu: name vtd address space with devfn
  intel_iommu: allocate new key when creating new address space
  exec: introduce address_space_get_iotlb_entry()
  intel_iommu: support device iotlb descriptor
  virtio-pci: address space translation service (ATS) support
  acpi: add ATSR for q35
  memory: handle alias for iommu notifier
  vhost_net: device IOTLB support

Peter Xu (1):
  Revert "intel_iommu: Throw hw_error on notify_started"

 exec.c                                             |  33 +++++
 hw/block/virtio-blk.c                              |   2 +-
 hw/char/virtio-serial-bus.c                        |   3 +-
 hw/i386/acpi-build.c                               |   9 ++
 hw/i386/intel_iommu.c                              | 100 +++++++++++---
 hw/i386/intel_iommu_internal.h                     |  13 +-
 hw/i386/x86-iommu.c                                |  17 +++
 hw/pci/pcie.c                                      |  16 +++
 hw/scsi/virtio-scsi.c                              |   4 +-
 hw/virtio/vhost-backend.c                          | 104 ++++++++++++++
 hw/virtio/vhost.c                                  | 149 +++++++++++++++++----
 hw/virtio/virtio-pci.c                             |  21 +++
 hw/virtio/virtio-pci.h                             |   4 +
 hw/virtio/virtio.c                                 |  62 +++++----
 include/exec/memory.h                              |   6 +
 include/hw/acpi/acpi-defs.h                        |  12 ++
 include/hw/i386/x86-iommu.h                        |   1 +
 include/hw/pci/pcie.h                              |   4 +
 include/hw/virtio/vhost-backend.h                  |  14 ++
 include/hw/virtio/vhost.h                          |   4 +
 include/hw/virtio/virtio-access.h                  |  87 ++++++++++--
 include/hw/virtio/virtio-bus.h                     |   1 +
 include/hw/virtio/virtio.h                         |   8 +-
 include/standard-headers/linux/input-event-codes.h |  32 +++++
 include/standard-headers/linux/input.h             |   1 +
 include/standard-headers/linux/pci_regs.h          |   1 +
 include/standard-headers/linux/virtio_config.h     |  10 +-
 include/standard-headers/linux/virtio_ids.h        |   1 +
 include/standard-headers/linux/virtio_net.h        |   3 +
 linux-headers/asm-arm/kvm.h                        |   4 +-
 linux-headers/asm-arm64/kvm.h                      |   2 +
 linux-headers/asm-s390/kvm.h                       |  41 ++++++
 linux-headers/asm-x86/unistd_x32.h                 |   4 +-
 linux-headers/linux/kvm.h                          |  18 ++-
 linux-headers/linux/vhost.h                        |  33 +++++
 memory.c                                           |   9 ++
 net/tap.c                                          |   1 +
 37 files changed, 740 insertions(+), 94 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-09-05  1:24   ` Wei Xu
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 include/standard-headers/linux/input-event-codes.h | 32 +++++++++++++++++
 include/standard-headers/linux/input.h             |  1 +
 include/standard-headers/linux/virtio_config.h     | 10 +++++-
 include/standard-headers/linux/virtio_ids.h        |  1 +
 include/standard-headers/linux/virtio_net.h        |  3 ++
 linux-headers/asm-arm/kvm.h                        |  4 +--
 linux-headers/asm-arm64/kvm.h                      |  2 ++
 linux-headers/asm-s390/kvm.h                       | 41 ++++++++++++++++++++++
 linux-headers/asm-x86/unistd_x32.h                 |  4 +--
 linux-headers/linux/kvm.h                          | 18 ++++++++--
 linux-headers/linux/vhost.h                        | 33 +++++++++++++++++
 11 files changed, 142 insertions(+), 7 deletions(-)

diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
index 354f0de..5c10f7e 100644
--- a/include/standard-headers/linux/input-event-codes.h
+++ b/include/standard-headers/linux/input-event-codes.h
@@ -611,6 +611,37 @@
 #define KEY_KBDINPUTASSIST_ACCEPT		0x264
 #define KEY_KBDINPUTASSIST_CANCEL		0x265
 
+/* Diagonal movement keys */
+#define KEY_RIGHT_UP			0x266
+#define KEY_RIGHT_DOWN			0x267
+#define KEY_LEFT_UP			0x268
+#define KEY_LEFT_DOWN			0x269
+
+#define KEY_ROOT_MENU			0x26a /* Show Device's Root Menu */
+/* Show Top Menu of the Media (e.g. DVD) */
+#define KEY_MEDIA_TOP_MENU		0x26b
+#define KEY_NUMERIC_11			0x26c
+#define KEY_NUMERIC_12			0x26d
+/*
+ * Toggle Audio Description: refers to an audio service that helps blind and
+ * visually impaired consumers understand the action in a program. Note: in
+ * some countries this is referred to as "Video Description".
+ */
+#define KEY_AUDIO_DESC			0x26e
+#define KEY_3D_MODE			0x26f
+#define KEY_NEXT_FAVORITE		0x270
+#define KEY_STOP_RECORD			0x271
+#define KEY_PAUSE_RECORD		0x272
+#define KEY_VOD				0x273 /* Video on Demand */
+#define KEY_UNMUTE			0x274
+#define KEY_FASTREVERSE			0x275
+#define KEY_SLOWREVERSE			0x276
+/*
+ * Control a data application associated with the currently viewed channel,
+ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
+ */
+#define KEY_DATA			0x275
+
 #define BTN_TRIGGER_HAPPY		0x2c0
 #define BTN_TRIGGER_HAPPY1		0x2c0
 #define BTN_TRIGGER_HAPPY2		0x2c1
@@ -749,6 +780,7 @@
 #define SW_ROTATE_LOCK		0x0c  /* set = rotate locked/disabled */
 #define SW_LINEIN_INSERT	0x0d  /* set = inserted */
 #define SW_MUTE_DEVICE		0x0e  /* set = device disabled */
+#define SW_PEN_INSERTED		0x0f  /* set = pen inserted */
 #define SW_MAX_			0x0f
 #define SW_CNT			(SW_MAX_+1)
 
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
index a52b202..7361a16 100644
--- a/include/standard-headers/linux/input.h
+++ b/include/standard-headers/linux/input.h
@@ -244,6 +244,7 @@ struct input_mask {
 #define BUS_ATARI		0x1B
 #define BUS_SPI			0x1C
 #define BUS_RMI			0x1D
+#define BUS_CEC			0x1E
 
 /*
  * MT_TOOL types
diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h
index b30d0cb..b777069 100644
--- a/include/standard-headers/linux/virtio_config.h
+++ b/include/standard-headers/linux/virtio_config.h
@@ -49,7 +49,7 @@
  * transport being used (eg. virtio_ring), the rest are per-device feature
  * bits. */
 #define VIRTIO_TRANSPORT_F_START	28
-#define VIRTIO_TRANSPORT_F_END		33
+#define VIRTIO_TRANSPORT_F_END		34
 
 #ifndef VIRTIO_CONFIG_NO_LEGACY
 /* Do we get callbacks when the ring is completely used, even if we've
@@ -63,4 +63,12 @@
 /* v1.0 compliant. */
 #define VIRTIO_F_VERSION_1		32
 
+/*
+ * If clear - device has the IOMMU bypass quirk feature.
+ * If set - use platform tools to detect the IOMMU.
+ *
+ * Note the reverse polarity (compared to most other features),
+ * this is for compatibility with legacy systems.
+ */
+#define VIRTIO_F_IOMMU_PLATFORM		33
 #endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 77925f5..3228d58 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -41,5 +41,6 @@
 #define VIRTIO_ID_CAIF	       12 /* Virtio caif */
 #define VIRTIO_ID_GPU          16 /* virtio GPU */
 #define VIRTIO_ID_INPUT        18 /* virtio input */
+#define VIRTIO_ID_VSOCK        19 /* virtio vsock transport */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
index a78f33e..30ff249 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -35,6 +35,7 @@
 #define VIRTIO_NET_F_CSUM	0	/* Host handles pkts w/ partial csum */
 #define VIRTIO_NET_F_GUEST_CSUM	1	/* Guest handles pkts w/ partial csum */
 #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
+#define VIRTIO_NET_F_MTU	3	/* Initial MTU advice */
 #define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
 #define VIRTIO_NET_F_GUEST_TSO4	7	/* Guest can handle TSOv4 in. */
 #define VIRTIO_NET_F_GUEST_TSO6	8	/* Guest can handle TSOv6 in. */
@@ -73,6 +74,8 @@ struct virtio_net_config {
 	 * Legal values are between 1 and 0x8000
 	 */
 	uint16_t max_virtqueue_pairs;
+	/* Default maximum transmit unit advice */
+	uint16_t mtu;
 } QEMU_PACKED;
 
 /*
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
index c98e4dc..541268c 100644
--- a/linux-headers/asm-arm/kvm.h
+++ b/linux-headers/asm-arm/kvm.h
@@ -139,8 +139,8 @@ struct kvm_arch_memory_slot {
 #define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
 
 #define KVM_REG_ARM_TIMER_CTL		ARM_CP15_REG32(0, 14, 3, 1)
-#define KVM_REG_ARM_TIMER_CNT		ARM_CP15_REG64(1, 14) 
-#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14) 
+#define KVM_REG_ARM_TIMER_CNT		ARM_CP15_REG64(1, 14)
+#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14)
 
 /* Normal registers are mapped as coprocessor 16. */
 #define KVM_REG_ARM_CORE		(0x0010 << KVM_REG_ARM_COPROC_SHIFT)
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
index 7d82d1f..fd5a276 100644
--- a/linux-headers/asm-arm64/kvm.h
+++ b/linux-headers/asm-arm64/kvm.h
@@ -87,9 +87,11 @@ struct kvm_regs {
 /* Supported VGICv3 address types  */
 #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
 #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
+#define KVM_VGIC_ITS_ADDR_TYPE		4
 
 #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
 #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
 
 #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_EL1_32BIT		1 /* CPU running a 32bit VM */
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 09ae5dc..ac63ca6 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
 	__u64 fac_list[256];
 };
 
+#define KVM_S390_VM_CPU_PROCESSOR_FEAT	2
+#define KVM_S390_VM_CPU_MACHINE_FEAT	3
+
+#define KVM_S390_VM_CPU_FEAT_NR_BITS	1024
+#define KVM_S390_VM_CPU_FEAT_ESOP	0
+#define KVM_S390_VM_CPU_FEAT_SIEF2	1
+#define KVM_S390_VM_CPU_FEAT_64BSCAO	2
+#define KVM_S390_VM_CPU_FEAT_SIIF	3
+#define KVM_S390_VM_CPU_FEAT_GPERE	4
+#define KVM_S390_VM_CPU_FEAT_GSLS	5
+#define KVM_S390_VM_CPU_FEAT_IB		6
+#define KVM_S390_VM_CPU_FEAT_CEI	7
+#define KVM_S390_VM_CPU_FEAT_IBS	8
+#define KVM_S390_VM_CPU_FEAT_SKEY	9
+#define KVM_S390_VM_CPU_FEAT_CMMA	10
+#define KVM_S390_VM_CPU_FEAT_PFMFI	11
+#define KVM_S390_VM_CPU_FEAT_SIGPIF	12
+struct kvm_s390_vm_cpu_feat {
+	__u64 feat[16];
+};
+
+#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC	4
+#define KVM_S390_VM_CPU_MACHINE_SUBFUNC		5
+/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
+struct kvm_s390_vm_cpu_subfunc {
+	__u8 plo[32];		/* always */
+	__u8 ptff[16];		/* with TOD-clock steering */
+	__u8 kmac[16];		/* with MSA */
+	__u8 kmc[16];		/* with MSA */
+	__u8 km[16];		/* with MSA */
+	__u8 kimd[16];		/* with MSA */
+	__u8 klmd[16];		/* with MSA */
+	__u8 pckmo[16];		/* with MSA3 */
+	__u8 kmctr[16];		/* with MSA4 */
+	__u8 kmf[16];		/* with MSA4 */
+	__u8 kmo[16];		/* with MSA4 */
+	__u8 pcc[16];		/* with MSA4 */
+	__u8 ppno[16];		/* with MSA5 */
+	__u8 reserved[1824];
+};
+
 /* kvm attributes for crypto */
 #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW	0
 #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW	1
diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
index 0230779..e5aea76 100644
--- a/linux-headers/asm-x86/unistd_x32.h
+++ b/linux-headers/asm-x86/unistd_x32.h
@@ -306,9 +306,7 @@
 #define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
 #define __NR_move_pages (__X32_SYSCALL_BIT + 533)
 #define __NR_preadv (__X32_SYSCALL_BIT + 534)
-#define __NR_preadv2 (__X32_SYSCALL_BIT + 534)
 #define __NR_pwritev (__X32_SYSCALL_BIT + 535)
-#define __NR_pwritev2 (__X32_SYSCALL_BIT + 535)
 #define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
 #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
 #define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
@@ -319,5 +317,7 @@
 #define __NR_io_setup (__X32_SYSCALL_BIT + 543)
 #define __NR_io_submit (__X32_SYSCALL_BIT + 544)
 #define __NR_execveat (__X32_SYSCALL_BIT + 545)
+#define __NR_preadv2 (__X32_SYSCALL_BIT + 546)
+#define __NR_pwritev2 (__X32_SYSCALL_BIT + 547)
 
 #endif /* _ASM_X86_UNISTD_X32_H */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index e60e21b..4806e06 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -866,6 +866,10 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_ARM_PMU_V3 126
 #define KVM_CAP_VCPU_ATTRIBUTES 127
 #define KVM_CAP_MAX_VCPU_ID 128
+#define KVM_CAP_X2APIC_API 129
+#define KVM_CAP_S390_USER_INSTR0 130
+#define KVM_CAP_MSI_DEVID 131
+#define KVM_CAP_PPC_HTM 132
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -878,7 +882,10 @@ struct kvm_irq_routing_msi {
 	__u32 address_lo;
 	__u32 address_hi;
 	__u32 data;
-	__u32 pad;
+	union {
+		__u32 pad;
+		__u32 devid;
+	};
 };
 
 struct kvm_irq_routing_s390_adapter {
@@ -1024,12 +1031,14 @@ struct kvm_one_reg {
 	__u64 addr;
 };
 
+#define KVM_MSI_VALID_DEVID	(1U << 0)
 struct kvm_msi {
 	__u32 address_lo;
 	__u32 address_hi;
 	__u32 data;
 	__u32 flags;
-	__u8  pad[16];
+	__u32 devid;
+	__u8  pad[12];
 };
 
 struct kvm_arm_device_addr {
@@ -1074,6 +1083,8 @@ enum kvm_device_type {
 #define KVM_DEV_TYPE_FLIC		KVM_DEV_TYPE_FLIC
 	KVM_DEV_TYPE_ARM_VGIC_V3,
 #define KVM_DEV_TYPE_ARM_VGIC_V3	KVM_DEV_TYPE_ARM_VGIC_V3
+	KVM_DEV_TYPE_ARM_VGIC_ITS,
+#define KVM_DEV_TYPE_ARM_VGIC_ITS	KVM_DEV_TYPE_ARM_VGIC_ITS
 	KVM_DEV_TYPE_MAX,
 };
 
@@ -1313,4 +1324,7 @@ struct kvm_assigned_msix_entry {
 	__u16 padding[3];
 };
 
+#define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
+#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
+
 #endif /* __LINUX_KVM_H */
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index 571294c..ac7a1f1 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -47,6 +47,32 @@ struct vhost_vring_addr {
 	__u64 log_guest_addr;
 };
 
+/* no alignment requirement */
+struct vhost_iotlb_msg {
+	__u64 iova;
+	__u64 size;
+	__u64 uaddr;
+#define VHOST_ACCESS_RO      0x1
+#define VHOST_ACCESS_WO      0x2
+#define VHOST_ACCESS_RW      0x3
+	__u8 perm;
+#define VHOST_IOTLB_MISS           1
+#define VHOST_IOTLB_UPDATE         2
+#define VHOST_IOTLB_INVALIDATE     3
+#define VHOST_IOTLB_ACCESS_FAIL    4
+	__u8 type;
+};
+
+#define VHOST_IOTLB_MSG 0x1
+
+struct vhost_msg {
+	int type;
+	union {
+		struct vhost_iotlb_msg iotlb;
+		__u8 padding[64];
+	};
+};
+
 struct vhost_memory_region {
 	__u64 guest_phys_addr;
 	__u64 memory_size; /* bytes */
@@ -146,6 +172,8 @@ struct vhost_memory {
 #define VHOST_F_LOG_ALL 26
 /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
 #define VHOST_NET_F_VIRTIO_NET_HDR 27
+/* Vhost have device IOTLB */
+#define VHOST_F_DEVICE_IOTLB 63
 
 /* VHOST_SCSI specific definitions */
 
@@ -175,4 +203,9 @@ struct vhost_scsi_target {
 #define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
 #define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
 
+/* VHOST_VSOCK specific defines */
+
+#define VHOST_VSOCK_SET_GUEST_CID	_IOW(VHOST_VIRTIO, 0x60, __u64)
+#define VHOST_VSOCK_SET_RUNNING		_IOW(VHOST_VIRTIO, 0x61, int)
+
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4 Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30  7:31   ` Cornelia Huck
                     ` (2 more replies)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn Jason Wang
                   ` (10 subsequent siblings)
  12 siblings, 3 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

Currently, all virtio devices bypass IOMMU completely. This is because
address_space_memory is assumed and used during DMA emulation. This
patch converts the virtio core API to use DMA API. This idea is

- introducing a new transport specific helper to query the dma address
  space. (only pci version is implemented).
- query and use this address space during virtio device guest memory
  accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled
  for this device.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Amit Shah <amit.shah@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-block@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/block/virtio-blk.c             |  2 +-
 hw/char/virtio-serial-bus.c       |  3 +-
 hw/scsi/virtio-scsi.c             |  4 ++-
 hw/virtio/virtio-pci.c            | 14 +++++++++
 hw/virtio/virtio.c                | 62 ++++++++++++++++++++++++---------------
 include/hw/virtio/virtio-access.h | 43 ++++++++++++++++++++-------
 include/hw/virtio/virtio-bus.h    |  1 +
 include/hw/virtio/virtio.h        |  8 +++--
 8 files changed, 98 insertions(+), 39 deletions(-)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 331d766..8fd6df7 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -856,7 +856,7 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
             }
         }
 
-        req = qemu_get_virtqueue_element(f, sizeof(VirtIOBlockReq));
+        req = qemu_get_virtqueue_element(vdev, f, sizeof(VirtIOBlockReq));
         virtio_blk_init_request(s, virtio_get_queue(vdev, vq_idx), req);
         req->next = s->rq;
         s->rq = req;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index db57a38..94f19ba 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -682,6 +682,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
 static int fetch_active_ports_list(QEMUFile *f,
                                    VirtIOSerial *s, uint32_t nr_active_ports)
 {
+    VirtIODevice *vdev = VIRTIO_DEVICE(s);
     uint32_t i;
 
     s->post_load = g_malloc0(sizeof(*s->post_load));
@@ -715,7 +716,7 @@ static int fetch_active_ports_list(QEMUFile *f,
             qemu_get_be64s(f, &port->iov_offset);
 
             port->elem =
-                qemu_get_virtqueue_element(f, sizeof(VirtQueueElement));
+                qemu_get_virtqueue_element(vdev, f, sizeof(VirtQueueElement));
 
             /*
              *  Port was throttled on source machine.  Let's
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ce57ef6..4cc7627 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -197,12 +197,14 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
     SCSIBus *bus = sreq->bus;
     VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
     VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
+    VirtIODevice *vdev = VIRTIO_DEVICE(s);
     VirtIOSCSIReq *req;
     uint32_t n;
 
     qemu_get_be32s(f, &n);
     assert(n < vs->conf.num_queues);
-    req = qemu_get_virtqueue_element(f, sizeof(VirtIOSCSIReq) + vs->cdb_size);
+    req = qemu_get_virtqueue_element(vdev, f,
+                                     sizeof(VirtIOSCSIReq) + vs->cdb_size);
     virtio_scsi_init_req(s, vs->cmd_vqs[n], req);
 
     if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 755f921..c10bf55 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1162,6 +1162,14 @@ static int virtio_pci_query_nvectors(DeviceState *d)
     return proxy->nvectors;
 }
 
+static AddressSpace *virtio_pci_get_dma_as(DeviceState *d)
+{
+    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
+    PCIDevice *dev = &proxy->pci_dev;
+
+    return pci_get_address_space(dev);
+}
+
 static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
                                    struct virtio_pci_cap *cap)
 {
@@ -1587,6 +1595,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
     }
 
     if (legacy) {
+        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+            error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
+                       "neither legacy nor transitional device.");
+            return ;
+        }
         /* legacy and transitional */
         pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
                      pci_get_word(config + PCI_VENDOR_ID));
@@ -2452,6 +2465,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
     k->ioeventfd_disabled = virtio_pci_ioeventfd_disabled;
     k->ioeventfd_set_disabled = virtio_pci_ioeventfd_set_disabled;
     k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
+    k->get_dma_as = virtio_pci_get_dma_as;
 }
 
 static const TypeInfo virtio_pci_bus_info = {
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 15ee3a7..99ea97c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -23,6 +23,7 @@
 #include "hw/virtio/virtio-bus.h"
 #include "migration/migration.h"
 #include "hw/virtio/virtio-access.h"
+#include "sysemu/dma.h"
 
 /*
  * The alignment to use between consumer and producer parts of vring.
@@ -122,7 +123,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n)
 static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc,
                             hwaddr desc_pa, int i)
 {
-    address_space_read(&address_space_memory, desc_pa + i * sizeof(VRingDesc),
+    address_space_read(virtio_get_dma_as(vdev), desc_pa + i * sizeof(VRingDesc),
                        MEMTXATTRS_UNSPECIFIED, (void *)desc, sizeof(VRingDesc));
     virtio_tswap64s(vdev, &desc->addr);
     virtio_tswap32s(vdev, &desc->len);
@@ -164,7 +165,7 @@ static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem,
     virtio_tswap32s(vq->vdev, &uelem->id);
     virtio_tswap32s(vq->vdev, &uelem->len);
     pa = vq->vring.used + offsetof(VRingUsed, ring[i]);
-    address_space_write(&address_space_memory, pa, MEMTXATTRS_UNSPECIFIED,
+    address_space_write(virtio_get_dma_as(vq->vdev), pa, MEMTXATTRS_UNSPECIFIED,
                        (void *)uelem, sizeof(VRingUsedElem));
 }
 
@@ -244,6 +245,7 @@ int virtio_queue_empty(VirtQueue *vq)
 static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
                                unsigned int len)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vq->vdev);
     unsigned int offset;
     int i;
 
@@ -251,17 +253,17 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
     for (i = 0; i < elem->in_num; i++) {
         size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
 
-        cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
-                                  elem->in_sg[i].iov_len,
-                                  1, size);
+        dma_memory_unmap(dma_as, elem->in_sg[i].iov_base, elem->in_sg[i].iov_len,
+                         DMA_DIRECTION_FROM_DEVICE, size);
 
         offset += size;
     }
 
     for (i = 0; i < elem->out_num; i++)
-        cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
-                                  elem->out_sg[i].iov_len,
-                                  0, elem->out_sg[i].iov_len);
+        dma_memory_unmap(dma_as, elem->out_sg[i].iov_base,
+                         elem->out_sg[i].iov_len,
+                         DMA_DIRECTION_TO_DEVICE,
+                         elem->out_sg[i].iov_len);
 }
 
 void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
@@ -451,7 +453,8 @@ int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
     return in_bytes <= in_total && out_bytes <= out_total;
 }
 
-static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,
+static void virtqueue_map_desc(VirtIODevice *vdev,
+                               unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,
                                unsigned int max_num_sg, bool is_write,
                                hwaddr pa, size_t sz)
 {
@@ -471,7 +474,10 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
             exit(1);
         }
 
-        iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
+        iov[num_sg].iov_base = dma_memory_map(virtio_get_dma_as(vdev), pa, &len,
+                                              is_write ?
+                                              DMA_DIRECTION_FROM_DEVICE:
+                                              DMA_DIRECTION_TO_DEVICE);
         iov[num_sg].iov_len = len;
         addr[num_sg] = pa;
 
@@ -482,9 +488,9 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
     *p_num_sg = num_sg;
 }
 
-static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
-                                unsigned int *num_sg, unsigned int max_size,
-                                int is_write)
+static void virtqueue_map_iovec(VirtIODevice *vdev, struct iovec *sg,
+                                hwaddr *addr, unsigned int *num_sg,
+                                unsigned int max_size, int is_write)
 {
     unsigned int i;
     hwaddr len;
@@ -503,7 +509,10 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
 
     for (i = 0; i < *num_sg; i++) {
         len = sg[i].iov_len;
-        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
+        sg[i].iov_base = dma_memory_map(virtio_get_dma_as(vdev),
+                                        addr[i], &len, is_write ?
+                                        DMA_DIRECTION_FROM_DEVICE :
+                                        DMA_DIRECTION_TO_DEVICE);
         if (!sg[i].iov_base) {
             error_report("virtio: error trying to map MMIO memory");
             exit(1);
@@ -515,12 +524,15 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
     }
 }
 
-void virtqueue_map(VirtQueueElement *elem)
+void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem)
 {
-    virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num,
-                        VIRTQUEUE_MAX_SIZE, 1);
-    virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num,
-                        VIRTQUEUE_MAX_SIZE, 0);
+    virtqueue_map_iovec(vdev, elem->in_sg, elem->in_addr, &elem->in_num,
+                        MIN(ARRAY_SIZE(elem->in_sg), ARRAY_SIZE(elem->in_addr)),
+                        1);
+    virtqueue_map_iovec(vdev, elem->out_sg, elem->out_addr, &elem->out_num,
+                        MIN(ARRAY_SIZE(elem->out_sg),
+                        ARRAY_SIZE(elem->out_addr)),
+                        0);
 }
 
 void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num)
@@ -594,14 +606,14 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     /* Collect all the descriptors */
     do {
         if (desc.flags & VRING_DESC_F_WRITE) {
-            virtqueue_map_desc(&in_num, addr + out_num, iov + out_num,
+            virtqueue_map_desc(vdev, &in_num, addr + out_num, iov + out_num,
                                VIRTQUEUE_MAX_SIZE - out_num, true, desc.addr, desc.len);
         } else {
             if (in_num) {
                 error_report("Incorrect order for descriptors");
                 exit(1);
             }
-            virtqueue_map_desc(&out_num, addr, iov,
+            virtqueue_map_desc(vdev, &out_num, addr, iov,
                                VIRTQUEUE_MAX_SIZE, false, desc.addr, desc.len);
         }
 
@@ -647,7 +659,7 @@ typedef struct VirtQueueElementOld {
     struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
 } VirtQueueElementOld;
 
-void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
+void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz)
 {
     VirtQueueElement *elem;
     VirtQueueElementOld data;
@@ -678,7 +690,7 @@ void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
         elem->out_sg[i].iov_len = data.out_sg[i].iov_len;
     }
 
-    virtqueue_map(elem);
+    virtqueue_map(vdev, elem);
     return elem;
 }
 
@@ -733,6 +745,10 @@ static int virtio_validate_features(VirtIODevice *vdev)
 {
     VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
 
+    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
+        !virtio_vdev_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM))
+        return -EFAULT;
+
     if (k->validate_features) {
         return k->validate_features(vdev);
     } else {
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 440b455..4071dad 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -17,12 +17,25 @@
 #define QEMU_VIRTIO_ACCESS_H
 
 #include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
 #include "exec/address-spaces.h"
 
 #if defined(TARGET_PPC64) || defined(TARGET_ARM)
 #define LEGACY_VIRTIO_IS_BIENDIAN 1
 #endif
 
+static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
+{
+    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
+    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+
+    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
+        k->get_dma_as) {
+        return k->get_dma_as(qbus->parent);
+    }
+    return &address_space_memory;
+}
+
 static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
 {
 #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
@@ -40,45 +53,55 @@ static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
 
 static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
     if (virtio_access_is_big_endian(vdev)) {
-        return lduw_be_phys(&address_space_memory, pa);
+        return lduw_be_phys(dma_as, pa);
     }
-    return lduw_le_phys(&address_space_memory, pa);
+    return lduw_le_phys(dma_as, pa);
 }
 
 static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
     if (virtio_access_is_big_endian(vdev)) {
-        return ldl_be_phys(&address_space_memory, pa);
+        return ldl_be_phys(dma_as, pa);
     }
-    return ldl_le_phys(&address_space_memory, pa);
+    return ldl_le_phys(dma_as, pa);
 }
 
 static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
     if (virtio_access_is_big_endian(vdev)) {
-        return ldq_be_phys(&address_space_memory, pa);
+        return ldq_be_phys(dma_as, pa);
     }
-    return ldq_le_phys(&address_space_memory, pa);
+    return ldq_le_phys(dma_as, pa);
 }
 
 static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
                                    uint16_t value)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
     if (virtio_access_is_big_endian(vdev)) {
-        stw_be_phys(&address_space_memory, pa, value);
+        stw_be_phys(dma_as, pa, value);
     } else {
-        stw_le_phys(&address_space_memory, pa, value);
+        stw_le_phys(dma_as, pa, value);
     }
 }
 
 static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
                                    uint32_t value)
 {
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
     if (virtio_access_is_big_endian(vdev)) {
-        stl_be_phys(&address_space_memory, pa, value);
+        stl_be_phys(dma_as, pa, value);
     } else {
-        stl_le_phys(&address_space_memory, pa, value);
+        stl_le_phys(dma_as, pa, value);
     }
 }
 
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index f3e5ef3..608ff48 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -98,6 +98,7 @@ typedef struct VirtioBusClass {
      * Note that changing this will break migration for this transport.
      */
     bool has_variable_vring_alignment;
+    AddressSpace *(*get_dma_as)(DeviceState *d);
 } VirtioBusClass;
 
 struct VirtioBusState {
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d2490c1..147d062 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -157,9 +157,9 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
 
-void virtqueue_map(VirtQueueElement *elem);
+void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem);
 void *virtqueue_pop(VirtQueue *vq, size_t sz);
-void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz);
+void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz);
 void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem);
 int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
                           unsigned int out_bytes);
@@ -252,7 +252,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
     DEFINE_PROP_BIT64("notify_on_empty", _state, _field,  \
                       VIRTIO_F_NOTIFY_ON_EMPTY, true), \
     DEFINE_PROP_BIT64("any_layout", _state, _field, \
-                      VIRTIO_F_ANY_LAYOUT, true)
+                      VIRTIO_F_ANY_LAYOUT, true), \
+    DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
+                      VIRTIO_F_IOMMU_PLATFORM, false)
 
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4 Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-09-05  6:56   ` Wei Xu
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 04/11] intel_iommu: allocate new key when creating new address space Jason Wang
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang,
	Richard Henderson, Eduardo Habkost

To avoid duplicated name and ease debugging.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/i386/intel_iommu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 28c31a2..db70310 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2303,6 +2303,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
     uintptr_t key = (uintptr_t)bus;
     VTDBus *vtd_bus = g_hash_table_lookup(s->vtd_as_by_busptr, &key);
     VTDAddressSpace *vtd_dev_as;
+    char name[128];
 
     if (!vtd_bus) {
         /* No corresponding free() */
@@ -2316,6 +2317,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
     vtd_dev_as = vtd_bus->dev_as[devfn];
 
     if (!vtd_dev_as) {
+        snprintf(name, sizeof(name), "intel_iommu_devfn_%d", devfn);
         vtd_bus->dev_as[devfn] = vtd_dev_as = g_malloc0(sizeof(VTDAddressSpace));
 
         vtd_dev_as->bus = bus;
@@ -2330,7 +2332,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
         memory_region_add_subregion(&vtd_dev_as->iommu, VTD_INTERRUPT_ADDR_FIRST,
                                     &vtd_dev_as->iommu_ir);
         address_space_init(&vtd_dev_as->as,
-                           &vtd_dev_as->iommu, "intel_iommu");
+                           &vtd_dev_as->iommu, name);
     }
     return vtd_dev_as;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 04/11] intel_iommu: allocate new key when creating new address space
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (2 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 05/11] exec: introduce address_space_get_iotlb_entry() Jason Wang
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang,
	Richard Henderson, Eduardo Habkost

We use the pointer to stack for key for new address space, this will break hash
table searching, fixing by g_malloc() a new key instead.

Cc: Michael S. Tsirkin <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/i386/intel_iommu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index db70310..3aea00b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2306,12 +2306,13 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
     char name[128];
 
     if (!vtd_bus) {
+        uintptr_t *new_key = g_malloc(sizeof(*new_key));
+        *new_key = (uintptr_t)bus;
         /* No corresponding free() */
         vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
                             X86_IOMMU_PCI_DEVFN_MAX);
         vtd_bus->bus = bus;
-        key = (uintptr_t)bus;
-        g_hash_table_insert(s->vtd_as_by_busptr, &key, vtd_bus);
+        g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
     }
 
     vtd_dev_as = vtd_bus->dev_as[devfn];
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 05/11] exec: introduce address_space_get_iotlb_entry()
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (3 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 04/11] intel_iommu: allocate new key when creating new address space Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor Jason Wang
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang,
	Peter Crosthwaite, Richard Henderson

This patch introduces a helper to query the iotlb entry for a
possible iova. This will be used by later device IOTLB API to enable
the capability for a dataplane (e.g vhost) to query the IOTLB.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 exec.c                | 33 +++++++++++++++++++++++++++++++++
 include/exec/memory.h |  6 ++++++
 2 files changed, 39 insertions(+)

diff --git a/exec.c b/exec.c
index 8ffde75..a1a8489 100644
--- a/exec.c
+++ b/exec.c
@@ -417,6 +417,39 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
 }
 
 /* Called from RCU critical section */
+IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+                                            bool is_write)
+{
+    IOMMUTLBEntry iotlb = {0};
+    MemoryRegionSection *section;
+    MemoryRegion *mr;
+    hwaddr plen;
+
+    for (;;) {
+        AddressSpaceDispatch *d = atomic_rcu_read(&as->dispatch);
+        section = address_space_translate_internal(d, addr, &addr, &plen, true);
+        mr = section->mr;
+
+        if (!mr->iommu_ops) {
+            break;
+        }
+
+        iotlb = mr->iommu_ops->translate(mr, addr, is_write);
+        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
+                | (addr & iotlb.addr_mask));
+        plen = MIN(plen, (addr | iotlb.addr_mask) - addr + 1);
+        if (!(iotlb.perm & (1 << is_write))) {
+            iotlb.target_as = NULL;
+            break;
+        }
+
+        as = iotlb.target_as;
+    }
+
+    return iotlb;
+}
+
+/* Called from RCU critical section */
 MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
                                       hwaddr *xlat, hwaddr *plen,
                                       bool is_write)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3e4d416..8e4513d 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1355,6 +1355,12 @@ void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
 void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
                             MemTxAttrs attrs, MemTxResult *result);
 
+/* address_space_get_iotlb_entry: translate an address into an IOTLB
+ * entry. Should be called from an RCU critical section.
+ */
+IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
+                                            bool is_write);
+
 /* address_space_translate: translate an address range into an address space
  * into a MemoryRegion and an address range into that section.  Should be
  * called from an RCU critical section, to avoid that the last reference
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (4 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 05/11] exec: introduce address_space_get_iotlb_entry() Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30 13:16   ` Peter Xu
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support Jason Wang
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang,
	Richard Henderson, Eduardo Habkost

This patch enables device IOTLB support for intel iommu. The major
work is to implement QI device IOTLB descriptor processing and notify
the device through iommu notifier.

Future work:
- Device IOTLB error processing, invalid and timeout

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/i386/intel_iommu.c          | 79 ++++++++++++++++++++++++++++++++++++++----
 hw/i386/intel_iommu_internal.h | 13 +++++--
 hw/i386/x86-iommu.c            | 17 +++++++++
 include/hw/i386/x86-iommu.h    |  1 +
 4 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 3aea00b..298faab 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -735,11 +735,18 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
                     "context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
                     ce->hi, ce->lo);
         return -VTD_FR_CONTEXT_ENTRY_INV;
-    } else if (ce->lo & VTD_CONTEXT_ENTRY_TT) {
-        VTD_DPRINTF(GENERAL, "error: unsupported Translation Type in "
-                    "context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
-                    ce->hi, ce->lo);
-        return -VTD_FR_CONTEXT_ENTRY_INV;
+    } else {
+        switch (ce->lo & VTD_CONTEXT_ENTRY_TT) {
+        case VTD_CONTEXT_TT_MULTI_LEVEL:
+            /* fall through */
+        case VTD_CONTEXT_TT_DEV_IOTLB:
+            break;
+        default:
+            VTD_DPRINTF(GENERAL, "error: unsupported Translation Type in "
+                        "context-entry hi 0x%"PRIx64 " lo 0x%"PRIx64,
+                        ce->hi, ce->lo);
+            return -VTD_FR_CONTEXT_ENTRY_INV;
+        }
     }
     return 0;
 }
@@ -1434,7 +1441,59 @@ static bool vtd_process_inv_iec_desc(IntelIOMMUState *s,
     vtd_iec_notify_all(s, !inv_desc->iec.granularity,
                        inv_desc->iec.index,
                        inv_desc->iec.index_mask);
+    return true;
+}
+
+static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
+                                          VTDInvDesc *inv_desc)
+{
+    VTDAddressSpace *vtd_dev_as;
+    IOMMUTLBEntry entry;
+    struct VTDBus *vtd_bus;
+    hwaddr addr;
+    uint64_t sz;
+    uint16_t sid;
+    uint8_t devfn;
+    bool size;
+    uint8_t bus_num;
+
+    addr = VTD_INV_DESC_DEVICE_IOTLB_ADDR(inv_desc->hi);
+    sid = VTD_INV_DESC_DEVICE_IOTLB_SID(inv_desc->lo);
+    devfn = sid & 0xff;
+    bus_num = sid >> 8;
+    size = VTD_INV_DESC_DEVICE_IOTLB_SIZE(inv_desc->hi);
+
+    if ((inv_desc->lo & VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO) ||
+        (inv_desc->hi & VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI)) {
+        VTD_DPRINTF(GENERAL, "error: non-zero reserved field in Device "
+                    "IOTLB Invalidate Descriptor hi 0x%"PRIx64 " lo 0x%"PRIx64,
+                    inv_desc->hi, inv_desc->lo);
+        return false;
+    }
 
+    vtd_bus = vtd_find_as_from_bus_num(s, bus_num);
+    if (!vtd_bus) {
+        goto done;
+    }
+
+    vtd_dev_as = vtd_bus->dev_as[devfn];
+    if (!vtd_dev_as) {
+        goto done;
+    }
+
+    if (size) {
+        sz = 1 << ffsll(~(addr | (VTD_PAGE_MASK_4K - 1)));
+        addr &= ~(sz - 1);
+    } else {
+        sz = VTD_PAGE_SIZE;
+    }
+
+    entry.target_as = &vtd_dev_as->as;
+    entry.addr_mask = sz - 1;
+    entry.iova = addr;
+    memory_region_notify_iommu(entry.target_as->root, entry);
+
+done:
     return true;
 }
 
@@ -1486,6 +1545,14 @@ static bool vtd_process_inv_desc(IntelIOMMUState *s)
         }
         break;
 
+    case VTD_INV_DESC_DEVICE:
+        VTD_DPRINTF(INV, "Device IOTLB Invalidation Descriptor hi 0x%"PRIx64
+                    " lo 0x%"PRIx64, inv_desc.hi, inv_desc.lo);
+        if (!vtd_process_device_iotlb_desc(s, &inv_desc)) {
+            return false;
+        }
+        break;
+
     default:
         VTD_DPRINTF(GENERAL, "error: unkonw Invalidation Descriptor type "
                     "hi 0x%"PRIx64 " lo 0x%"PRIx64 " type %"PRIu8,
@@ -2364,7 +2431,7 @@ static void vtd_init(IntelIOMMUState *s)
     s->next_frcd_reg = 0;
     s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW |
              VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;
-    s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
+    s->ecap = VTD_ECAP_QI | VTD_ECAP_DT | VTD_ECAP_IRO;
 
     if (x86_iommu->intr_supported) {
         s->ecap |= VTD_ECAP_IR | VTD_ECAP_EIM | VTD_ECAP_MHMV;
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 0829a50..b195d8a 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -183,6 +183,7 @@
 /* (offset >> 4) << 8 */
 #define VTD_ECAP_IRO                (DMAR_IOTLB_REG_OFFSET << 4)
 #define VTD_ECAP_QI                 (1ULL << 1)
+#define VTD_ECAP_DT                 (1ULL << 2)
 /* Interrupt Remapping support */
 #define VTD_ECAP_IR                 (1ULL << 3)
 #define VTD_ECAP_EIM                (1ULL << 4)
@@ -326,6 +327,7 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_TYPE               0xf
 #define VTD_INV_DESC_CC                 0x1 /* Context-cache Invalidate Desc */
 #define VTD_INV_DESC_IOTLB              0x2
+#define VTD_INV_DESC_DEVICE             0x3
 #define VTD_INV_DESC_IEC                0x4 /* Interrupt Entry Cache
                                                Invalidate Descriptor */
 #define VTD_INV_DESC_WAIT               0x5 /* Invalidation Wait Descriptor */
@@ -361,6 +363,13 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_IOTLB_RSVD_LO      0xffffffff0000ff00ULL
 #define VTD_INV_DESC_IOTLB_RSVD_HI      0xf80ULL
 
+/* Mask for Device IOTLB Invalidate Descriptor */
+#define VTD_INV_DESC_DEVICE_IOTLB_ADDR(val) ((val) & 0xfffffffffffff000ULL)
+#define VTD_INV_DESC_DEVICE_IOTLB_SIZE(val) ((val) & 0x1)
+#define VTD_INV_DESC_DEVICE_IOTLB_SID(val) (((val) >> 32) & 0xFFFFULL)
+#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
+#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
+
 /* Information about page-selective IOTLB invalidate */
 struct VTDIOTLBPageInvInfo {
     uint16_t domain_id;
@@ -399,8 +408,8 @@ typedef struct VTDRootEntry VTDRootEntry;
 #define VTD_CONTEXT_ENTRY_FPD       (1ULL << 1) /* Fault Processing Disable */
 #define VTD_CONTEXT_ENTRY_TT        (3ULL << 2) /* Translation Type */
 #define VTD_CONTEXT_TT_MULTI_LEVEL  0
-#define VTD_CONTEXT_TT_DEV_IOTLB    1
-#define VTD_CONTEXT_TT_PASS_THROUGH 2
+#define VTD_CONTEXT_TT_DEV_IOTLB    (1ULL << 2)
+#define VTD_CONTEXT_TT_PASS_THROUGH (2ULL << 2)
 /* Second Level Page Translation Pointer*/
 #define VTD_CONTEXT_ENTRY_SLPTPTR   (~0xfffULL)
 #define VTD_CONTEXT_ENTRY_RSVD_LO   (0xff0ULL | ~VTD_HAW_MASK)
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
index ce26b2a..a70a363 100644
--- a/hw/i386/x86-iommu.c
+++ b/hw/i386/x86-iommu.c
@@ -100,6 +100,18 @@ static void x86_iommu_intremap_prop_set(Object *o, bool value, Error **errp)
     s->intr_supported = value;
 }
 
+static bool x86_iommu_device_iotlb_prop_get(Object *o, Error **errp)
+{
+    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
+    return s->dt_supported;
+}
+
+static void x86_iommu_device_iotlb_prop_set(Object *o, bool value, Error **errp)
+{
+    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
+    s->dt_supported = value;
+}
+
 static void x86_iommu_instance_init(Object *o)
 {
     X86IOMMUState *s = X86_IOMMU_DEVICE(o);
@@ -108,6 +120,11 @@ static void x86_iommu_instance_init(Object *o)
     s->intr_supported = false;
     object_property_add_bool(o, "intremap", x86_iommu_intremap_prop_get,
                              x86_iommu_intremap_prop_set, NULL);
+    s->dt_supported = false;
+    object_property_add_bool(o, "device_iotlb",
+                             x86_iommu_device_iotlb_prop_get,
+                             x86_iommu_device_iotlb_prop_set,
+                             NULL);
 }
 
 static const TypeInfo x86_iommu_info = {
diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h
index c48e8dd..aa44014 100644
--- a/include/hw/i386/x86-iommu.h
+++ b/include/hw/i386/x86-iommu.h
@@ -67,6 +67,7 @@ typedef struct IEC_Notifier IEC_Notifier;
 struct X86IOMMUState {
     SysBusDevice busdev;
     bool intr_supported;        /* Whether vIOMMU supports IR */
+    bool dt_supported;          /* Whether vIOMMU supports DT */
     QLIST_HEAD(, IEC_Notifier) iec_notifiers; /* IEC notify list */
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (5 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30 13:21   ` Peter Xu
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 08/11] acpi: add ATSR for q35 Jason Wang
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

This patches enable the Address Translation Service support for virtio
pci devices. This is needed for a guest visible Device IOTLB
implementation and will be required by vhost device IOTLB API
implementation for intel IOMMU.

Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/pci/pcie.c                             | 16 ++++++++++++++++
 hw/virtio/virtio-pci.c                    |  7 +++++++
 hw/virtio/virtio-pci.h                    |  4 ++++
 include/hw/acpi/acpi-defs.h               | 11 +++++++++++
 include/hw/pci/pcie.h                     |  4 ++++
 include/standard-headers/linux/pci_regs.h |  1 +
 6 files changed, 43 insertions(+)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 99cfb45..02195d9 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -717,3 +717,19 @@ void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num)
                         PCI_EXT_CAP_DSN_SIZEOF);
     pci_set_quad(dev->config + offset + pci_dsn_cap, ser_num);
 }
+
+void pcie_ats_init(PCIDevice *dev, uint16_t offset)
+{
+    pcie_add_capability(dev, PCI_EXT_CAP_ID_ATS, 0x1,
+                        offset, PCI_EXT_CAP_ATS_SIZEOF);
+
+    dev->exp.ats_cap = offset;
+
+    /* Invalidate Queue Depth 0, Page Aligned Request 0 */
+    pci_set_word(dev->config + offset + PCI_ATS_CAP, 0);
+    /* STU 0, Disabled by default */
+    pci_set_word(dev->config + offset + PCI_ATS_CTRL, 0);
+
+    pci_set_word(dev->wmask + dev->exp.ats_cap + PCI_ATS_CTRL, 0x800f);
+}
+
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index c10bf55..cc5ef3c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1797,6 +1797,11 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
          * PCI Power Management Interface Specification.
          */
         pci_set_word(pci_dev->config + pos + PCI_PM_PMC, 0x3);
+
+        if (proxy->flags & VIRTIO_PCI_FLAG_ATS) {
+            pcie_ats_init(pci_dev, 256);
+        }
+
     } else {
         /*
          * make future invocations of pci_is_express() return false
@@ -1846,6 +1851,8 @@ static Property virtio_pci_properties[] = {
                     VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, false),
     DEFINE_PROP_BIT("x-disable-pcie", VirtIOPCIProxy, flags,
                     VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, false),
+    DEFINE_PROP_BIT("ats", VirtIOPCIProxy, flags,
+                    VIRTIO_PCI_FLAG_ATS_BIT, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 25fbf8a..b19c6b8 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -64,6 +64,7 @@ enum {
     VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT,
     VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT,
     VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT,
+    VIRTIO_PCI_FLAG_ATS_BIT,
 };
 
 /* Need to activate work-arounds for buggy guests at vmstate load. */
@@ -84,6 +85,9 @@ enum {
 #define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \
     (1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT)
 
+/* address space translation service */
+#define VIRTIO_PCI_FLAG_ATS (1 << VIRTIO_PCI_FLAG_ATS_BIT)
+
 typedef struct {
     MSIMessage msg;
     int virq;
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 41c1d95..b26ef99 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -595,6 +595,17 @@ struct AcpiDmarHardwareUnit {
 } QEMU_PACKED;
 typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
 
+/* Type 2: Root Port ATS Capability Reporting Structure */
+struct AcpiDmarRootPortATS {
+    uint16_t type;
+    uint16_t length;
+    uint8_t flags;
+    uint8_t reserved;
+    uint16_t pci_segment;
+    AcpiDmarDeviceScope scope[0];
+} QEMU_PACKED;
+typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
+
 /* Masks for Flags field above */
 #define ACPI_DMAR_INCLUDE_PCI_ALL   1
 
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 056d25e..b08451d 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -74,6 +74,9 @@ struct PCIExpressDevice {
     /* AER */
     uint16_t aer_cap;
     PCIEAERLog aer_log;
+
+    /* Offset of ATS capability in config space */
+    uint16_t ats_cap;
 };
 
 #define COMPAT_PROP_PCP "power_controller_present"
@@ -120,6 +123,7 @@ void pcie_add_capability(PCIDevice *dev,
 
 void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn);
 void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num);
+void pcie_ats_init(PCIDevice *dev, uint16_t offset);
 
 extern const VMStateDescription vmstate_pcie_device;
 
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
index 4040951..ac426a0 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -674,6 +674,7 @@
 #define PCI_EXT_CAP_ID_MAX	PCI_EXT_CAP_ID_DPC
 
 #define PCI_EXT_CAP_DSN_SIZEOF	12
+#define PCI_EXT_CAP_ATS_SIZEOF	8
 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
 
 /* Advanced Error Reporting */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 08/11] acpi: add ATSR for q35
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (6 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier Jason Wang
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

This patch provides ATSR which was a requirement for software that
wants to enable ATS on endpoint devices behind a Root Port. This is
done simply by setting ALL_PORTS which indicates all PCI-Express Root
Ports support ATS transactions.
---
 hw/i386/acpi-build.c        | 9 +++++++++
 include/hw/acpi/acpi-defs.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a26a4bb..1fd84a9 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2527,6 +2527,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
 
     AcpiTableDmar *dmar;
     AcpiDmarHardwareUnit *drhd;
+    AcpiDmarRootPortATS *atsr;
     uint8_t dmar_flags = 0;
     X86IOMMUState *iommu = x86_iommu_get_default();
     AcpiDmarDeviceScope *scope = NULL;
@@ -2559,6 +2560,14 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
     scope->bus = Q35_PSEUDO_BUS_PLATFORM;
     scope->path[0] = cpu_to_le16(Q35_PSEUDO_DEVFN_IOAPIC);
 
+    if (iommu->dt_supported) {
+        atsr = acpi_data_push(table_data, sizeof(*atsr));
+        atsr->type = cpu_to_le16(ACPI_DMAR_TYPE_ATSR);
+        atsr->length = cpu_to_le16(sizeof(*atsr));
+        atsr->flags = ACPI_DMAR_ATSR_ALL_PORTS;
+        atsr->pci_segment = cpu_to_le16(0);
+    }
+
     build_header(linker, table_data, (void *)(table_data->data + dmar_start),
                  "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index b26ef99..79a49a8 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -608,5 +608,6 @@ typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
 
 /* Masks for Flags field above */
 #define ACPI_DMAR_INCLUDE_PCI_ALL   1
+#define ACPI_DMAR_ATSR_ALL_PORTS    1
 
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (7 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 08/11] acpi: add ATSR for q35 Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30 13:28   ` Peter Xu
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started" Jason Wang
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 memory.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/memory.c b/memory.c
index 0eb6895..ca0a698 100644
--- a/memory.c
+++ b/memory.c
@@ -1515,6 +1515,11 @@ bool memory_region_is_logging(MemoryRegion *mr, uint8_t client)
 
 void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
 {
+    if (mr->alias) {
+        memory_region_register_iommu_notifier(mr->alias, n);
+        return;
+    }
+
     if (mr->iommu_ops->notify_started &&
         QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
         mr->iommu_ops->notify_started(mr);
@@ -1554,6 +1559,10 @@ void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n, bool is_write)
 
 void memory_region_unregister_iommu_notifier(MemoryRegion *mr, Notifier *n)
 {
+    if (mr->alias) {
+        memory_region_unregister_iommu_notifier(mr->alias, n);
+        return;
+    }
     notifier_remove(n);
     if (mr->iommu_ops->notify_stopped &&
         QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (8 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-08-30  3:37   ` Alex Williamson
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support Jason Wang
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Alex Williamson,
	Jason Wang

From: Peter Xu <peterx@redhat.com>

This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
device IOTLB API will get notified and send invalidation request to
vhost through this notifier.

Cc: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/i386/intel_iommu.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 298faab..15d1216 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -25,7 +25,6 @@
 #include "exec/address-spaces.h"
 #include "intel_iommu_internal.h"
 #include "hw/pci/pci.h"
-#include "hw/pci/pci_bus.h"
 #include "hw/i386/pc.h"
 #include "hw/boards.h"
 #include "hw/i386/x86-iommu.h"
@@ -2041,16 +2040,6 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
     return ret;
 }
 
-static void vtd_iommu_notify_started(MemoryRegion *iommu)
-{
-    VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
-
-    hw_error("Device at bus %s addr %02x.%d requires iommu notifier which "
-             "is currently not supported by intel-iommu emulation",
-             vtd_as->bus->qbus.name, PCI_SLOT(vtd_as->devfn),
-             PCI_FUNC(vtd_as->devfn));
-}
-
 static const VMStateDescription vtd_vmstate = {
     .name = "iommu-intel",
     .unmigratable = 1,
@@ -2418,7 +2407,6 @@ static void vtd_init(IntelIOMMUState *s)
     memset(s->womask, 0, DMAR_REG_SIZE);
 
     s->iommu_ops.translate = vtd_iommu_translate;
-    s->iommu_ops.notify_started = vtd_iommu_notify_started;
     s->root = 0;
     s->root_extended = false;
     s->dmar_enabled = false;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (9 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started" Jason Wang
@ 2016-08-30  3:06 ` Jason Wang
  2016-09-01  3:34   ` Peter Xu
  2016-08-30  3:25 ` [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support no-reply
  2016-08-30  3:29 ` no-reply
  12 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-30  3:06 UTC (permalink / raw)
  To: mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, wexu, vkaplans, Jason Wang

This patches implements Device IOTLB support for vhost kernel. This is
done through:

1) switch to use dma helpers when map/unmap vrings from vhost codes
2) kernel support for Device IOTLB API:

- allow vhost-net to query the IOMMU IOTLB entry through eventfd
- enable the ability for qemu to update a specified mapping of vhost
- through ioctl.
- enable the ability to invalidate a specified range of iova for the
  device IOTLB of vhost through ioctl. In x86/intel_iommu case this is
  triggered through iommu memory region notifier from device IOTLB
  invalidation descriptor processing routine.

With all the above, kernel vhost_net can co-operate with IOMMU.

Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/virtio/vhost-backend.c         | 104 ++++++++++++++++++++++++++
 hw/virtio/vhost.c                 | 149 ++++++++++++++++++++++++++++++++------
 include/hw/virtio/vhost-backend.h |  14 ++++
 include/hw/virtio/vhost.h         |   4 +
 include/hw/virtio/virtio-access.h |  44 ++++++++++-
 net/tap.c                         |   1 +
 6 files changed, 291 insertions(+), 25 deletions(-)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 7681f15..a5754f3 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -172,6 +172,107 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
     return idx - dev->vq_index;
 }
 
+static void vhost_kernel_iotlb_read(void *opaque)
+{
+    struct vhost_dev *dev = opaque;
+    struct vhost_msg msg;
+    ssize_t len;
+
+    while((len = read((uintptr_t)dev->opaque, &msg, sizeof msg)) > 0) {
+        struct vhost_iotlb_msg *imsg = &msg.iotlb;
+        if (len < sizeof msg) {
+            error_report("Wrong vhost message len: %d", (int)len);
+            break;
+        }
+        if (msg.type != VHOST_IOTLB_MSG) {
+            error_report("Unknown vhost iotlb message type");
+            break;
+        }
+        switch (imsg->type) {
+        case VHOST_IOTLB_MISS:
+            vhost_device_iotlb_miss(dev, imsg->iova,
+                                    imsg->perm != VHOST_ACCESS_RO);
+            break;
+        case VHOST_IOTLB_UPDATE:
+        case VHOST_IOTLB_INVALIDATE:
+            error_report("Unexpected IOTLB message type");
+            break;
+        case VHOST_IOTLB_ACCESS_FAIL:
+            /* FIXME: report device iotlb error */
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+static int vhost_kernel_update_device_iotlb(struct vhost_dev *dev,
+                                            uint64_t iova, uint64_t uaddr,
+                                            uint64_t len,
+                                            IOMMUAccessFlags perm)
+{
+    struct vhost_msg msg = {
+        .type = VHOST_IOTLB_MSG,
+        .iotlb = {
+            .iova = iova,
+            .uaddr = uaddr,
+            .size = len,
+            .type = VHOST_IOTLB_UPDATE,
+        }
+    };
+
+    switch (perm) {
+    case IOMMU_RO:
+        msg.iotlb.perm = VHOST_ACCESS_RO;
+        break;
+    case IOMMU_WO:
+        msg.iotlb.perm = VHOST_ACCESS_WO;
+        break;
+    case IOMMU_RW:
+        msg.iotlb.perm = VHOST_ACCESS_RW;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
+        error_report("Fail to update device iotlb");
+        return -EFAULT;
+    }
+
+    return 0;
+}
+
+static int vhost_kernel_invalidate_device_iotlb(struct vhost_dev *dev,
+                                                uint64_t iova, uint64_t len)
+{
+    struct vhost_msg msg = {
+        .type = VHOST_IOTLB_MSG,
+        .iotlb = {
+            .iova = iova,
+            .size = len,
+            .type = VHOST_IOTLB_INVALIDATE,
+        }
+    };
+
+    if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
+        error_report("Fail to invalidate device iotlb");
+        return -EFAULT;
+    }
+
+    return 0;
+}
+
+static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev,
+                                           int enabled)
+{
+    if (enabled)
+        qemu_set_fd_handler((uintptr_t)dev->opaque,
+                            vhost_kernel_iotlb_read, NULL, dev);
+    else
+        qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL);
+}
+
 static const VhostOps kernel_ops = {
         .backend_type = VHOST_BACKEND_TYPE_KERNEL,
         .vhost_backend_init = vhost_kernel_init,
@@ -197,6 +298,9 @@ static const VhostOps kernel_ops = {
         .vhost_set_owner = vhost_kernel_set_owner,
         .vhost_reset_device = vhost_kernel_reset_device,
         .vhost_get_vq_index = vhost_kernel_get_vq_index,
+        .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
+        .vhost_update_device_iotlb = vhost_kernel_update_device_iotlb,
+        .vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb,
 };
 
 int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 3d0c807..94e577b 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -437,7 +437,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
             continue;
         }
         l = vq->ring_size;
-        p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
+        p = virtio_memory_map(dev->vdev, vq->ring_phys, &l, 1);
         if (!p || l != vq->ring_size) {
             error_report("Unable to map ring buffer for ring %d", i);
             r = -ENOMEM;
@@ -446,7 +446,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
             error_report("Ring buffer relocated for ring %d", i);
             r = -EBUSY;
         }
-        cpu_physical_memory_unmap(p, l, 0, 0);
+        virtio_memory_unmap(dev->vdev, p, l, 0, 0);
     }
     return r;
 }
@@ -674,13 +674,18 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
     return 0;
 }
 
-static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
+static int vhost_dev_set_features(struct vhost_dev *dev,
+                                  bool enable_log)
 {
     uint64_t features = dev->acked_features;
+    bool has_iommu = mr_has_iommu_ops(virtio_get_dma_as(dev->vdev)->root);
     int r;
     if (enable_log) {
         features |= 0x1ULL << VHOST_F_LOG_ALL;
     }
+    if (has_iommu) {
+        features |= 0x1ULL << VIRTIO_F_IOMMU_PLATFORM;
+    }
     r = dev->vhost_ops->vhost_set_features(dev, features);
     if (r < 0) {
         VHOST_OPS_DEBUG("vhost_set_features failed");
@@ -817,6 +822,56 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
     return -errno;
 }
 
+static int vhost_memory_region_lookup(struct vhost_dev *hdev,
+                                      uint64_t gpa, uint64_t *uaddr,
+                                      uint64_t *len)
+{
+    int i;
+
+    for (i = 0; i < hdev->mem->nregions; i++) {
+        struct vhost_memory_region *reg = hdev->mem->regions + i;
+
+        if (gpa >= reg->guest_phys_addr &&
+            reg->guest_phys_addr + reg->memory_size > gpa) {
+            *uaddr = reg->userspace_addr + gpa - reg->guest_phys_addr;
+            *len = reg->guest_phys_addr + reg->memory_size - gpa;
+            return 0;
+        }
+    }
+
+    return -EFAULT;
+}
+
+void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
+{
+    IOMMUTLBEntry iotlb;
+    uint64_t uaddr, len;
+
+    rcu_read_lock();
+
+    iotlb = address_space_get_iotlb_entry(virtio_get_dma_as(dev->vdev),
+                                          iova, write);
+    if (iotlb.target_as != NULL) {
+        if (vhost_memory_region_lookup(dev, iotlb.translated_addr,
+                                       &uaddr, &len)) {
+            error_report("Fail to lookup the translated address "
+                         "%"PRIx64, iotlb.translated_addr);
+            goto out;
+        }
+
+        len = MIN(iotlb.addr_mask + 1, len);
+        iova = iova & ~iotlb.addr_mask;
+
+        if (dev->vhost_ops->vhost_update_device_iotlb(dev, iova, uaddr,
+                                                      len, iotlb.perm)) {
+            error_report("Fail to update device iotlb");
+            goto out;
+        }
+    }
+out:
+    rcu_read_unlock();
+}
+
 static int vhost_virtqueue_start(struct vhost_dev *dev,
                                 struct VirtIODevice *vdev,
                                 struct vhost_virtqueue *vq,
@@ -859,21 +914,21 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 
     s = l = virtio_queue_get_desc_size(vdev, idx);
     a = virtio_queue_get_desc_addr(vdev, idx);
-    vq->desc = cpu_physical_memory_map(a, &l, 0);
+    vq->desc = virtio_memory_map(vdev, a, &l, 0);
     if (!vq->desc || l != s) {
         r = -ENOMEM;
         goto fail_alloc_desc;
     }
     s = l = virtio_queue_get_avail_size(vdev, idx);
     a = virtio_queue_get_avail_addr(vdev, idx);
-    vq->avail = cpu_physical_memory_map(a, &l, 0);
+    vq->avail = virtio_memory_map(vdev, a, &l, 0);
     if (!vq->avail || l != s) {
         r = -ENOMEM;
         goto fail_alloc_avail;
     }
     vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);
     vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);
-    vq->used = cpu_physical_memory_map(a, &l, 1);
+    vq->used = virtio_memory_map(vdev, a, &l, 1);
     if (!vq->used || l != s) {
         r = -ENOMEM;
         goto fail_alloc_used;
@@ -881,7 +936,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
 
     vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);
     vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);
-    vq->ring = cpu_physical_memory_map(a, &l, 1);
+    vq->ring = virtio_memory_map(vdev, a, &l, 1);
     if (!vq->ring || l != s) {
         r = -ENOMEM;
         goto fail_alloc_ring;
@@ -913,20 +968,19 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
     }
 
     return 0;
-
 fail_kick:
 fail_alloc:
-    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
-                              0, 0);
+    virtio_memory_unmap(vdev, vq->ring, virtio_queue_get_ring_size(vdev, idx),
+                        0, 0);
 fail_alloc_ring:
-    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
-                              0, 0);
+    virtio_memory_unmap(vdev, vq->used, virtio_queue_get_used_size(vdev, idx),
+                        0, 0);
 fail_alloc_used:
-    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
-                              0, 0);
+    virtio_memory_unmap(vdev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
+                        0, 0);
 fail_alloc_avail:
-    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
-                              0, 0);
+    virtio_memory_unmap(vdev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
+                        0, 0);
 fail_alloc_desc:
     return r;
 }
@@ -959,14 +1013,14 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
                                                 vhost_vq_index);
     }
 
-    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
-                              0, virtio_queue_get_ring_size(vdev, idx));
-    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
-                              1, virtio_queue_get_used_size(vdev, idx));
-    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
-                              0, virtio_queue_get_avail_size(vdev, idx));
-    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
-                              0, virtio_queue_get_desc_size(vdev, idx));
+    virtio_memory_unmap(vdev, vq->ring, virtio_queue_get_ring_size(vdev, idx),
+                        0, virtio_queue_get_ring_size(vdev, idx));
+    virtio_memory_unmap(vdev, vq->used, virtio_queue_get_used_size(vdev, idx),
+                        1, virtio_queue_get_used_size(vdev, idx));
+    virtio_memory_unmap(vdev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
+                        0, virtio_queue_get_avail_size(vdev, idx));
+    virtio_memory_unmap(vdev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
+                         0, virtio_queue_get_desc_size(vdev, idx));
 }
 
 static void vhost_eventfd_add(MemoryListener *listener,
@@ -1023,6 +1077,9 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
         r = -errno;
         goto fail_call;
     }
+
+    vq->dev = dev;
+
     return 0;
 fail_call:
     event_notifier_cleanup(&vq->masked_notifier);
@@ -1034,12 +1091,25 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
     event_notifier_cleanup(&vq->masked_notifier);
 }
 
+static void vhost_iommu_unmap_notify(Notifier *n, void *data)
+{
+    struct vhost_dev *hdev = container_of(n, struct vhost_dev, n);
+    IOMMUTLBEntry *iotlb = data;
+
+    if (hdev->vhost_ops->vhost_invalidate_device_iotlb(hdev,
+                                                       iotlb->iova,
+                                                       iotlb->addr_mask +1)) {
+        error_report("Fail to invalidate device iotlb");
+    }
+}
+
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
                    VhostBackendType backend_type, uint32_t busyloop_timeout)
 {
     uint64_t features;
     int i, r, n_initialized_vqs = 0;
 
+    hdev->vdev = NULL;
     hdev->migration_blocker = NULL;
 
     r = vhost_set_backend_type(hdev, backend_type);
@@ -1104,6 +1174,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
         .priority = 10
     };
 
+    hdev->n.notify = vhost_iommu_unmap_notify;
+
     if (hdev->migration_blocker == NULL) {
         if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
             error_setg(&hdev->migration_blocker,
@@ -1296,11 +1368,18 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
     assert(hdev->vhost_ops);
 
     hdev->started = true;
+    hdev->vdev = vdev;
 
     r = vhost_dev_set_features(hdev, hdev->log_enabled);
     if (r < 0) {
         goto fail_features;
     }
+
+    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
+        memory_region_register_iommu_notifier(virtio_get_dma_as(vdev)->root,
+                                              &hdev->n);
+    }
+
     r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
     if (r < 0) {
         VHOST_OPS_DEBUG("vhost_set_mem_table failed");
@@ -1334,7 +1413,22 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
         }
     }
 
+    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
+
+    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
+        /* Update used ring information for IOTLB to work correctly */
+        for (i = 0; i < hdev->nvqs; ++i) {
+            struct vhost_virtqueue *vq = hdev->vqs + i;
+            vhost_device_iotlb_miss(hdev, vq->used_phys, true);
+        }
+    }
     return 0;
+#if 0
+fail_iotlb:
+    if (hdev->vhost_ops->vhost_set_vring_enable) {
+        hdev->vhost_ops->vhost_set_vring_enable(hdev, 0);
+    }
+#endif
 fail_log:
     vhost_log_put(hdev, false);
 fail_vq:
@@ -1345,6 +1439,7 @@ fail_vq:
                              hdev->vq_index + i);
     }
     i = hdev->nvqs;
+
 fail_mem:
 fail_features:
 
@@ -1359,6 +1454,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 
     /* should only be called after backend is connected */
     assert(hdev->vhost_ops);
+    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
 
     for (i = 0; i < hdev->nvqs; ++i) {
         vhost_virtqueue_stop(hdev,
@@ -1367,8 +1463,13 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
                              hdev->vq_index + i);
     }
 
+    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
+        memory_region_unregister_iommu_notifier(virtio_get_dma_as(vdev)->root,
+                                                &hdev->n);
+    }
     vhost_log_put(hdev, true);
     hdev->started = false;
+    hdev->vdev = NULL;
 }
 
 int vhost_net_set_backend(struct vhost_dev *hdev,
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index cf7f0b5..5cf8c70 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -8,9 +8,12 @@
  *
  */
 
+
 #ifndef VHOST_BACKEND_H
 #define VHOST_BACKEND_H
 
+#include "exec/memory.h"
+
 typedef enum VhostBackendType {
     VHOST_BACKEND_TYPE_NONE = 0,
     VHOST_BACKEND_TYPE_KERNEL = 1,
@@ -73,6 +76,14 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
 typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
                                            uint64_t start1, uint64_t size1,
                                            uint64_t start2, uint64_t size2);
+typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev *dev,
+                                           int enabled);
+typedef int (*vhost_update_device_iotlb_op)(struct vhost_dev *dev,
+                                            uint64_t iova, uint64_t uaddr,
+                                            uint64_t len,
+                                            IOMMUAccessFlags perm);
+typedef int (*vhost_invalidate_device_iotlb_op)(struct vhost_dev *dev,
+                                                uint64_t iova, uint64_t len);
 
 typedef struct VhostOps {
     VhostBackendType backend_type;
@@ -102,6 +113,9 @@ typedef struct VhostOps {
     vhost_requires_shm_log_op vhost_requires_shm_log;
     vhost_migration_done_op vhost_migration_done;
     vhost_backend_can_merge_op vhost_backend_can_merge;
+    vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
+    vhost_update_device_iotlb_op vhost_update_device_iotlb;
+    vhost_invalidate_device_iotlb_op vhost_invalidate_device_iotlb;
 } VhostOps;
 
 extern const VhostOps user_ops;
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index e433089..b971fa1 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -20,6 +20,7 @@ struct vhost_virtqueue {
     unsigned long long ring_phys;
     unsigned ring_size;
     EventNotifier masked_notifier;
+    struct vhost_dev *dev;
 };
 
 typedef unsigned long vhost_log_chunk_t;
@@ -37,6 +38,7 @@ struct vhost_log {
 
 struct vhost_memory;
 struct vhost_dev {
+    VirtIODevice *vdev;
     MemoryListener memory_listener;
     struct vhost_memory *mem;
     int n_mem_sections;
@@ -61,6 +63,7 @@ struct vhost_dev {
     void *opaque;
     struct vhost_log *log;
     QLIST_ENTRY(vhost_dev) entry;
+    Notifier n;
 };
 
 int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
@@ -90,4 +93,5 @@ bool vhost_has_free_slot(void);
 int vhost_net_set_backend(struct vhost_dev *hdev,
                           struct vhost_vring_file *file);
 
+void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
 #endif
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 4071dad..3560bba 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -18,6 +18,7 @@
 
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-bus.h"
+#include "sysemu/dma.h"
 #include "exec/address-spaces.h"
 
 #if defined(TARGET_PPC64) || defined(TARGET_ARM)
@@ -200,4 +201,45 @@ static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
 {
     *s = virtio_tswap64(vdev, *s);
 }
-#endif /* QEMU_VIRTIO_ACCESS_H */
+
+static inline bool mr_has_iommu_ops(MemoryRegion *mr)
+{
+    if (mr->alias) {
+        return mr_has_iommu_ops(mr->alias);
+    }
+
+    if (mr->iommu_ops)
+        return true;
+    else
+        return false;
+}
+
+static inline void *virtio_memory_map(VirtIODevice *vdev, hwaddr addr,
+                                      hwaddr *plen, int is_write)
+{
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
+    if (!mr_has_iommu_ops(dma_as->root)) {
+      return dma_memory_map(dma_as, addr, plen, is_write ?
+                            DMA_DIRECTION_FROM_DEVICE :
+                            DMA_DIRECTION_TO_DEVICE);
+    } else {
+      return (void *)addr;
+    }
+}
+
+
+static inline void virtio_memory_unmap(VirtIODevice *vdev, void *buffer,
+                                       hwaddr len, int is_write,
+                                       hwaddr access_len)
+{
+    AddressSpace *dma_as = virtio_get_dma_as(vdev);
+
+    if (!mr_has_iommu_ops(dma_as->root)) {
+      dma_memory_unmap(dma_as, buffer, len, is_write ?
+                       DMA_DIRECTION_FROM_DEVICE : DMA_DIRECTION_TO_DEVICE,
+                       access_len);
+    }
+}
+
+#endif /* _QEMU_VIRTIO_ACCESS_H */
diff --git a/net/tap.c b/net/tap.c
index 6abb962..363805e 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -696,6 +696,7 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
                                  "tap: open vhost char device failed");
                 return;
             }
+            fcntl(vhostfd, F_SETFL, O_NONBLOCK);
         }
         options.opaque = (void *)(uintptr_t)vhostfd;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (10 preceding siblings ...)
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support Jason Wang
@ 2016-08-30  3:25 ` no-reply
  2016-08-30  3:29 ` no-reply
  12 siblings, 0 replies; 52+ messages in thread
From: no-reply @ 2016-08-30  3:25 UTC (permalink / raw)
  To: jasowang
  Cc: famz, mst, qemu-devel, peterx, vkaplans, wexu, cornelia.huck, pbonzini

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support
Type: series
Message-id: 1472526419-5900-1-git-send-email-jasowang@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1472526419-5900-1-git-send-email-jasowang@redhat.com -> patchew/1472526419-5900-1-git-send-email-jasowang@redhat.com
Switched to a new branch 'test'
321c6b2 vhost_net: device IOTLB support
7a3b4b7 Revert "intel_iommu: Throw hw_error on notify_started"
9b0d39c memory: handle alias for iommu notifier
05d5b5f acpi: add ATSR for q35
42f3929 virtio-pci: address space translation service (ATS) support
8668581 intel_iommu: support device iotlb descriptor
5cc4f42 exec: introduce address_space_get_iotlb_entry()
136e6e9 intel_iommu: allocate new key when creating new address space
25a674b intel_iommu: name vtd address space with devfn
f5d36b8 virtio: convert to use DMA api
045aae2 linux-headers: update to 4.8-rc4

=== OUTPUT BEGIN ===
Checking PATCH 1/11: linux-headers: update to 4.8-rc4...
Checking PATCH 2/11: virtio: convert to use DMA api...
WARNING: line over 80 characters
#163: FILE: hw/virtio/virtio.c:256:
+        dma_memory_unmap(dma_as, elem->in_sg[i].iov_base, elem->in_sg[i].iov_len,

WARNING: line over 80 characters
#186: FILE: hw/virtio/virtio.c:458:
+                               unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,

ERROR: spaces required around that ':' (ctx:VxE)
#197: FILE: hw/virtio/virtio.c:480:
+                                              DMA_DIRECTION_FROM_DEVICE:
                                                                        ^

ERROR: braces {} are necessary for all arms of this statement
#287: FILE: hw/virtio/virtio.c:749:
+    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
[...]

total: 2 errors, 2 warnings, 346 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/11: intel_iommu: name vtd address space with devfn...
Checking PATCH 4/11: intel_iommu: allocate new key when creating new address space...
Checking PATCH 5/11: exec: introduce address_space_get_iotlb_entry()...
Checking PATCH 6/11: intel_iommu: support device iotlb descriptor...
ERROR: use ctz64() instead of ffsll()
#93: FILE: hw/i386/intel_iommu.c:1485:
+        sz = 1 << ffsll(~(addr | (VTD_PAGE_MASK_4K - 1)));

total: 1 errors, 0 warnings, 177 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 7/11: virtio-pci: address space translation service (ATS) support...
Checking PATCH 8/11: acpi: add ATSR for q35...
Checking PATCH 9/11: memory: handle alias for iommu notifier...
Checking PATCH 10/11: Revert "intel_iommu: Throw hw_error on notify_started"...
Checking PATCH 11/11: vhost_net: device IOTLB support...
ERROR: space required before the open parenthesis '('
#40: FILE: hw/virtio/vhost-backend.c:181:
+    while((len = read((uintptr_t)dev->opaque, &msg, sizeof msg)) > 0) {

ERROR: spaces required around that '+' (ctx:WxV)
#354: FILE: hw/virtio/vhost.c:1101:
+                                                       iotlb->addr_mask +1)) {
                                                                         ^

ERROR: if this code is redundant consider removing it
#411: FILE: hw/virtio/vhost.c:1426:
+#if 0

ERROR: braces {} are necessary for all arms of this statement
#550: FILE: include/hw/virtio/virtio-access.h:211:
+    if (mr->iommu_ops)
[...]
+    else
[...]

ERROR: suspect code indent for conditional statements (4, 6)
#561: FILE: include/hw/virtio/virtio-access.h:222:
+    if (!mr_has_iommu_ops(dma_as->root)) {
+      return dma_memory_map(dma_as, addr, plen, is_write ?

ERROR: suspect code indent for conditional statements (4, 6)
#577: FILE: include/hw/virtio/virtio-access.h:238:
+    if (!mr_has_iommu_ops(dma_as->root)) {
+      dma_memory_unmap(dma_as, buffer, len, is_write ?

total: 6 errors, 0 warnings, 519 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support
  2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
                   ` (11 preceding siblings ...)
  2016-08-30  3:25 ` [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support no-reply
@ 2016-08-30  3:29 ` no-reply
  12 siblings, 0 replies; 52+ messages in thread
From: no-reply @ 2016-08-30  3:29 UTC (permalink / raw)
  To: jasowang
  Cc: famz, mst, qemu-devel, peterx, vkaplans, wexu, cornelia.huck, pbonzini

Hi,

Your series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Subject: [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support
Type: series
Message-id: 1472526419-5900-1-git-send-email-jasowang@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
make J=8 docker-test-quick@centos6
make J=8 docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
321c6b2 vhost_net: device IOTLB support
7a3b4b7 Revert "intel_iommu: Throw hw_error on notify_started"
9b0d39c memory: handle alias for iommu notifier
05d5b5f acpi: add ATSR for q35
42f3929 virtio-pci: address space translation service (ATS) support
8668581 intel_iommu: support device iotlb descriptor
5cc4f42 exec: introduce address_space_get_iotlb_entry()
136e6e9 intel_iommu: allocate new key when creating new address space
25a674b intel_iommu: name vtd address space with devfn
f5d36b8 virtio: convert to use DMA api
045aae2 linux-headers: update to 4.8-rc4

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf'
  BUILD centos6
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY RUNNER
  RUN test-quick in centos6
No C++ compiler available; disabling C++ specific optional code
Install prefix    /tmp/qemu-test/src/tests/docker/install
BIOS directory    /tmp/qemu-test/src/tests/docker/install/share/qemu
binary directory  /tmp/qemu-test/src/tests/docker/install/bin
library directory /tmp/qemu-test/src/tests/docker/install/lib
module directory  /tmp/qemu-test/src/tests/docker/install/lib/qemu
libexec directory /tmp/qemu-test/src/tests/docker/install/libexec
include directory /tmp/qemu-test/src/tests/docker/install/include
config directory  /tmp/qemu-test/src/tests/docker/install/etc
local state directory   /tmp/qemu-test/src/tests/docker/install/var
Manual directory  /tmp/qemu-test/src/tests/docker/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common  -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
uuid support      no
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
vhdx              no
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
  GEN   x86_64-softmmu/config-devices.mak.tmp
  GEN   aarch64-softmmu/config-devices.mak.tmp
  GEN   config-host.h
  GEN   qemu-options.def
  GEN   qmp-commands.h
  GEN   qapi-types.h
  GEN   qapi-visit.h
  GEN   qapi-event.h
  GEN   x86_64-softmmu/config-devices.mak
  GEN   aarch64-softmmu/config-devices.mak
  GEN   qmp-introspect.h
  GEN   tests/test-qapi-types.h
  GEN   tests/test-qapi-visit.h
  GEN   tests/test-qmp-commands.h
  GEN   tests/test-qapi-event.h
  GEN   tests/test-qmp-introspect.h
  GEN   config-all-devices.mak
  GEN   trace/generated-events.h
  GEN   trace/generated-tracers.h
  GEN   trace/generated-tcg-tracers.h
  GEN   trace/generated-helpers-wrappers.h
  GEN   trace/generated-helpers.h
  CC    tests/qemu-iotests/socket_scm_helper.o
  GEN   qga/qapi-generated/qga-qapi-types.h
  GEN   qga/qapi-generated/qga-qmp-commands.h
  GEN   qga/qapi-generated/qga-qapi-visit.h
  GEN   qga/qapi-generated/qga-qapi-types.c
  GEN   qga/qapi-generated/qga-qapi-visit.c
  GEN   qga/qapi-generated/qga-qmp-marshal.c
  GEN   qmp-introspect.c
  GEN   qapi-types.c
  GEN   qapi-visit.c
  GEN   qapi-event.c
  CC    qapi/qapi-visit-core.o
  CC    qapi/qapi-dealloc-visitor.o
  CC    qapi/qmp-input-visitor.o
  CC    qapi/qmp-output-visitor.o
  CC    qapi/qmp-registry.o
  CC    qapi/qmp-dispatch.o
  CC    qapi/string-input-visitor.o
  CC    qapi/string-output-visitor.o
  CC    qapi/opts-visitor.o
  CC    qapi/qapi-clone-visitor.o
  CC    qapi/qmp-event.o
  CC    qapi/qapi-util.o
  CC    qobject/qnull.o
  CC    qobject/qint.o
  CC    qobject/qstring.o
  CC    qobject/qdict.o
  CC    qobject/qlist.o
  CC    qobject/qfloat.o
  CC    qobject/qbool.o
  CC    qobject/qjson.o
  CC    qobject/qobject.o
  CC    qobject/json-lexer.o
  CC    qobject/json-streamer.o
  CC    qobject/json-parser.o
  GEN   trace/generated-events.c
  CC    trace/control.o
  CC    trace/qmp.o
  CC    util/osdep.o
  CC    util/cutils.o
  CC    util/unicode.o
  CC    util/qemu-timer-common.o
  CC    util/compatfd.o
  CC    util/event_notifier-posix.o
  CC    util/mmap-alloc.o
  CC    util/oslib-posix.o
  CC    util/qemu-openpty.o
  CC    util/qemu-thread-posix.o
  CC    util/memfd.o
  CC    util/envlist.o
  CC    util/path.o
  CC    util/module.o
  CC    util/bitmap.o
  CC    util/bitops.o
  CC    util/hbitmap.o
  CC    util/fifo8.o
  CC    util/acl.o
  CC    util/error.o
  CC    util/id.o
  CC    util/qemu-error.o
  CC    util/iov.o
  CC    util/qemu-config.o
  CC    util/qemu-sockets.o
  CC    util/uri.o
  CC    util/notify.o
  CC    util/qemu-option.o
  CC    util/crc32c.o
  CC    util/qemu-progress.o
  CC    util/hexdump.o
  CC    util/throttle.o
  CC    util/getauxval.o
  CC    util/readline.o
  CC    util/rfifolock.o
  CC    util/rcu.o
  CC    util/qemu-coroutine-io.o
  CC    util/qemu-coroutine.o
  CC    util/qemu-coroutine-lock.o
  CC    util/qemu-coroutine-sleep.o
  CC    util/coroutine-ucontext.o
  CC    util/buffer.o
  CC    util/timed-average.o
  CC    util/base64.o
  CC    util/log.o
  CC    util/qdist.o
  CC    util/qht.o
  CC    util/range.o
  CC    crypto/pbkdf-stub.o
  CC    stubs/arch-query-cpu-def.o
  CC    stubs/bdrv-next-monitor-owned.o
  CC    stubs/blk-commit-all.o
  CC    stubs/blockdev-close-all-bdrv-states.o
/tmp/qemu-test/src/util/qht.c: In function ‘qht_reset_size’:
/tmp/qemu-test/src/util/qht.c:413: warning: ‘new’ may be used uninitialized in this function
  CC    stubs/clock-warp.o
  CC    stubs/cpu-get-clock.o
  CC    stubs/cpu-get-icount.o
  CC    stubs/dump.o
  CC    stubs/fdset-add-fd.o
  CC    stubs/fdset-find-fd.o
  CC    stubs/fdset-get-fd.o
  CC    stubs/fdset-remove-fd.o
  CC    stubs/gdbstub.o
  CC    stubs/get-fd.o
  CC    stubs/get-next-serial.o
  CC    stubs/get-vm-name.o
  CC    stubs/is-daemonized.o
  CC    stubs/iothread-lock.o
  CC    stubs/machine-init-done.o
  CC    stubs/migr-blocker.o
  CC    stubs/mon-is-qmp.o
  CC    stubs/mon-printf.o
  CC    stubs/monitor-init.o
  CC    stubs/notify-event.o
  CC    stubs/qtest.o
  CC    stubs/replay.o
  CC    stubs/replay-user.o
  CC    stubs/reset.o
  CC    stubs/runstate-check.o
  CC    stubs/set-fd-handler.o
  CC    stubs/slirp.o
  CC    stubs/sysbus.o
  CC    stubs/trace-control.o
  CC    stubs/uuid.o
  CC    stubs/vm-stop.o
  CC    stubs/vmstate.o
  CC    stubs/cpus.o
  CC    stubs/kvm.o
  CC    stubs/qmp_pc_dimm_device_list.o
  CC    stubs/target-monitor-defs.o
  CC    stubs/target-get-monitor-def.o
  CC    stubs/vhost.o
  CC    stubs/iohandler.o
  CC    stubs/smbios_type_38.o
  CC    stubs/ipmi.o
  CC    stubs/pc_madt_cpu_entry.o
  CC    contrib/ivshmem-client/ivshmem-client.o
  CC    contrib/ivshmem-client/main.o
  CC    contrib/ivshmem-server/ivshmem-server.o
  CC    contrib/ivshmem-server/main.o
  CC    qemu-nbd.o
  CC    async.o
  CC    thread-pool.o
  CC    block.o
  CC    blockjob.o
  CC    main-loop.o
  CC    iohandler.o
  CC    qemu-timer.o
  CC    aio-posix.o
  CC    qemu-io-cmds.o
  CC    block/raw_bsd.o
  CC    block/qcow.o
  CC    block/vdi.o
  CC    block/vmdk.o
  CC    block/cloop.o
  CC    block/bochs.o
  CC    block/vpc.o
  CC    block/vvfat.o
  CC    block/qcow2.o
  CC    block/qcow2-refcount.o
  CC    block/qcow2-cluster.o
  CC    block/qcow2-snapshot.o
  CC    block/qcow2-cache.o
  CC    block/qed.o
  CC    block/qed-gencb.o
  CC    block/qed-l2-cache.o
  CC    block/qed-table.o
  CC    block/qed-cluster.o
  CC    block/qed-check.o
  CC    block/quorum.o
  CC    block/parallels.o
  CC    block/blkdebug.o
  CC    block/blkverify.o
  CC    block/blkreplay.o
  CC    block/block-backend.o
  CC    block/snapshot.o
  CC    block/qapi.o
  CC    block/raw-posix.o
  CC    block/null.o
  CC    block/mirror.o
  CC    block/commit.o
  CC    block/io.o
  CC    block/throttle-groups.o
  CC    block/nbd.o
  CC    block/nbd-client.o
  CC    block/sheepdog.o
  CC    block/accounting.o
  CC    block/dirty-bitmap.o
  CC    block/write-threshold.o
  CC    block/crypto.o
  CC    nbd/server.o
  CC    nbd/client.o
  CC    nbd/common.o
  CC    block/dmg.o
  CC    crypto/init.o
  CC    crypto/hash.o
  CC    crypto/hash-glib.o
  CC    crypto/aes.o
  CC    crypto/desrfb.o
  CC    crypto/cipher.o
  CC    crypto/tlscreds.o
  CC    crypto/tlscredsanon.o
  CC    crypto/tlscredsx509.o
  CC    crypto/tlssession.o
  CC    crypto/secret.o
  CC    crypto/random-platform.o
  CC    crypto/pbkdf.o
  CC    crypto/ivgen.o
  CC    crypto/ivgen-essiv.o
  CC    crypto/ivgen-plain.o
  CC    crypto/ivgen-plain64.o
  CC    crypto/afsplit.o
  CC    crypto/xts.o
  CC    crypto/block.o
  CC    crypto/block-qcow.o
  CC    io/channel.o
  CC    crypto/block-luks.o
  CC    io/channel-buffer.o
  CC    io/channel-command.o
  CC    io/channel-file.o
  CC    io/channel-socket.o
  CC    io/channel-tls.o
  CC    io/channel-watch.o
  CC    io/channel-websock.o
  CC    io/channel-util.o
  CC    io/task.o
  CC    qom/object.o
  CC    qom/container.o
  CC    qom/qom-qobject.o
  CC    qom/object_interfaces.o
  GEN   qemu-img-cmds.h
  CC    qemu-io.o
  CC    qemu-bridge-helper.o
  CC    blockdev.o
  CC    blockdev-nbd.o
  CC    iothread.o
  CC    qdev-monitor.o
  CC    device-hotplug.o
  CC    os-posix.o
  CC    qemu-char.o
  CC    page_cache.o
  CC    accel.o
  CC    bt-host.o
  CC    bt-vhci.o
  CC    dma-helpers.o
  CC    vl.o
  CC    tpm.o
  CC    device_tree.o
  GEN   qmp-marshal.c
  CC    qmp.o
  CC    hmp.o
  CC    tcg-runtime.o
  CC    audio/audio.o
  CC    audio/noaudio.o
  CC    audio/wavaudio.o
  CC    audio/mixeng.o
  CC    audio/sdlaudio.o
  CC    audio/ossaudio.o
  CC    audio/wavcapture.o
  CC    backends/rng.o
  CC    backends/rng-egd.o
  CC    backends/rng-random.o
  CC    backends/msmouse.o
  CC    backends/testdev.o
  CC    backends/tpm.o
  CC    backends/hostmem.o
  CC    backends/hostmem-ram.o
  CC    backends/hostmem-file.o
  CC    block/stream.o
  CC    block/backup.o
  CC    disas/arm.o
  CC    disas/i386.o
  CC    fsdev/qemu-fsdev-dummy.o
  CC    fsdev/qemu-fsdev-opts.o
  CC    hw/acpi/core.o
  CC    hw/acpi/piix4.o
  CC    hw/acpi/pcihp.o
  CC    hw/acpi/ich9.o
  CC    hw/acpi/tco.o
  CC    hw/acpi/cpu_hotplug.o
  CC    hw/acpi/memory_hotplug.o
  CC    hw/acpi/memory_hotplug_acpi_table.o
  CC    hw/acpi/cpu.o
  CC    hw/acpi/acpi_interface.o
  CC    hw/acpi/bios-linker-loader.o
  CC    hw/acpi/aml-build.o
  CC    hw/acpi/ipmi.o
  CC    hw/audio/sb16.o
  CC    hw/audio/es1370.o
  CC    hw/audio/ac97.o
  CC    hw/audio/fmopl.o
  CC    hw/audio/adlib.o
  CC    hw/audio/gus.o
  CC    hw/audio/gusemu_hal.o
  CC    hw/audio/gusemu_mixer.o
  CC    hw/audio/cs4231a.o
  CC    hw/audio/intel-hda.o
  CC    hw/audio/hda-codec.o
  CC    hw/audio/pcspk.o
  CC    hw/audio/wm8750.o
  CC    hw/audio/pl041.o
  CC    hw/audio/lm4549.o
  CC    hw/audio/marvell_88w8618.o
  CC    hw/block/block.o
  CC    hw/block/cdrom.o
  CC    hw/block/hd-geometry.o
  CC    hw/block/fdc.o
  CC    hw/block/m25p80.o
  CC    hw/block/nand.o
  CC    hw/block/pflash_cfi01.o
  CC    hw/block/pflash_cfi02.o
  CC    hw/block/ecc.o
  CC    hw/block/onenand.o
  CC    hw/block/nvme.o
  CC    hw/bt/core.o
  CC    hw/bt/l2cap.o
  CC    hw/bt/sdp.o
  CC    hw/bt/hci.o
  CC    hw/bt/hid.o
  CC    hw/bt/hci-csr.o
  CC    hw/char/ipoctal232.o
  CC    hw/char/parallel.o
  CC    hw/char/pl011.o
  CC    hw/char/serial.o
  CC    hw/char/serial-isa.o
  CC    hw/char/serial-pci.o
  CC    hw/char/virtio-console.o
  CC    hw/char/cadence_uart.o
  CC    hw/char/debugcon.o
  CC    hw/char/imx_serial.o
  CC    hw/core/qdev.o
  CC    hw/core/qdev-properties.o
  CC    hw/core/bus.o
  CC    hw/core/fw-path-provider.o
  CC    hw/core/irq.o
  CC    hw/core/hotplug.o
  CC    hw/core/ptimer.o
  CC    hw/core/sysbus.o
  CC    hw/core/machine.o
  CC    hw/core/null-machine.o
  CC    hw/core/loader.o
  CC    hw/core/qdev-properties-system.o
  CC    hw/core/register.o
  CC    hw/core/platform-bus.o
  CC    hw/display/ads7846.o
  CC    hw/display/cirrus_vga.o
  CC    hw/display/pl110.o
  CC    hw/display/ssd0303.o
  CC    hw/display/ssd0323.o
  CC    hw/display/vga-pci.o
  CC    hw/display/vga-isa.o
  CC    hw/display/vmware_vga.o
  CC    hw/display/blizzard.o
  CC    hw/display/exynos4210_fimd.o
  CC    hw/display/framebuffer.o
  CC    hw/display/tc6393xb.o
  CC    hw/dma/pl080.o
  CC    hw/dma/pl330.o
  CC    hw/dma/i8257.o
  CC    hw/dma/xlnx-zynq-devcfg.o
  CC    hw/gpio/max7310.o
  CC    hw/gpio/pl061.o
  CC    hw/gpio/zaurus.o
  CC    hw/gpio/gpio_key.o
  CC    hw/i2c/core.o
  CC    hw/i2c/smbus.o
  CC    hw/i2c/smbus_eeprom.o
  CC    hw/i2c/i2c-ddc.o
  CC    hw/i2c/versatile_i2c.o
  CC    hw/i2c/smbus_ich9.o
  CC    hw/i2c/pm_smbus.o
  CC    hw/i2c/bitbang_i2c.o
  CC    hw/i2c/exynos4210_i2c.o
  CC    hw/i2c/imx_i2c.o
  CC    hw/i2c/aspeed_i2c.o
  CC    hw/ide/core.o
  CC    hw/ide/atapi.o
  CC    hw/ide/qdev.o
  CC    hw/ide/pci.o
  CC    hw/ide/isa.o
  CC    hw/ide/piix.o
  CC    hw/ide/microdrive.o
  CC    hw/ide/ahci.o
  CC    hw/ide/ich.o
  CC    hw/input/hid.o
  CC    hw/input/lm832x.o
  CC    hw/input/pckbd.o
  CC    hw/input/pl050.o
  CC    hw/input/ps2.o
  CC    hw/input/stellaris_input.o
  CC    hw/input/tsc2005.o
  CC    hw/input/vmmouse.o
  CC    hw/input/virtio-input.o
  CC    hw/input/virtio-input-hid.o
  CC    hw/input/virtio-input-host.o
  CC    hw/intc/i8259_common.o
  CC    hw/intc/i8259.o
  CC    hw/intc/pl190.o
  CC    hw/intc/imx_avic.o
  CC    hw/intc/realview_gic.o
  CC    hw/intc/ioapic_common.o
  CC    hw/intc/arm_gic_common.o
  CC    hw/intc/arm_gic.o
  CC    hw/intc/arm_gicv2m.o
  CC    hw/intc/arm_gicv3_common.o
  CC    hw/intc/arm_gicv3.o
  CC    hw/intc/arm_gicv3_dist.o
  CC    hw/intc/arm_gicv3_redist.o
  CC    hw/ipack/ipack.o
  CC    hw/ipack/tpci200.o
  CC    hw/ipmi/ipmi.o
  CC    hw/ipmi/ipmi_bmc_sim.o
  CC    hw/ipmi/ipmi_bmc_extern.o
  CC    hw/ipmi/isa_ipmi_kcs.o
  CC    hw/ipmi/isa_ipmi_bt.o
  CC    hw/isa/isa-bus.o
  CC    hw/isa/apm.o
  CC    hw/mem/pc-dimm.o
  CC    hw/mem/nvdimm.o
  CC    hw/misc/applesmc.o
  CC    hw/misc/max111x.o
  CC    hw/misc/tmp105.o
  CC    hw/misc/debugexit.o
  CC    hw/misc/sga.o
  CC    hw/misc/pc-testdev.o
  CC    hw/misc/pci-testdev.o
  CC    hw/misc/arm_l2x0.o
  CC    hw/misc/arm_integrator_debug.o
  CC    hw/misc/a9scu.o
  CC    hw/misc/arm11scu.o
  CC    hw/net/ne2000.o
  CC    hw/net/eepro100.o
  CC    hw/net/pcnet-pci.o
  CC    hw/net/pcnet.o
  CC    hw/net/e1000.o
  CC    hw/net/e1000x_common.o
  CC    hw/net/net_tx_pkt.o
  CC    hw/net/net_rx_pkt.o
  CC    hw/net/e1000e.o
  CC    hw/net/e1000e_core.o
  CC    hw/net/rtl8139.o
  CC    hw/net/vmxnet3.o
  CC    hw/net/smc91c111.o
  CC    hw/net/lan9118.o
  CC    hw/net/ne2000-isa.o
  CC    hw/net/xgmac.o
  CC    hw/net/allwinner_emac.o
  CC    hw/net/imx_fec.o
  CC    hw/net/cadence_gem.o
  CC    hw/net/stellaris_enet.o
  CC    hw/net/rocker/rocker.o
  CC    hw/net/rocker/rocker_fp.o
  CC    hw/net/rocker/rocker_desc.o
  CC    hw/net/rocker/rocker_world.o
  CC    hw/net/rocker/rocker_of_dpa.o
  CC    hw/nvram/eeprom93xx.o
  CC    hw/nvram/fw_cfg.o
  CC    hw/pci-bridge/pci_bridge_dev.o
  CC    hw/pci-bridge/pci_expander_bridge.o
  CC    hw/pci-bridge/xio3130_upstream.o
  CC    hw/pci-bridge/xio3130_downstream.o
  CC    hw/pci-bridge/ioh3420.o
  CC    hw/pci-bridge/i82801b11.o
  CC    hw/pci-host/pam.o
  CC    hw/pci-host/versatile.o
  CC    hw/pci-host/piix.o
  CC    hw/pci-host/q35.o
  CC    hw/pci-host/gpex.o
  CC    hw/pci/pci.o
  CC    hw/pci/pci_bridge.o
  CC    hw/pci/msix.o
/tmp/qemu-test/src/hw/nvram/fw_cfg.c: In function ‘fw_cfg_dma_transfer’:
/tmp/qemu-test/src/hw/nvram/fw_cfg.c:330: warning: ‘read’ may be used uninitialized in this function
  CC    hw/pci/msi.o
  CC    hw/pci/shpc.o
  CC    hw/pci/slotid_cap.o
  CC    hw/pci/pci_host.o
  CC    hw/pci/pcie_host.o
  CC    hw/pci/pcie.o
  CC    hw/pci/pcie_aer.o
  CC    hw/pci/pcie_port.o
  CC    hw/pci/pci-stub.o
  CC    hw/pcmcia/pcmcia.o
  CC    hw/scsi/scsi-disk.o
  CC    hw/scsi/scsi-generic.o
  CC    hw/scsi/scsi-bus.o
  CC    hw/scsi/lsi53c895a.o
  CC    hw/scsi/mptsas.o
  CC    hw/scsi/mptconfig.o
  CC    hw/scsi/mptendian.o
  CC    hw/scsi/megasas.o
  CC    hw/scsi/vmw_pvscsi.o
  CC    hw/scsi/esp.o
  CC    hw/scsi/esp-pci.o
  CC    hw/sd/pl181.o
  CC    hw/sd/ssi-sd.o
  CC    hw/sd/sd.o
  CC    hw/sd/core.o
  CC    hw/sd/sdhci.o
  CC    hw/smbios/smbios.o
  CC    hw/smbios/smbios_type_38.o
  CC    hw/ssi/pl022.o
  CC    hw/ssi/ssi.o
  CC    hw/ssi/xilinx_spips.o
  CC    hw/ssi/aspeed_smc.o
  CC    hw/timer/arm_timer.o
  CC    hw/timer/arm_mptimer.o
  CC    hw/timer/a9gtimer.o
  CC    hw/timer/cadence_ttc.o
  CC    hw/timer/ds1338.o
  CC    hw/timer/hpet.o
  CC    hw/timer/i8254_common.o
  CC    hw/timer/i8254.o
  CC    hw/timer/pl031.o
  CC    hw/timer/twl92230.o
  CC    hw/timer/imx_epit.o
  CC    hw/timer/imx_gpt.o
  CC    hw/timer/stm32f2xx_timer.o
  CC    hw/timer/aspeed_timer.o
  CC    hw/tpm/tpm_tis.o
  CC    hw/tpm/tpm_passthrough.o
  CC    hw/tpm/tpm_util.o
  CC    hw/usb/core.o
  CC    hw/usb/combined-packet.o
  CC    hw/usb/bus.o
  CC    hw/usb/libhw.o
  CC    hw/usb/desc.o
  CC    hw/usb/desc-msos.o
  CC    hw/usb/hcd-uhci.o
  CC    hw/usb/hcd-ohci.o
  CC    hw/usb/hcd-ehci.o
  CC    hw/usb/hcd-ehci-pci.o
  CC    hw/usb/hcd-ehci-sysbus.o
  CC    hw/usb/hcd-xhci.o
  CC    hw/usb/hcd-musb.o
  CC    hw/usb/dev-hub.o
  CC    hw/usb/dev-hid.o
  CC    hw/usb/dev-wacom.o
  CC    hw/usb/dev-storage.o
  CC    hw/usb/dev-uas.o
  CC    hw/usb/dev-audio.o
  CC    hw/usb/dev-serial.o
  CC    hw/usb/dev-network.o
  CC    hw/usb/dev-bluetooth.o
  CC    hw/usb/dev-smartcard-reader.o
  CC    hw/usb/dev-mtp.o
  CC    hw/usb/host-stub.o
  CC    hw/virtio/virtio-rng.o
  CC    hw/virtio/virtio-pci.o
  CC    hw/virtio/virtio-bus.o
  CC    hw/virtio/virtio-mmio.o
  CC    hw/watchdog/watchdog.o
  CC    hw/watchdog/wdt_i6300esb.o
  CC    hw/watchdog/wdt_ib700.o
  CC    migration/migration.o
  CC    migration/socket.o
  CC    migration/fd.o
  CC    migration/exec.o
  CC    migration/tls.o
  CC    migration/vmstate.o
  CC    migration/qemu-file.o
  CC    migration/qemu-file-channel.o
  CC    migration/xbzrle.o
  CC    migration/postcopy-ram.o
  CC    migration/qjson.o
  CC    migration/block.o
  CC    net/net.o
  CC    net/queue.o
  CC    net/checksum.o
  CC    net/util.o
  CC    net/hub.o
  CC    net/socket.o
  CC    net/dump.o
  CC    net/eth.o
  CC    net/l2tpv3.o
  CC    net/tap.o
  CC    net/vhost-user.o
  CC    net/tap-linux.o
  CC    net/slirp.o
  CC    net/filter.o
  CC    net/filter-buffer.o
  CC    net/filter-mirror.o
  CC    qom/cpu.o
  CC    replay/replay.o
  CC    replay/replay-internal.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:68: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  CC    replay/replay-events.o
  CC    replay/replay-time.o
  CC    replay/replay-input.o
  CC    slirp/cksum.o
  CC    replay/replay-char.o
  CC    slirp/if.o
  CC    slirp/ip_icmp.o
  CC    slirp/ip6_icmp.o
  CC    slirp/ip6_input.o
  CC    slirp/ip6_output.o
  CC    slirp/ip_input.o
  CC    slirp/ip_output.o
  CC    slirp/dnssearch.o
  CC    slirp/dhcpv6.o
  CC    slirp/slirp.o
  CC    slirp/mbuf.o
  CC    slirp/misc.o
  CC    slirp/sbuf.o
  CC    slirp/socket.o
  CC    slirp/tcp_input.o
  CC    slirp/tcp_output.o
  CC    slirp/tcp_subr.o
/tmp/qemu-test/src/slirp/tcp_input.c: In function ‘tcp_input’:
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_p’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_len’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_tos’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_id’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_off’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_ttl’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_sum’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_src.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_dst.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:220: warning: ‘save_ip6.ip_nh’ may be used uninitialized in this function
  CC    slirp/tcp_timer.o
  CC    slirp/udp.o
  CC    slirp/udp6.o
  CC    slirp/bootp.o
  CC    slirp/tftp.o
  CC    slirp/arp_table.o
  CC    slirp/ndp_table.o
  CC    ui/keymaps.o
  CC    ui/console.o
  CC    ui/cursor.o
  CC    ui/qemu-pixman.o
  CC    ui/input.o
  CC    ui/input-legacy.o
  CC    ui/input-keymap.o
  CC    ui/input-linux.o
  CC    ui/sdl.o
  CC    ui/sdl_zoom.o
  CC    ui/x_keymap.o
  CC    ui/vnc.o
  CC    ui/vnc-enc-zlib.o
  CC    ui/vnc-enc-hextile.o
  CC    ui/vnc-enc-tight.o
  CC    ui/vnc-enc-zrle.o
  CC    ui/vnc-palette.o
  CC    ui/vnc-auth-vencrypt.o
  CC    ui/vnc-ws.o
  CC    ui/vnc-jobs.o
  LINK  tests/qemu-iotests/socket_scm_helper
  CC    qga/commands.o
  CC    qga/guest-agent-command-state.o
  CC    qga/main.o
  CC    qga/commands-posix.o
  CC    qga/channel-posix.o
  AS    optionrom/multiboot.o
  CC    qga/qapi-generated/qga-qapi-types.o
  AS    optionrom/linuxboot.o
  CC    qga/qapi-generated/qga-qapi-visit.o
  CC    qga/qapi-generated/qga-qmp-marshal.o
  CC    optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
  AS    optionrom/kvmvapic.o
  CC    qmp-introspect.o
  CC    qapi-types.o
  Building optionrom/multiboot.img
  Building optionrom/linuxboot.img
  Building optionrom/linuxboot_dma.img
  Building optionrom/kvmvapic.img
  Building optionrom/multiboot.raw
  CC    qapi-visit.o
  Building optionrom/linuxboot.raw
  Building optionrom/linuxboot_dma.raw
  CC    qapi-event.o
  Building optionrom/kvmvapic.raw
  Signing optionrom/multiboot.bin
  Signing optionrom/linuxboot.bin
  Signing optionrom/linuxboot_dma.bin
  Signing optionrom/kvmvapic.bin
  AR    libqemustub.a
  CC    qemu-img.o
  CC    qmp-marshal.o
  CC    trace/generated-events.o
  AR    libqemuutil.a
  LINK  qemu-ga
  LINK  ivshmem-client
  LINK  ivshmem-server
  LINK  qemu-nbd
  LINK  qemu-img
  LINK  qemu-io
  LINK  qemu-bridge-helper
  GEN   aarch64-softmmu/hmp-commands.h
  GEN   aarch64-softmmu/hmp-commands-info.h
  GEN   aarch64-softmmu/qmp-commands-old.h
  GEN   aarch64-softmmu/config-target.h
  GEN   x86_64-softmmu/hmp-commands.h
  GEN   x86_64-softmmu/hmp-commands-info.h
  GEN   x86_64-softmmu/qmp-commands-old.h
  GEN   x86_64-softmmu/config-target.h
  CC    aarch64-softmmu/exec.o
  CC    aarch64-softmmu/cpu-exec.o
  CC    aarch64-softmmu/translate-all.o
  CC    aarch64-softmmu/tcg/tcg.o
  CC    aarch64-softmmu/translate-common.o
  CC    aarch64-softmmu/cpu-exec-common.o
  CC    aarch64-softmmu/tcg/tcg-op.o
  CC    aarch64-softmmu/tcg/optimize.o
  CC    x86_64-softmmu/exec.o
  CC    aarch64-softmmu/tcg/tcg-common.o
  CC    aarch64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/translate-all.o
  CC    aarch64-softmmu/disas.o
  CC    x86_64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/translate-common.o
  CC    x86_64-softmmu/cpu-exec-common.o
  GEN   aarch64-softmmu/gdbstub-xml.c
  CC    aarch64-softmmu/kvm-stub.o
  CC    aarch64-softmmu/arch_init.o
  CC    aarch64-softmmu/cpus.o
  CC    aarch64-softmmu/monitor.o
  CC    aarch64-softmmu/gdbstub.o
  CC    x86_64-softmmu/tcg/tcg.o
  CC    x86_64-softmmu/tcg/tcg-op.o
  CC    aarch64-softmmu/balloon.o
  CC    x86_64-softmmu/tcg/optimize.o
  CC    aarch64-softmmu/ioport.o
  CC    aarch64-softmmu/numa.o
  CC    aarch64-softmmu/qtest.o
  CC    x86_64-softmmu/tcg/tcg-common.o
  CC    aarch64-softmmu/bootdevice.o
  CC    x86_64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/disas.o
  CC    aarch64-softmmu/memory.o
  CC    x86_64-softmmu/arch_init.o
  CC    aarch64-softmmu/cputlb.o
  CC    aarch64-softmmu/memory_mapping.o
  CC    x86_64-softmmu/cpus.o
  CC    aarch64-softmmu/dump.o
  CC    aarch64-softmmu/migration/ram.o
  CC    x86_64-softmmu/monitor.o
  CC    x86_64-softmmu/gdbstub.o
  CC    x86_64-softmmu/balloon.o
  CC    aarch64-softmmu/migration/savevm.o
  CC    x86_64-softmmu/ioport.o
  CC    x86_64-softmmu/numa.o
  CC    x86_64-softmmu/qtest.o
  CC    x86_64-softmmu/bootdevice.o
  CC    aarch64-softmmu/xen-common-stub.o
  CC    aarch64-softmmu/xen-hvm-stub.o
  CC    x86_64-softmmu/kvm-all.o
  CC    x86_64-softmmu/memory.o
  CC    aarch64-softmmu/hw/block/virtio-blk.o
  CC    x86_64-softmmu/cputlb.o
  CC    x86_64-softmmu/memory_mapping.o
  CC    x86_64-softmmu/dump.o
  CC    x86_64-softmmu/migration/ram.o
  CC    aarch64-softmmu/hw/block/dataplane/virtio-blk.o
  CC    aarch64-softmmu/hw/char/exynos4210_uart.o
  CC    aarch64-softmmu/hw/char/omap_uart.o
  CC    x86_64-softmmu/migration/savevm.o
  CC    x86_64-softmmu/xen-common-stub.o
  CC    aarch64-softmmu/hw/char/digic-uart.o
  CC    aarch64-softmmu/hw/char/stm32f2xx_usart.o
  CC    aarch64-softmmu/hw/char/bcm2835_aux.o
  CC    x86_64-softmmu/xen-hvm-stub.o
  CC    aarch64-softmmu/hw/char/virtio-serial-bus.o
  CC    aarch64-softmmu/hw/core/nmi.o
  CC    aarch64-softmmu/hw/cpu/arm11mpcore.o
  CC    aarch64-softmmu/hw/cpu/realview_mpcore.o
  CC    aarch64-softmmu/hw/cpu/a9mpcore.o
  CC    x86_64-softmmu/hw/acpi/nvdimm.o
  CC    aarch64-softmmu/hw/cpu/a15mpcore.o
  CC    x86_64-softmmu/hw/block/virtio-blk.o
  CC    aarch64-softmmu/hw/cpu/core.o
  CC    aarch64-softmmu/hw/display/omap_dss.o
  CC    x86_64-softmmu/hw/block/dataplane/virtio-blk.o
  CC    aarch64-softmmu/hw/display/omap_lcdc.o
  CC    x86_64-softmmu/hw/char/virtio-serial-bus.o
  CC    x86_64-softmmu/hw/core/nmi.o
  CC    aarch64-softmmu/hw/display/pxa2xx_lcd.o
  CC    aarch64-softmmu/hw/display/bcm2835_fb.o
  CC    x86_64-softmmu/hw/cpu/core.o
  CC    x86_64-softmmu/hw/display/vga.o
  CC    aarch64-softmmu/hw/display/vga.o
  CC    x86_64-softmmu/hw/display/virtio-gpu.o
  CC    x86_64-softmmu/hw/display/virtio-gpu-3d.o
  CC    x86_64-softmmu/hw/display/virtio-gpu-pci.o
  CC    x86_64-softmmu/hw/display/virtio-vga.o
  CC    x86_64-softmmu/hw/intc/apic.o
  CC    x86_64-softmmu/hw/intc/apic_common.o
  CC    aarch64-softmmu/hw/display/virtio-gpu.o
  CC    x86_64-softmmu/hw/intc/ioapic.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-3d.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-pci.o
  CC    x86_64-softmmu/hw/isa/lpc_ich9.o
  CC    aarch64-softmmu/hw/display/dpcd.o
  CC    aarch64-softmmu/hw/display/xlnx_dp.o
  CC    aarch64-softmmu/hw/dma/xlnx_dpdma.o
  CC    aarch64-softmmu/hw/dma/omap_dma.o
  CC    aarch64-softmmu/hw/dma/soc_dma.o
  CC    aarch64-softmmu/hw/dma/pxa2xx_dma.o
  CC    aarch64-softmmu/hw/dma/bcm2835_dma.o
  CC    x86_64-softmmu/hw/misc/vmport.o
  CC    aarch64-softmmu/hw/gpio/omap_gpio.o
  CC    x86_64-softmmu/hw/misc/ivshmem.o
  CC    aarch64-softmmu/hw/gpio/imx_gpio.o
  CC    x86_64-softmmu/hw/misc/pvpanic.o
  CC    x86_64-softmmu/hw/misc/edu.o
  CC    x86_64-softmmu/hw/misc/hyperv_testdev.o
  CC    aarch64-softmmu/hw/i2c/omap_i2c.o
  CC    aarch64-softmmu/hw/input/pxa2xx_keypad.o
  CC    aarch64-softmmu/hw/input/tsc210x.o
  CC    aarch64-softmmu/hw/intc/armv7m_nvic.o
  CC    x86_64-softmmu/hw/net/virtio-net.o
  CC    x86_64-softmmu/hw/net/vhost_net.o
  CC    aarch64-softmmu/hw/intc/exynos4210_gic.o
  CC    x86_64-softmmu/hw/scsi/virtio-scsi.o
  CC    x86_64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC    aarch64-softmmu/hw/intc/exynos4210_combiner.o
  CC    x86_64-softmmu/hw/scsi/vhost-scsi.o
  CC    aarch64-softmmu/hw/intc/omap_intc.o
  CC    x86_64-softmmu/hw/timer/mc146818rtc.o
  CC    aarch64-softmmu/hw/intc/bcm2835_ic.o
  CC    x86_64-softmmu/hw/vfio/common.o
  CC    x86_64-softmmu/hw/vfio/pci.o
  CC    x86_64-softmmu/hw/vfio/pci-quirks.o
  CC    x86_64-softmmu/hw/vfio/platform.o
  CC    aarch64-softmmu/hw/intc/bcm2836_control.o
  CC    aarch64-softmmu/hw/intc/allwinner-a10-pic.o
  CC    aarch64-softmmu/hw/intc/aspeed_vic.o
  CC    x86_64-softmmu/hw/vfio/calxeda-xgmac.o
  CC    x86_64-softmmu/hw/vfio/amd-xgbe.o
  CC    aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
  CC    x86_64-softmmu/hw/vfio/spapr.o
  CC    x86_64-softmmu/hw/virtio/virtio.o
  CC    x86_64-softmmu/hw/virtio/virtio-balloon.o
  CC    x86_64-softmmu/hw/virtio/vhost.o
  CC    aarch64-softmmu/hw/misc/ivshmem.o
  CC    aarch64-softmmu/hw/misc/arm_sysctl.o
  CC    aarch64-softmmu/hw/misc/cbus.o
  CC    x86_64-softmmu/hw/virtio/vhost-backend.o
  CC    x86_64-softmmu/hw/virtio/vhost-user.o
  CC    x86_64-softmmu/hw/i386/multiboot.o
  CC    x86_64-softmmu/hw/i386/pc.o
  CC    aarch64-softmmu/hw/misc/exynos4210_pmu.o
  CC    aarch64-softmmu/hw/misc/imx_ccm.o
/tmp/qemu-test/src/hw/virtio/vhost-backend.c: In function ‘vhost_kernel_update_device_iotlb’:
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:216: error: unknown field ‘iotlb’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: error: unknown field ‘iova’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: warning: missing braces around initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: warning: (near initialization for ‘msg.<anonymous>.iotlb’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: error: unknown field ‘uaddr’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: error: unknown field ‘size’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: error: unknown field ‘type’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c: In function ‘vhost_kernel_invalidate_device_iotlb’:
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:251: error: unknown field ‘iotlb’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: error: unknown field ‘iova’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: warning: missing braces around initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: warning: (near initialization for ‘msg.<anonymous>.iotlb’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: error: unknown field ‘size’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: error: unknown field ‘type’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: warning: (near initialization for ‘msg.<anonymous>’)
make[1]: *** [hw/virtio/vhost-backend.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/hw/misc/imx31_ccm.o
  CC    aarch64-softmmu/hw/misc/imx25_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_src.o
  CC    aarch64-softmmu/hw/misc/mst_fpga.o
  CC    aarch64-softmmu/hw/misc/omap_clk.o
  CC    aarch64-softmmu/hw/misc/omap_gpmc.o
  CC    aarch64-softmmu/hw/misc/omap_l4.o
  CC    aarch64-softmmu/hw/misc/omap_sdrc.o
  CC    aarch64-softmmu/hw/misc/omap_tap.o
  CC    aarch64-softmmu/hw/misc/bcm2835_mbox.o
  CC    aarch64-softmmu/hw/misc/bcm2835_property.o
  CC    aarch64-softmmu/hw/misc/zynq_slcr.o
  CC    aarch64-softmmu/hw/misc/zynq-xadc.o
  CC    aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
make: *** [subdir-x86_64-softmmu] Error 2
make: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/hw/misc/edu.o
  CC    aarch64-softmmu/hw/misc/auxbus.o
  CC    aarch64-softmmu/hw/misc/aspeed_scu.o
  CC    aarch64-softmmu/hw/net/virtio-net.o
  CC    aarch64-softmmu/hw/net/vhost_net.o
  CC    aarch64-softmmu/hw/pcmcia/pxa2xx.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC    aarch64-softmmu/hw/scsi/vhost-scsi.o
  CC    aarch64-softmmu/hw/sd/omap_mmc.o
  CC    aarch64-softmmu/hw/sd/pxa2xx_mmci.o
  CC    aarch64-softmmu/hw/ssi/omap_spi.o
  CC    aarch64-softmmu/hw/ssi/imx_spi.o
  CC    aarch64-softmmu/hw/timer/exynos4210_mct.o
  CC    aarch64-softmmu/hw/timer/exynos4210_pwm.o
  CC    aarch64-softmmu/hw/timer/exynos4210_rtc.o
  CC    aarch64-softmmu/hw/timer/omap_gptimer.o
  CC    aarch64-softmmu/hw/timer/omap_synctimer.o
  CC    aarch64-softmmu/hw/timer/pxa2xx_timer.o
  CC    aarch64-softmmu/hw/timer/digic-timer.o
  CC    aarch64-softmmu/hw/timer/allwinner-a10-pit.o
  CC    aarch64-softmmu/hw/usb/tusb6010.o
  CC    aarch64-softmmu/hw/vfio/common.o
  CC    aarch64-softmmu/hw/vfio/pci.o
  CC    aarch64-softmmu/hw/vfio/pci-quirks.o
  CC    aarch64-softmmu/hw/vfio/platform.o
  CC    aarch64-softmmu/hw/vfio/calxeda-xgmac.o
  CC    aarch64-softmmu/hw/vfio/amd-xgbe.o
  CC    aarch64-softmmu/hw/vfio/spapr.o
  CC    aarch64-softmmu/hw/virtio/virtio.o
  CC    aarch64-softmmu/hw/virtio/virtio-balloon.o
  CC    aarch64-softmmu/hw/virtio/vhost.o
  CC    aarch64-softmmu/hw/virtio/vhost-backend.o
  CC    aarch64-softmmu/hw/virtio/vhost-user.o
  CC    aarch64-softmmu/hw/arm/boot.o
  CC    aarch64-softmmu/hw/arm/collie.o
/tmp/qemu-test/src/hw/virtio/vhost-backend.c: In function ‘vhost_kernel_update_device_iotlb’:
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:216: error: unknown field ‘iotlb’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: error: unknown field ‘iova’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: warning: missing braces around initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:217: warning: (near initialization for ‘msg.<anonymous>.iotlb’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: error: unknown field ‘uaddr’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:218: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: error: unknown field ‘size’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:219: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: error: unknown field ‘type’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:220: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c: In function ‘vhost_kernel_invalidate_device_iotlb’:
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:251: error: unknown field ‘iotlb’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: error: unknown field ‘iova’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: warning: missing braces around initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:252: warning: (near initialization for ‘msg.<anonymous>.iotlb’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: error: unknown field ‘size’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:253: warning: (near initialization for ‘msg.<anonymous>’)
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: error: unknown field ‘type’ specified in initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: warning: excess elements in union initializer
/tmp/qemu-test/src/hw/virtio/vhost-backend.c:254: warning: (near initialization for ‘msg.<anonymous>’)
make[1]: *** [hw/virtio/vhost-backend.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [subdir-aarch64-softmmu] Error 2
tests/docker/Makefile.include:104: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 1
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started" Jason Wang
@ 2016-08-30  3:37   ` Alex Williamson
  2016-08-31  2:45     ` Jason Wang
  0 siblings, 1 reply; 52+ messages in thread
From: Alex Williamson @ 2016-08-30  3:37 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, qemu-devel, pbonzini, peterx, cornelia.huck, wexu, vkaplans

On Tue, 30 Aug 2016 11:06:58 +0800
Jason Wang <jasowang@redhat.com> wrote:

> From: Peter Xu <peterx@redhat.com>
> 
> This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
> device IOTLB API will get notified and send invalidation request to
> vhost through this notifier.

AFAICT this series does not address the original problem for which
commit 3cb3b1549f54 was added.  We've only addressed the very narrow
use case of a device iotlb firing the iommu notifier therefore this
change is a regression versus 2.7 since it allows invalid
configurations with a physical iommu which will never receive the
necessary notifies from intel-iommu emulation to work properly.  Thanks,

Alex

> Cc: Alex Williamson <alex.williamson@redhat.com>
> Signed-off-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>  hw/i386/intel_iommu.c | 12 ------------
>  1 file changed, 12 deletions(-)
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 298faab..15d1216 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -25,7 +25,6 @@
>  #include "exec/address-spaces.h"
>  #include "intel_iommu_internal.h"
>  #include "hw/pci/pci.h"
> -#include "hw/pci/pci_bus.h"
>  #include "hw/i386/pc.h"
>  #include "hw/boards.h"
>  #include "hw/i386/x86-iommu.h"
> @@ -2041,16 +2040,6 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
>      return ret;
>  }
>  
> -static void vtd_iommu_notify_started(MemoryRegion *iommu)
> -{
> -    VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
> -
> -    hw_error("Device at bus %s addr %02x.%d requires iommu notifier which "
> -             "is currently not supported by intel-iommu emulation",
> -             vtd_as->bus->qbus.name, PCI_SLOT(vtd_as->devfn),
> -             PCI_FUNC(vtd_as->devfn));
> -}
> -
>  static const VMStateDescription vtd_vmstate = {
>      .name = "iommu-intel",
>      .unmigratable = 1,
> @@ -2418,7 +2407,6 @@ static void vtd_init(IntelIOMMUState *s)
>      memset(s->womask, 0, DMAR_REG_SIZE);
>  
>      s->iommu_ops.translate = vtd_iommu_translate;
> -    s->iommu_ops.notify_started = vtd_iommu_notify_started;
>      s->root = 0;
>      s->root_extended = false;
>      s->dmar_enabled = false;

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
@ 2016-08-30  7:31   ` Cornelia Huck
  2016-08-30 10:02     ` Michael S. Tsirkin
  2016-08-31  2:47     ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
  2016-09-05  2:26   ` Wei Xu
  2016-09-05  2:33   ` Michael S. Tsirkin
  2 siblings, 2 replies; 52+ messages in thread
From: Cornelia Huck @ 2016-08-30  7:31 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, 30 Aug 2016 11:06:50 +0800
Jason Wang <jasowang@redhat.com> wrote:

> Currently, all virtio devices bypass IOMMU completely. This is because
> address_space_memory is assumed and used during DMA emulation. This
> patch converts the virtio core API to use DMA API. This idea is
> 
> - introducing a new transport specific helper to query the dma address
>   space. (only pci version is implemented).
> - query and use this address space during virtio device guest memory
>   accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled
>   for this device.
> 
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Amit Shah <amit.shah@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: qemu-block@nongnu.org
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>  hw/block/virtio-blk.c             |  2 +-
>  hw/char/virtio-serial-bus.c       |  3 +-
>  hw/scsi/virtio-scsi.c             |  4 ++-
>  hw/virtio/virtio-pci.c            | 14 +++++++++
>  hw/virtio/virtio.c                | 62 ++++++++++++++++++++++++---------------
>  include/hw/virtio/virtio-access.h | 43 ++++++++++++++++++++-------
>  include/hw/virtio/virtio-bus.h    |  1 +
>  include/hw/virtio/virtio.h        |  8 +++--
>  8 files changed, 98 insertions(+), 39 deletions(-)
> 

> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> index 440b455..4071dad 100644
> --- a/include/hw/virtio/virtio-access.h
> +++ b/include/hw/virtio/virtio-access.h
> @@ -17,12 +17,25 @@
>  #define QEMU_VIRTIO_ACCESS_H
> 
>  #include "hw/virtio/virtio.h"
> +#include "hw/virtio/virtio-bus.h"
>  #include "exec/address-spaces.h"
> 
>  #if defined(TARGET_PPC64) || defined(TARGET_ARM)
>  #define LEGACY_VIRTIO_IS_BIENDIAN 1
>  #endif
> 
> +static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
> +{
> +    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +
> +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
> +        k->get_dma_as) {
> +        return k->get_dma_as(qbus->parent);
> +    }
> +    return &address_space_memory;
> +}

One thing I'm a bit worried about is that we're introducing a check
even if we know that the device will never support
VIRTIO_F_IOMMU_PLATFORM (i.e. virtio-ccw). The qom incantations will
add cycles to any invocation of this.

Is the address space likely to change during device lifetime? Can we
cache it in some way?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  7:31   ` Cornelia Huck
@ 2016-08-30 10:02     ` Michael S. Tsirkin
  2016-08-30 10:21       ` Michael S. Tsirkin
  2016-08-31  2:47     ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
  1 sibling, 1 reply; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-08-30 10:02 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, Aug 30, 2016 at 09:31:27AM +0200, Cornelia Huck wrote:
> On Tue, 30 Aug 2016 11:06:50 +0800
> Jason Wang <jasowang@redhat.com> wrote:
> 
> > Currently, all virtio devices bypass IOMMU completely. This is because
> > address_space_memory is assumed and used during DMA emulation. This
> > patch converts the virtio core API to use DMA API. This idea is
> > 
> > - introducing a new transport specific helper to query the dma address
> >   space. (only pci version is implemented).
> > - query and use this address space during virtio device guest memory
> >   accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled
> >   for this device.
> > 
> > Cc: Michael S. Tsirkin <mst@redhat.com>
> > Cc: Stefan Hajnoczi <stefanha@redhat.com>
> > Cc: Kevin Wolf <kwolf@redhat.com>
> > Cc: Amit Shah <amit.shah@redhat.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Cc: qemu-block@nongnu.org
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > ---
> >  hw/block/virtio-blk.c             |  2 +-
> >  hw/char/virtio-serial-bus.c       |  3 +-
> >  hw/scsi/virtio-scsi.c             |  4 ++-
> >  hw/virtio/virtio-pci.c            | 14 +++++++++
> >  hw/virtio/virtio.c                | 62 ++++++++++++++++++++++++---------------
> >  include/hw/virtio/virtio-access.h | 43 ++++++++++++++++++++-------
> >  include/hw/virtio/virtio-bus.h    |  1 +
> >  include/hw/virtio/virtio.h        |  8 +++--
> >  8 files changed, 98 insertions(+), 39 deletions(-)
> > 
> 
> > diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> > index 440b455..4071dad 100644
> > --- a/include/hw/virtio/virtio-access.h
> > +++ b/include/hw/virtio/virtio-access.h
> > @@ -17,12 +17,25 @@
> >  #define QEMU_VIRTIO_ACCESS_H
> > 
> >  #include "hw/virtio/virtio.h"
> > +#include "hw/virtio/virtio-bus.h"
> >  #include "exec/address-spaces.h"
> > 
> >  #if defined(TARGET_PPC64) || defined(TARGET_ARM)
> >  #define LEGACY_VIRTIO_IS_BIENDIAN 1
> >  #endif
> > 
> > +static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
> > +{
> > +    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> > +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > +
> > +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
> > +        k->get_dma_as) {
> > +        return k->get_dma_as(qbus->parent);
> > +    }
> > +    return &address_space_memory;
> > +}
> 
> One thing I'm a bit worried about is that we're introducing a check
> even if we know that the device will never support
> VIRTIO_F_IOMMU_PLATFORM (i.e. virtio-ccw). The qom incantations will
> add cycles to any invocation of this.

Yes - let's do container_of calls as opposed to QOM on data path.

> Is the address space likely to change during device lifetime? Can we
> cache it in some way?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30 10:02     ` Michael S. Tsirkin
@ 2016-08-30 10:21       ` Michael S. Tsirkin
  2016-08-30 11:11         ` [Qemu-devel] qom and debug (was: [PATCH for 2.8 02/11] virtio: convert to use DMA api) Cornelia Huck
  0 siblings, 1 reply; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-08-30 10:21 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, Aug 30, 2016 at 01:02:14PM +0300, Michael S. Tsirkin wrote:
> On Tue, Aug 30, 2016 at 09:31:27AM +0200, Cornelia Huck wrote:
> > On Tue, 30 Aug 2016 11:06:50 +0800
> > Jason Wang <jasowang@redhat.com> wrote:
> > 
> > > Currently, all virtio devices bypass IOMMU completely. This is because
> > > address_space_memory is assumed and used during DMA emulation. This
> > > patch converts the virtio core API to use DMA API. This idea is
> > > 
> > > - introducing a new transport specific helper to query the dma address
> > >   space. (only pci version is implemented).
> > > - query and use this address space during virtio device guest memory
> > >   accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled
> > >   for this device.
> > > 
> > > Cc: Michael S. Tsirkin <mst@redhat.com>
> > > Cc: Stefan Hajnoczi <stefanha@redhat.com>
> > > Cc: Kevin Wolf <kwolf@redhat.com>
> > > Cc: Amit Shah <amit.shah@redhat.com>
> > > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > > Cc: qemu-block@nongnu.org
> > > Signed-off-by: Jason Wang <jasowang@redhat.com>
> > > ---
> > >  hw/block/virtio-blk.c             |  2 +-
> > >  hw/char/virtio-serial-bus.c       |  3 +-
> > >  hw/scsi/virtio-scsi.c             |  4 ++-
> > >  hw/virtio/virtio-pci.c            | 14 +++++++++
> > >  hw/virtio/virtio.c                | 62 ++++++++++++++++++++++++---------------
> > >  include/hw/virtio/virtio-access.h | 43 ++++++++++++++++++++-------
> > >  include/hw/virtio/virtio-bus.h    |  1 +
> > >  include/hw/virtio/virtio.h        |  8 +++--
> > >  8 files changed, 98 insertions(+), 39 deletions(-)
> > > 
> > 
> > > diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> > > index 440b455..4071dad 100644
> > > --- a/include/hw/virtio/virtio-access.h
> > > +++ b/include/hw/virtio/virtio-access.h
> > > @@ -17,12 +17,25 @@
> > >  #define QEMU_VIRTIO_ACCESS_H
> > > 
> > >  #include "hw/virtio/virtio.h"
> > > +#include "hw/virtio/virtio-bus.h"
> > >  #include "exec/address-spaces.h"
> > > 
> > >  #if defined(TARGET_PPC64) || defined(TARGET_ARM)
> > >  #define LEGACY_VIRTIO_IS_BIENDIAN 1
> > >  #endif
> > > 
> > > +static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
> > > +{
> > > +    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> > > +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> > > +
> > > +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
> > > +        k->get_dma_as) {
> > > +        return k->get_dma_as(qbus->parent);
> > > +    }
> > > +    return &address_space_memory;
> > > +}
> > 
> > One thing I'm a bit worried about is that we're introducing a check
> > even if we know that the device will never support
> > VIRTIO_F_IOMMU_PLATFORM (i.e. virtio-ccw). The qom incantations will
> > add cycles to any invocation of this.
> 
> Yes - let's do container_of calls as opposed to QOM on data path.

BTW downstreams are building with --disable-qom-cast-debug which drops
all QOM casts on data path - one way is to say we just make this the
default upstream as well. Another to say that we want to distinguish
fast path calls from slow path, this way we will be able to bring back
some of the checks.


> > Is the address space likely to change during device lifetime? Can we
> > cache it in some way?

^ permalink raw reply	[flat|nested] 52+ messages in thread

* [Qemu-devel] qom and debug (was: [PATCH for 2.8 02/11] virtio: convert to use DMA api)
  2016-08-30 10:21       ` Michael S. Tsirkin
@ 2016-08-30 11:11         ` Cornelia Huck
  2016-08-30 11:15           ` Michael S. Tsirkin
  0 siblings, 1 reply; 52+ messages in thread
From: Cornelia Huck @ 2016-08-30 11:11 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, 30 Aug 2016 13:21:23 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> BTW downstreams are building with --disable-qom-cast-debug which drops
> all QOM casts on data path - one way is to say we just make this the
> default upstream as well. Another to say that we want to distinguish
> fast path calls from slow path, this way we will be able to bring back
> some of the checks.

I find CONFIG_QOM_CAST_DEBUG a bit inconsistent, btw:

- for object casts, we optimize away all checks and just return the
object for !debug
- for class casts, we optimize away only the caching and still keep the
checking (why would we drop the caching if this can speed up things?)

We certainly want to have debug turned on during development to avoid
nasty surprises later (otherwise, why even bother?), but it makes sense
to turn it off for a release. (Is there an easy way to turn it off for
the release, normal or stable, and keep it during the development
cycle?)

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] qom and debug (was: [PATCH for 2.8 02/11] virtio: convert to use DMA api)
  2016-08-30 11:11         ` [Qemu-devel] qom and debug (was: [PATCH for 2.8 02/11] virtio: convert to use DMA api) Cornelia Huck
@ 2016-08-30 11:15           ` Michael S. Tsirkin
  2016-08-30 11:37             ` [Qemu-devel] qom and debug Cornelia Huck
  0 siblings, 1 reply; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-08-30 11:15 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, Aug 30, 2016 at 01:11:05PM +0200, Cornelia Huck wrote:
> On Tue, 30 Aug 2016 13:21:23 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > BTW downstreams are building with --disable-qom-cast-debug which drops
> > all QOM casts on data path - one way is to say we just make this the
> > default upstream as well. Another to say that we want to distinguish
> > fast path calls from slow path, this way we will be able to bring back
> > some of the checks.
> 
> I find CONFIG_QOM_CAST_DEBUG a bit inconsistent, btw:
> 
> - for object casts, we optimize away all checks and just return the
> object for !debug
> - for class casts, we optimize away only the caching and still keep the
> checking (why would we drop the caching if this can speed up things?)
> 
> We certainly want to have debug turned on during development to avoid
> nasty surprises later (otherwise, why even bother?), but it makes sense
> to turn it off for a release. (Is there an easy way to turn it off for
> the release, normal or stable, and keep it during the development
> cycle?)

I think the assumption was class casts are not on data path.
Ideally we'd keep it on for release too for non-datapath things,
to help improve security.

-- 
MST

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] qom and debug
  2016-08-30 11:15           ` Michael S. Tsirkin
@ 2016-08-30 11:37             ` Cornelia Huck
  2016-08-30 11:57               ` Michael S. Tsirkin
  0 siblings, 1 reply; 52+ messages in thread
From: Cornelia Huck @ 2016-08-30 11:37 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, 30 Aug 2016 14:15:14 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, Aug 30, 2016 at 01:11:05PM +0200, Cornelia Huck wrote:
> > On Tue, 30 Aug 2016 13:21:23 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > BTW downstreams are building with --disable-qom-cast-debug which drops
> > > all QOM casts on data path - one way is to say we just make this the
> > > default upstream as well. Another to say that we want to distinguish
> > > fast path calls from slow path, this way we will be able to bring back
> > > some of the checks.
> > 
> > I find CONFIG_QOM_CAST_DEBUG a bit inconsistent, btw:
> > 
> > - for object casts, we optimize away all checks and just return the
> > object for !debug
> > - for class casts, we optimize away only the caching and still keep the
> > checking (why would we drop the caching if this can speed up things?)
> > 
> > We certainly want to have debug turned on during development to avoid
> > nasty surprises later (otherwise, why even bother?), but it makes sense
> > to turn it off for a release. (Is there an easy way to turn it off for
> > the release, normal or stable, and keep it during the development
> > cycle?)
> 
> I think the assumption was class casts are not on data path.
> Ideally we'd keep it on for release too for non-datapath things,
> to help improve security.

This would probably need some more fine-grained configuration.

For now, what about this completely untested patch that at least adds
caching for the class->interfaces case if debug is off?

diff --git a/qom/object.c b/qom/object.c
index 8166b7d..05f1fe4 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -696,12 +696,16 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
                                               const char *func)
 {
     ObjectClass *ret;
+    int i;
 
     trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
                                            typename, file, line, func);
 
-#ifdef CONFIG_QOM_CAST_DEBUG
-    int i;
+#ifndef CONFIG_QOM_CAST_DEBUG
+    if (!class || !class->interfaces) {
+        return class;
+    }
+#endif
 
     for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
         if (class->class_cast_cache[i] == typename) {
@@ -709,11 +713,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
             goto out;
         }
     }
-#else
-    if (!class || !class->interfaces) {
-        return class;
-    }
-#endif
 
     ret = object_class_dynamic_cast(class, typename);
     if (!ret && class) {
@@ -722,7 +721,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
         abort();
     }
 
-#ifdef CONFIG_QOM_CAST_DEBUG
     if (class && ret == class) {
         for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
             class->class_cast_cache[i - 1] = class->class_cast_cache[i];
@@ -730,7 +728,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
         class->class_cast_cache[i - 1] = typename;
     }
 out:
-#endif
     return ret;
 }
 

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] qom and debug
  2016-08-30 11:37             ` [Qemu-devel] qom and debug Cornelia Huck
@ 2016-08-30 11:57               ` Michael S. Tsirkin
  0 siblings, 0 replies; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-08-30 11:57 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Jason Wang, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, Aug 30, 2016 at 01:37:41PM +0200, Cornelia Huck wrote:
> On Tue, 30 Aug 2016 14:15:14 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, Aug 30, 2016 at 01:11:05PM +0200, Cornelia Huck wrote:
> > > On Tue, 30 Aug 2016 13:21:23 +0300
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > BTW downstreams are building with --disable-qom-cast-debug which drops
> > > > all QOM casts on data path - one way is to say we just make this the
> > > > default upstream as well. Another to say that we want to distinguish
> > > > fast path calls from slow path, this way we will be able to bring back
> > > > some of the checks.
> > > 
> > > I find CONFIG_QOM_CAST_DEBUG a bit inconsistent, btw:
> > > 
> > > - for object casts, we optimize away all checks and just return the
> > > object for !debug
> > > - for class casts, we optimize away only the caching and still keep the
> > > checking (why would we drop the caching if this can speed up things?)
> > > 
> > > We certainly want to have debug turned on during development to avoid
> > > nasty surprises later (otherwise, why even bother?), but it makes sense
> > > to turn it off for a release. (Is there an easy way to turn it off for
> > > the release, normal or stable, and keep it during the development
> > > cycle?)
> > 
> > I think the assumption was class casts are not on data path.
> > Ideally we'd keep it on for release too for non-datapath things,
> > to help improve security.
> 
> This would probably need some more fine-grained configuration.

We can start with Jason's patch :)

> For now, what about this completely untested patch that at least adds
> caching for the class->interfaces case if debug is off?

Fine with me.

> diff --git a/qom/object.c b/qom/object.c
> index 8166b7d..05f1fe4 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -696,12 +696,16 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
>                                                const char *func)
>  {
>      ObjectClass *ret;
> +    int i;
>  
>      trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
>                                             typename, file, line, func);
>  
> -#ifdef CONFIG_QOM_CAST_DEBUG
> -    int i;
> +#ifndef CONFIG_QOM_CAST_DEBUG
> +    if (!class || !class->interfaces) {
> +        return class;
> +    }
> +#endif
>  
>      for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
>          if (class->class_cast_cache[i] == typename) {
> @@ -709,11 +713,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
>              goto out;
>          }
>      }
> -#else
> -    if (!class || !class->interfaces) {
> -        return class;
> -    }
> -#endif
>  
>      ret = object_class_dynamic_cast(class, typename);
>      if (!ret && class) {
> @@ -722,7 +721,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
>          abort();
>      }
>  
> -#ifdef CONFIG_QOM_CAST_DEBUG
>      if (class && ret == class) {
>          for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
>              class->class_cast_cache[i - 1] = class->class_cast_cache[i];
> @@ -730,7 +728,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
>          class->class_cast_cache[i - 1] = typename;
>      }
>  out:
> -#endif
>      return ret;
>  }
>  

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor Jason Wang
@ 2016-08-30 13:16   ` Peter Xu
  2016-08-31  2:54     ` Jason Wang
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-08-30 13:16 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans,
	Richard Henderson, Eduardo Habkost

On Tue, Aug 30, 2016 at 11:06:54AM +0800, Jason Wang wrote:
> This patch enables device IOTLB support for intel iommu. The major
> work is to implement QI device IOTLB descriptor processing and notify
> the device through iommu notifier.

IMHO it'll be nicer if we can mention the new bit in the commit
message, like:

    One new property "device-iotlb" is introduced to enable device
    IOTLB capability for VT-d IOMMU device. By default, it is turned
    off. To enable it:

      -device intel-iommu,device-iotlb=on

[...]

> +static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
> +                                          VTDInvDesc *inv_desc)
> +{

[...]

> +    entry.target_as = &vtd_dev_as->as;
> +    entry.addr_mask = sz - 1;
> +    entry.iova = addr;

Do we need to setup translated_addr and perm fields as well?

[...]

> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
> index ce26b2a..a70a363 100644
> --- a/hw/i386/x86-iommu.c
> +++ b/hw/i386/x86-iommu.c
> @@ -100,6 +100,18 @@ static void x86_iommu_intremap_prop_set(Object *o, bool value, Error **errp)
>      s->intr_supported = value;
>  }
>  
> +static bool x86_iommu_device_iotlb_prop_get(Object *o, Error **errp)
> +{
> +    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
> +    return s->dt_supported;
> +}
> +
> +static void x86_iommu_device_iotlb_prop_set(Object *o, bool value, Error **errp)
> +{
> +    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
> +    s->dt_supported = value;
> +}
> +
>  static void x86_iommu_instance_init(Object *o)
>  {
>      X86IOMMUState *s = X86_IOMMU_DEVICE(o);
> @@ -108,6 +120,11 @@ static void x86_iommu_instance_init(Object *o)
>      s->intr_supported = false;
>      object_property_add_bool(o, "intremap", x86_iommu_intremap_prop_get,
>                               x86_iommu_intremap_prop_set, NULL);
> +    s->dt_supported = false;
> +    object_property_add_bool(o, "device_iotlb",
> +                             x86_iommu_device_iotlb_prop_get,
> +                             x86_iommu_device_iotlb_prop_set,
> +                             NULL);

Nit 1: use "device-iotlb" instead of "device_iotlb"?

Nit 2: use Property bit (like vtd_properties)?

Thanks,

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support Jason Wang
@ 2016-08-30 13:21   ` Peter Xu
  2016-08-31  2:55     ` Jason Wang
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-08-30 13:21 UTC (permalink / raw)
  To: Jason Wang; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans

On Tue, Aug 30, 2016 at 11:06:55AM +0800, Jason Wang wrote:

[...]

> +/* Type 2: Root Port ATS Capability Reporting Structure */
> +struct AcpiDmarRootPortATS {
> +    uint16_t type;
> +    uint16_t length;
> +    uint8_t flags;
> +    uint8_t reserved;
> +    uint16_t pci_segment;
> +    AcpiDmarDeviceScope scope[0];
> +} QEMU_PACKED;
> +typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
> +

Maybe better moved into patch 8 (next one)? Since it's not related to
virtio bits, but ACPI.

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier Jason Wang
@ 2016-08-30 13:28   ` Peter Xu
  0 siblings, 0 replies; 52+ messages in thread
From: Peter Xu @ 2016-08-30 13:28 UTC (permalink / raw)
  To: Jason Wang; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans

On Tue, Aug 30, 2016 at 11:06:57AM +0800, Jason Wang wrote:
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>

Reviewed-by: Peter Xu <peterx@redhat.com>

> ---
>  memory.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/memory.c b/memory.c
> index 0eb6895..ca0a698 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1515,6 +1515,11 @@ bool memory_region_is_logging(MemoryRegion *mr, uint8_t client)
>  
>  void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
>  {
> +    if (mr->alias) {
> +        memory_region_register_iommu_notifier(mr->alias, n);
> +        return;
> +    }
> +
>      if (mr->iommu_ops->notify_started &&
>          QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
>          mr->iommu_ops->notify_started(mr);
> @@ -1554,6 +1559,10 @@ void memory_region_iommu_replay(MemoryRegion *mr, Notifier *n, bool is_write)
>  
>  void memory_region_unregister_iommu_notifier(MemoryRegion *mr, Notifier *n)
>  {
> +    if (mr->alias) {
> +        memory_region_unregister_iommu_notifier(mr->alias, n);
> +        return;
> +    }
>      notifier_remove(n);
>      if (mr->iommu_ops->notify_stopped &&
>          QLIST_EMPTY(&mr->iommu_notify.notifiers)) {
> -- 
> 2.7.4
> 

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-08-30  3:37   ` Alex Williamson
@ 2016-08-31  2:45     ` Jason Wang
  2016-09-01  2:29       ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-31  2:45 UTC (permalink / raw)
  To: Alex Williamson
  Cc: mst, qemu-devel, pbonzini, peterx, cornelia.huck, wexu, vkaplans



On 2016年08月30日 11:37, Alex Williamson wrote:
> On Tue, 30 Aug 2016 11:06:58 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>> From: Peter Xu <peterx@redhat.com>
>>
>> This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
>> device IOTLB API will get notified and send invalidation request to
>> vhost through this notifier.
> AFAICT this series does not address the original problem for which
> commit 3cb3b1549f54 was added.  We've only addressed the very narrow
> use case of a device iotlb firing the iommu notifier therefore this
> change is a regression versus 2.7 since it allows invalid
> configurations with a physical iommu which will never receive the
> necessary notifies from intel-iommu emulation to work properly.  Thanks,
>
> Alex

Looking at vfio, it cares about map but vhost only cares about IOTLB 
invalidation. Then I think we probably need another kind of notifier in 
this case to avoid this.

>> Cc: Alex Williamson <alex.williamson@redhat.com>
>> Signed-off-by: Peter Xu <peterx@redhat.com>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>   hw/i386/intel_iommu.c | 12 ------------
>>   1 file changed, 12 deletions(-)
>>
>> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
>> index 298faab..15d1216 100644
>> --- a/hw/i386/intel_iommu.c
>> +++ b/hw/i386/intel_iommu.c
>> @@ -25,7 +25,6 @@
>>   #include "exec/address-spaces.h"
>>   #include "intel_iommu_internal.h"
>>   #include "hw/pci/pci.h"
>> -#include "hw/pci/pci_bus.h"
>>   #include "hw/i386/pc.h"
>>   #include "hw/boards.h"
>>   #include "hw/i386/x86-iommu.h"
>> @@ -2041,16 +2040,6 @@ static IOMMUTLBEntry vtd_iommu_translate(MemoryRegion *iommu, hwaddr addr,
>>       return ret;
>>   }
>>   
>> -static void vtd_iommu_notify_started(MemoryRegion *iommu)
>> -{
>> -    VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
>> -
>> -    hw_error("Device at bus %s addr %02x.%d requires iommu notifier which "
>> -             "is currently not supported by intel-iommu emulation",
>> -             vtd_as->bus->qbus.name, PCI_SLOT(vtd_as->devfn),
>> -             PCI_FUNC(vtd_as->devfn));
>> -}
>> -
>>   static const VMStateDescription vtd_vmstate = {
>>       .name = "iommu-intel",
>>       .unmigratable = 1,
>> @@ -2418,7 +2407,6 @@ static void vtd_init(IntelIOMMUState *s)
>>       memset(s->womask, 0, DMAR_REG_SIZE);
>>   
>>       s->iommu_ops.translate = vtd_iommu_translate;
>> -    s->iommu_ops.notify_started = vtd_iommu_notify_started;
>>       s->root = 0;
>>       s->root_extended = false;
>>       s->dmar_enabled = false;

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  7:31   ` Cornelia Huck
  2016-08-30 10:02     ` Michael S. Tsirkin
@ 2016-08-31  2:47     ` Jason Wang
  1 sibling, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-31  2:47 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: mst, qemu-devel, pbonzini, peterx, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block



On 2016年08月30日 15:31, Cornelia Huck wrote:
> On Tue, 30 Aug 2016 11:06:50 +0800
> Jason Wang <jasowang@redhat.com> wrote:
>
>> Currently, all virtio devices bypass IOMMU completely. This is because
>> address_space_memory is assumed and used during DMA emulation. This
>> patch converts the virtio core API to use DMA API. This idea is
>>
>> - introducing a new transport specific helper to query the dma address
>>    space. (only pci version is implemented).
>> - query and use this address space during virtio device guest memory
>>    accessing when iommu platform (VIRTIO_F_IOMMU_PLATFORM) was enabled
>>    for this device.
>>
>> Cc: Michael S. Tsirkin <mst@redhat.com>
>> Cc: Stefan Hajnoczi <stefanha@redhat.com>
>> Cc: Kevin Wolf <kwolf@redhat.com>
>> Cc: Amit Shah <amit.shah@redhat.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: qemu-block@nongnu.org
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>   hw/block/virtio-blk.c             |  2 +-
>>   hw/char/virtio-serial-bus.c       |  3 +-
>>   hw/scsi/virtio-scsi.c             |  4 ++-
>>   hw/virtio/virtio-pci.c            | 14 +++++++++
>>   hw/virtio/virtio.c                | 62 ++++++++++++++++++++++++---------------
>>   include/hw/virtio/virtio-access.h | 43 ++++++++++++++++++++-------
>>   include/hw/virtio/virtio-bus.h    |  1 +
>>   include/hw/virtio/virtio.h        |  8 +++--
>>   8 files changed, 98 insertions(+), 39 deletions(-)
>>
>> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
>> index 440b455..4071dad 100644
>> --- a/include/hw/virtio/virtio-access.h
>> +++ b/include/hw/virtio/virtio-access.h
>> @@ -17,12 +17,25 @@
>>   #define QEMU_VIRTIO_ACCESS_H
>>
>>   #include "hw/virtio/virtio.h"
>> +#include "hw/virtio/virtio-bus.h"
>>   #include "exec/address-spaces.h"
>>
>>   #if defined(TARGET_PPC64) || defined(TARGET_ARM)
>>   #define LEGACY_VIRTIO_IS_BIENDIAN 1
>>   #endif
>>
>> +static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
>> +{
>> +    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
>> +
>> +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
>> +        k->get_dma_as) {
>> +        return k->get_dma_as(qbus->parent);
>> +    }
>> +    return &address_space_memory;
>> +}
> One thing I'm a bit worried about is that we're introducing a check
> even if we know that the device will never support
> VIRTIO_F_IOMMU_PLATFORM (i.e. virtio-ccw). The qom incantations will
> add cycles to any invocation of this.
>
> Is the address space likely to change during device lifetime? Can we
> cache it in some way?
>

I think so, we can cache it in vdev and set it during features set.

Then we can avoid qom stuffs during data path.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor
  2016-08-30 13:16   ` Peter Xu
@ 2016-08-31  2:54     ` Jason Wang
  2016-09-01  1:26       ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-08-31  2:54 UTC (permalink / raw)
  To: Peter Xu
  Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans,
	Richard Henderson, Eduardo Habkost



On 2016年08月30日 21:16, Peter Xu wrote:
> On Tue, Aug 30, 2016 at 11:06:54AM +0800, Jason Wang wrote:
>> This patch enables device IOTLB support for intel iommu. The major
>> work is to implement QI device IOTLB descriptor processing and notify
>> the device through iommu notifier.
> IMHO it'll be nicer if we can mention the new bit in the commit
> message, like:
>
>      One new property "device-iotlb" is introduced to enable device
>      IOTLB capability for VT-d IOMMU device. By default, it is turned
>      off. To enable it:
>
>        -device intel-iommu,device-iotlb=on
>
> [...]

Yes, this looks better.

>
>> +static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
>> +                                          VTDInvDesc *inv_desc)
>> +{
> [...]
>
>> +    entry.target_as = &vtd_dev_as->as;
>> +    entry.addr_mask = sz - 1;
>> +    entry.iova = addr;
> Do we need to setup translated_addr and perm fields as well?
>
> [...]

Good question, tough vhost does not care about those two fileds now (we 
only care about invalidation). But I think it's better to add them, it 
may be used in the future (e.g CM which may also depends on notifier).

>
>> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
>> index ce26b2a..a70a363 100644
>> --- a/hw/i386/x86-iommu.c
>> +++ b/hw/i386/x86-iommu.c
>> @@ -100,6 +100,18 @@ static void x86_iommu_intremap_prop_set(Object *o, bool value, Error **errp)
>>       s->intr_supported = value;
>>   }
>>   
>> +static bool x86_iommu_device_iotlb_prop_get(Object *o, Error **errp)
>> +{
>> +    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
>> +    return s->dt_supported;
>> +}
>> +
>> +static void x86_iommu_device_iotlb_prop_set(Object *o, bool value, Error **errp)
>> +{
>> +    X86IOMMUState *s = X86_IOMMU_DEVICE(o);
>> +    s->dt_supported = value;
>> +}
>> +
>>   static void x86_iommu_instance_init(Object *o)
>>   {
>>       X86IOMMUState *s = X86_IOMMU_DEVICE(o);
>> @@ -108,6 +120,11 @@ static void x86_iommu_instance_init(Object *o)
>>       s->intr_supported = false;
>>       object_property_add_bool(o, "intremap", x86_iommu_intremap_prop_get,
>>                                x86_iommu_intremap_prop_set, NULL);
>> +    s->dt_supported = false;
>> +    object_property_add_bool(o, "device_iotlb",
>> +                             x86_iommu_device_iotlb_prop_get,
>> +                             x86_iommu_device_iotlb_prop_set,
>> +                             NULL);
> Nit 1: use "device-iotlb" instead of "device_iotlb"?

Yes.

> Nit 2: use Property bit (like vtd_properties)?

Not sure, I thought this may be reused by AMD IOMMU but maybe I was wrong.

>
> Thanks,
>
> -- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support
  2016-08-30 13:21   ` Peter Xu
@ 2016-08-31  2:55     ` Jason Wang
  0 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-08-31  2:55 UTC (permalink / raw)
  To: Peter Xu; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans



On 2016年08月30日 21:21, Peter Xu wrote:
> On Tue, Aug 30, 2016 at 11:06:55AM +0800, Jason Wang wrote:
>
> [...]
>
>> +/* Type 2: Root Port ATS Capability Reporting Structure */
>> +struct AcpiDmarRootPortATS {
>> +    uint16_t type;
>> +    uint16_t length;
>> +    uint8_t flags;
>> +    uint8_t reserved;
>> +    uint16_t pci_segment;
>> +    AcpiDmarDeviceScope scope[0];
>> +} QEMU_PACKED;
>> +typedef struct AcpiDmarRootPortATS AcpiDmarRootPortATS;
>> +
> Maybe better moved into patch 8 (next one)? Since it's not related to
> virtio bits, but ACPI.
>
> -- peterx

Right, will move this.

Thanks

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor
  2016-08-31  2:54     ` Jason Wang
@ 2016-09-01  1:26       ` Peter Xu
  0 siblings, 0 replies; 52+ messages in thread
From: Peter Xu @ 2016-09-01  1:26 UTC (permalink / raw)
  To: Jason Wang
  Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans,
	Richard Henderson, Eduardo Habkost

On Wed, Aug 31, 2016 at 10:54:36AM +0800, Jason Wang wrote:
> >>  static void x86_iommu_instance_init(Object *o)
> >>  {
> >>      X86IOMMUState *s = X86_IOMMU_DEVICE(o);
> >>@@ -108,6 +120,11 @@ static void x86_iommu_instance_init(Object *o)
> >>      s->intr_supported = false;
> >>      object_property_add_bool(o, "intremap", x86_iommu_intremap_prop_get,
> >>                               x86_iommu_intremap_prop_set, NULL);
> >>+    s->dt_supported = false;
> >>+    object_property_add_bool(o, "device_iotlb",
> >>+                             x86_iommu_device_iotlb_prop_get,
> >>+                             x86_iommu_device_iotlb_prop_set,
> >>+                             NULL);
> >Nit 1: use "device-iotlb" instead of "device_iotlb"?
> 
> Yes.
> 
> >Nit 2: use Property bit (like vtd_properties)?
> 
> Not sure, I thought this may be reused by AMD IOMMU but maybe I was wrong.

I mean to create another Property for x86-iommus. :)

Anyway both work for me, and actually "intremap" property is doing it
that way as well...

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-08-31  2:45     ` Jason Wang
@ 2016-09-01  2:29       ` Peter Xu
  2016-09-01  2:43         ` Alex Williamson
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-01  2:29 UTC (permalink / raw)
  To: Jason Wang
  Cc: Alex Williamson, mst, qemu-devel, pbonzini, cornelia.huck, wexu,
	vkaplans

On Wed, Aug 31, 2016 at 10:45:37AM +0800, Jason Wang wrote:
> 
> 
> On 2016年08月30日 11:37, Alex Williamson wrote:
> >On Tue, 30 Aug 2016 11:06:58 +0800
> >Jason Wang <jasowang@redhat.com> wrote:
> >
> >>From: Peter Xu <peterx@redhat.com>
> >>
> >>This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
> >>device IOTLB API will get notified and send invalidation request to
> >>vhost through this notifier.
> >AFAICT this series does not address the original problem for which
> >commit 3cb3b1549f54 was added.  We've only addressed the very narrow
> >use case of a device iotlb firing the iommu notifier therefore this
> >change is a regression versus 2.7 since it allows invalid
> >configurations with a physical iommu which will never receive the
> >necessary notifies from intel-iommu emulation to work properly.  Thanks,
> >
> >Alex
> 
> Looking at vfio, it cares about map but vhost only cares about IOTLB
> invalidation. Then I think we probably need another kind of notifier in this
> case to avoid this.

Shall we leverage IOMMUTLBEntry.perm == IOMMU_NONE as a sign for
invalidation? If so, we can use the same IOTLB interface as before.
IMHO these two interfaces are not conflicting?

Alex,

Do you mean we should still disallow user from passing through devices
while Intel IOMMU enabled? If so, not sure whether patch below can
solve the issue.

It seems that we need a "name" for either IOMMU notifier
provider/consumer, and we should not allow (provider==Intel &&
consumer==VFIO) happen. In the following case, I added a name for
provider, and VFIO checks it.

--------8<----------

diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 883db13..936c2e6 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -725,6 +725,7 @@ static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
 }

 static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
+    .iommu_type = "typhoon",
     .translate = typhoon_translate_iommu,
 };

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 28c31a2..f5e3875 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2347,6 +2347,7 @@ static void vtd_init(IntelIOMMUState *s)
     memset(s->w1cmask, 0, DMAR_REG_SIZE);
     memset(s->womask, 0, DMAR_REG_SIZE);

+    s->iommu_ops.iommu_type = "intel";
     s->iommu_ops.translate = vtd_iommu_translate;
     s->iommu_ops.notify_started = vtd_iommu_notify_started;
     s->root = 0;
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 653e711..9cfbb73 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -323,6 +323,7 @@ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
 }

 static MemoryRegionIOMMUOps pbm_iommu_ops = {
+    .iommu_type = "pbm",
     .translate = pbm_translate_iommu,
 };

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 6bc4d4d..e3e8739 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -244,6 +244,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
 };

 static MemoryRegionIOMMUOps spapr_iommu_ops = {
+    .iommu_type = "spapr",
     .translate = spapr_tce_translate_iommu,
     .get_min_page_size = spapr_tce_get_min_page_size,
     .notify_started = spapr_tce_notify_started,
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 9c1c04e..4414462 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -443,6 +443,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
 }

 static const MemoryRegionIOMMUOps s390_iommu_ops = {
+    .iommu_type = "s390",
     .translate = s390_translate_iommu,
 };

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index b313e7c..317e08b 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -441,6 +441,11 @@ static void vfio_listener_region_add(MemoryListener *listener,
     if (memory_region_is_iommu(section->mr)) {
         VFIOGuestIOMMU *giommu;

+        if (!strcmp(memory_region_iommu_type(section->mr), "intel")) {
+            error_report("Device passthrough cannot work with Intel IOMMU");
+            exit(1);
+        }
+
         trace_vfio_listener_region_add_iommu(iova, end);
         /*
          * FIXME: For VFIO iommu types which have KVM acceleration to
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3e4d416..f012f77 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -149,6 +149,8 @@ struct MemoryRegionOps {
 typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps;

 struct MemoryRegionIOMMUOps {
+    /* Type of IOMMU */
+    const char *iommu_type;
     /* Return a TLB entry that contains a given address. */
     IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr, bool is_write);
     /* Returns minimum supported page size */
@@ -593,6 +595,21 @@ static inline bool memory_region_is_iommu(MemoryRegion *mr)
     return mr->iommu_ops;
 }

+/**
+ * memory_region_iommu_type: return type of IOMMU
+ *
+ * Returns type of IOMMU, empty string ("") if not a IOMMU region.
+ *
+ * @mr: the memory region being queried
+ */
+static inline const char *memory_region_iommu_type(MemoryRegion *mr)
+{
+    if (mr->iommu_ops && mr->iommu_ops->iommu_type) {
+        return mr->iommu_ops->iommu_type;
+    }
+
+    return "";
+}

 /**
  * memory_region_iommu_get_min_page_size: get minimum supported page size

------>8--------

Thanks,

-- peterx

^ permalink raw reply related	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-01  2:29       ` Peter Xu
@ 2016-09-01  2:43         ` Alex Williamson
  2016-09-01  3:58           ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Alex Williamson @ 2016-09-01  2:43 UTC (permalink / raw)
  To: Peter Xu
  Cc: Jason Wang, mst, qemu-devel, pbonzini, cornelia.huck, wexu,
	vkaplans, David Gibson

[cc +dgibson]

On Thu, 1 Sep 2016 10:29:29 +0800
Peter Xu <peterx@redhat.com> wrote:

> On Wed, Aug 31, 2016 at 10:45:37AM +0800, Jason Wang wrote:
> > 
> > 
> > On 2016年08月30日 11:37, Alex Williamson wrote:  
> > >On Tue, 30 Aug 2016 11:06:58 +0800
> > >Jason Wang <jasowang@redhat.com> wrote:
> > >  
> > >>From: Peter Xu <peterx@redhat.com>
> > >>
> > >>This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
> > >>device IOTLB API will get notified and send invalidation request to
> > >>vhost through this notifier.  
> > >AFAICT this series does not address the original problem for which
> > >commit 3cb3b1549f54 was added.  We've only addressed the very narrow
> > >use case of a device iotlb firing the iommu notifier therefore this
> > >change is a regression versus 2.7 since it allows invalid
> > >configurations with a physical iommu which will never receive the
> > >necessary notifies from intel-iommu emulation to work properly.  Thanks,
> > >
> > >Alex  
> > 
> > Looking at vfio, it cares about map but vhost only cares about IOTLB
> > invalidation. Then I think we probably need another kind of notifier in this
> > case to avoid this.  
> 
> Shall we leverage IOMMUTLBEntry.perm == IOMMU_NONE as a sign for
> invalidation? If so, we can use the same IOTLB interface as before.
> IMHO these two interfaces are not conflicting?
> 
> Alex,
> 
> Do you mean we should still disallow user from passing through devices
> while Intel IOMMU enabled? If so, not sure whether patch below can
> solve the issue.
> 
> It seems that we need a "name" for either IOMMU notifier
> provider/consumer, and we should not allow (provider==Intel &&
> consumer==VFIO) happen. In the following case, I added a name for
> provider, and VFIO checks it.

Absolutely not, intel-iommu emulation is simply incomplete, the IOMMU
notifier is never called for mappings.  There's a whole aspect of
iommu notifiers that intel-iommu simply hasn't bothered to implement.
Don't punish vfio for actually making use of the interface as it was
intended to be used.  AFAICT you're implementing the unmap/invalidation
half, without the actual mapping half of the interface.  It's broken
and incompatible with any iommu notifiers that expect to see both
sides.  Thanks,

Alex


> --------8<----------
> 
> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
> index 883db13..936c2e6 100644
> --- a/hw/alpha/typhoon.c
> +++ b/hw/alpha/typhoon.c
> @@ -725,6 +725,7 @@ static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
>  }
> 
>  static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
> +    .iommu_type = "typhoon",
>      .translate = typhoon_translate_iommu,
>  };
> 
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 28c31a2..f5e3875 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -2347,6 +2347,7 @@ static void vtd_init(IntelIOMMUState *s)
>      memset(s->w1cmask, 0, DMAR_REG_SIZE);
>      memset(s->womask, 0, DMAR_REG_SIZE);
> 
> +    s->iommu_ops.iommu_type = "intel";
>      s->iommu_ops.translate = vtd_iommu_translate;
>      s->iommu_ops.notify_started = vtd_iommu_notify_started;
>      s->root = 0;
> diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
> index 653e711..9cfbb73 100644
> --- a/hw/pci-host/apb.c
> +++ b/hw/pci-host/apb.c
> @@ -323,6 +323,7 @@ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr,
>  }
> 
>  static MemoryRegionIOMMUOps pbm_iommu_ops = {
> +    .iommu_type = "pbm",
>      .translate = pbm_translate_iommu,
>  };
> 
> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
> index 6bc4d4d..e3e8739 100644
> --- a/hw/ppc/spapr_iommu.c
> +++ b/hw/ppc/spapr_iommu.c
> @@ -244,6 +244,7 @@ static const VMStateDescription vmstate_spapr_tce_table = {
>  };
> 
>  static MemoryRegionIOMMUOps spapr_iommu_ops = {
> +    .iommu_type = "spapr",
>      .translate = spapr_tce_translate_iommu,
>      .get_min_page_size = spapr_tce_get_min_page_size,
>      .notify_started = spapr_tce_notify_started,
> diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
> index 9c1c04e..4414462 100644
> --- a/hw/s390x/s390-pci-bus.c
> +++ b/hw/s390x/s390-pci-bus.c
> @@ -443,6 +443,7 @@ static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *iommu, hwaddr addr,
>  }
> 
>  static const MemoryRegionIOMMUOps s390_iommu_ops = {
> +    .iommu_type = "s390",
>      .translate = s390_translate_iommu,
>  };
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index b313e7c..317e08b 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -441,6 +441,11 @@ static void vfio_listener_region_add(MemoryListener *listener,
>      if (memory_region_is_iommu(section->mr)) {
>          VFIOGuestIOMMU *giommu;
> 
> +        if (!strcmp(memory_region_iommu_type(section->mr), "intel")) {
> +            error_report("Device passthrough cannot work with Intel IOMMU");
> +            exit(1);
> +        }
> +
>          trace_vfio_listener_region_add_iommu(iova, end);
>          /*
>           * FIXME: For VFIO iommu types which have KVM acceleration to
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 3e4d416..f012f77 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -149,6 +149,8 @@ struct MemoryRegionOps {
>  typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps;
> 
>  struct MemoryRegionIOMMUOps {
> +    /* Type of IOMMU */
> +    const char *iommu_type;
>      /* Return a TLB entry that contains a given address. */
>      IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr, bool is_write);
>      /* Returns minimum supported page size */
> @@ -593,6 +595,21 @@ static inline bool memory_region_is_iommu(MemoryRegion *mr)
>      return mr->iommu_ops;
>  }
> 
> +/**
> + * memory_region_iommu_type: return type of IOMMU
> + *
> + * Returns type of IOMMU, empty string ("") if not a IOMMU region.
> + *
> + * @mr: the memory region being queried
> + */
> +static inline const char *memory_region_iommu_type(MemoryRegion *mr)
> +{
> +    if (mr->iommu_ops && mr->iommu_ops->iommu_type) {
> +        return mr->iommu_ops->iommu_type;
> +    }
> +
> +    return "";
> +}
> 
>  /**
>   * memory_region_iommu_get_min_page_size: get minimum supported page size
> 
> ------>8--------  
> 
> Thanks,
> 
> -- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support Jason Wang
@ 2016-09-01  3:34   ` Peter Xu
  2016-09-01  7:36     ` Jason Wang
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-01  3:34 UTC (permalink / raw)
  To: Jason Wang; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans

On Tue, Aug 30, 2016 at 11:06:59AM +0800, Jason Wang wrote:
> This patches implements Device IOTLB support for vhost kernel. This is
> done through:
> 
> 1) switch to use dma helpers when map/unmap vrings from vhost codes
> 2) kernel support for Device IOTLB API:
> 
> - allow vhost-net to query the IOMMU IOTLB entry through eventfd
> - enable the ability for qemu to update a specified mapping of vhost
> - through ioctl.
> - enable the ability to invalidate a specified range of iova for the
>   device IOTLB of vhost through ioctl. In x86/intel_iommu case this is
>   triggered through iommu memory region notifier from device IOTLB
>   invalidation descriptor processing routine.
> 
> With all the above, kernel vhost_net can co-operate with IOMMU.
> 
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>  hw/virtio/vhost-backend.c         | 104 ++++++++++++++++++++++++++
>  hw/virtio/vhost.c                 | 149 ++++++++++++++++++++++++++++++++------
>  include/hw/virtio/vhost-backend.h |  14 ++++
>  include/hw/virtio/vhost.h         |   4 +
>  include/hw/virtio/virtio-access.h |  44 ++++++++++-
>  net/tap.c                         |   1 +
>  6 files changed, 291 insertions(+), 25 deletions(-)
> 
> diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
> index 7681f15..a5754f3 100644
> --- a/hw/virtio/vhost-backend.c
> +++ b/hw/virtio/vhost-backend.c
> @@ -172,6 +172,107 @@ static int vhost_kernel_get_vq_index(struct vhost_dev *dev, int idx)
>      return idx - dev->vq_index;
>  }
>  
> +static void vhost_kernel_iotlb_read(void *opaque)
> +{
> +    struct vhost_dev *dev = opaque;
> +    struct vhost_msg msg;
> +    ssize_t len;
> +
> +    while((len = read((uintptr_t)dev->opaque, &msg, sizeof msg)) > 0) {
> +        struct vhost_iotlb_msg *imsg = &msg.iotlb;
> +        if (len < sizeof msg) {
> +            error_report("Wrong vhost message len: %d", (int)len);
> +            break;
> +        }
> +        if (msg.type != VHOST_IOTLB_MSG) {
> +            error_report("Unknown vhost iotlb message type");
> +            break;
> +        }
> +        switch (imsg->type) {
> +        case VHOST_IOTLB_MISS:
> +            vhost_device_iotlb_miss(dev, imsg->iova,
> +                                    imsg->perm != VHOST_ACCESS_RO);
> +            break;
> +        case VHOST_IOTLB_UPDATE:
> +        case VHOST_IOTLB_INVALIDATE:
> +            error_report("Unexpected IOTLB message type");
> +            break;
> +        case VHOST_IOTLB_ACCESS_FAIL:
> +            /* FIXME: report device iotlb error */
> +            break;
> +        default:
> +            break;
> +        }
> +    }
> +}
> +
> +static int vhost_kernel_update_device_iotlb(struct vhost_dev *dev,
> +                                            uint64_t iova, uint64_t uaddr,
> +                                            uint64_t len,
> +                                            IOMMUAccessFlags perm)
> +{
> +    struct vhost_msg msg = {
> +        .type = VHOST_IOTLB_MSG,
> +        .iotlb = {
> +            .iova = iova,
> +            .uaddr = uaddr,
> +            .size = len,
> +            .type = VHOST_IOTLB_UPDATE,
> +        }
> +    };
> +
> +    switch (perm) {
> +    case IOMMU_RO:
> +        msg.iotlb.perm = VHOST_ACCESS_RO;
> +        break;
> +    case IOMMU_WO:
> +        msg.iotlb.perm = VHOST_ACCESS_WO;
> +        break;
> +    case IOMMU_RW:
> +        msg.iotlb.perm = VHOST_ACCESS_RW;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
> +        error_report("Fail to update device iotlb");
> +        return -EFAULT;
> +    }
> +
> +    return 0;
> +}
> +
> +static int vhost_kernel_invalidate_device_iotlb(struct vhost_dev *dev,
> +                                                uint64_t iova, uint64_t len)
> +{
> +    struct vhost_msg msg = {
> +        .type = VHOST_IOTLB_MSG,
> +        .iotlb = {
> +            .iova = iova,
> +            .size = len,
> +            .type = VHOST_IOTLB_INVALIDATE,
> +        }
> +    };
> +
> +    if (write((uintptr_t)dev->opaque, &msg, sizeof msg) != sizeof msg) {
> +        error_report("Fail to invalidate device iotlb");
> +        return -EFAULT;
> +    }
> +
> +    return 0;
> +}
> +
> +static void vhost_kernel_set_iotlb_callback(struct vhost_dev *dev,
> +                                           int enabled)
> +{
> +    if (enabled)
> +        qemu_set_fd_handler((uintptr_t)dev->opaque,
> +                            vhost_kernel_iotlb_read, NULL, dev);
> +    else
> +        qemu_set_fd_handler((uintptr_t)dev->opaque, NULL, NULL, NULL);
> +}
> +
>  static const VhostOps kernel_ops = {
>          .backend_type = VHOST_BACKEND_TYPE_KERNEL,
>          .vhost_backend_init = vhost_kernel_init,
> @@ -197,6 +298,9 @@ static const VhostOps kernel_ops = {
>          .vhost_set_owner = vhost_kernel_set_owner,
>          .vhost_reset_device = vhost_kernel_reset_device,
>          .vhost_get_vq_index = vhost_kernel_get_vq_index,
> +        .vhost_set_iotlb_callback = vhost_kernel_set_iotlb_callback,
> +        .vhost_update_device_iotlb = vhost_kernel_update_device_iotlb,
> +        .vhost_invalidate_device_iotlb = vhost_kernel_invalidate_device_iotlb,
>  };
>  
>  int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 3d0c807..94e577b 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -437,7 +437,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
>              continue;
>          }
>          l = vq->ring_size;
> -        p = cpu_physical_memory_map(vq->ring_phys, &l, 1);
> +        p = virtio_memory_map(dev->vdev, vq->ring_phys, &l, 1);
>          if (!p || l != vq->ring_size) {
>              error_report("Unable to map ring buffer for ring %d", i);
>              r = -ENOMEM;
> @@ -446,7 +446,7 @@ static int vhost_verify_ring_mappings(struct vhost_dev *dev,
>              error_report("Ring buffer relocated for ring %d", i);
>              r = -EBUSY;
>          }
> -        cpu_physical_memory_unmap(p, l, 0, 0);
> +        virtio_memory_unmap(dev->vdev, p, l, 0, 0);
>      }
>      return r;
>  }
> @@ -674,13 +674,18 @@ static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
>      return 0;
>  }
>  
> -static int vhost_dev_set_features(struct vhost_dev *dev, bool enable_log)
> +static int vhost_dev_set_features(struct vhost_dev *dev,
> +                                  bool enable_log)
>  {
>      uint64_t features = dev->acked_features;
> +    bool has_iommu = mr_has_iommu_ops(virtio_get_dma_as(dev->vdev)->root);
>      int r;
>      if (enable_log) {
>          features |= 0x1ULL << VHOST_F_LOG_ALL;
>      }
> +    if (has_iommu) {
> +        features |= 0x1ULL << VIRTIO_F_IOMMU_PLATFORM;
> +    }
>      r = dev->vhost_ops->vhost_set_features(dev, features);
>      if (r < 0) {
>          VHOST_OPS_DEBUG("vhost_set_features failed");
> @@ -817,6 +822,56 @@ static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,
>      return -errno;
>  }
>  
> +static int vhost_memory_region_lookup(struct vhost_dev *hdev,
> +                                      uint64_t gpa, uint64_t *uaddr,
> +                                      uint64_t *len)
> +{
> +    int i;
> +
> +    for (i = 0; i < hdev->mem->nregions; i++) {
> +        struct vhost_memory_region *reg = hdev->mem->regions + i;
> +
> +        if (gpa >= reg->guest_phys_addr &&
> +            reg->guest_phys_addr + reg->memory_size > gpa) {
> +            *uaddr = reg->userspace_addr + gpa - reg->guest_phys_addr;
> +            *len = reg->guest_phys_addr + reg->memory_size - gpa;
> +            return 0;
> +        }
> +    }
> +
> +    return -EFAULT;
> +}
> +
> +void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
> +{
> +    IOMMUTLBEntry iotlb;
> +    uint64_t uaddr, len;
> +
> +    rcu_read_lock();
> +
> +    iotlb = address_space_get_iotlb_entry(virtio_get_dma_as(dev->vdev),
> +                                          iova, write);
> +    if (iotlb.target_as != NULL) {
> +        if (vhost_memory_region_lookup(dev, iotlb.translated_addr,
> +                                       &uaddr, &len)) {
> +            error_report("Fail to lookup the translated address "
> +                         "%"PRIx64, iotlb.translated_addr);
> +            goto out;
> +        }
> +
> +        len = MIN(iotlb.addr_mask + 1, len);
> +        iova = iova & ~iotlb.addr_mask;
> +
> +        if (dev->vhost_ops->vhost_update_device_iotlb(dev, iova, uaddr,
> +                                                      len, iotlb.perm)) {
> +            error_report("Fail to update device iotlb");
> +            goto out;
> +        }
> +    }

Question: when will target_as == NULL? Do we need an assertion here if
it should never happen?

> +out:
> +    rcu_read_unlock();
> +}
> +
>  static int vhost_virtqueue_start(struct vhost_dev *dev,
>                                  struct VirtIODevice *vdev,
>                                  struct vhost_virtqueue *vq,
> @@ -859,21 +914,21 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
>  
>      s = l = virtio_queue_get_desc_size(vdev, idx);
>      a = virtio_queue_get_desc_addr(vdev, idx);
> -    vq->desc = cpu_physical_memory_map(a, &l, 0);
> +    vq->desc = virtio_memory_map(vdev, a, &l, 0);
>      if (!vq->desc || l != s) {
>          r = -ENOMEM;
>          goto fail_alloc_desc;
>      }
>      s = l = virtio_queue_get_avail_size(vdev, idx);
>      a = virtio_queue_get_avail_addr(vdev, idx);
> -    vq->avail = cpu_physical_memory_map(a, &l, 0);
> +    vq->avail = virtio_memory_map(vdev, a, &l, 0);
>      if (!vq->avail || l != s) {
>          r = -ENOMEM;
>          goto fail_alloc_avail;
>      }
>      vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);
>      vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);
> -    vq->used = cpu_physical_memory_map(a, &l, 1);
> +    vq->used = virtio_memory_map(vdev, a, &l, 1);
>      if (!vq->used || l != s) {
>          r = -ENOMEM;
>          goto fail_alloc_used;
> @@ -881,7 +936,7 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
>  
>      vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);
>      vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);
> -    vq->ring = cpu_physical_memory_map(a, &l, 1);
> +    vq->ring = virtio_memory_map(vdev, a, &l, 1);
>      if (!vq->ring || l != s) {
>          r = -ENOMEM;
>          goto fail_alloc_ring;
> @@ -913,20 +968,19 @@ static int vhost_virtqueue_start(struct vhost_dev *dev,
>      }
>  
>      return 0;
> -
>  fail_kick:
>  fail_alloc:
> -    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
> -                              0, 0);
> +    virtio_memory_unmap(vdev, vq->ring, virtio_queue_get_ring_size(vdev, idx),
> +                        0, 0);
>  fail_alloc_ring:
> -    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
> -                              0, 0);
> +    virtio_memory_unmap(vdev, vq->used, virtio_queue_get_used_size(vdev, idx),
> +                        0, 0);
>  fail_alloc_used:
> -    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
> -                              0, 0);
> +    virtio_memory_unmap(vdev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
> +                        0, 0);
>  fail_alloc_avail:
> -    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
> -                              0, 0);
> +    virtio_memory_unmap(vdev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
> +                        0, 0);
>  fail_alloc_desc:
>      return r;
>  }
> @@ -959,14 +1013,14 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
>                                                  vhost_vq_index);
>      }
>  
> -    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
> -                              0, virtio_queue_get_ring_size(vdev, idx));
> -    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),
> -                              1, virtio_queue_get_used_size(vdev, idx));
> -    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),
> -                              0, virtio_queue_get_avail_size(vdev, idx));
> -    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),
> -                              0, virtio_queue_get_desc_size(vdev, idx));
> +    virtio_memory_unmap(vdev, vq->ring, virtio_queue_get_ring_size(vdev, idx),
> +                        0, virtio_queue_get_ring_size(vdev, idx));
> +    virtio_memory_unmap(vdev, vq->used, virtio_queue_get_used_size(vdev, idx),
> +                        1, virtio_queue_get_used_size(vdev, idx));
> +    virtio_memory_unmap(vdev, vq->avail, virtio_queue_get_avail_size(vdev, idx),
> +                        0, virtio_queue_get_avail_size(vdev, idx));
> +    virtio_memory_unmap(vdev, vq->desc, virtio_queue_get_desc_size(vdev, idx),
> +                         0, virtio_queue_get_desc_size(vdev, idx));
>  }
>  
>  static void vhost_eventfd_add(MemoryListener *listener,
> @@ -1023,6 +1077,9 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
>          r = -errno;
>          goto fail_call;
>      }
> +
> +    vq->dev = dev;
> +
>      return 0;
>  fail_call:
>      event_notifier_cleanup(&vq->masked_notifier);
> @@ -1034,12 +1091,25 @@ static void vhost_virtqueue_cleanup(struct vhost_virtqueue *vq)
>      event_notifier_cleanup(&vq->masked_notifier);
>  }
>  
> +static void vhost_iommu_unmap_notify(Notifier *n, void *data)
> +{
> +    struct vhost_dev *hdev = container_of(n, struct vhost_dev, n);
> +    IOMMUTLBEntry *iotlb = data;
> +
> +    if (hdev->vhost_ops->vhost_invalidate_device_iotlb(hdev,
> +                                                       iotlb->iova,
> +                                                       iotlb->addr_mask +1)) {
> +        error_report("Fail to invalidate device iotlb");
> +    }
> +}
> +
>  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>                     VhostBackendType backend_type, uint32_t busyloop_timeout)
>  {
>      uint64_t features;
>      int i, r, n_initialized_vqs = 0;
>  
> +    hdev->vdev = NULL;
>      hdev->migration_blocker = NULL;
>  
>      r = vhost_set_backend_type(hdev, backend_type);
> @@ -1104,6 +1174,8 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>          .priority = 10
>      };
>  
> +    hdev->n.notify = vhost_iommu_unmap_notify;
> +
>      if (hdev->migration_blocker == NULL) {
>          if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) {
>              error_setg(&hdev->migration_blocker,
> @@ -1296,11 +1368,18 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>      assert(hdev->vhost_ops);
>  
>      hdev->started = true;
> +    hdev->vdev = vdev;
>  
>      r = vhost_dev_set_features(hdev, hdev->log_enabled);
>      if (r < 0) {
>          goto fail_features;
>      }
> +
> +    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
> +        memory_region_register_iommu_notifier(virtio_get_dma_as(vdev)->root,
> +                                              &hdev->n);
> +    }
> +
>      r = hdev->vhost_ops->vhost_set_mem_table(hdev, hdev->mem);
>      if (r < 0) {
>          VHOST_OPS_DEBUG("vhost_set_mem_table failed");
> @@ -1334,7 +1413,22 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
>          }
>      }
>  
> +    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
> +
> +    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
> +        /* Update used ring information for IOTLB to work correctly */
> +        for (i = 0; i < hdev->nvqs; ++i) {
> +            struct vhost_virtqueue *vq = hdev->vqs + i;
> +            vhost_device_iotlb_miss(hdev, vq->used_phys, true);
> +        }
> +    }
>      return 0;
> +#if 0
> +fail_iotlb:
> +    if (hdev->vhost_ops->vhost_set_vring_enable) {
> +        hdev->vhost_ops->vhost_set_vring_enable(hdev, 0);
> +    }
> +#endif

Maybe we can remove these lines if not to be used.

>  fail_log:
>      vhost_log_put(hdev, false);
>  fail_vq:
> @@ -1345,6 +1439,7 @@ fail_vq:
>                               hdev->vq_index + i);
>      }
>      i = hdev->nvqs;
> +

Nit: A newline without context change.

>  fail_mem:
>  fail_features:
>  
> @@ -1359,6 +1454,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>  
>      /* should only be called after backend is connected */
>      assert(hdev->vhost_ops);
> +    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
>  
>      for (i = 0; i < hdev->nvqs; ++i) {
>          vhost_virtqueue_stop(hdev,
> @@ -1367,8 +1463,13 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>                               hdev->vq_index + i);
>      }
>  
> +    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
> +        memory_region_unregister_iommu_notifier(virtio_get_dma_as(vdev)->root,
> +                                                &hdev->n);
> +    }
>      vhost_log_put(hdev, true);
>      hdev->started = false;
> +    hdev->vdev = NULL;
>  }
>  
>  int vhost_net_set_backend(struct vhost_dev *hdev,
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index cf7f0b5..5cf8c70 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -8,9 +8,12 @@
>   *
>   */
>  
> +

Another nit for newline.

>  #ifndef VHOST_BACKEND_H
>  #define VHOST_BACKEND_H
>  
> +#include "exec/memory.h"
> +
>  typedef enum VhostBackendType {
>      VHOST_BACKEND_TYPE_NONE = 0,
>      VHOST_BACKEND_TYPE_KERNEL = 1,
> @@ -73,6 +76,14 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
>  typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
>                                             uint64_t start1, uint64_t size1,
>                                             uint64_t start2, uint64_t size2);
> +typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev *dev,
> +                                           int enabled);
> +typedef int (*vhost_update_device_iotlb_op)(struct vhost_dev *dev,
> +                                            uint64_t iova, uint64_t uaddr,
> +                                            uint64_t len,
> +                                            IOMMUAccessFlags perm);
> +typedef int (*vhost_invalidate_device_iotlb_op)(struct vhost_dev *dev,
> +                                                uint64_t iova, uint64_t len);
>  
>  typedef struct VhostOps {
>      VhostBackendType backend_type;
> @@ -102,6 +113,9 @@ typedef struct VhostOps {
>      vhost_requires_shm_log_op vhost_requires_shm_log;
>      vhost_migration_done_op vhost_migration_done;
>      vhost_backend_can_merge_op vhost_backend_can_merge;
> +    vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
> +    vhost_update_device_iotlb_op vhost_update_device_iotlb;
> +    vhost_invalidate_device_iotlb_op vhost_invalidate_device_iotlb;
>  } VhostOps;
>  
>  extern const VhostOps user_ops;
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index e433089..b971fa1 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -20,6 +20,7 @@ struct vhost_virtqueue {
>      unsigned long long ring_phys;
>      unsigned ring_size;
>      EventNotifier masked_notifier;
> +    struct vhost_dev *dev;
>  };
>  
>  typedef unsigned long vhost_log_chunk_t;
> @@ -37,6 +38,7 @@ struct vhost_log {
>  
>  struct vhost_memory;
>  struct vhost_dev {
> +    VirtIODevice *vdev;
>      MemoryListener memory_listener;
>      struct vhost_memory *mem;
>      int n_mem_sections;
> @@ -61,6 +63,7 @@ struct vhost_dev {
>      void *opaque;
>      struct vhost_log *log;
>      QLIST_ENTRY(vhost_dev) entry;
> +    Notifier n;
>  };
>  
>  int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
> @@ -90,4 +93,5 @@ bool vhost_has_free_slot(void);
>  int vhost_net_set_backend(struct vhost_dev *hdev,
>                            struct vhost_vring_file *file);
>  
> +void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
>  #endif
> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> index 4071dad..3560bba 100644
> --- a/include/hw/virtio/virtio-access.h
> +++ b/include/hw/virtio/virtio-access.h
> @@ -18,6 +18,7 @@
>  
>  #include "hw/virtio/virtio.h"
>  #include "hw/virtio/virtio-bus.h"
> +#include "sysemu/dma.h"
>  #include "exec/address-spaces.h"
>  
>  #if defined(TARGET_PPC64) || defined(TARGET_ARM)
> @@ -200,4 +201,45 @@ static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
>  {
>      *s = virtio_tswap64(vdev, *s);
>  }
> -#endif /* QEMU_VIRTIO_ACCESS_H */
> +
> +static inline bool mr_has_iommu_ops(MemoryRegion *mr)
> +{
> +    if (mr->alias) {
> +        return mr_has_iommu_ops(mr->alias);
> +    }
> +
> +    if (mr->iommu_ops)
> +        return true;
> +    else
> +        return false;
> +}

Shall we just enhance memory_region_is_iommu() with alias handling,
then call memory_region_is_iommu() directly?

> +
> +static inline void *virtio_memory_map(VirtIODevice *vdev, hwaddr addr,
> +                                      hwaddr *plen, int is_write)
> +{
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
> +    if (!mr_has_iommu_ops(dma_as->root)) {
> +      return dma_memory_map(dma_as, addr, plen, is_write ?
         ^^ indents :)

> +                            DMA_DIRECTION_FROM_DEVICE :
> +                            DMA_DIRECTION_TO_DEVICE);
> +    } else {
> +      return (void *)addr;
         ^^ and here

> +    }
> +}
> +
> +
> +static inline void virtio_memory_unmap(VirtIODevice *vdev, void *buffer,
> +                                       hwaddr len, int is_write,
> +                                       hwaddr access_len)
> +{
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
> +    if (!mr_has_iommu_ops(dma_as->root)) {
> +      dma_memory_unmap(dma_as, buffer, len, is_write ?
         ^^ and here

And... One general question on the vhost fd used to communicate
between QEMU and vhost: I see that data is coming from both directions
on this fd, would this be a problem?

For example, invalidations are triggered by guest kernel writting to
IOMMU IQ registers (which is a vcpu thread), this may trigger write()
to the vhost fd, meanwhile QEMU event loop is reading it? How are we
handling possible concurrent operations on this same fd? Please just
point out if I missed anything. :)

Thanks,

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-01  2:43         ` Alex Williamson
@ 2016-09-01  3:58           ` Peter Xu
  2016-09-02  4:15             ` David Gibson
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-01  3:58 UTC (permalink / raw)
  To: Alex Williamson
  Cc: Jason Wang, mst, qemu-devel, pbonzini, cornelia.huck, wexu,
	vkaplans, David Gibson

On Wed, Aug 31, 2016 at 08:43:42PM -0600, Alex Williamson wrote:
> > > >>This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
> > > >>device IOTLB API will get notified and send invalidation request to
> > > >>vhost through this notifier.  
> > > >AFAICT this series does not address the original problem for which
> > > >commit 3cb3b1549f54 was added.  We've only addressed the very narrow
> > > >use case of a device iotlb firing the iommu notifier therefore this
> > > >change is a regression versus 2.7 since it allows invalid
> > > >configurations with a physical iommu which will never receive the
> > > >necessary notifies from intel-iommu emulation to work properly.  Thanks,
> > > >
> > > >Alex  
> > > 
> > > Looking at vfio, it cares about map but vhost only cares about IOTLB
> > > invalidation. Then I think we probably need another kind of notifier in this
> > > case to avoid this.  
> > 
> > Shall we leverage IOMMUTLBEntry.perm == IOMMU_NONE as a sign for
> > invalidation? If so, we can use the same IOTLB interface as before.
> > IMHO these two interfaces are not conflicting?
> > 
> > Alex,
> > 
> > Do you mean we should still disallow user from passing through devices
> > while Intel IOMMU enabled? If so, not sure whether patch below can
> > solve the issue.
> > 
> > It seems that we need a "name" for either IOMMU notifier
> > provider/consumer, and we should not allow (provider==Intel &&
> > consumer==VFIO) happen. In the following case, I added a name for
> > provider, and VFIO checks it.
> 
> Absolutely not, intel-iommu emulation is simply incomplete, the IOMMU
> notifier is never called for mappings.  There's a whole aspect of
> iommu notifiers that intel-iommu simply hasn't bothered to implement.
> Don't punish vfio for actually making use of the interface as it was
> intended to be used.  AFAICT you're implementing the unmap/invalidation
> half, without the actual mapping half of the interface.  It's broken
> and incompatible with any iommu notifiers that expect to see both
> sides.  Thanks,

Yeah I think I got your point. Thanks for the explanation.

Now I agree with Jason that we may need another notifier mechanism.

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support
  2016-09-01  3:34   ` Peter Xu
@ 2016-09-01  7:36     ` Jason Wang
  2016-09-02  5:47       ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Jason Wang @ 2016-09-01  7:36 UTC (permalink / raw)
  To: Peter Xu; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans



On 2016年09月01日 11:34, Peter Xu wrote:
> On Tue, Aug 30, 2016 at 11:06:59AM +0800, Jason Wang wrote:
>> This patches implements Device IOTLB support for vhost kernel. This is
>> done through:
>>
>> 1) switch to use dma helpers when map/unmap vrings from vhost codes
>> 2) kernel support for Device IOTLB API:
>>
>> - allow vhost-net to query the IOMMU IOTLB entry through eventfd
>> - enable the ability for qemu to update a specified mapping of vhost
>> - through ioctl.
>> - enable the ability to invalidate a specified range of iova for the
>>    device IOTLB of vhost through ioctl. In x86/intel_iommu case this is
>>    triggered through iommu memory region notifier from device IOTLB
>>    invalidation descriptor processing routine.
>>
>> With all the above, kernel vhost_net can co-operate with IOMMU.
>>
>> Cc: Michael S. Tsirkin <mst@redhat.com>
>> Signed-off-by: Jason Wang <jasowang@redhat.com>
>> ---
>>   hw/virtio/vhost-backend.c         | 104 ++++++++++++++++++++++++++
>>   hw/virtio/vhost.c                 | 149 ++++++++++++++++++++++++++++++++------
>>   include/hw/virtio/vhost-backend.h |  14 ++++
>>   include/hw/virtio/vhost.h         |   4 +
>>   include/hw/virtio/virtio-access.h |  44 ++++++++++-
>>   net/tap.c                         |   1 +
>>   6 files changed, 291 insertions(+), 25 deletions(-)

[...]

>> +
>> +void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
>> +{
>> +    IOMMUTLBEntry iotlb;
>> +    uint64_t uaddr, len;
>> +
>> +    rcu_read_lock();
>> +
>> +    iotlb = address_space_get_iotlb_entry(virtio_get_dma_as(dev->vdev),
>> +                                          iova, write);
>> +    if (iotlb.target_as != NULL) {
>> +        if (vhost_memory_region_lookup(dev, iotlb.translated_addr,
>> +                                       &uaddr, &len)) {
>> +            error_report("Fail to lookup the translated address "
>> +                         "%"PRIx64, iotlb.translated_addr);
>> +            goto out;
>> +        }
>> +
>> +        len = MIN(iotlb.addr_mask + 1, len);
>> +        iova = iova & ~iotlb.addr_mask;
>> +
>> +        if (dev->vhost_ops->vhost_update_device_iotlb(dev, iova, uaddr,
>> +                                                      len, iotlb.perm)) {
>> +            error_report("Fail to update device iotlb");
>> +            goto out;
>> +        }
>> +    }
> Question: when will target_as == NULL? Do we need an assertion here if
> it should never happen?

Good catch, looks like we need check perm against IOMMU_NONE here for 
invalid translation instead of checking target_as.

>> +out:
>> +    rcu_read_unlock();
>> +}
>> +


>> +    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, true);
>> +
>> +    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
>> +        /* Update used ring information for IOTLB to work correctly */
>> +        for (i = 0; i < hdev->nvqs; ++i) {
>> +            struct vhost_virtqueue *vq = hdev->vqs + i;
>> +            vhost_device_iotlb_miss(hdev, vq->used_phys, true);
>> +        }
>> +    }
>>       return 0;
>> +#if 0
>> +fail_iotlb:
>> +    if (hdev->vhost_ops->vhost_set_vring_enable) {
>> +        hdev->vhost_ops->vhost_set_vring_enable(hdev, 0);
>> +    }
>> +#endif
> Maybe we can remove these lines if not to be used.

Yes.

>
>>   fail_log:
>>       vhost_log_put(hdev, false);
>>   fail_vq:
>> @@ -1345,6 +1439,7 @@ fail_vq:
>>                                hdev->vq_index + i);
>>       }
>>       i = hdev->nvqs;
>> +
> Nit: A newline without context change.

Will remove this in next version.

>
>>   fail_mem:
>>   fail_features:
>>   
>> @@ -1359,6 +1454,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>>   
>>       /* should only be called after backend is connected */
>>       assert(hdev->vhost_ops);
>> +    hdev->vhost_ops->vhost_set_iotlb_callback(hdev, false);
>>   
>>       for (i = 0; i < hdev->nvqs; ++i) {
>>           vhost_virtqueue_stop(hdev,
>> @@ -1367,8 +1463,13 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
>>                                hdev->vq_index + i);
>>       }
>>   
>> +    if (mr_has_iommu_ops(virtio_get_dma_as(vdev)->root)) {
>> +        memory_region_unregister_iommu_notifier(virtio_get_dma_as(vdev)->root,
>> +                                                &hdev->n);
>> +    }
>>       vhost_log_put(hdev, true);
>>       hdev->started = false;
>> +    hdev->vdev = NULL;
>>   }
>>   
>>   int vhost_net_set_backend(struct vhost_dev *hdev,
>> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
>> index cf7f0b5..5cf8c70 100644
>> --- a/include/hw/virtio/vhost-backend.h
>> +++ b/include/hw/virtio/vhost-backend.h
>> @@ -8,9 +8,12 @@
>>    *
>>    */
>>   
>> +
> Another nit for newline.

Will remove this in next version.

>
>>   #ifndef VHOST_BACKEND_H
>>   #define VHOST_BACKEND_H
>>   
>> +#include "exec/memory.h"
>> +
>>   typedef enum VhostBackendType {
>>       VHOST_BACKEND_TYPE_NONE = 0,
>>       VHOST_BACKEND_TYPE_KERNEL = 1,
>> @@ -73,6 +76,14 @@ typedef int (*vhost_migration_done_op)(struct vhost_dev *dev,
>>   typedef bool (*vhost_backend_can_merge_op)(struct vhost_dev *dev,
>>                                              uint64_t start1, uint64_t size1,
>>                                              uint64_t start2, uint64_t size2);
>> +typedef void (*vhost_set_iotlb_callback_op)(struct vhost_dev *dev,
>> +                                           int enabled);
>> +typedef int (*vhost_update_device_iotlb_op)(struct vhost_dev *dev,
>> +                                            uint64_t iova, uint64_t uaddr,
>> +                                            uint64_t len,
>> +                                            IOMMUAccessFlags perm);
>> +typedef int (*vhost_invalidate_device_iotlb_op)(struct vhost_dev *dev,
>> +                                                uint64_t iova, uint64_t len);
>>   
>>   typedef struct VhostOps {
>>       VhostBackendType backend_type;
>> @@ -102,6 +113,9 @@ typedef struct VhostOps {
>>       vhost_requires_shm_log_op vhost_requires_shm_log;
>>       vhost_migration_done_op vhost_migration_done;
>>       vhost_backend_can_merge_op vhost_backend_can_merge;
>> +    vhost_set_iotlb_callback_op vhost_set_iotlb_callback;
>> +    vhost_update_device_iotlb_op vhost_update_device_iotlb;
>> +    vhost_invalidate_device_iotlb_op vhost_invalidate_device_iotlb;
>>   } VhostOps;
>>   
>>   extern const VhostOps user_ops;
>> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
>> index e433089..b971fa1 100644
>> --- a/include/hw/virtio/vhost.h
>> +++ b/include/hw/virtio/vhost.h
>> @@ -20,6 +20,7 @@ struct vhost_virtqueue {
>>       unsigned long long ring_phys;
>>       unsigned ring_size;
>>       EventNotifier masked_notifier;
>> +    struct vhost_dev *dev;
>>   };
>>   
>>   typedef unsigned long vhost_log_chunk_t;
>> @@ -37,6 +38,7 @@ struct vhost_log {
>>   
>>   struct vhost_memory;
>>   struct vhost_dev {
>> +    VirtIODevice *vdev;
>>       MemoryListener memory_listener;
>>       struct vhost_memory *mem;
>>       int n_mem_sections;
>> @@ -61,6 +63,7 @@ struct vhost_dev {
>>       void *opaque;
>>       struct vhost_log *log;
>>       QLIST_ENTRY(vhost_dev) entry;
>> +    Notifier n;
>>   };
>>   
>>   int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
>> @@ -90,4 +93,5 @@ bool vhost_has_free_slot(void);
>>   int vhost_net_set_backend(struct vhost_dev *hdev,
>>                             struct vhost_vring_file *file);
>>   
>> +void vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
>>   #endif
>> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
>> index 4071dad..3560bba 100644
>> --- a/include/hw/virtio/virtio-access.h
>> +++ b/include/hw/virtio/virtio-access.h
>> @@ -18,6 +18,7 @@
>>   
>>   #include "hw/virtio/virtio.h"
>>   #include "hw/virtio/virtio-bus.h"
>> +#include "sysemu/dma.h"
>>   #include "exec/address-spaces.h"
>>   
>>   #if defined(TARGET_PPC64) || defined(TARGET_ARM)
>> @@ -200,4 +201,45 @@ static inline void virtio_tswap64s(VirtIODevice *vdev, uint64_t *s)
>>   {
>>       *s = virtio_tswap64(vdev, *s);
>>   }
>> -#endif /* QEMU_VIRTIO_ACCESS_H */
>> +
>> +static inline bool mr_has_iommu_ops(MemoryRegion *mr)
>> +{
>> +    if (mr->alias) {
>> +        return mr_has_iommu_ops(mr->alias);
>> +    }
>> +
>> +    if (mr->iommu_ops)
>> +        return true;
>> +    else
>> +        return false;
>> +}
> Shall we just enhance memory_region_is_iommu() with alias handling,
> then call memory_region_is_iommu() directly?

Good idea, will do this in next version.

>
>> +
>> +static inline void *virtio_memory_map(VirtIODevice *vdev, hwaddr addr,
>> +                                      hwaddr *plen, int is_write)
>> +{
>> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
>> +
>> +    if (!mr_has_iommu_ops(dma_as->root)) {
>> +      return dma_memory_map(dma_as, addr, plen, is_write ?
>           ^^ indents :)
>

Will fix this :)

>> +                            DMA_DIRECTION_FROM_DEVICE :
>> +                            DMA_DIRECTION_TO_DEVICE);
>> +    } else {
>> +      return (void *)addr;
>           ^^ and here

And this.

>> +    }
>> +}
>> +
>> +
>> +static inline void virtio_memory_unmap(VirtIODevice *vdev, void *buffer,
>> +                                       hwaddr len, int is_write,
>> +                                       hwaddr access_len)
>> +{
>> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
>> +
>> +    if (!mr_has_iommu_ops(dma_as->root)) {
>> +      dma_memory_unmap(dma_as, buffer, len, is_write ?
>           ^^ and here
>
> And... One general question on the vhost fd used to communicate
> between QEMU and vhost: I see that data is coming from both directions
> on this fd, would this be a problem?

Looks not :)

>
> For example, invalidations are triggered by guest kernel writting to
> IOMMU IQ registers (which is a vcpu thread), this may trigger write()
> to the vhost fd, meanwhile QEMU event loop is reading it? How are we
> handling possible concurrent operations on this same fd? Please just
> point out if I missed anything. :)

The synchronization were done in kernel:

- message dequeue and enqueue were protected by a spinlock
- the data path and control path (e.g IOTLB updating) were synchronized 
through mutex

Thanks

>
> Thanks,
>
> -- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-01  3:58           ` Peter Xu
@ 2016-09-02  4:15             ` David Gibson
  2016-09-02  5:37               ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: David Gibson @ 2016-09-02  4:15 UTC (permalink / raw)
  To: Peter Xu
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

[-- Attachment #1: Type: text/plain, Size: 2732 bytes --]

On Thu, 1 Sep 2016 11:58:48 +0800
Peter Xu <peterx@redhat.com> wrote:

> On Wed, Aug 31, 2016 at 08:43:42PM -0600, Alex Williamson wrote:
> > > > >>This reverts commit 3cb3b1549f5401dc3a5e1d073e34063dc274136f. Vhost
> > > > >>device IOTLB API will get notified and send invalidation request to
> > > > >>vhost through this notifier.    
> > > > >AFAICT this series does not address the original problem for which
> > > > >commit 3cb3b1549f54 was added.  We've only addressed the very narrow
> > > > >use case of a device iotlb firing the iommu notifier therefore this
> > > > >change is a regression versus 2.7 since it allows invalid
> > > > >configurations with a physical iommu which will never receive the
> > > > >necessary notifies from intel-iommu emulation to work properly.  Thanks,
> > > > >
> > > > >Alex    
> > > > 
> > > > Looking at vfio, it cares about map but vhost only cares about IOTLB
> > > > invalidation. Then I think we probably need another kind of notifier in this
> > > > case to avoid this.    
> > > 
> > > Shall we leverage IOMMUTLBEntry.perm == IOMMU_NONE as a sign for
> > > invalidation? If so, we can use the same IOTLB interface as before.
> > > IMHO these two interfaces are not conflicting?
> > > 
> > > Alex,
> > > 
> > > Do you mean we should still disallow user from passing through devices
> > > while Intel IOMMU enabled? If so, not sure whether patch below can
> > > solve the issue.
> > > 
> > > It seems that we need a "name" for either IOMMU notifier
> > > provider/consumer, and we should not allow (provider==Intel &&
> > > consumer==VFIO) happen. In the following case, I added a name for
> > > provider, and VFIO checks it.  
> > 
> > Absolutely not, intel-iommu emulation is simply incomplete, the IOMMU
> > notifier is never called for mappings.  There's a whole aspect of
> > iommu notifiers that intel-iommu simply hasn't bothered to implement.
> > Don't punish vfio for actually making use of the interface as it was
> > intended to be used.  AFAICT you're implementing the unmap/invalidation
> > half, without the actual mapping half of the interface.  It's broken
> > and incompatible with any iommu notifiers that expect to see both
> > sides.  Thanks,  
> 
> Yeah I think I got your point. Thanks for the explanation.
> 
> Now I agree with Jason that we may need another notifier mechanism.

What!?  I see no reason you need a different notifier, just fix the
implementation of the current one.  As a bonus this will also give you
working VFIO passthrough with vIOMMU on x86, something which should
work already, but doesn't.


-- 
David Gibson <dgibson@redhat.com>
Senior Software Engineer, Virtualization, Red Hat

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  4:15             ` David Gibson
@ 2016-09-02  5:37               ` Peter Xu
  2016-09-02  6:10                 ` David Gibson
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-02  5:37 UTC (permalink / raw)
  To: David Gibson
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, Sep 02, 2016 at 02:15:04PM +1000, David Gibson wrote:
> What!?  I see no reason you need a different notifier, just fix the
> implementation of the current one.  As a bonus this will also give you
> working VFIO passthrough with vIOMMU on x86, something which should
> work already, but doesn't.

Hi, David,

Do you mean that we can enhance the interface to suite the two needs?
E.g., adding a "IOTLB notification type" definition:

- "full": for those who is listening on all mapping changes including
  additions (VFIO use case)

- "cache_only": for those who only cares about cache invalidations
  (device IOTLB, aka, vhost use case)

We can:

- add notify type when we register the notifiers (e.g., when VFIO
  registers IOMMU notifier, it should specify the type as "full", so
  it won't receive notification if it's device IOTLB invalidations).

- pass this type when trigger the notification, so for each IOMMU
  notify handler, it can selectively disgard the notification.

Not sure whether above makes sense.

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support
  2016-09-01  7:36     ` Jason Wang
@ 2016-09-02  5:47       ` Peter Xu
  0 siblings, 0 replies; 52+ messages in thread
From: Peter Xu @ 2016-09-02  5:47 UTC (permalink / raw)
  To: Jason Wang; +Cc: mst, qemu-devel, pbonzini, cornelia.huck, wexu, vkaplans

On Thu, Sep 01, 2016 at 03:36:40PM +0800, Jason Wang wrote:
> The synchronization were done in kernel:
> 
> - message dequeue and enqueue were protected by a spinlock
> - the data path and control path (e.g IOTLB updating) were synchronized
> through mutex

Yes I didn't notice it's the vhost chr device... Thanks!

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  5:37               ` Peter Xu
@ 2016-09-02  6:10                 ` David Gibson
  2016-09-02  6:15                   ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: David Gibson @ 2016-09-02  6:10 UTC (permalink / raw)
  To: Peter Xu
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]

On Fri, 2 Sep 2016 13:37:33 +0800
Peter Xu <peterx@redhat.com> wrote:

> On Fri, Sep 02, 2016 at 02:15:04PM +1000, David Gibson wrote:
> > What!?  I see no reason you need a different notifier, just fix the
> > implementation of the current one.  As a bonus this will also give you
> > working VFIO passthrough with vIOMMU on x86, something which should
> > work already, but doesn't.  
> 
> Hi, David,
> 
> Do you mean that we can enhance the interface to suite the two needs?
> E.g., adding a "IOTLB notification type" definition:
> 
> - "full": for those who is listening on all mapping changes including
>   additions (VFIO use case)
> 
> - "cache_only": for those who only cares about cache invalidations
>   (device IOTLB, aka, vhost use case)
> 
> We can:
> 
> - add notify type when we register the notifiers (e.g., when VFIO
>   registers IOMMU notifier, it should specify the type as "full", so
>   it won't receive notification if it's device IOTLB invalidations).
> 
> - pass this type when trigger the notification, so for each IOMMU
>   notify handler, it can selectively disgard the notification.
> 
> Not sure whether above makes sense.

No, implement the full notifier, and a listener which only wants the
invalidates can just ignore callbacks which add new mappings.

As I said, you'll need this to get VFIO working with vIOMMU which
someone is bound to want soon enough anyway.

-- 
David Gibson <dgibson@redhat.com>
Senior Software Engineer, Virtualization, Red Hat

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  6:10                 ` David Gibson
@ 2016-09-02  6:15                   ` Peter Xu
  2016-09-02  6:18                     ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-02  6:15 UTC (permalink / raw)
  To: David Gibson
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, Sep 02, 2016 at 04:10:14PM +1000, David Gibson wrote:
> On Fri, 2 Sep 2016 13:37:33 +0800
> Peter Xu <peterx@redhat.com> wrote:
> 
> > On Fri, Sep 02, 2016 at 02:15:04PM +1000, David Gibson wrote:
> > > What!?  I see no reason you need a different notifier, just fix the
> > > implementation of the current one.  As a bonus this will also give you
> > > working VFIO passthrough with vIOMMU on x86, something which should
> > > work already, but doesn't.  
> > 
> > Hi, David,
> > 
> > Do you mean that we can enhance the interface to suite the two needs?
> > E.g., adding a "IOTLB notification type" definition:
> > 
> > - "full": for those who is listening on all mapping changes including
> >   additions (VFIO use case)
> > 
> > - "cache_only": for those who only cares about cache invalidations
> >   (device IOTLB, aka, vhost use case)
> > 
> > We can:
> > 
> > - add notify type when we register the notifiers (e.g., when VFIO
> >   registers IOMMU notifier, it should specify the type as "full", so
> >   it won't receive notification if it's device IOTLB invalidations).
> > 
> > - pass this type when trigger the notification, so for each IOMMU
> >   notify handler, it can selectively disgard the notification.
> > 
> > Not sure whether above makes sense.
> 
> No, implement the full notifier, and a listener which only wants the
> invalidates can just ignore callbacks which add new mappings.
> 
> As I said, you'll need this to get VFIO working with vIOMMU which
> someone is bound to want soon enough anyway.

But for vhost cases, we do not need CM bit enabled. That might be the
difference?

I think we need to have vhost working even without CM bit. Device
IOTLB should be able to achieve that.

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  6:15                   ` Peter Xu
@ 2016-09-02  6:18                     ` Peter Xu
  2016-09-02  7:00                       ` David Gibson
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-02  6:18 UTC (permalink / raw)
  To: David Gibson
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, Sep 02, 2016 at 02:15:57PM +0800, Peter Xu wrote:
> > No, implement the full notifier, and a listener which only wants the
> > invalidates can just ignore callbacks which add new mappings.
> > 
> > As I said, you'll need this to get VFIO working with vIOMMU which
> > someone is bound to want soon enough anyway.
> 
> But for vhost cases, we do not need CM bit enabled. That might be the
> difference?
> 
> I think we need to have vhost working even without CM bit. Device
> IOTLB should be able to achieve that.

The problem is that, IMHO we should be very careful on enabling CM
bit. After enabling it, system might get slower (though I haven't
tried it yet), or even very slow? So maybe we will only enable it when
really needed (e.g., to do device passthrough and build the shadow
table).

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  6:18                     ` Peter Xu
@ 2016-09-02  7:00                       ` David Gibson
  2016-09-02  9:31                         ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: David Gibson @ 2016-09-02  7:00 UTC (permalink / raw)
  To: Peter Xu
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

[-- Attachment #1: Type: text/plain, Size: 1095 bytes --]

On Fri, 2 Sep 2016 14:18:47 +0800
Peter Xu <peterx@redhat.com> wrote:

> On Fri, Sep 02, 2016 at 02:15:57PM +0800, Peter Xu wrote:
> > > No, implement the full notifier, and a listener which only wants the
> > > invalidates can just ignore callbacks which add new mappings.
> > > 
> > > As I said, you'll need this to get VFIO working with vIOMMU which
> > > someone is bound to want soon enough anyway.  
> > 
> > But for vhost cases, we do not need CM bit enabled. That might be the
> > difference?
> > 
> > I think we need to have vhost working even without CM bit. Device
> > IOTLB should be able to achieve that.  
> 
> The problem is that, IMHO we should be very careful on enabling CM
> bit. After enabling it, system might get slower (though I haven't
> tried it yet), or even very slow? So maybe we will only enable it when
> really needed (e.g., to do device passthrough and build the shadow
> table).

Um.. what's the CM bit and what does it have to do with anything?

-- 
David Gibson <dgibson@redhat.com>
Senior Software Engineer, Virtualization, Red Hat

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  7:00                       ` David Gibson
@ 2016-09-02  9:31                         ` Peter Xu
  2016-09-02 15:13                           ` Alex Williamson
  0 siblings, 1 reply; 52+ messages in thread
From: Peter Xu @ 2016-09-02  9:31 UTC (permalink / raw)
  To: David Gibson
  Cc: Alex Williamson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, Sep 02, 2016 at 05:00:28PM +1000, David Gibson wrote:
> On Fri, 2 Sep 2016 14:18:47 +0800
> Peter Xu <peterx@redhat.com> wrote:
> 
> > On Fri, Sep 02, 2016 at 02:15:57PM +0800, Peter Xu wrote:
> > > > No, implement the full notifier, and a listener which only wants the
> > > > invalidates can just ignore callbacks which add new mappings.
> > > > 
> > > > As I said, you'll need this to get VFIO working with vIOMMU which
> > > > someone is bound to want soon enough anyway.  
> > > 
> > > But for vhost cases, we do not need CM bit enabled. That might be the
> > > difference?
> > > 
> > > I think we need to have vhost working even without CM bit. Device
> > > IOTLB should be able to achieve that.  
> > 
> > The problem is that, IMHO we should be very careful on enabling CM
> > bit. After enabling it, system might get slower (though I haven't
> > tried it yet), or even very slow? So maybe we will only enable it when
> > really needed (e.g., to do device passthrough and build the shadow
> > table).
> 
> Um.. what's the CM bit and what does it have to do with anything?

It's used to trace guest IO address space mapping changes.

Pasted from VT-d spec chap 6.1:

    The Caching Mode (CM) field in Capability Register indicates if
    the hardware implementation caches not-present or erroneous
    translation-structure entries. When the CM field is reported as
    Set, any software updates to any remapping structures (including
    updates to not-present entries or present entries whose
    programming resulted in translation faults) requires explicit
    invalidation of the caches.

    Hardware implementations of this architecture must support
    operation corresponding to CM=0. Operation corresponding to CM=1
    may be supported by software implementations (emulation) of this
    architecture for efficient virtualization of remapping hardware.
    Software managing remapping hardware should be written to handle
    both caching modes.

    Software implementations virtualizing the remapping architecture
    (such as a VMM emulating remapping hardware to an operating system
    running within a guest partition) may report CM=1 to efficiently
    virtualize the hardware. Software virtualization typically
    requires the guest remapping structures to be shadowed in the
    host. Reporting the Caching Mode as Set for the virtual hardware
    requires the guest software to explicitly issue invalidation
    operations on the virtual hardware for any/all updates to the
    guest remapping structures. The virtualizing software may trap
    these guest invalidation operations to keep the shadow translation
    structures consistent to guest translation structure
    modifications, without resorting to other less efficient
    techniques (such as write-protecting the guest translation
    structures through the processor’s paging facility).

Currently it is not supported for Intel vIOMMUs.

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02  9:31                         ` Peter Xu
@ 2016-09-02 15:13                           ` Alex Williamson
  2016-09-05  6:28                             ` Peter Xu
  0 siblings, 1 reply; 52+ messages in thread
From: Alex Williamson @ 2016-09-02 15:13 UTC (permalink / raw)
  To: Peter Xu
  Cc: David Gibson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, 2 Sep 2016 17:31:00 +0800
Peter Xu <peterx@redhat.com> wrote:

> On Fri, Sep 02, 2016 at 05:00:28PM +1000, David Gibson wrote:
> > On Fri, 2 Sep 2016 14:18:47 +0800
> > Peter Xu <peterx@redhat.com> wrote:
> >   
> > > On Fri, Sep 02, 2016 at 02:15:57PM +0800, Peter Xu wrote:  
> > > > > No, implement the full notifier, and a listener which only wants the
> > > > > invalidates can just ignore callbacks which add new mappings.
> > > > > 
> > > > > As I said, you'll need this to get VFIO working with vIOMMU which
> > > > > someone is bound to want soon enough anyway.    
> > > > 
> > > > But for vhost cases, we do not need CM bit enabled. That might be the
> > > > difference?
> > > > 
> > > > I think we need to have vhost working even without CM bit. Device
> > > > IOTLB should be able to achieve that.    
> > > 
> > > The problem is that, IMHO we should be very careful on enabling CM
> > > bit. After enabling it, system might get slower (though I haven't
> > > tried it yet), or even very slow? So maybe we will only enable it when
> > > really needed (e.g., to do device passthrough and build the shadow
> > > table).  
> > 
> > Um.. what's the CM bit and what does it have to do with anything?  
> 
> It's used to trace guest IO address space mapping changes.
> 
> Pasted from VT-d spec chap 6.1:
> 
>     The Caching Mode (CM) field in Capability Register indicates if
>     the hardware implementation caches not-present or erroneous
>     translation-structure entries. When the CM field is reported as
>     Set, any software updates to any remapping structures (including
>     updates to not-present entries or present entries whose
>     programming resulted in translation faults) requires explicit
>     invalidation of the caches.
> 
>     Hardware implementations of this architecture must support
>     operation corresponding to CM=0. Operation corresponding to CM=1
>     may be supported by software implementations (emulation) of this
>     architecture for efficient virtualization of remapping hardware.
>     Software managing remapping hardware should be written to handle
>     both caching modes.
> 
>     Software implementations virtualizing the remapping architecture
>     (such as a VMM emulating remapping hardware to an operating system
>     running within a guest partition) may report CM=1 to efficiently
>     virtualize the hardware. Software virtualization typically
>     requires the guest remapping structures to be shadowed in the
>     host. Reporting the Caching Mode as Set for the virtual hardware
>     requires the guest software to explicitly issue invalidation
>     operations on the virtual hardware for any/all updates to the
>     guest remapping structures. The virtualizing software may trap
>     these guest invalidation operations to keep the shadow translation
>     structures consistent to guest translation structure
>     modifications, without resorting to other less efficient
>     techniques (such as write-protecting the guest translation
>     structures through the processor’s paging facility).
> 
> Currently it is not supported for Intel vIOMMUs.

Maybe memory_region_register_iommu_notifier() could take an
IOMMUAccessFlags argument (filter) that is passed to the notify_started
callback.  If a notifier client only cares about IOMMU_NONE
(invalidations), intel-iommu could allow it, regardless of the CM
setting (though I'm dubious whether this is complete in the generic
case or really only for device iotlbs).  If a client requires IOMMU_RW
then intel-iommu would currently bomb-out like it does now, or once
that gets fixed it would bomb if CM=0.  Ideally intel-iommu would
be fully functional, but somehow it was allowed into the tree
with this massive gap in support for QEMU iommu interfaces.  Thanks,

Alex

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4 Jason Wang
@ 2016-09-05  1:24   ` Wei Xu
  2016-09-05  1:26     ` Michael S. Tsirkin
  0 siblings, 1 reply; 52+ messages in thread
From: Wei Xu @ 2016-09-05  1:24 UTC (permalink / raw)
  To: Jason Wang, mst, qemu-devel; +Cc: peterx, vkaplans, cornelia.huck, pbonzini



On 2016年08月30日 11:06, Jason Wang wrote:
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>   include/standard-headers/linux/input-event-codes.h | 32 +++++++++++++++++
>   include/standard-headers/linux/input.h             |  1 +
>   include/standard-headers/linux/virtio_config.h     | 10 +++++-
>   include/standard-headers/linux/virtio_ids.h        |  1 +
>   include/standard-headers/linux/virtio_net.h        |  3 ++
>   linux-headers/asm-arm/kvm.h                        |  4 +--
>   linux-headers/asm-arm64/kvm.h                      |  2 ++
>   linux-headers/asm-s390/kvm.h                       | 41 ++++++++++++++++++++++
>   linux-headers/asm-x86/unistd_x32.h                 |  4 +--
>   linux-headers/linux/kvm.h                          | 18 ++++++++--
>   linux-headers/linux/vhost.h                        | 33 +++++++++++++++++
>   11 files changed, 142 insertions(+), 7 deletions(-)
>
> diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
> index 354f0de..5c10f7e 100644
> --- a/include/standard-headers/linux/input-event-codes.h
> +++ b/include/standard-headers/linux/input-event-codes.h
> @@ -611,6 +611,37 @@
>   #define KEY_KBDINPUTASSIST_ACCEPT		0x264
>   #define KEY_KBDINPUTASSIST_CANCEL		0x265
>
> +/* Diagonal movement keys */
> +#define KEY_RIGHT_UP			0x266
> +#define KEY_RIGHT_DOWN			0x267
> +#define KEY_LEFT_UP			0x268
> +#define KEY_LEFT_DOWN			0x269
> +
> +#define KEY_ROOT_MENU			0x26a /* Show Device's Root Menu */
> +/* Show Top Menu of the Media (e.g. DVD) */
> +#define KEY_MEDIA_TOP_MENU		0x26b
> +#define KEY_NUMERIC_11			0x26c
> +#define KEY_NUMERIC_12			0x26d
> +/*
> + * Toggle Audio Description: refers to an audio service that helps blind and
> + * visually impaired consumers understand the action in a program. Note: in
> + * some countries this is referred to as "Video Description".
> + */
> +#define KEY_AUDIO_DESC			0x26e
> +#define KEY_3D_MODE			0x26f
> +#define KEY_NEXT_FAVORITE		0x270
> +#define KEY_STOP_RECORD			0x271
> +#define KEY_PAUSE_RECORD		0x272
> +#define KEY_VOD				0x273 /* Video on Demand */
> +#define KEY_UNMUTE			0x274
> +#define KEY_FASTREVERSE			0x275
> +#define KEY_SLOWREVERSE			0x276
> +/*
> + * Control a data application associated with the currently viewed channel,
> + * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
> + */
> +#define KEY_DATA			0x275
> +
>   #define BTN_TRIGGER_HAPPY		0x2c0
>   #define BTN_TRIGGER_HAPPY1		0x2c0
>   #define BTN_TRIGGER_HAPPY2		0x2c1
> @@ -749,6 +780,7 @@
>   #define SW_ROTATE_LOCK		0x0c  /* set = rotate locked/disabled */
>   #define SW_LINEIN_INSERT	0x0d  /* set = inserted */
>   #define SW_MUTE_DEVICE		0x0e  /* set = device disabled */
> +#define SW_PEN_INSERTED		0x0f  /* set = pen inserted */
>   #define SW_MAX_			0x0f
>   #define SW_CNT			(SW_MAX_+1)
>
> diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
> index a52b202..7361a16 100644
> --- a/include/standard-headers/linux/input.h
> +++ b/include/standard-headers/linux/input.h
> @@ -244,6 +244,7 @@ struct input_mask {
>   #define BUS_ATARI		0x1B
>   #define BUS_SPI			0x1C
>   #define BUS_RMI			0x1D
> +#define BUS_CEC			0x1E
>
>   /*
>    * MT_TOOL types
> diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h
> index b30d0cb..b777069 100644
> --- a/include/standard-headers/linux/virtio_config.h
> +++ b/include/standard-headers/linux/virtio_config.h
> @@ -49,7 +49,7 @@
>    * transport being used (eg. virtio_ring), the rest are per-device feature
>    * bits. */
>   #define VIRTIO_TRANSPORT_F_START	28
> -#define VIRTIO_TRANSPORT_F_END		33
> +#define VIRTIO_TRANSPORT_F_END		34
>
>   #ifndef VIRTIO_CONFIG_NO_LEGACY
>   /* Do we get callbacks when the ring is completely used, even if we've
> @@ -63,4 +63,12 @@
>   /* v1.0 compliant. */
>   #define VIRTIO_F_VERSION_1		32
>
> +/*
> + * If clear - device has the IOMMU bypass quirk feature.
> + * If set - use platform tools to detect the IOMMU.
> + *
> + * Note the reverse polarity (compared to most other features),
> + * this is for compatibility with legacy systems.
> + */
> +#define VIRTIO_F_IOMMU_PLATFORM		33
>   #endif /* _LINUX_VIRTIO_CONFIG_H */
> diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
> index 77925f5..3228d58 100644
> --- a/include/standard-headers/linux/virtio_ids.h
> +++ b/include/standard-headers/linux/virtio_ids.h
> @@ -41,5 +41,6 @@
>   #define VIRTIO_ID_CAIF	       12 /* Virtio caif */
>   #define VIRTIO_ID_GPU          16 /* virtio GPU */
>   #define VIRTIO_ID_INPUT        18 /* virtio input */
> +#define VIRTIO_ID_VSOCK        19 /* virtio vsock transport */
>
>   #endif /* _LINUX_VIRTIO_IDS_H */
> diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
> index a78f33e..30ff249 100644
> --- a/include/standard-headers/linux/virtio_net.h
> +++ b/include/standard-headers/linux/virtio_net.h
> @@ -35,6 +35,7 @@
>   #define VIRTIO_NET_F_CSUM	0	/* Host handles pkts w/ partial csum */
>   #define VIRTIO_NET_F_GUEST_CSUM	1	/* Guest handles pkts w/ partial csum */
>   #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
> +#define VIRTIO_NET_F_MTU	3	/* Initial MTU advice */
>   #define VIRTIO_NET_F_MAC	5	/* Host has given MAC address. */
>   #define VIRTIO_NET_F_GUEST_TSO4	7	/* Guest can handle TSOv4 in. */
>   #define VIRTIO_NET_F_GUEST_TSO6	8	/* Guest can handle TSOv6 in. */
> @@ -73,6 +74,8 @@ struct virtio_net_config {
>   	 * Legal values are between 1 and 0x8000
>   	 */
>   	uint16_t max_virtqueue_pairs;
> +	/* Default maximum transmit unit advice */
> +	uint16_t mtu;
>   } QEMU_PACKED;
>
>   /*
> diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
> index c98e4dc..541268c 100644
> --- a/linux-headers/asm-arm/kvm.h
> +++ b/linux-headers/asm-arm/kvm.h
> @@ -139,8 +139,8 @@ struct kvm_arch_memory_slot {
>   #define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
>
>   #define KVM_REG_ARM_TIMER_CTL		ARM_CP15_REG32(0, 14, 3, 1)
> -#define KVM_REG_ARM_TIMER_CNT		ARM_CP15_REG64(1, 14)
> -#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14)
> +#define KVM_REG_ARM_TIMER_CNT		ARM_CP15_REG64(1, 14)
> +#define KVM_REG_ARM_TIMER_CVAL		ARM_CP15_REG64(3, 14)
>
>   /* Normal registers are mapped as coprocessor 16. */
>   #define KVM_REG_ARM_CORE		(0x0010 << KVM_REG_ARM_COPROC_SHIFT)
> diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
> index 7d82d1f..fd5a276 100644
> --- a/linux-headers/asm-arm64/kvm.h
> +++ b/linux-headers/asm-arm64/kvm.h
> @@ -87,9 +87,11 @@ struct kvm_regs {
>   /* Supported VGICv3 address types  */
>   #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>   #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
> +#define KVM_VGIC_ITS_ADDR_TYPE		4
>
>   #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>   #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
> +#define KVM_VGIC_V3_ITS_SIZE		(2 * SZ_64K)
>
>   #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>   #define KVM_ARM_VCPU_EL1_32BIT		1 /* CPU running a 32bit VM */
> diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
> index 09ae5dc..ac63ca6 100644
> --- a/linux-headers/asm-s390/kvm.h
> +++ b/linux-headers/asm-s390/kvm.h
> @@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
>   	__u64 fac_list[256];
>   };
>
> +#define KVM_S390_VM_CPU_PROCESSOR_FEAT	2
> +#define KVM_S390_VM_CPU_MACHINE_FEAT	3
> +
> +#define KVM_S390_VM_CPU_FEAT_NR_BITS	1024
> +#define KVM_S390_VM_CPU_FEAT_ESOP	0
> +#define KVM_S390_VM_CPU_FEAT_SIEF2	1
> +#define KVM_S390_VM_CPU_FEAT_64BSCAO	2
> +#define KVM_S390_VM_CPU_FEAT_SIIF	3
> +#define KVM_S390_VM_CPU_FEAT_GPERE	4
> +#define KVM_S390_VM_CPU_FEAT_GSLS	5
> +#define KVM_S390_VM_CPU_FEAT_IB		6
> +#define KVM_S390_VM_CPU_FEAT_CEI	7
> +#define KVM_S390_VM_CPU_FEAT_IBS	8
> +#define KVM_S390_VM_CPU_FEAT_SKEY	9
> +#define KVM_S390_VM_CPU_FEAT_CMMA	10
> +#define KVM_S390_VM_CPU_FEAT_PFMFI	11
> +#define KVM_S390_VM_CPU_FEAT_SIGPIF	12
> +struct kvm_s390_vm_cpu_feat {
> +	__u64 feat[16];
> +};
> +
> +#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC	4
> +#define KVM_S390_VM_CPU_MACHINE_SUBFUNC		5
> +/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
> +struct kvm_s390_vm_cpu_subfunc {
> +	__u8 plo[32];		/* always */
> +	__u8 ptff[16];		/* with TOD-clock steering */
> +	__u8 kmac[16];		/* with MSA */
> +	__u8 kmc[16];		/* with MSA */
> +	__u8 km[16];		/* with MSA */
> +	__u8 kimd[16];		/* with MSA */
> +	__u8 klmd[16];		/* with MSA */
> +	__u8 pckmo[16];		/* with MSA3 */
> +	__u8 kmctr[16];		/* with MSA4 */
> +	__u8 kmf[16];		/* with MSA4 */
> +	__u8 kmo[16];		/* with MSA4 */
> +	__u8 pcc[16];		/* with MSA4 */
> +	__u8 ppno[16];		/* with MSA5 */
> +	__u8 reserved[1824];
> +};
> +
>   /* kvm attributes for crypto */
>   #define KVM_S390_VM_CRYPTO_ENABLE_AES_KW	0
>   #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW	1
> diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
> index 0230779..e5aea76 100644
> --- a/linux-headers/asm-x86/unistd_x32.h
> +++ b/linux-headers/asm-x86/unistd_x32.h
> @@ -306,9 +306,7 @@
>   #define __NR_vmsplice (__X32_SYSCALL_BIT + 532)
>   #define __NR_move_pages (__X32_SYSCALL_BIT + 533)
>   #define __NR_preadv (__X32_SYSCALL_BIT + 534)
> -#define __NR_preadv2 (__X32_SYSCALL_BIT + 534)
>   #define __NR_pwritev (__X32_SYSCALL_BIT + 535)
> -#define __NR_pwritev2 (__X32_SYSCALL_BIT + 535)
>   #define __NR_rt_tgsigqueueinfo (__X32_SYSCALL_BIT + 536)
>   #define __NR_recvmmsg (__X32_SYSCALL_BIT + 537)
>   #define __NR_sendmmsg (__X32_SYSCALL_BIT + 538)
> @@ -319,5 +317,7 @@
>   #define __NR_io_setup (__X32_SYSCALL_BIT + 543)
>   #define __NR_io_submit (__X32_SYSCALL_BIT + 544)
>   #define __NR_execveat (__X32_SYSCALL_BIT + 545)
> +#define __NR_preadv2 (__X32_SYSCALL_BIT + 546)
> +#define __NR_pwritev2 (__X32_SYSCALL_BIT + 547)
>
>   #endif /* _ASM_X86_UNISTD_X32_H */
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index e60e21b..4806e06 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -866,6 +866,10 @@ struct kvm_ppc_smmu_info {
>   #define KVM_CAP_ARM_PMU_V3 126
>   #define KVM_CAP_VCPU_ATTRIBUTES 127
>   #define KVM_CAP_MAX_VCPU_ID 128
> +#define KVM_CAP_X2APIC_API 129
> +#define KVM_CAP_S390_USER_INSTR0 130
> +#define KVM_CAP_MSI_DEVID 131
> +#define KVM_CAP_PPC_HTM 132
>
>   #ifdef KVM_CAP_IRQ_ROUTING
>
> @@ -878,7 +882,10 @@ struct kvm_irq_routing_msi {
>   	__u32 address_lo;
>   	__u32 address_hi;
>   	__u32 data;
> -	__u32 pad;
> +	union {
> +		__u32 pad;
> +		__u32 devid;
> +	};
>   };
>
>   struct kvm_irq_routing_s390_adapter {
> @@ -1024,12 +1031,14 @@ struct kvm_one_reg {
>   	__u64 addr;
>   };
>
> +#define KVM_MSI_VALID_DEVID	(1U << 0)
>   struct kvm_msi {
>   	__u32 address_lo;
>   	__u32 address_hi;
>   	__u32 data;
>   	__u32 flags;
> -	__u8  pad[16];
> +	__u32 devid;
> +	__u8  pad[12];
>   };
>
>   struct kvm_arm_device_addr {
> @@ -1074,6 +1083,8 @@ enum kvm_device_type {
>   #define KVM_DEV_TYPE_FLIC		KVM_DEV_TYPE_FLIC
>   	KVM_DEV_TYPE_ARM_VGIC_V3,
>   #define KVM_DEV_TYPE_ARM_VGIC_V3	KVM_DEV_TYPE_ARM_VGIC_V3
> +	KVM_DEV_TYPE_ARM_VGIC_ITS,
> +#define KVM_DEV_TYPE_ARM_VGIC_ITS	KVM_DEV_TYPE_ARM_VGIC_ITS
>   	KVM_DEV_TYPE_MAX,
>   };
>
> @@ -1313,4 +1324,7 @@ struct kvm_assigned_msix_entry {
>   	__u16 padding[3];
>   };
>
> +#define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
> +#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
> +
>   #endif /* __LINUX_KVM_H */
> diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
> index 571294c..ac7a1f1 100644
> --- a/linux-headers/linux/vhost.h
> +++ b/linux-headers/linux/vhost.h
> @@ -47,6 +47,32 @@ struct vhost_vring_addr {
>   	__u64 log_guest_addr;
>   };
>
> +/* no alignment requirement */
> +struct vhost_iotlb_msg {
> +	__u64 iova;
> +	__u64 size;
> +	__u64 uaddr;
> +#define VHOST_ACCESS_RO      0x1
> +#define VHOST_ACCESS_WO      0x2
> +#define VHOST_ACCESS_RW      0x3
> +	__u8 perm;
> +#define VHOST_IOTLB_MISS           1
> +#define VHOST_IOTLB_UPDATE         2
> +#define VHOST_IOTLB_INVALIDATE     3
> +#define VHOST_IOTLB_ACCESS_FAIL    4
> +	__u8 type;
> +};
> +
> +#define VHOST_IOTLB_MSG 0x1
> +
> +struct vhost_msg {
> +	int type;
> +	union {
> +		struct vhost_iotlb_msg iotlb;
> +		__u8 padding[64];
> +	};
> +};
> +
>   struct vhost_memory_region {
>   	__u64 guest_phys_addr;
>   	__u64 memory_size; /* bytes */
> @@ -146,6 +172,8 @@ struct vhost_memory {
>   #define VHOST_F_LOG_ALL 26
>   /* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
>   #define VHOST_NET_F_VIRTIO_NET_HDR 27
> +/* Vhost have device IOTLB */
> +#define VHOST_F_DEVICE_IOTLB 63
>
>   /* VHOST_SCSI specific definitions */
>
> @@ -175,4 +203,9 @@ struct vhost_scsi_target {
>   #define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
>   #define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
>
> +/* VHOST_VSOCK specific defines */
> +
> +#define VHOST_VSOCK_SET_GUEST_CID	_IOW(VHOST_VIRTIO, 0x60, __u64)
> +#define VHOST_VSOCK_SET_RUNNING		_IOW(VHOST_VIRTIO, 0x61, int)
> +
>   #endif
>

Looks this patch includes quite a few misc changes from upstream, it's a 
bit confused to find out which one is related to virtio/vhost dmar 
support, while the upstream header shows a separate commit for new IOTLB 
api, is it possible to split this patch to dmar related one and a
common pull from upstream?

upstream log:
git log -p include/uapi/linux/vhost.h
commit 6b1e6cc7855b09a0a9bfa1d9f30172ba366f161c
Author: Jason Wang <jasowang@redhat.com>
Date: Thu Jun 23 02:04:32 2016 -0400

vhost: new device IOTLB API

This patch tries to implement an device IOTLB for vhost. This could
be used with userspace(qemu) implementation of DMA remapping to
emulate an IOMMU for the guest.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4
  2016-09-05  1:24   ` Wei Xu
@ 2016-09-05  1:26     ` Michael S. Tsirkin
  2016-09-06  6:28       ` Jason Wang
  0 siblings, 1 reply; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-09-05  1:26 UTC (permalink / raw)
  To: Wei Xu; +Cc: Jason Wang, qemu-devel, peterx, vkaplans, cornelia.huck, pbonzini

On Mon, Sep 05, 2016 at 09:24:37AM +0800, Wei Xu wrote:
> Looks this patch includes quite a few misc changes from upstream, it's a bit
> confused to find out which one is related to virtio/vhost dmar support,
> while the upstream header shows a separate commit for new IOTLB api, is it
> possible to split this patch to dmar related one and a
> common pull from upstream?
> 
> upstream log:
> git log -p include/uapi/linux/vhost.h
> commit 6b1e6cc7855b09a0a9bfa1d9f30172ba366f161c
> Author: Jason Wang <jasowang@redhat.com>
> Date: Thu Jun 23 02:04:32 2016 -0400
> 
> vhost: new device IOTLB API
> 
> This patch tries to implement an device IOTLB for vhost. This could
> be used with userspace(qemu) implementation of DMA remapping to
> emulate an IOMMU for the guest.


You don't need to sync all headers. Just commit the ones that make
sense.

-- 
MST

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
  2016-08-30  7:31   ` Cornelia Huck
@ 2016-09-05  2:26   ` Wei Xu
  2016-09-06  6:30     ` Jason Wang
  2016-09-05  2:33   ` Michael S. Tsirkin
  2 siblings, 1 reply; 52+ messages in thread
From: Wei Xu @ 2016-09-05  2:26 UTC (permalink / raw)
  To: Jason Wang, mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, vkaplans, Stefan Hajnoczi,
	Kevin Wolf, Amit Shah, qemu-block

On 2016年08月30日 11:06, Jason Wang wrote:
> @@ -1587,6 +1595,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
>       }
>
>       if (legacy) {
> +        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
> +            error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
> +                       "neither legacy nor transitional device.");
> +            return ;
> +        }

Not sure if i understand it correctly, the transitional device here 
maybe a bit hard to understand, just a tip for your convenience,
besides the denied prompt, can we add what kind of device is supported 
to the message? such as modern device only, like this.

"VIRTIO_F_IOMMU_PLATFORM is supported by modern device only, it
is not supported by either legacy or transitional device."

>           /* legacy and transitional */
>           pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
>                        pci_get_word(config + PCI_VENDOR_ID));

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
  2016-08-30  7:31   ` Cornelia Huck
  2016-09-05  2:26   ` Wei Xu
@ 2016-09-05  2:33   ` Michael S. Tsirkin
  2 siblings, 0 replies; 52+ messages in thread
From: Michael S. Tsirkin @ 2016-09-05  2:33 UTC (permalink / raw)
  To: Jason Wang
  Cc: qemu-devel, pbonzini, peterx, cornelia.huck, wexu, vkaplans,
	Stefan Hajnoczi, Kevin Wolf, Amit Shah, qemu-block

On Tue, Aug 30, 2016 at 11:06:50AM +0800, Jason Wang wrote:
> @@ -1587,6 +1595,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
>      }
>  
>      if (legacy) {
> +        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
> +            error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
> +                       "neither legacy nor transitional device.");
> +            return ;
> +        }
>          /* legacy and transitional */
>          pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
>                       pci_get_word(config + PCI_VENDOR_ID));


We probably should have code to fail init if modern is disabled
since the configuration is inconsistent.

But I do not think we should break transitional devices
with this flag.


> @@ -2452,6 +2465,7 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
>      k->ioeventfd_disabled = virtio_pci_ioeventfd_disabled;
>      k->ioeventfd_set_disabled = virtio_pci_ioeventfd_set_disabled;
>      k->ioeventfd_assign = virtio_pci_ioeventfd_assign;
> +    k->get_dma_as = virtio_pci_get_dma_as;
>  }
>  
>  static const TypeInfo virtio_pci_bus_info = {
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 15ee3a7..99ea97c 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -23,6 +23,7 @@
>  #include "hw/virtio/virtio-bus.h"
>  #include "migration/migration.h"
>  #include "hw/virtio/virtio-access.h"
> +#include "sysemu/dma.h"
>  
>  /*
>   * The alignment to use between consumer and producer parts of vring.
> @@ -122,7 +123,7 @@ void virtio_queue_update_rings(VirtIODevice *vdev, int n)
>  static void vring_desc_read(VirtIODevice *vdev, VRingDesc *desc,
>                              hwaddr desc_pa, int i)
>  {
> -    address_space_read(&address_space_memory, desc_pa + i * sizeof(VRingDesc),
> +    address_space_read(virtio_get_dma_as(vdev), desc_pa + i * sizeof(VRingDesc),
>                         MEMTXATTRS_UNSPECIFIED, (void *)desc, sizeof(VRingDesc));
>      virtio_tswap64s(vdev, &desc->addr);
>      virtio_tswap32s(vdev, &desc->len);
> @@ -164,7 +165,7 @@ static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem,
>      virtio_tswap32s(vq->vdev, &uelem->id);
>      virtio_tswap32s(vq->vdev, &uelem->len);
>      pa = vq->vring.used + offsetof(VRingUsed, ring[i]);
> -    address_space_write(&address_space_memory, pa, MEMTXATTRS_UNSPECIFIED,
> +    address_space_write(virtio_get_dma_as(vq->vdev), pa, MEMTXATTRS_UNSPECIFIED,
>                         (void *)uelem, sizeof(VRingUsedElem));
>  }
>  
> @@ -244,6 +245,7 @@ int virtio_queue_empty(VirtQueue *vq)
>  static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
>                                 unsigned int len)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vq->vdev);
>      unsigned int offset;
>      int i;
>  
> @@ -251,17 +253,17 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
>      for (i = 0; i < elem->in_num; i++) {
>          size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
>  
> -        cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
> -                                  elem->in_sg[i].iov_len,
> -                                  1, size);
> +        dma_memory_unmap(dma_as, elem->in_sg[i].iov_base, elem->in_sg[i].iov_len,
> +                         DMA_DIRECTION_FROM_DEVICE, size);
>  
>          offset += size;
>      }
>  
>      for (i = 0; i < elem->out_num; i++)
> -        cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
> -                                  elem->out_sg[i].iov_len,
> -                                  0, elem->out_sg[i].iov_len);
> +        dma_memory_unmap(dma_as, elem->out_sg[i].iov_base,
> +                         elem->out_sg[i].iov_len,
> +                         DMA_DIRECTION_TO_DEVICE,
> +                         elem->out_sg[i].iov_len);
>  }
>  
>  void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
> @@ -451,7 +453,8 @@ int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
>      return in_bytes <= in_total && out_bytes <= out_total;
>  }
>  
> -static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,
> +static void virtqueue_map_desc(VirtIODevice *vdev,
> +                               unsigned int *p_num_sg, hwaddr *addr, struct iovec *iov,
>                                 unsigned int max_num_sg, bool is_write,
>                                 hwaddr pa, size_t sz)
>  {
> @@ -471,7 +474,10 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
>              exit(1);
>          }
>  
> -        iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
> +        iov[num_sg].iov_base = dma_memory_map(virtio_get_dma_as(vdev), pa, &len,
> +                                              is_write ?
> +                                              DMA_DIRECTION_FROM_DEVICE:
> +                                              DMA_DIRECTION_TO_DEVICE);
>          iov[num_sg].iov_len = len;
>          addr[num_sg] = pa;
>  
> @@ -482,9 +488,9 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
>      *p_num_sg = num_sg;
>  }
>  
> -static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
> -                                unsigned int *num_sg, unsigned int max_size,
> -                                int is_write)
> +static void virtqueue_map_iovec(VirtIODevice *vdev, struct iovec *sg,
> +                                hwaddr *addr, unsigned int *num_sg,
> +                                unsigned int max_size, int is_write)
>  {
>      unsigned int i;
>      hwaddr len;
> @@ -503,7 +509,10 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
>  
>      for (i = 0; i < *num_sg; i++) {
>          len = sg[i].iov_len;
> -        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
> +        sg[i].iov_base = dma_memory_map(virtio_get_dma_as(vdev),
> +                                        addr[i], &len, is_write ?
> +                                        DMA_DIRECTION_FROM_DEVICE :
> +                                        DMA_DIRECTION_TO_DEVICE);
>          if (!sg[i].iov_base) {
>              error_report("virtio: error trying to map MMIO memory");
>              exit(1);
> @@ -515,12 +524,15 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
>      }
>  }
>  
> -void virtqueue_map(VirtQueueElement *elem)
> +void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem)
>  {
> -    virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num,
> -                        VIRTQUEUE_MAX_SIZE, 1);
> -    virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num,
> -                        VIRTQUEUE_MAX_SIZE, 0);
> +    virtqueue_map_iovec(vdev, elem->in_sg, elem->in_addr, &elem->in_num,
> +                        MIN(ARRAY_SIZE(elem->in_sg), ARRAY_SIZE(elem->in_addr)),
> +                        1);
> +    virtqueue_map_iovec(vdev, elem->out_sg, elem->out_addr, &elem->out_num,
> +                        MIN(ARRAY_SIZE(elem->out_sg),
> +                        ARRAY_SIZE(elem->out_addr)),
> +                        0);
>  }
>  
>  void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num)
> @@ -594,14 +606,14 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
>      /* Collect all the descriptors */
>      do {
>          if (desc.flags & VRING_DESC_F_WRITE) {
> -            virtqueue_map_desc(&in_num, addr + out_num, iov + out_num,
> +            virtqueue_map_desc(vdev, &in_num, addr + out_num, iov + out_num,
>                                 VIRTQUEUE_MAX_SIZE - out_num, true, desc.addr, desc.len);
>          } else {
>              if (in_num) {
>                  error_report("Incorrect order for descriptors");
>                  exit(1);
>              }
> -            virtqueue_map_desc(&out_num, addr, iov,
> +            virtqueue_map_desc(vdev, &out_num, addr, iov,
>                                 VIRTQUEUE_MAX_SIZE, false, desc.addr, desc.len);
>          }
>  
> @@ -647,7 +659,7 @@ typedef struct VirtQueueElementOld {
>      struct iovec out_sg[VIRTQUEUE_MAX_SIZE];
>  } VirtQueueElementOld;
>  
> -void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
> +void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz)
>  {
>      VirtQueueElement *elem;
>      VirtQueueElementOld data;
> @@ -678,7 +690,7 @@ void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
>          elem->out_sg[i].iov_len = data.out_sg[i].iov_len;
>      }
>  
> -    virtqueue_map(elem);
> +    virtqueue_map(vdev, elem);
>      return elem;
>  }
>  
> @@ -733,6 +745,10 @@ static int virtio_validate_features(VirtIODevice *vdev)
>  {
>      VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
>  
> +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
> +        !virtio_vdev_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM))
> +        return -EFAULT;
> +
>      if (k->validate_features) {
>          return k->validate_features(vdev);
>      } else {


This will have the effect of breaking all drivers older than 4.8.
I don't think it's necessary since most guests do not enable
the vIOMMU even if it's present. Further, xen guests
are using DMA API even without VIRTIO_F_IOMMU_PLATFORM.
So things will continue to work for many legacy drivers.

> diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
> index 440b455..4071dad 100644
> --- a/include/hw/virtio/virtio-access.h
> +++ b/include/hw/virtio/virtio-access.h
> @@ -17,12 +17,25 @@
>  #define QEMU_VIRTIO_ACCESS_H
>  
>  #include "hw/virtio/virtio.h"
> +#include "hw/virtio/virtio-bus.h"
>  #include "exec/address-spaces.h"
>  
>  #if defined(TARGET_PPC64) || defined(TARGET_ARM)
>  #define LEGACY_VIRTIO_IS_BIENDIAN 1
>  #endif
>  
> +static inline AddressSpace *virtio_get_dma_as(VirtIODevice *vdev)
> +{
> +    BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
> +    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
> +
> +    if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM) &&
> +        k->get_dma_as) {
> +        return k->get_dma_as(qbus->parent);
> +    }
> +    return &address_space_memory;
> +}
> +
>  static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
>  {
>  #if defined(LEGACY_VIRTIO_IS_BIENDIAN)
> @@ -40,45 +53,55 @@ static inline bool virtio_access_is_big_endian(VirtIODevice *vdev)
>  
>  static inline uint16_t virtio_lduw_phys(VirtIODevice *vdev, hwaddr pa)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
>      if (virtio_access_is_big_endian(vdev)) {
> -        return lduw_be_phys(&address_space_memory, pa);
> +        return lduw_be_phys(dma_as, pa);
>      }
> -    return lduw_le_phys(&address_space_memory, pa);
> +    return lduw_le_phys(dma_as, pa);
>  }
>  
>  static inline uint32_t virtio_ldl_phys(VirtIODevice *vdev, hwaddr pa)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
>      if (virtio_access_is_big_endian(vdev)) {
> -        return ldl_be_phys(&address_space_memory, pa);
> +        return ldl_be_phys(dma_as, pa);
>      }
> -    return ldl_le_phys(&address_space_memory, pa);
> +    return ldl_le_phys(dma_as, pa);
>  }
>  
>  static inline uint64_t virtio_ldq_phys(VirtIODevice *vdev, hwaddr pa)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
>      if (virtio_access_is_big_endian(vdev)) {
> -        return ldq_be_phys(&address_space_memory, pa);
> +        return ldq_be_phys(dma_as, pa);
>      }
> -    return ldq_le_phys(&address_space_memory, pa);
> +    return ldq_le_phys(dma_as, pa);
>  }
>  
>  static inline void virtio_stw_phys(VirtIODevice *vdev, hwaddr pa,
>                                     uint16_t value)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
>      if (virtio_access_is_big_endian(vdev)) {
> -        stw_be_phys(&address_space_memory, pa, value);
> +        stw_be_phys(dma_as, pa, value);
>      } else {
> -        stw_le_phys(&address_space_memory, pa, value);
> +        stw_le_phys(dma_as, pa, value);
>      }
>  }
>  
>  static inline void virtio_stl_phys(VirtIODevice *vdev, hwaddr pa,
>                                     uint32_t value)
>  {
> +    AddressSpace *dma_as = virtio_get_dma_as(vdev);
> +
>      if (virtio_access_is_big_endian(vdev)) {
> -        stl_be_phys(&address_space_memory, pa, value);
> +        stl_be_phys(dma_as, pa, value);
>      } else {
> -        stl_le_phys(&address_space_memory, pa, value);
> +        stl_le_phys(dma_as, pa, value);
>      }
>  }
>  
> diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
> index f3e5ef3..608ff48 100644
> --- a/include/hw/virtio/virtio-bus.h
> +++ b/include/hw/virtio/virtio-bus.h
> @@ -98,6 +98,7 @@ typedef struct VirtioBusClass {
>       * Note that changing this will break migration for this transport.
>       */
>      bool has_variable_vring_alignment;
> +    AddressSpace *(*get_dma_as)(DeviceState *d);
>  } VirtioBusClass;
>  
>  struct VirtioBusState {
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index d2490c1..147d062 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -157,9 +157,9 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
>  void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
>                      unsigned int len, unsigned int idx);
>  
> -void virtqueue_map(VirtQueueElement *elem);
> +void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem);
>  void *virtqueue_pop(VirtQueue *vq, size_t sz);
> -void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz);
> +void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz);
>  void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem);
>  int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
>                            unsigned int out_bytes);
> @@ -252,7 +252,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
>      DEFINE_PROP_BIT64("notify_on_empty", _state, _field,  \
>                        VIRTIO_F_NOTIFY_ON_EMPTY, true), \
>      DEFINE_PROP_BIT64("any_layout", _state, _field, \
> -                      VIRTIO_F_ANY_LAYOUT, true)
> +                      VIRTIO_F_ANY_LAYOUT, true), \
> +    DEFINE_PROP_BIT64("iommu_platform", _state, _field, \
> +                      VIRTIO_F_IOMMU_PLATFORM, false)
>  
>  hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
>  hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
> -- 
> 2.7.4

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started"
  2016-09-02 15:13                           ` Alex Williamson
@ 2016-09-05  6:28                             ` Peter Xu
  0 siblings, 0 replies; 52+ messages in thread
From: Peter Xu @ 2016-09-05  6:28 UTC (permalink / raw)
  To: Alex Williamson
  Cc: David Gibson, Jason Wang, mst, qemu-devel, pbonzini,
	cornelia.huck, wexu, vkaplans

On Fri, Sep 02, 2016 at 09:13:01AM -0600, Alex Williamson wrote:
> Maybe memory_region_register_iommu_notifier() could take an
> IOMMUAccessFlags argument (filter) that is passed to the notify_started
> callback.  If a notifier client only cares about IOMMU_NONE
> (invalidations), intel-iommu could allow it, regardless of the CM
> setting (though I'm dubious whether this is complete in the generic
> case or really only for device iotlbs).  If a client requires IOMMU_RW
> then intel-iommu would currently bomb-out like it does now, or once
> that gets fixed it would bomb if CM=0.  Ideally intel-iommu would
> be fully functional, but somehow it was allowed into the tree
> with this massive gap in support for QEMU iommu interfaces.  Thanks,

Yes, this idea should solve the issue, and looks simple.

This should be based on the assumption that we will have only one
notify register for each IOMMU memory region. However I think that
does suit our use cases (no mix use for the two types).

Meanwhile, I think we can cache this "notifier type" (or
IOMMUAccessFlags) inside that memory region, and we can further verify
the type any time we want (e.g., we can skip the notification if the
type is not matched).

I'll try to post a patch based on your suggestion, and see whether we
like it.

Thanks!

-- peterx

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn
  2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn Jason Wang
@ 2016-09-05  6:56   ` Wei Xu
  0 siblings, 0 replies; 52+ messages in thread
From: Wei Xu @ 2016-09-05  6:56 UTC (permalink / raw)
  To: Jason Wang, mst, qemu-devel
  Cc: pbonzini, peterx, cornelia.huck, vkaplans, Richard Henderson,
	Eduardo Habkost

On 2016年08月30日 11:06, Jason Wang wrote:
> To avoid duplicated name and ease debugging.
>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Richard Henderson <rth@twiddle.net>
> Cc: Eduardo Habkost <ehabkost@redhat.com>
> Acked-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
>   hw/i386/intel_iommu.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> index 28c31a2..db70310 100644
> --- a/hw/i386/intel_iommu.c
> +++ b/hw/i386/intel_iommu.c
> @@ -2303,6 +2303,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
>       uintptr_t key = (uintptr_t)bus;
>       VTDBus *vtd_bus = g_hash_table_lookup(s->vtd_as_by_busptr, &key);
>       VTDAddressSpace *vtd_dev_as;
> +    char name[128];
>
>       if (!vtd_bus) {
>           /* No corresponding free() */
> @@ -2316,6 +2317,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
>       vtd_dev_as = vtd_bus->dev_as[devfn];
>
>       if (!vtd_dev_as) {
> +        snprintf(name, sizeof(name), "intel_iommu_devfn_%d", devfn);
>           vtd_bus->dev_as[devfn] = vtd_dev_as = g_malloc0(sizeof(VTDAddressSpace));
>
>           vtd_dev_as->bus = bus;
> @@ -2330,7 +2332,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
>           memory_region_add_subregion(&vtd_dev_as->iommu, VTD_INTERRUPT_ADDR_FIRST,
>                                       &vtd_dev_as->iommu_ir);
>           address_space_init(&vtd_dev_as->as,
> -                           &vtd_dev_as->iommu, "intel_iommu");
> +                           &vtd_dev_as->iommu, name);

No need to use the name for iommu region as before?

>       }
>       return vtd_dev_as;
>   }
>

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4
  2016-09-05  1:26     ` Michael S. Tsirkin
@ 2016-09-06  6:28       ` Jason Wang
  0 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-09-06  6:28 UTC (permalink / raw)
  To: Michael S. Tsirkin, Wei Xu
  Cc: qemu-devel, peterx, cornelia.huck, vkaplans, pbonzini



On 2016年09月05日 09:26, Michael S. Tsirkin wrote:
> On Mon, Sep 05, 2016 at 09:24:37AM +0800, Wei Xu wrote:
>> Looks this patch includes quite a few misc changes from upstream, it's a bit
>> confused to find out which one is related to virtio/vhost dmar support,
>> while the upstream header shows a separate commit for new IOTLB api, is it
>> possible to split this patch to dmar related one and a
>> common pull from upstream?
>>
>> upstream log:
>> git log -p include/uapi/linux/vhost.h
>> commit 6b1e6cc7855b09a0a9bfa1d9f30172ba366f161c
>> Author: Jason Wang <jasowang@redhat.com>
>> Date: Thu Jun 23 02:04:32 2016 -0400
>>
>> vhost: new device IOTLB API
>>
>> This patch tries to implement an device IOTLB for vhost. This could
>> be used with userspace(qemu) implementation of DMA remapping to
>> emulate an IOMMU for the guest.
>
> You don't need to sync all headers. Just commit the ones that make
> sense.
>

Ok.

^ permalink raw reply	[flat|nested] 52+ messages in thread

* Re: [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api
  2016-09-05  2:26   ` Wei Xu
@ 2016-09-06  6:30     ` Jason Wang
  0 siblings, 0 replies; 52+ messages in thread
From: Jason Wang @ 2016-09-06  6:30 UTC (permalink / raw)
  To: Wei Xu, mst, qemu-devel
  Cc: Kevin Wolf, qemu-block, Amit Shah, peterx, vkaplans,
	Stefan Hajnoczi, cornelia.huck, pbonzini



On 2016年09月05日 10:26, Wei Xu wrote:
> On 2016年08月30日 11:06, Jason Wang wrote:
>> @@ -1587,6 +1595,11 @@ static void 
>> virtio_pci_device_plugged(DeviceState *d, Error **errp)
>>       }
>>
>>       if (legacy) {
>> +        if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
>> +            error_setg(errp, "VIRTIO_F_IOMMU_PLATFORM was supported by"
>> +                       "neither legacy nor transitional device.");
>> +            return ;
>> +        }
>
> Not sure if i understand it correctly, the transitional device here 
> maybe a bit hard to understand, 

"transitional" were defined by spec.

> just a tip for your convenience,
> besides the denied prompt, can we add what kind of device is supported 
> to the message? such as modern device only, like this.
>
> "VIRTIO_F_IOMMU_PLATFORM is supported by modern device only, it
> is not supported by either legacy or transitional device."

Ok.

>
>>           /* legacy and transitional */
>>           pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
>>                        pci_get_word(config + PCI_VENDOR_ID));
>

^ permalink raw reply	[flat|nested] 52+ messages in thread

end of thread, other threads:[~2016-09-06  6:30 UTC | newest]

Thread overview: 52+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-30  3:06 [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 01/11] linux-headers: update to 4.8-rc4 Jason Wang
2016-09-05  1:24   ` Wei Xu
2016-09-05  1:26     ` Michael S. Tsirkin
2016-09-06  6:28       ` Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
2016-08-30  7:31   ` Cornelia Huck
2016-08-30 10:02     ` Michael S. Tsirkin
2016-08-30 10:21       ` Michael S. Tsirkin
2016-08-30 11:11         ` [Qemu-devel] qom and debug (was: [PATCH for 2.8 02/11] virtio: convert to use DMA api) Cornelia Huck
2016-08-30 11:15           ` Michael S. Tsirkin
2016-08-30 11:37             ` [Qemu-devel] qom and debug Cornelia Huck
2016-08-30 11:57               ` Michael S. Tsirkin
2016-08-31  2:47     ` [Qemu-devel] [PATCH for 2.8 02/11] virtio: convert to use DMA api Jason Wang
2016-09-05  2:26   ` Wei Xu
2016-09-06  6:30     ` Jason Wang
2016-09-05  2:33   ` Michael S. Tsirkin
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 03/11] intel_iommu: name vtd address space with devfn Jason Wang
2016-09-05  6:56   ` Wei Xu
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 04/11] intel_iommu: allocate new key when creating new address space Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 05/11] exec: introduce address_space_get_iotlb_entry() Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 06/11] intel_iommu: support device iotlb descriptor Jason Wang
2016-08-30 13:16   ` Peter Xu
2016-08-31  2:54     ` Jason Wang
2016-09-01  1:26       ` Peter Xu
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 07/11] virtio-pci: address space translation service (ATS) support Jason Wang
2016-08-30 13:21   ` Peter Xu
2016-08-31  2:55     ` Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 08/11] acpi: add ATSR for q35 Jason Wang
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 09/11] memory: handle alias for iommu notifier Jason Wang
2016-08-30 13:28   ` Peter Xu
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 10/11] Revert "intel_iommu: Throw hw_error on notify_started" Jason Wang
2016-08-30  3:37   ` Alex Williamson
2016-08-31  2:45     ` Jason Wang
2016-09-01  2:29       ` Peter Xu
2016-09-01  2:43         ` Alex Williamson
2016-09-01  3:58           ` Peter Xu
2016-09-02  4:15             ` David Gibson
2016-09-02  5:37               ` Peter Xu
2016-09-02  6:10                 ` David Gibson
2016-09-02  6:15                   ` Peter Xu
2016-09-02  6:18                     ` Peter Xu
2016-09-02  7:00                       ` David Gibson
2016-09-02  9:31                         ` Peter Xu
2016-09-02 15:13                           ` Alex Williamson
2016-09-05  6:28                             ` Peter Xu
2016-08-30  3:06 ` [Qemu-devel] [PATCH for 2.8 11/11] vhost_net: device IOTLB support Jason Wang
2016-09-01  3:34   ` Peter Xu
2016-09-01  7:36     ` Jason Wang
2016-09-02  5:47       ` Peter Xu
2016-08-30  3:25 ` [Qemu-devel] [PATCH for 2.8 00/11] virtio/vhost DMAR support no-reply
2016-08-30  3:29 ` no-reply

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.