diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c index c9c7d7b290..3e48fc3733 100644 --- a/xen/drivers/passthrough/amd/iommu_cmd.c +++ b/xen/drivers/passthrough/amd/iommu_cmd.c @@ -22,48 +22,36 @@ #include #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)); - - iommu->cmd_buffer.tail = tail; - return 1; + printk_once(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;