qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

intel-iommu: trace domain id during page walk

This patch only modifies the trace points.

Previously we were tracing page walk levels. They are redundant since
we have page mask (size) already. Now we trace something much more
useful which is the domain ID of the page walking. That can be very
useful when we trace more than one devices on the same system, so that
we can know which map is for which domain.

CC: QEMU Stable <qemu-stable@nongnu.org>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit d118c06ebbee2d23ddf873cae4a809311aa61310)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>

authored by

Peter Xu and committed by
Michael Roth
d5c60a95 78b85a98

+11 -7
+10 -6
hw/i386/intel_iommu.c
··· 756 756 * @notify_unmap: whether we should notify invalid entries 757 757 * @as: VT-d address space of the device 758 758 * @aw: maximum address width 759 + * @domain: domain ID of the page walk 759 760 */ 760 761 typedef struct { 761 762 VTDAddressSpace *as; ··· 763 764 void *private; 764 765 bool notify_unmap; 765 766 uint8_t aw; 767 + uint16_t domain_id; 766 768 } vtd_page_walk_info; 767 769 768 - static int vtd_page_walk_one(IOMMUTLBEntry *entry, int level, 769 - vtd_page_walk_info *info) 770 + static int vtd_page_walk_one(IOMMUTLBEntry *entry, vtd_page_walk_info *info) 770 771 { 771 772 vtd_page_walk_hook hook_fn = info->hook_fn; 772 773 void *private = info->private; 773 774 774 775 assert(hook_fn); 775 - trace_vtd_page_walk_one(level, entry->iova, entry->translated_addr, 776 - entry->addr_mask, entry->perm); 776 + trace_vtd_page_walk_one(info->domain_id, entry->iova, 777 + entry->translated_addr, entry->addr_mask, 778 + entry->perm); 777 779 return hook_fn(entry, private); 778 780 } 779 781 ··· 844 846 trace_vtd_page_walk_skip_perm(iova, iova_next); 845 847 goto next; 846 848 } 847 - ret = vtd_page_walk_one(&entry, level, info); 849 + ret = vtd_page_walk_one(&entry, info); 848 850 if (ret < 0) { 849 851 return ret; 850 852 } ··· 856 858 * Translated address is meaningless, zero it. 857 859 */ 858 860 entry.translated_addr = 0x0; 859 - ret = vtd_page_walk_one(&entry, level, info); 861 + ret = vtd_page_walk_one(&entry, info); 860 862 if (ret < 0) { 861 863 return ret; 862 864 } ··· 1466 1468 .notify_unmap = true, 1467 1469 .aw = s->aw_bits, 1468 1470 .as = vtd_as, 1471 + .domain_id = domain_id, 1469 1472 }; 1470 1473 1471 1474 /* ··· 2947 2950 .notify_unmap = false, 2948 2951 .aw = s->aw_bits, 2949 2952 .as = vtd_as, 2953 + .domain_id = VTD_CONTEXT_ENTRY_DID(ce.hi), 2950 2954 }; 2951 2955 2952 2956 vtd_page_walk(&ce, 0, ~0ULL, &info);
+1 -1
hw/i386/trace-events
··· 39 39 vtd_replay_ce_valid(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t domain, uint64_t hi, uint64_t lo) "replay valid context device %02"PRIx8":%02"PRIx8".%02"PRIx8" domain 0x%"PRIx16" hi 0x%"PRIx64" lo 0x%"PRIx64 40 40 vtd_replay_ce_invalid(uint8_t bus, uint8_t dev, uint8_t fn) "replay invalid context device %02"PRIx8":%02"PRIx8".%02"PRIx8 41 41 vtd_page_walk_level(uint64_t addr, uint32_t level, uint64_t start, uint64_t end) "walk (base=0x%"PRIx64", level=%"PRIu32") iova range 0x%"PRIx64" - 0x%"PRIx64 42 - vtd_page_walk_one(uint32_t level, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "detected page level 0x%"PRIx32" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d" 42 + vtd_page_walk_one(uint16_t domain, uint64_t iova, uint64_t gpa, uint64_t mask, int perm) "domain 0x%"PRIu16" iova 0x%"PRIx64" -> gpa 0x%"PRIx64" mask 0x%"PRIx64" perm %d" 43 43 vtd_page_walk_skip_read(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to unable to read" 44 44 vtd_page_walk_skip_perm(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to perm empty" 45 45 vtd_page_walk_skip_reserve(uint64_t iova, uint64_t next) "Page walk skip iova 0x%"PRIx64" - 0x%"PRIx64" due to rsrv set"