94df5b2180
When running on a 64kB page size host and protecting a VFIO device
with the virtio-iommu, qemu crashes with this kind of message:
qemu-kvm: virtio-iommu page mask 0xfffffffffffff000 is incompatible
with mask 0x20010000
qemu: hardware error: vfio: DMA mapping failed, unable to continue
This is due to the fact the IOMMU MR corresponding to the VFIO device
is enabled very late on domain attach, after the machine init.
The device reports a minimal 64kB page size but it is too late to be
applied. virtio_iommu_set_page_size_mask() fails and this causes
vfio_listener_region_add() to end up with hw_error();
To work around this issue, we transiently enable the IOMMU MR on
machine init to collect the page size requirements and then restore
the bypass state.
Fixes: 90519b9053
("virtio-iommu: Add bypass mode support to assigned device")
Signed-off-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20230705165118.28194-2-eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Tested-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
157 lines
13 KiB
Plaintext
157 lines
13 KiB
Plaintext
# See docs/devel/tracing.rst for syntax documentation.
|
|
|
|
# vhost.c
|
|
vhost_commit(bool started, bool changed) "Started: %d Changed: %d"
|
|
vhost_region_add_section(const char *name, uint64_t gpa, uint64_t size, uint64_t host) "%s: 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64
|
|
vhost_region_add_section_merge(const char *name, uint64_t new_size, uint64_t gpa, uint64_t owr) "%s: size: 0x%"PRIx64 " gpa: 0x%"PRIx64 " owr: 0x%"PRIx64
|
|
vhost_region_add_section_aligned(const char *name, uint64_t gpa, uint64_t size, uint64_t host) "%s: 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64
|
|
vhost_section(const char *name) "%s"
|
|
vhost_reject_section(const char *name, int d) "%s:%d"
|
|
vhost_iotlb_miss(void *dev, int step) "%p step %d"
|
|
vhost_dev_cleanup(void *dev) "%p"
|
|
vhost_dev_start(void *dev, const char *name, bool vrings) "%p:%s vrings:%d"
|
|
vhost_dev_stop(void *dev, const char *name, bool vrings) "%p:%s vrings:%d"
|
|
|
|
|
|
# vhost-user.c
|
|
vhost_user_postcopy_end_entry(void) ""
|
|
vhost_user_postcopy_end_exit(void) ""
|
|
vhost_user_postcopy_fault_handler(const char *name, uint64_t fault_address, int nregions) "%s: @0x%"PRIx64" nregions:%d"
|
|
vhost_user_postcopy_fault_handler_loop(int i, uint64_t client_base, uint64_t size) "%d: client 0x%"PRIx64" +0x%"PRIx64
|
|
vhost_user_postcopy_fault_handler_found(int i, uint64_t region_offset, uint64_t rb_offset) "%d: region_offset: 0x%"PRIx64" rb_offset:0x%"PRIx64
|
|
vhost_user_postcopy_listen(void) ""
|
|
vhost_user_set_mem_table_postcopy(uint64_t client_addr, uint64_t qhva, int reply_i, int region_i) "client:0x%"PRIx64" for hva: 0x%"PRIx64" reply %d region %d"
|
|
vhost_user_set_mem_table_withfd(int index, const char *name, uint64_t memory_size, uint64_t guest_phys_addr, uint64_t userspace_addr, uint64_t offset) "%d:%s: size:0x%"PRIx64" GPA:0x%"PRIx64" QVA/userspace:0x%"PRIx64" RB offset:0x%"PRIx64
|
|
vhost_user_postcopy_waker(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64
|
|
vhost_user_postcopy_waker_found(uint64_t client_addr) "0x%"PRIx64
|
|
vhost_user_postcopy_waker_nomatch(const char *rb, uint64_t rb_offset) "%s + 0x%"PRIx64
|
|
vhost_user_read(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
|
|
vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
|
|
vhost_user_create_notifier(int idx, void *n) "idx:%d n:%p"
|
|
|
|
# vhost-vdpa.c
|
|
vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
|
|
vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
|
|
vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
|
|
vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
|
|
vhost_vdpa_listener_region_add_unaligned(void *v, const char *name, uint64_t offset_as, uint64_t offset_page) "vdpa: %p region %s offset_within_address_space %"PRIu64" offset_within_region %"PRIu64
|
|
vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d"
|
|
vhost_vdpa_listener_region_del_unaligned(void *v, const char *name, uint64_t offset_as, uint64_t offset_page) "vdpa: %p region %s offset_within_address_space %"PRIu64" offset_within_region %"PRIu64
|
|
vhost_vdpa_listener_region_del(void *vdpa, uint64_t iova, uint64_t llend) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64
|
|
vhost_vdpa_add_status(void *dev, uint8_t status) "dev: %p status: 0x%"PRIx8
|
|
vhost_vdpa_init(void *dev, void *vdpa) "dev: %p vdpa: %p"
|
|
vhost_vdpa_cleanup(void *dev, void *vdpa) "dev: %p vdpa: %p"
|
|
vhost_vdpa_memslots_limit(void *dev, int ret) "dev: %p = 0x%x"
|
|
vhost_vdpa_set_mem_table(void *dev, uint32_t nregions, uint32_t padding) "dev: %p nregions: %"PRIu32" padding: 0x%"PRIx32
|
|
vhost_vdpa_dump_regions(void *dev, int i, uint64_t guest_phys_addr, uint64_t memory_size, uint64_t userspace_addr, uint64_t flags_padding) "dev: %p %d: guest_phys_addr: 0x%"PRIx64" memory_size: 0x%"PRIx64" userspace_addr: 0x%"PRIx64" flags_padding: 0x%"PRIx64
|
|
vhost_vdpa_set_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
|
|
vhost_vdpa_get_device_id(void *dev, uint32_t device_id) "dev: %p device_id %"PRIu32
|
|
vhost_vdpa_reset_device(void *dev) "dev: %p"
|
|
vhost_vdpa_get_vq_index(void *dev, int idx, int vq_idx) "dev: %p idx: %d vq idx: %d"
|
|
vhost_vdpa_set_vring_ready(void *dev) "dev: %p"
|
|
vhost_vdpa_dump_config(void *dev, const char *line) "dev: %p %s"
|
|
vhost_vdpa_set_config(void *dev, uint32_t offset, uint32_t size, uint32_t flags) "dev: %p offset: %"PRIu32" size: %"PRIu32" flags: 0x%"PRIx32
|
|
vhost_vdpa_get_config(void *dev, void *config, uint32_t config_len) "dev: %p config: %p config_len: %"PRIu32
|
|
vhost_vdpa_suspend(void *dev) "dev: %p"
|
|
vhost_vdpa_dev_start(void *dev, bool started) "dev: %p started: %d"
|
|
vhost_vdpa_set_log_base(void *dev, uint64_t base, unsigned long long size, int refcnt, int fd, void *log) "dev: %p base: 0x%"PRIx64" size: %llu refcnt: %d fd: %d log: %p"
|
|
vhost_vdpa_set_vring_addr(void *dev, unsigned int index, unsigned int flags, uint64_t desc_user_addr, uint64_t used_user_addr, uint64_t avail_user_addr, uint64_t log_guest_addr) "dev: %p index: %u flags: 0x%x desc_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" log_guest_addr: 0x%"PRIx64
|
|
vhost_vdpa_set_vring_num(void *dev, unsigned int index, unsigned int num) "dev: %p index: %u num: %u"
|
|
vhost_vdpa_set_vring_base(void *dev, unsigned int index, unsigned int num) "dev: %p index: %u num: %u"
|
|
vhost_vdpa_get_vring_base(void *dev, unsigned int index, unsigned int num) "dev: %p index: %u num: %u"
|
|
vhost_vdpa_set_vring_kick(void *dev, unsigned int index, int fd) "dev: %p index: %u fd: %d"
|
|
vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index: %u fd: %d"
|
|
vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
|
|
vhost_vdpa_set_owner(void *dev) "dev: %p"
|
|
vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
|
|
vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
|
|
vhost_vdpa_set_config_call(void *dev, int fd)"dev: %p fd: %d"
|
|
|
|
# virtio.c
|
|
virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
|
|
virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
|
|
virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
|
|
virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
|
|
virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
|
|
virtio_notify_irqfd(void *vdev, void *vq) "vdev %p vq %p"
|
|
virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
|
|
virtio_set_status(void *vdev, uint8_t val) "vdev %p val %u"
|
|
|
|
# virtio-rng.c
|
|
virtio_rng_guest_not_ready(void *rng) "rng %p: guest not ready"
|
|
virtio_rng_cpu_is_stopped(void *rng, int size) "rng %p: cpu is stopped, dropping %d bytes"
|
|
virtio_rng_popped(void *rng) "rng %p: elem popped"
|
|
virtio_rng_pushed(void *rng, size_t len) "rng %p: %zd bytes pushed"
|
|
virtio_rng_request(void *rng, size_t size, unsigned quota) "rng %p: %zd bytes requested, %u bytes quota left"
|
|
virtio_rng_vm_state_change(void *rng, int running, int state) "rng %p: state change to running %d state %d"
|
|
|
|
# virtio-balloon.c
|
|
#
|
|
virtio_balloon_bad_addr(uint64_t gpa) "0x%"PRIx64
|
|
virtio_balloon_handle_output(const char *name, uint64_t gpa) "section name: %s gpa: 0x%"PRIx64
|
|
virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) "num_pages: %d actual: %d"
|
|
virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) "actual: %d oldactual: %d"
|
|
virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon target: 0x%"PRIx64" num_pages: %d"
|
|
|
|
# virtio-mmio.c
|
|
virtio_mmio_read(uint64_t offset) "virtio_mmio_read offset 0x%" PRIx64
|
|
virtio_mmio_write_offset(uint64_t offset, uint64_t value) "virtio_mmio_write offset 0x%" PRIx64 " value 0x%" PRIx64
|
|
virtio_mmio_guest_page(uint64_t size, int shift) "guest page size 0x%" PRIx64 " shift %d"
|
|
virtio_mmio_queue_write(uint64_t value, int max_size) "mmio_queue write 0x%" PRIx64 " max %d"
|
|
virtio_mmio_setting_irq(int level) "virtio_mmio setting IRQ %d"
|
|
|
|
# virtio-pci.c
|
|
virtio_pci_notify(uint16_t vector) "virtio_pci_notify vec 0x%x"
|
|
virtio_pci_notify_write(uint64_t addr, uint64_t val, unsigned int size) "0x%" PRIx64" = 0x%" PRIx64 " (%d)"
|
|
virtio_pci_notify_write_pio(uint64_t addr, uint64_t val, unsigned int size) "0x%" PRIx64" = 0x%" PRIx64 " (%d)"
|
|
|
|
# hw/virtio/virtio-iommu.c
|
|
virtio_iommu_device_reset(void) "reset!"
|
|
virtio_iommu_system_reset(void) "system reset!"
|
|
virtio_iommu_get_features(uint64_t features) "device supports features=0x%"PRIx64
|
|
virtio_iommu_device_status(uint8_t status) "driver status = %d"
|
|
virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint32_t domain_start, uint32_t domain_end, uint32_t probe_size, uint8_t bypass) "page_size_mask=0x%"PRIx64" input range start=0x%"PRIx64" input range end=0x%"PRIx64" domain range start=%d domain range end=%d probe_size=0x%x bypass=0x%x"
|
|
virtio_iommu_set_config(uint8_t bypass) "bypass=0x%x"
|
|
virtio_iommu_attach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
|
|
virtio_iommu_detach(uint32_t domain_id, uint32_t ep_id) "domain=%d endpoint=%d"
|
|
virtio_iommu_map(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64 " phys_start=0x%"PRIx64" flags=%d"
|
|
virtio_iommu_unmap(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
|
|
virtio_iommu_unmap_done(uint32_t domain_id, uint64_t virt_start, uint64_t virt_end) "domain=%d virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
|
|
virtio_iommu_translate(const char *name, uint32_t rid, uint64_t iova, int flag) "mr=%s rid=%d addr=0x%"PRIx64" flag=%d"
|
|
virtio_iommu_init_iommu_mr(char *iommu_mr) "init %s"
|
|
virtio_iommu_get_endpoint(uint32_t ep_id) "Alloc endpoint=%d"
|
|
virtio_iommu_put_endpoint(uint32_t ep_id) "Free endpoint=%d"
|
|
virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d"
|
|
virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
|
|
virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
|
|
virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, uint64_t addr) "FAULT reason=%d flags=%d endpoint=%d address =0x%"PRIx64
|
|
virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end) "dev= %d, type=%d start=0x%"PRIx64" end=0x%"PRIx64
|
|
virtio_iommu_notify_map(const char *name, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start, uint32_t flags) "mr=%s virt_start=0x%"PRIx64" virt_end=0x%"PRIx64" phys_start=0x%"PRIx64" flags=%d"
|
|
virtio_iommu_notify_unmap(const char *name, uint64_t virt_start, uint64_t virt_end) "mr=%s virt_start=0x%"PRIx64" virt_end=0x%"PRIx64
|
|
virtio_iommu_remap(const char *name, uint64_t virt_start, uint64_t virt_end, uint64_t phys_start) "mr=%s virt_start=0x%"PRIx64" virt_end=0x%"PRIx64" phys_start=0x%"PRIx64
|
|
virtio_iommu_set_page_size_mask(const char *name, uint64_t old, uint64_t new) "mr=%s old_mask=0x%"PRIx64" new_mask=0x%"PRIx64
|
|
virtio_iommu_notify_flag_add(const char *name) "add notifier to mr %s"
|
|
virtio_iommu_notify_flag_del(const char *name) "del notifier from mr %s"
|
|
virtio_iommu_switch_address_space(uint8_t bus, uint8_t slot, uint8_t fn, bool on) "Device %02x:%02x.%x switching address space (iommu enabled=%d)"
|
|
virtio_iommu_freeze_granule(uint64_t page_size_mask) "granule set to 0x%"PRIx64
|
|
|
|
# virtio-mem.c
|
|
virtio_mem_send_response(uint16_t type) "type=%" PRIu16
|
|
virtio_mem_plug_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 " nb_blocks=%" PRIu16
|
|
virtio_mem_unplug_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 " nb_blocks=%" PRIu16
|
|
virtio_mem_unplugged_all(void) ""
|
|
virtio_mem_unplug_all_request(void) ""
|
|
virtio_mem_resized_usable_region(uint64_t old_size, uint64_t new_size) "old_size=0x%" PRIx64 "new_size=0x%" PRIx64
|
|
virtio_mem_state_request(uint64_t addr, uint16_t nb_blocks) "addr=0x%" PRIx64 " nb_blocks=%" PRIu16
|
|
virtio_mem_state_response(uint16_t state) "state=%" PRIu16
|
|
|
|
# virtio-pmem.c
|
|
virtio_pmem_flush_request(void) "flush request"
|
|
virtio_pmem_response(void) "flush response"
|
|
virtio_pmem_flush_done(int type) "fsync return=%d"
|
|
|
|
# virtio-gpio.c
|
|
virtio_gpio_start(void) "start"
|
|
virtio_gpio_stop(void) "stop"
|
|
virtio_gpio_set_status(uint8_t status) "0x%x"
|