Skip to content

Commit

Permalink
Merge branches 'arm/smmu', 'virtio', 'x86/amd', 'x86/vt-d' and 'core'…
Browse files Browse the repository at this point in the history
… into next
  • Loading branch information
joergroedel committed Jan 4, 2022
6 parents c9e6606 + 91d6988 + 4cb3600 + 664c0b5 + c95a9c2 + aade40b commit 66dc1b7
Show file tree
Hide file tree
Showing 20 changed files with 493 additions and 570 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ properties:
- qcom,sc7280-smmu-500
- qcom,sc8180x-smmu-500
- qcom,sdm845-smmu-500
- qcom,sdx55-smmu-500
- qcom,sm6350-smmu-500
- qcom,sm8150-smmu-500
- qcom,sm8250-smmu-500
- qcom,sm8350-smmu-500
- qcom,sm8450-smmu-500
- const: arm,mmu-500
- description: Qcom Adreno GPUs implementing "arm,smmu-v2"
items:
Expand Down
2 changes: 0 additions & 2 deletions drivers/iommu/amd/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,6 @@ struct amd_iommu {
/* DebugFS Info */
struct dentry *debugfs;
#endif
/* IRQ notifier for IntCapXT interrupt */
struct irq_affinity_notify intcapxt_notify;
};

static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)
Expand Down
109 changes: 59 additions & 50 deletions drivers/iommu/amd/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,16 +806,27 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
u32 status, i;
u64 entry;

if (!iommu->ga_log)
return -EINVAL;

status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);

/* Check if already running */
if (status & (MMIO_STATUS_GALOG_RUN_MASK))
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
if (WARN_ON(status & (MMIO_STATUS_GALOG_RUN_MASK)))
return 0;

entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
&entry, sizeof(entry));
entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
(BIT_ULL(52)-1)) & ~7ULL;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
&entry, sizeof(entry));
writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);


iommu_feature_enable(iommu, CONTROL_GAINT_EN);
iommu_feature_enable(iommu, CONTROL_GALOG_EN);

Expand All @@ -825,7 +836,7 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
break;
}

if (i >= LOOP_TIMEOUT)
if (WARN_ON(i >= LOOP_TIMEOUT))
return -EINVAL;
#endif /* CONFIG_IRQ_REMAP */
return 0;
Expand All @@ -834,8 +845,6 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu)
static int iommu_init_ga_log(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
u64 entry;

if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir))
return 0;

Expand All @@ -849,16 +858,6 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)
if (!iommu->ga_log_tail)
goto err_out;

entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET,
&entry, sizeof(entry));
entry = (iommu_virt_to_phys(iommu->ga_log_tail) &
(BIT_ULL(52)-1)) & ~7ULL;
memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET,
&entry, sizeof(entry));
writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET);
writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET);

return 0;
err_out:
free_ga_log(iommu);
Expand Down Expand Up @@ -1523,7 +1522,7 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
}

/*
* This function clues the initialization function for one IOMMU
* This function glues the initialization function for one IOMMU
* together and also allocates the command buffer and programs the
* hardware. It does NOT enable the IOMMU. This is done afterwards.
*/
Expand Down Expand Up @@ -2016,48 +2015,18 @@ union intcapxt {
};
} __attribute__ ((packed));

/*
* There isn't really any need to mask/unmask at the irqchip level because
* the 64-bit INTCAPXT registers can be updated atomically without tearing
* when the affinity is being updated.
*/
static void intcapxt_unmask_irq(struct irq_data *data)
{
}

static void intcapxt_mask_irq(struct irq_data *data)
{
}

static struct irq_chip intcapxt_controller;

static int intcapxt_irqdomain_activate(struct irq_domain *domain,
struct irq_data *irqd, bool reserve)
{
struct amd_iommu *iommu = irqd->chip_data;
struct irq_cfg *cfg = irqd_cfg(irqd);
union intcapxt xt;

xt.capxt = 0ULL;
xt.dest_mode_logical = apic->dest_mode_logical;
xt.vector = cfg->vector;
xt.destid_0_23 = cfg->dest_apicid & GENMASK(23, 0);
xt.destid_24_31 = cfg->dest_apicid >> 24;

/**
* Current IOMMU implemtation uses the same IRQ for all
* 3 IOMMU interrupts.
*/
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET);
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET);
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET);
return 0;
}

static void intcapxt_irqdomain_deactivate(struct irq_domain *domain,
struct irq_data *irqd)
{
intcapxt_mask_irq(irqd);
}


Expand Down Expand Up @@ -2091,6 +2060,38 @@ static void intcapxt_irqdomain_free(struct irq_domain *domain, unsigned int virq
irq_domain_free_irqs_top(domain, virq, nr_irqs);
}


static void intcapxt_unmask_irq(struct irq_data *irqd)
{
struct amd_iommu *iommu = irqd->chip_data;
struct irq_cfg *cfg = irqd_cfg(irqd);
union intcapxt xt;

xt.capxt = 0ULL;
xt.dest_mode_logical = apic->dest_mode_logical;
xt.vector = cfg->vector;
xt.destid_0_23 = cfg->dest_apicid & GENMASK(23, 0);
xt.destid_24_31 = cfg->dest_apicid >> 24;

/**
* Current IOMMU implementation uses the same IRQ for all
* 3 IOMMU interrupts.
*/
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET);
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET);
writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET);
}

static void intcapxt_mask_irq(struct irq_data *irqd)
{
struct amd_iommu *iommu = irqd->chip_data;

writeq(0, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET);
writeq(0, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET);
writeq(0, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET);
}


static int intcapxt_set_affinity(struct irq_data *irqd,
const struct cpumask *mask, bool force)
{
Expand All @@ -2100,8 +2101,12 @@ static int intcapxt_set_affinity(struct irq_data *irqd,
ret = parent->chip->irq_set_affinity(parent, mask, force);
if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE)
return ret;
return 0;
}

return intcapxt_irqdomain_activate(irqd->domain, irqd, false);
static int intcapxt_set_wake(struct irq_data *irqd, unsigned int on)
{
return on ? -EOPNOTSUPP : 0;
}

static struct irq_chip intcapxt_controller = {
Expand All @@ -2111,7 +2116,8 @@ static struct irq_chip intcapxt_controller = {
.irq_ack = irq_chip_ack_parent,
.irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_set_affinity = intcapxt_set_affinity,
.flags = IRQCHIP_SKIP_SET_WAKE,
.irq_set_wake = intcapxt_set_wake,
.flags = IRQCHIP_MASK_ON_SUSPEND,
};

static const struct irq_domain_ops intcapxt_domain_ops = {
Expand Down Expand Up @@ -2173,7 +2179,6 @@ static int iommu_setup_intcapxt(struct amd_iommu *iommu)
return ret;
}

iommu_feature_enable(iommu, CONTROL_INTCAPXT_EN);
return 0;
}

Expand All @@ -2196,6 +2201,10 @@ static int iommu_init_irq(struct amd_iommu *iommu)

iommu->int_enabled = true;
enable_faults:

if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE)
iommu_feature_enable(iommu, CONTROL_INTCAPXT_EN);

iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);

if (iommu->ppr_log != NULL)
Expand Down

0 comments on commit 66dc1b7

Please sign in to comment.