[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/2 V2] iommu/amd: Fix logic for clearing the IOMMU interrupt bits
>>> On 10.06.13 at 07:05, <suravee.suthikulpanit@xxxxxxx> wrote: > From: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > > The IOMMU interrupt bits in the IOMMU status registers are > "read-only, and write-1-to-clear (RW1C). Therefore, the existing > logic which reads the register, set the bit, and then writing back > the values could accidentally clear certain bits if it has been set. > > The correct logic would just be writing only the value which only > set the interrupt bits, and leave the rest to zeros. > > This patch also, clean up #define masks as Jan has suggested. This went to far, and imo in the wrong direction - the mask values are what ultimately should stay, since the shift values can be computed from them. And this cleanup should really be done only when [gs]et_field_in_reg_u32() get the redundant shift parameter eliminated (i.e. in a separate, post-4.3 patch). But as said already in the response to Tim's reply on patch 2 - this patch also had a few other issues, so I'm going to reply with a v3 once I'm done with the fixing/cleanup. Jan > Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > --- > V2 changes: > - Additional fixes as pointed out by Jan. > - Clean up unnecessary #define mask as suggested by Jan. > > xen/drivers/passthrough/amd/iommu_cmd.c | 18 +++-- > xen/drivers/passthrough/amd/iommu_init.c | 31 ++++----- > xen/include/asm-x86/hvm/svm/amd-iommu-defs.h | 95 > +++++++++++--------------- > 3 files changed, 63 insertions(+), 81 deletions(-) > > diff --git a/xen/drivers/passthrough/amd/iommu_cmd.c > b/xen/drivers/passthrough/amd/iommu_cmd.c > index 4c60149..f0283d4 100644 > --- a/xen/drivers/passthrough/amd/iommu_cmd.c > +++ b/xen/drivers/passthrough/amd/iommu_cmd.c > @@ -75,11 +75,9 @@ static void flush_command_buffer(struct amd_iommu *iommu) > u32 cmd[4], status; > int loop_count, comp_wait; > > - /* clear 'ComWaitInt' in status register (WIC) */ > - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0, > - IOMMU_STATUS_COMP_WAIT_INT_MASK, > - IOMMU_STATUS_COMP_WAIT_INT_SHIFT, &status); > - writel(status, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > + /* RW1C 'ComWaitInt' in status register */ > + writel((1 << IOMMU_STATUS_COMP_WAIT_INT_SHIFT), > + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > > /* send an empty COMPLETION_WAIT command to flush command buffer */ > cmd[3] = cmd[2] = 0; > @@ -96,16 +94,16 @@ static void flush_command_buffer(struct amd_iommu *iommu) > do { > status = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > comp_wait = get_field_from_reg_u32(status, > - IOMMU_STATUS_COMP_WAIT_INT_MASK, > - > IOMMU_STATUS_COMP_WAIT_INT_SHIFT); > + (1 << IOMMU_STATUS_COMP_WAIT_INT_SHIFT), > + IOMMU_STATUS_COMP_WAIT_INT_SHIFT); > --loop_count; > } while ( !comp_wait && loop_count ); > > if ( comp_wait ) > { > - /* clear 'ComWaitInt' in status register (WIC) */ > - status &= IOMMU_STATUS_COMP_WAIT_INT_MASK; > - writel(status, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > + /* RW1C 'ComWaitInt' in status register */ > + writel((1 << IOMMU_STATUS_COMP_WAIT_INT_SHIFT), > + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > return; > } > AMD_IOMMU_DEBUG("Warning: ComWaitInt bit did not assert!\n"); > diff --git a/xen/drivers/passthrough/amd/iommu_init.c > b/xen/drivers/passthrough/amd/iommu_init.c > index a939c73..a85c63f 100644 > --- a/xen/drivers/passthrough/amd/iommu_init.c > +++ b/xen/drivers/passthrough/amd/iommu_init.c > @@ -439,8 +439,8 @@ static void iommu_reset_log(struct amd_iommu *iommu, > > ctrl_func(iommu, IOMMU_CONTROL_DISABLED); > > - /*clear overflow bit */ > - iommu_clear_bit(&entry, of_bit); > + /* RW1C overflow bit */ > + iommu_set_bit(&entry, of_bit); > writel(entry, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > > /*reset event log base address */ > @@ -622,11 +622,9 @@ static void iommu_check_event_log(struct amd_iommu > *iommu) > if ( iommu_get_bit(entry, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT) ) > iommu_reset_log(iommu, &iommu->event_log, > set_iommu_event_log_control); > > - /* reset interrupt status bit */ > - entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > - iommu_set_bit(&entry, IOMMU_STATUS_EVENT_LOG_INT_SHIFT); > - > - writel(entry, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > + /* RW1C interrupt status bit */ > + writel((1 << IOMMU_STATUS_EVENT_LOG_INT_SHIFT), > + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > > spin_unlock_irqrestore(&iommu->lock, flags); > } > @@ -692,11 +690,9 @@ static void iommu_check_ppr_log(struct amd_iommu *iommu) > if ( iommu_get_bit(entry, IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT) ) > iommu_reset_log(iommu, &iommu->ppr_log, set_iommu_ppr_log_control); > > - /* reset interrupt status bit */ > - entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > - iommu_set_bit(&entry, IOMMU_STATUS_PPR_LOG_INT_SHIFT); > - > - writel(entry, iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > + /* RW1C interrupt status bit */ > + writel((1 << IOMMU_STATUS_PPR_LOG_INT_SHIFT), > + iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > > spin_unlock_irqrestore(&iommu->lock, flags); > } > @@ -733,10 +729,13 @@ static void iommu_interrupt_handler(int irq, void > *dev_id, > > spin_lock_irqsave(&iommu->lock, flags); > > - /* Silence interrupts from both event and PPR logging */ > - entry = readl(iommu->mmio_base + IOMMU_STATUS_MMIO_OFFSET); > - iommu_clear_bit(&entry, IOMMU_STATUS_EVENT_LOG_INT_SHIFT); > - iommu_clear_bit(&entry, IOMMU_STATUS_PPR_LOG_INT_SHIFT); > + /* Silence interrupts from both event and PPR > + * by clearing the enable logging bits in the > + * control register */ > + entry = readl(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET); > + iommu_clear_bit(&entry, IOMMU_CONTROL_EVENT_LOG_INT_SHIFT); > + iommu_clear_bit(&entry, IOMMU_CONTROL_PPR_LOG_INT_SHIFT); > + /* RW1C status bit */ > writel(entry, iommu->mmio_base+IOMMU_STATUS_MMIO_OFFSET); > > spin_unlock_irqrestore(&iommu->lock, flags); > diff --git a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h > b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h > index d2176d0..2f2d740 100644 > --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h > +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h > @@ -313,31 +313,21 @@ > #define IOMMU_LOG_ENTRY_TIMEOUT 1000 > > /* Control Register */ > -#define IOMMU_CONTROL_MMIO_OFFSET 0x18 > -#define IOMMU_CONTROL_TRANSLATION_ENABLE_MASK 0x00000001 > -#define IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT 0 > -#define IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_MASK 0x00000002 > -#define IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT 1 > -#define IOMMU_CONTROL_EVENT_LOG_ENABLE_MASK 0x00000004 > -#define IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT 2 > -#define IOMMU_CONTROL_EVENT_LOG_INT_MASK 0x00000008 > -#define IOMMU_CONTROL_EVENT_LOG_INT_SHIFT 3 > -#define IOMMU_CONTROL_COMP_WAIT_INT_MASK 0x00000010 > -#define IOMMU_CONTROL_COMP_WAIT_INT_SHIFT 4 > -#define IOMMU_CONTROL_INVALIDATION_TIMEOUT_MASK 0x000000E0 > -#define IOMMU_CONTROL_INVALIDATION_TIMEOUT_SHIFT 5 > -#define IOMMU_CONTROL_PASS_POSTED_WRITE_MASK 0x00000100 > -#define IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT 8 > -#define IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_MASK 0x00000200 > -#define IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT 9 > -#define IOMMU_CONTROL_COHERENT_MASK 0x00000400 > -#define IOMMU_CONTROL_COHERENT_SHIFT 10 > -#define IOMMU_CONTROL_ISOCHRONOUS_MASK 0x00000800 > -#define IOMMU_CONTROL_ISOCHRONOUS_SHIFT 11 > -#define IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_MASK 0x00001000 > -#define IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT 12 > -#define IOMMU_CONTROL_RESTART_MASK 0x80000000 > -#define IOMMU_CONTROL_RESTART_SHIFT 31 > +#define IOMMU_CONTROL_MMIO_OFFSET 0x18 > +#define IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT 0 > +#define IOMMU_CONTROL_HT_TUNNEL_TRANSLATION_SHIFT 1 > +#define IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT 2 > +#define IOMMU_CONTROL_EVENT_LOG_INT_SHIFT 3 > +#define IOMMU_CONTROL_COMP_WAIT_INT_SHIFT 4 > +#define IOMMU_CONTROL_INVALIDATION_TIMEOUT_SHIFT 5 > +#define IOMMU_CONTROL_PASS_POSTED_WRITE_SHIFT 8 > +#define IOMMU_CONTROL_RESP_PASS_POSTED_WRITE_SHIFT 9 > +#define IOMMU_CONTROL_COHERENT_SHIFT 10 > +#define IOMMU_CONTROL_ISOCHRONOUS_SHIFT 11 > +#define IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT 12 > +#define IOMMU_CONTROL_PPR_LOG_ENABLE_SHIFT 13 > +#define IOMMU_CONTROL_PPR_LOG_INT_SHIFT 14 > +#define IOMMU_CONTROL_RESTART_SHIFT 31 > > #define IOMMU_CONTROL_PPR_LOG_ENABLE_SHIFT 13 > #define IOMMU_CONTROL_PPR_INT_SHIFT 14 > @@ -363,38 +353,33 @@ > #define IOMMU_EXCLUSION_LIMIT_HIGH_SHIFT 0 > > /* Extended Feature Register*/ > -#define IOMMU_EXT_FEATURE_MMIO_OFFSET 0x30 > -#define IOMMU_EXT_FEATURE_PREFSUP_SHIFT 0x0 > -#define IOMMU_EXT_FEATURE_PPRSUP_SHIFT 0x1 > -#define IOMMU_EXT_FEATURE_XTSUP_SHIFT 0x2 > -#define IOMMU_EXT_FEATURE_NXSUP_SHIFT 0x3 > -#define IOMMU_EXT_FEATURE_GTSUP_SHIFT 0x4 > -#define IOMMU_EXT_FEATURE_IASUP_SHIFT 0x6 > -#define IOMMU_EXT_FEATURE_GASUP_SHIFT 0x7 > -#define IOMMU_EXT_FEATURE_HESUP_SHIFT 0x8 > -#define IOMMU_EXT_FEATURE_PCSUP_SHIFT 0x9 > -#define IOMMU_EXT_FEATURE_HATS_SHIFT 0x10 > -#define IOMMU_EXT_FEATURE_HATS_MASK 0x00000C00 > -#define IOMMU_EXT_FEATURE_GATS_SHIFT 0x12 > -#define IOMMU_EXT_FEATURE_GATS_MASK 0x00003000 > -#define IOMMU_EXT_FEATURE_GLXSUP_SHIFT 0x14 > -#define IOMMU_EXT_FEATURE_GLXSUP_MASK 0x0000C000 > - > -#define IOMMU_EXT_FEATURE_PASMAX_SHIFT 0x0 > -#define IOMMU_EXT_FEATURE_PASMAX_MASK 0x0000001F > +#define IOMMU_EXT_FEATURE_MMIO_OFFSET 0x30 > +#define IOMMU_EXT_FEATURE_PREFSUP_SHIFT 0x0 > +#define IOMMU_EXT_FEATURE_PPRSUP_SHIFT 0x1 > +#define IOMMU_EXT_FEATURE_XTSUP_SHIFT 0x2 > +#define IOMMU_EXT_FEATURE_NXSUP_SHIFT 0x3 > +#define IOMMU_EXT_FEATURE_GTSUP_SHIFT 0x4 > +#define IOMMU_EXT_FEATURE_IASUP_SHIFT 0x6 > +#define IOMMU_EXT_FEATURE_GASUP_SHIFT 0x7 > +#define IOMMU_EXT_FEATURE_HESUP_SHIFT 0x8 > +#define IOMMU_EXT_FEATURE_PCSUP_SHIFT 0x9 > +#define IOMMU_EXT_FEATURE_HATS_SHIFT 0x10 > +#define IOMMU_EXT_FEATURE_HATS_MASK 0x00000C00 > +#define IOMMU_EXT_FEATURE_GATS_SHIFT 0x12 > +#define IOMMU_EXT_FEATURE_GATS_MASK 0x00003000 > +#define IOMMU_EXT_FEATURE_GLXSUP_SHIFT 0x14 > +#define IOMMU_EXT_FEATURE_GLXSUP_MASK 0x0000C000 > + > +#define IOMMU_EXT_FEATURE_PASMAX_SHIFT 0x0 > +#define IOMMU_EXT_FEATURE_PASMAX_MASK 0x0000001F > > /* Status Register*/ > -#define IOMMU_STATUS_MMIO_OFFSET 0x2020 > -#define IOMMU_STATUS_EVENT_OVERFLOW_MASK 0x00000001 > -#define IOMMU_STATUS_EVENT_OVERFLOW_SHIFT 0 > -#define IOMMU_STATUS_EVENT_LOG_INT_MASK 0x00000002 > -#define IOMMU_STATUS_EVENT_LOG_INT_SHIFT 1 > -#define IOMMU_STATUS_COMP_WAIT_INT_MASK 0x00000004 > -#define IOMMU_STATUS_COMP_WAIT_INT_SHIFT 2 > -#define IOMMU_STATUS_EVENT_LOG_RUN_MASK 0x00000008 > -#define IOMMU_STATUS_EVENT_LOG_RUN_SHIFT 3 > -#define IOMMU_STATUS_CMD_BUFFER_RUN_MASK 0x00000010 > -#define IOMMU_STATUS_CMD_BUFFER_RUN_SHIFT 4 > +#define IOMMU_STATUS_MMIO_OFFSET 0x2020 > +#define IOMMU_STATUS_EVENT_OVERFLOW_SHIFT 0 > +#define IOMMU_STATUS_EVENT_LOG_INT_SHIFT 1 > +#define IOMMU_STATUS_COMP_WAIT_INT_SHIFT 2 > +#define IOMMU_STATUS_EVENT_LOG_RUN_SHIFT 3 > +#define IOMMU_STATUS_CMD_BUFFER_RUN_SHIFT 4 > #define IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT 5 > #define IOMMU_STATUS_PPR_LOG_INT_SHIFT 6 > #define IOMMU_STATUS_PPR_LOG_RUN_SHIFT 7 > -- > 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |