diff --git a/xen/drivers/passthrough/amd/iommu-defs.h b/xen/drivers/passthrough/amd/iommu-defs.h index 963009de6a..50613ca150 100644 --- a/xen/drivers/passthrough/amd/iommu-defs.h +++ b/xen/drivers/passthrough/amd/iommu-defs.h @@ -481,7 +481,6 @@ struct amd_iommu_pte { #define INV_IOMMU_ALL_PAGES_ADDRESS ((1ULL << 63) - 1) #define IOMMU_RING_BUFFER_PTR_MASK 0x0007FFF0 -#define IOMMU_RING_BUFFER_PTR_SHIFT 4 #define IOMMU_CMD_DEVICE_ID_MASK 0x0000FFFF #define IOMMU_CMD_DEVICE_ID_SHIFT 0 diff --git a/xen/drivers/passthrough/amd/iommu.h b/xen/drivers/passthrough/amd/iommu.h index 0b598d06f8..1abfdc685a 100644 --- a/xen/drivers/passthrough/amd/iommu.h +++ b/xen/drivers/passthrough/amd/iommu.h @@ -58,12 +58,11 @@ struct table_struct { }; struct ring_buffer { + spinlock_t lock; /* protect buffer pointers */ void *buffer; - unsigned long entries; - unsigned long alloc_size; uint32_t tail; uint32_t head; - spinlock_t lock; /* protect buffer pointers */ + uint32_t size; }; typedef struct iommu_cap { @@ -379,19 +378,6 @@ static inline int iommu_has_cap(struct amd_iommu *iommu, uint32_t bit) return !!(iommu->cap.header & (1u << bit)); } -/* access tail or head pointer of ring buffer */ -static inline uint32_t iommu_get_rb_pointer(uint32_t reg) -{ - return get_field_from_reg_u32(reg, IOMMU_RING_BUFFER_PTR_MASK, - IOMMU_RING_BUFFER_PTR_SHIFT); -} - -static inline void iommu_set_rb_pointer(uint32_t *reg, uint32_t val) -{ - set_field_in_reg_u32(val, *reg, IOMMU_RING_BUFFER_PTR_MASK, - IOMMU_RING_BUFFER_PTR_SHIFT, reg); -} - /* access device id field from iommu cmd */ static inline uint16_t iommu_get_devid_from_cmd(uint32_t cmd) { diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c b/xen/drivers/passthrough/amd/iommu_cmd.c index 1eae339692..249ed345a0 100644 --- a/xen/drivers/passthrough/amd/iommu_cmd.c +++ b/xen/drivers/passthrough/amd/iommu_cmd.c @@ -24,16 +24,15 @@ static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[]) { uint32_t tail, head; - tail = iommu->cmd_buffer.tail; - if ( ++tail == iommu->cmd_buffer.entries ) + tail = iommu->cmd_buffer.tail + IOMMU_CMD_BUFFER_ENTRY_SIZE; + if ( tail == iommu->cmd_buffer.size ) tail = 0; - head = iommu_get_rb_pointer(readl(iommu->mmio_base + - IOMMU_CMD_BUFFER_HEAD_OFFSET)); + head = readl(iommu->mmio_base + + IOMMU_CMD_BUFFER_HEAD_OFFSET) & IOMMU_RING_BUFFER_PTR_MASK; if ( head != tail ) { - memcpy(iommu->cmd_buffer.buffer + - (iommu->cmd_buffer.tail * IOMMU_CMD_BUFFER_ENTRY_SIZE), + memcpy(iommu->cmd_buffer.buffer + iommu->cmd_buffer.tail, cmd, IOMMU_CMD_BUFFER_ENTRY_SIZE); iommu->cmd_buffer.tail = tail; @@ -45,13 +44,11 @@ static int queue_iommu_command(struct amd_iommu *iommu, u32 cmd[]) static void commit_iommu_command_buffer(struct amd_iommu *iommu) { - u32 tail = 0; - - iommu_set_rb_pointer(&tail, iommu->cmd_buffer.tail); - writel(tail, iommu->mmio_base+IOMMU_CMD_BUFFER_TAIL_OFFSET); + writel(iommu->cmd_buffer.tail, + iommu->mmio_base + IOMMU_CMD_BUFFER_TAIL_OFFSET); } -int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]) +static int send_iommu_command(struct amd_iommu *iommu, u32 cmd[]) { if ( queue_iommu_command(iommu, cmd) ) { @@ -261,7 +258,7 @@ static void invalidate_interrupt_table(struct amd_iommu *iommu, u16 device_id) send_iommu_command(iommu, cmd); } -void invalidate_iommu_all(struct amd_iommu *iommu) +static void invalidate_iommu_all(struct amd_iommu *iommu) { u32 cmd[4], entry; diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c index 5544dd9505..c42b608f07 100644 --- a/xen/drivers/passthrough/amd/iommu_init.c +++ b/xen/drivers/passthrough/amd/iommu_init.c @@ -117,7 +117,7 @@ static void register_iommu_cmd_buffer_in_mmio_space(struct amd_iommu *iommu) iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT); writel(entry, iommu->mmio_base + IOMMU_CMD_BUFFER_BASE_LOW_OFFSET); - power_of2_entries = get_order_from_bytes(iommu->cmd_buffer.alloc_size) + + power_of2_entries = get_order_from_bytes(iommu->cmd_buffer.size) + IOMMU_CMD_BUFFER_POWER_OF2_ENTRIES_PER_PAGE; entry = 0; @@ -145,7 +145,7 @@ static void register_iommu_event_log_in_mmio_space(struct amd_iommu *iommu) iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT); writel(entry, iommu->mmio_base + IOMMU_EVENT_LOG_BASE_LOW_OFFSET); - power_of2_entries = get_order_from_bytes(iommu->event_log.alloc_size) + + power_of2_entries = get_order_from_bytes(iommu->event_log.size) + IOMMU_EVENT_LOG_POWER_OF2_ENTRIES_PER_PAGE; entry = 0; @@ -173,7 +173,7 @@ static void register_iommu_ppr_log_in_mmio_space(struct amd_iommu *iommu) iommu_set_addr_lo_to_reg(&entry, addr_lo >> PAGE_SHIFT); writel(entry, iommu->mmio_base + IOMMU_PPR_LOG_BASE_LOW_OFFSET); - power_of2_entries = get_order_from_bytes(iommu->ppr_log.alloc_size) + + power_of2_entries = get_order_from_bytes(iommu->ppr_log.size) + IOMMU_PPR_LOG_POWER_OF2_ENTRIES_PER_PAGE; entry = 0; @@ -300,7 +300,7 @@ static int iommu_read_log(struct amd_iommu *iommu, unsigned int entry_size, void (*parse_func)(struct amd_iommu *, u32 *)) { - u32 tail, head, *entry, tail_offest, head_offset; + u32 tail, *entry, tail_offest, head_offset; BUG_ON(!iommu || ((log != &iommu->event_log) && (log != &iommu->ppr_log))); @@ -315,23 +315,21 @@ static int iommu_read_log(struct amd_iommu *iommu, IOMMU_EVENT_LOG_HEAD_OFFSET : IOMMU_PPR_LOG_HEAD_OFFSET; - tail = readl(iommu->mmio_base + tail_offest); - tail = iommu_get_rb_pointer(tail); + tail = readl(iommu->mmio_base + tail_offest) & IOMMU_RING_BUFFER_PTR_MASK; while ( tail != log->head ) { /* read event log entry */ - entry = (u32 *)(log->buffer + log->head * entry_size); + entry = log->buffer + log->head; parse_func(iommu, entry); - if ( ++log->head == log->entries ) + + log->head += entry_size; + if ( log->head == log->size ) log->head = 0; /* update head pointer */ - head = 0; - iommu_set_rb_pointer(&head, log->head); - - writel(head, iommu->mmio_base + head_offset); + writel(log->head, iommu->mmio_base + head_offset); } spin_unlock(&log->lock); @@ -1000,7 +998,7 @@ static void __init deallocate_buffer(void *buf, unsigned long sz) static void __init deallocate_ring_buffer(struct ring_buffer *ring_buf) { - deallocate_buffer(ring_buf->buffer, ring_buf->alloc_size); + deallocate_buffer(ring_buf->buffer, ring_buf->size); ring_buf->buffer = NULL; ring_buf->head = 0; ring_buf->tail = 0; @@ -1035,11 +1033,9 @@ static void *__init allocate_ring_buffer(struct ring_buffer *ring_buf, ring_buf->tail = 0; spin_lock_init(&ring_buf->lock); - - ring_buf->alloc_size = PAGE_SIZE << get_order_from_bytes(entries * - entry_size); - ring_buf->entries = ring_buf->alloc_size / entry_size; - ring_buf->buffer = allocate_buffer(ring_buf->alloc_size, name, clear); + + ring_buf->size = PAGE_SIZE << get_order_from_bytes(entries * entry_size); + ring_buf->buffer = allocate_buffer(ring_buf->size, name, clear); return ring_buf->buffer; }