Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:GA
xen.22544
xsa373-4.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa373-4.patch of Package xen.22544
AMD/IOMMU: wait for command slot to be available No caller cared about send_iommu_command() indicating unavailability of a slot. Hence if a sufficient number prior commands timed out, we did blindly assume that the requested command was submitted to the IOMMU when really it wasn't. This could mean both a hanging system (waiting for a command to complete that was never seen by the IOMMU) or blindly propagating success back to callers, making them believe they're fine to e.g. free previously unmapped pages. Fold the three involved functions into one, add spin waiting for an available slot along the lines of VT-d's qinval_next_index(), and as a consequence drop all error indicator return types/values. This is part of XSA-373. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Paul Durrant <paul@xen.org> --- a/xen/drivers/passthrough/amd/iommu_cmd.c +++ b/xen/drivers/passthrough/amd/iommu_cmd.c @@ -22,48 +22,39 @@ #include <asm/hvm/svm/amd-iommu-proto.h> #include "../ats.h" -static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[]) +static void send_iommu_command(struct amd_iommu *iommu, + const uint32_t cmd[4]) { - uint32_t tail, head; + uint32_t tail; tail = iommu->cmd_buffer.tail; if ( ++tail == iommu->cmd_buffer.entries ) tail = 0; - head = iommu_get_rb_pointer(readl(iommu->mmio_base + - IOMMU_CMD_BUFFER_HEAD_OFFSET)); - if ( head != tail ) + while ( tail == iommu_get_rb_pointer(readl(iommu->mmio_base + + IOMMU_CMD_BUFFER_HEAD_OFFSET)) ) { - memcpy(iommu->cmd_buffer.buffer + - (iommu->cmd_buffer.tail * sizeof(cmd_entry_t)), - cmd, sizeof(cmd_entry_t)); + static bool logged; - iommu->cmd_buffer.tail = tail; - return 1; + if ( !test_and_set_bool(logged) ) + printk(XENLOG_ERR + "AMD IOMMU %04x:%02x:%02x.%u: no cmd slot available\n", + iommu->seg, PCI_BUS(iommu->bdf), + PCI_SLOT(iommu->bdf), PCI_FUNC(iommu->bdf)); + cpu_relax(); } - return 0; -} + memcpy(iommu->cmd_buffer.buffer + + (iommu->cmd_buffer.tail * sizeof(cmd_entry_t)), + cmd, sizeof(cmd_entry_t)); -static void commit_iommu_command_buffer(struct amd_iommu *iommu) -{ - u32 tail = 0; + iommu->cmd_buffer.tail = tail; + tail = 0; iommu_set_rb_pointer(&tail, iommu->cmd_buffer.tail); writel(tail, iommu->mmio_base+IOMMU_CMD_BUFFER_TAIL_OFFSET); } -int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]) -{ - if ( queue_iommu_command(iommu, cmd) ) - { - commit_iommu_command_buffer(iommu); - return 1; - } - - return 0; -} - static void flush_command_buffer(struct amd_iommu *iommu) { u32 cmd[4], status;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor