forked from luck/tmp_suning_uos_patched
s390/pci: fix CPU address in MSI for directed IRQ
The directed MSIs are delivered to CPUs whose address is
written to the MSI message address. The current code assumes
that a CPU logical number (as it is seen by the kernel)
is also the CPU address.
The above assumption is not correct, as the CPU address
is rather the value returned by STAP instruction. That
value does not necessarily match the kernel logical CPU
number.
Fixes: e979ce7bce
("s390/pci: provide support for CPU directed interrupts")
Cc: <stable@vger.kernel.org> # v5.2+
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
b650545978
commit
a2bd4097b3
|
@ -103,9 +103,10 @@ static int zpci_set_irq_affinity(struct irq_data *data, const struct cpumask *de
|
||||||
{
|
{
|
||||||
struct msi_desc *entry = irq_get_msi_desc(data->irq);
|
struct msi_desc *entry = irq_get_msi_desc(data->irq);
|
||||||
struct msi_msg msg = entry->msg;
|
struct msi_msg msg = entry->msg;
|
||||||
|
int cpu_addr = smp_cpu_get_cpu_address(cpumask_first(dest));
|
||||||
|
|
||||||
msg.address_lo &= 0xff0000ff;
|
msg.address_lo &= 0xff0000ff;
|
||||||
msg.address_lo |= (cpumask_first(dest) << 8);
|
msg.address_lo |= (cpu_addr << 8);
|
||||||
pci_write_msi_msg(data->irq, &msg);
|
pci_write_msi_msg(data->irq, &msg);
|
||||||
|
|
||||||
return IRQ_SET_MASK_OK;
|
return IRQ_SET_MASK_OK;
|
||||||
|
@ -238,6 +239,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||||
unsigned long bit;
|
unsigned long bit;
|
||||||
struct msi_desc *msi;
|
struct msi_desc *msi;
|
||||||
struct msi_msg msg;
|
struct msi_msg msg;
|
||||||
|
int cpu_addr;
|
||||||
int rc, irq;
|
int rc, irq;
|
||||||
|
|
||||||
zdev->aisb = -1UL;
|
zdev->aisb = -1UL;
|
||||||
|
@ -287,9 +289,15 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
|
||||||
handle_percpu_irq);
|
handle_percpu_irq);
|
||||||
msg.data = hwirq - bit;
|
msg.data = hwirq - bit;
|
||||||
if (irq_delivery == DIRECTED) {
|
if (irq_delivery == DIRECTED) {
|
||||||
|
if (msi->affinity)
|
||||||
|
cpu = cpumask_first(&msi->affinity->mask);
|
||||||
|
else
|
||||||
|
cpu = 0;
|
||||||
|
cpu_addr = smp_cpu_get_cpu_address(cpu);
|
||||||
|
|
||||||
msg.address_lo = zdev->msi_addr & 0xff0000ff;
|
msg.address_lo = zdev->msi_addr & 0xff0000ff;
|
||||||
msg.address_lo |= msi->affinity ?
|
msg.address_lo |= (cpu_addr << 8);
|
||||||
(cpumask_first(&msi->affinity->mask) << 8) : 0;
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
|
airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user