* Re: [PATCH 2/2] PCI/MSI: Remove arch_msi_check_device()
From: Yijing Wang @ 2014-07-14 2:11 UTC (permalink / raw)
To: Alexander Gordeev, linux-kernel; +Cc: linux-pci, linuxppc-dev
In-Reply-To: <1005232855c3af2c0c669818ee63be445389b6ad.1405160163.git.agordeev@redhat.com>
> /**
> - * pci_msi_check_device - check whether MSI may be enabled on a device
> + * msi_check_device - check whether MSI may be enabled on a device
> * @dev: pointer to the pci_dev data structure of MSI device function
> * @nvec: how many MSIs have been requested ?
> - * @type: are we checking for MSI or MSI-X ?
> *
> * Look at global flags, the device itself, and its parent buses
> * to determine if MSI/-X are supported for the device. If MSI/-X is
> * supported return 0, else return an error code.
> **/
> -static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> +static int msi_check_device(struct pci_dev *dev, int nvec)
> {
> struct pci_bus *bus;
> - int ret;
>
> /* MSI must be globally enabled and supported by the device */
> - if (!pci_msi_enable || !dev || dev->no_msi)
> + if (!pci_msi_enable)
> + return -EINVAL;
> +
> + if (!dev || dev->no_msi || dev->current_state != PCI_D0)
> return -EINVAL;
>
> /*
> @@ -846,10 +837,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
> return -EINVAL;
>
> - ret = arch_msi_check_device(dev, nvec, type);
> - if (ret)
> - return ret;
> -
Move the arch_msi_check_device() into arch_msi_setup_irq(), make we can not detect whether the device in this platform
supports MSI or MSI-X aeap. If we delay this, maybe we will do a lot unnecessary working for MSI/MSI-X setup.
Thanks!
Yijing.
> return 0;
> }
>
> @@ -954,13 +941,13 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
> int status, nr_entries;
> int i, j;
>
> - if (!entries || !dev->msix_cap || dev->current_state != PCI_D0)
> - return -EINVAL;
> -
> - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX);
> + status = msi_check_device(dev, nvec);
> if (status)
> return status;
>
> + if (!entries)
> + return -EINVAL;
> +
> nr_entries = pci_msix_vec_count(dev);
> if (nr_entries < 0)
> return nr_entries;
> @@ -1085,8 +1072,9 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> int nvec;
> int rc;
>
> - if (dev->current_state != PCI_D0)
> - return -EINVAL;
> + rc = msi_check_device(dev, minvec);
> + if (rc)
> + return rc;
>
> WARN_ON(!!dev->msi_enabled);
>
> @@ -1109,17 +1097,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> nvec = maxvec;
>
> do {
> - rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
> - if (rc < 0) {
> - return rc;
> - } else if (rc > 0) {
> - if (rc < minvec)
> - return -ENOSPC;
> - nvec = rc;
> - }
> - } while (rc);
> -
> - do {
> rc = msi_capability_init(dev, nvec);
> if (rc < 0) {
> return rc;
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 92a2f99..3b873bc 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -59,7 +59,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
> void arch_teardown_msi_irq(unsigned int irq);
> int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
> void arch_teardown_msi_irqs(struct pci_dev *dev);
> -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
> void arch_restore_msi_irqs(struct pci_dev *dev);
>
> void default_teardown_msi_irqs(struct pci_dev *dev);
> @@ -76,8 +75,6 @@ struct msi_chip {
> int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
> struct msi_desc *desc);
> void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
> - int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
> - int nvec, int type);
> };
>
> #endif /* LINUX_MSI_H */
>
--
Thanks!
Yijing
^ permalink raw reply
* Re: [RFC PATCH V3 06/17] ppc/pnv: allocate pe->iommu_table dynamically
From: Benjamin Herrenschmidt @ 2014-07-14 3:12 UTC (permalink / raw)
To: David Laight
Cc: 'Wei Yang', Alexey Kardashevskiy,
linux-pci@vger.kernel.org, gwshan@linux.vnet.ibm.com,
qiudayu@linux.vnet.ibm.com, bhelgaas@google.com,
yan@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D17264AD8@AcuExch.aculab.com>
On Wed, 2014-06-25 at 09:20 +0000, David Laight wrote:
> What are the sizes of the iommu table and the PE structure?
> If the table is a round number of pages then you probably don't want
> to embed it inside the PE structure.
The problem isn't the table itself but the struct iommu_table which
contains the pointer to the actual table and various other bits of
controlling state.
Cheers,
Ben.
^ permalink raw reply
* [PATCH] dmaengine: fsl raid parity continuation support
From: xuelin.shi @ 2014-07-14 7:20 UTC (permalink / raw)
To: dan.j.williams, vinod.koul
Cc: dmaengine, Xuelin Shi, linuxppc-dev, Xuelin Shi
From: Xuelin Shi <xuelin.shi@freescale.com>
support more than 16 disks parity computation.
Signed-off-by: Xuelin Shi <b29237@freescale.com>
---
comment: passed the raid6 recovery test.
drivers/dma/fsl_raid.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 1dc5981..935d05a 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -328,6 +328,8 @@ static struct dma_async_tx_descriptor *re_jr_prep_genq(
struct cmpnd_frame *cf;
u32 cdb;
unsigned int i, j;
+ unsigned int save_src_cnt = src_cnt;
+ int cont_q = 0;
if (len > MAX_DATA_LENGTH) {
pr_err("Length greater than %d not supported\n",
@@ -340,6 +342,11 @@ static struct dma_async_tx_descriptor *re_jr_prep_genq(
if (desc <= 0)
return NULL;
+ if (scf && (flags & DMA_PREP_CONTINUE)) {
+ cont_q = 1;
+ src_cnt += 1;
+ }
+
/* Filling xor CDB */
cdb = RE_XOR_OPCODE << RE_CDB_OPCODE_SHIFT;
cdb |= (src_cnt - 1) << RE_CDB_NRCS_SHIFT;
@@ -351,8 +358,10 @@ static struct dma_async_tx_descriptor *re_jr_prep_genq(
if (scf != NULL) {
/* compute q = src0*coef0^src1*coef1^..., * is GF(8) mult */
- for (i = 0; i < src_cnt; i++)
+ for (i = 0; i < save_src_cnt; i++)
xor->gfm[i] = scf[i];
+ if (cont_q)
+ xor->gfm[i++] = 1;
} else {
/* compute P, that is XOR all srcs */
for (i = 0; i < src_cnt; i++)
@@ -367,9 +376,12 @@ static struct dma_async_tx_descriptor *re_jr_prep_genq(
fill_cfd_frame(cf, 1, len, dest, 0);
/* Fill CFD's rest of the frames with source buffers */
- for (i = 2, j = 0; j < src_cnt; i++, j++)
+ for (i = 2, j = 0; j < save_src_cnt; i++, j++)
fill_cfd_frame(cf, i, len, src[j], 0);
+ if (cont_q)
+ fill_cfd_frame(cf, i++, len, dest, 0);
+
/* Setting the final bit in the last source buffer frame in CFD */
cf[i - 1].efrl32 |= 1 << CF_FINAL_SHIFT;
@@ -404,6 +416,7 @@ static struct dma_async_tx_descriptor *re_jr_prep_pq(
u32 cdb;
u8 *p;
int gfmq_len, i, j;
+ unsigned long save_src_cnt = src_cnt;
if (len > MAX_DATA_LENGTH) {
pr_err("Length greater than %d not supported\n",
@@ -445,6 +458,9 @@ static struct dma_async_tx_descriptor *re_jr_prep_pq(
return re_jr_prep_genq(chan, dest[1], src, src_cnt,
scf, len, flags);
+ if (flags & DMA_PREP_CONTINUE)
+ src_cnt += 3;
+
jr = container_of(chan, struct re_jr, chan);
desc = re_jr_alloc_desc(jr, flags);
if (desc <= 0)
@@ -482,9 +498,19 @@ static struct dma_async_tx_descriptor *re_jr_prep_pq(
fill_cfd_frame(cf, i, len, dest[j], 0);
/* Fill CFD's rest of the frames with source buffers */
- for (i = 3, j = 0; j < src_cnt; i++, j++)
+ for (i = 3, j = 0; j < save_src_cnt; i++, j++)
fill_cfd_frame(cf, i, len, src[j], 0);
+ /* PQ computation continuation */
+ if (src_cnt - save_src_cnt == 3) {
+ p[save_src_cnt] = 0;
+ p[save_src_cnt + 1] = 0;
+ p[save_src_cnt + 2] = 1;
+ fill_cfd_frame(cf, i++, len, dest[0], 0);
+ fill_cfd_frame(cf, i++, len, dest[1], 0);
+ fill_cfd_frame(cf, i++, len, dest[1], 0);
+ }
+
/* Setting the final bit in the last source buffer frame in CFD */
cf[i - 1].efrl32 |= 1 << CF_FINAL_SHIFT;
--
1.9.1
^ permalink raw reply related
* [PATCH] dmaengine: fix potential race condition in fsl raid
From: xuelin.shi @ 2014-07-14 7:20 UTC (permalink / raw)
To: dan.j.williams, vinod.koul
Cc: dmaengine, Xuelin Shi, linuxppc-dev, Xuelin Shi
From: Xuelin Shi <xuelin.shi@freescale.com>
checking available slots in HW should be under the lock.
Signed-off-by: Xuelin Shi <b29237@freescale.com>
---
drivers/dma/fsl_raid.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c
index 935d05a..fccad86 100644
--- a/drivers/dma/fsl_raid.c
+++ b/drivers/dma/fsl_raid.c
@@ -112,11 +112,11 @@ static void re_jr_issue_pending(struct dma_chan *chan)
jr = container_of(chan, struct re_jr, chan);
+ spin_lock_irqsave(&jr->desc_lock, flags);
avail = RE_JR_INB_SLOT_AVAIL(in_be32(&jr->jrregs->inbring_slot_avail));
if (!avail)
- return;
+ goto out;
- spin_lock_irqsave(&jr->desc_lock, flags);
list_for_each_entry_safe(desc, _desc, &jr->submit_q, node) {
if (!avail)
break;
@@ -132,6 +132,7 @@ static void re_jr_issue_pending(struct dma_chan *chan)
out_be32(&jr->jrregs->inbring_add_job, RE_JR_INB_JOB_ADD(1));
avail--;
}
+out:
spin_unlock_irqrestore(&jr->desc_lock, flags);
}
--
1.9.1
^ permalink raw reply related
* [PATCH] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Mike Qiu @ 2014-07-14 8:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: benh, Mike Qiu, gwshan
[ 121.133381] WARNING: at drivers/pci/search.c:223
[ 121.133422] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
[ 121.133424] task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
[ 121.133425] NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
[ 121.133427] REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
[ 121.133428] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
[ 121.133433] CFAR: c00000000003752c SOFTE: 0
GPR00: c000000000037530 c000000001447220 c000000001448c30 c0000003bca1dc00
GPR04: 0000000000000000 c000000000066064 9000000000009032 0000000000000008
GPR08: 0000000000000007 0000000000000001 0000000000000100 000000003003d200
GPR12: 0000000044002482 c00000000fee0000 0000000000000000 c0000000015e8830
GPR16: c0000000015e8c30 0000000000000000 c0000000015e8430 c0000000015e8030
GPR20: c000000001348c30 c000000001482180 0000000000000000 0000000000000000
GPR24: 0000000000200200 c0000003bc243500 c0000003feff4070 c0000003bcec3000
GPR28: c0000000014cac00 c0000003bca1dc00 0000000000000000 0000000000000000
[ 121.133454] NIP [c000000000497b70] .pci_get_slot+0x40/0x110
[ 121.133457] LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
[ 121.133458] Call Trace:
[ 121.133461] [c000000001447220] [c000000000721730] .of_get_property+0x30/0x60 (unreliable)
[ 121.133464] [c0000000014472b0] [c000000000037530] .eeh_pe_loc_get+0x150/0x190
[ 121.133466] [c000000001447340] [c000000000034684] .eeh_dev_check_failure+0x1b4/0x550
[ 121.133468] [c0000000014473f0] [c000000000034ab0] .eeh_check_failure+0x90/0xf0
[ 121.133493] [c000000001447490] [d000000002c03e84] .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
[ 121.133501] [c000000001447520] [d000000002c041a4] .lpfc_poll_eratt+0x64/0x100 [lpfc]
[ 121.133504] [c0000000014475a0] [c0000000000b45b4] .call_timer_fn+0x64/0x190
[ 121.133506] [c000000001447650] [c0000000000b4d1c] .run_timer_softirq+0x2cc/0x3e0
[ 121.133508] [c000000001447760] [c0000000000a90c8] .__do_softirq+0x198/0x3c0
[ 121.133510] [c000000001447880] [c0000000000a9658] .irq_exit+0xc8/0x110
[ 121.133513] [c000000001447900] [c00000000001e010] .timer_interrupt+0xa0/0xe0
[ 121.133515] [c000000001447980] [c0000000000026d8] decrementer_common+0x158/0x180
[ 121.133518] --- Exception: 901 at .arch_local_irq_restore+0x74/0x90
pci_get_slot() should not be used in interrupt. But eeh subsystem do
the error checking in interrupt in this situation.
This patch is to solve this issue.
Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
---
arch/powerpc/kernel/eeh_pe.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eb..6f4bfee 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -792,6 +792,28 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
}
/**
+ * __dn_get_pdev - Retrieve the pci_dev from device_node by bus/devfn
+ * @dn: device_node of the pci_dev
+ * @data: the pci device's bus/devfn
+ *
+ * Retrieve the pci_dev using the given device_node and bus/devfn.
+ */
+void *__dn_get_pdev(struct device_node *dn, void *data)
+{
+ struct pci_dn *pdn = PCI_DN(dn);
+ int busno = *((int *)data) >> 8;
+ int devfn = *((int *)data) & 0xff;
+
+ if (!pdn)
+ return NULL;
+
+ if (pdn->busno == busno && pdn->devfn == devfn)
+ return pdn->pcidev;
+
+ return NULL;
+}
+
+/**
* eeh_pe_loc_get - Retrieve location code binding to the given PE
* @pe: EEH PE
*
@@ -807,6 +829,7 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
struct pci_dev *pdev;
struct device_node *dn;
const char *loc;
+ int bdevfn;
if (!bus)
return "N/A";
@@ -823,7 +846,9 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
if (loc)
return loc;
- pdev = pci_get_slot(bus, 0x0);
+ /* Get the root port */
+ bdevfn = (bus->number) << 8 || 0x0;
+ pdev = traverse_pci_devices(hose->dn, __dn_get_pdev, &bdevfn);
} else {
pdev = bus->self;
}
@@ -846,8 +871,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
loc = "N/A";
out:
- if (pci_is_root_bus(bus) && pdev)
- pci_dev_put(pdev);
return loc;
}
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH 2/2] PCI/MSI: Remove arch_msi_check_device()
From: Alexander Gordeev @ 2014-07-14 9:55 UTC (permalink / raw)
To: Yijing Wang; +Cc: linux-pci, linuxppc-dev, linux-kernel
In-Reply-To: <53C33C6D.8020103@huawei.com>
On Mon, Jul 14, 2014 at 10:11:57AM +0800, Yijing Wang wrote:
> > /**
> > - * pci_msi_check_device - check whether MSI may be enabled on a device
> > + * msi_check_device - check whether MSI may be enabled on a device
> > * @dev: pointer to the pci_dev data structure of MSI device function
> > * @nvec: how many MSIs have been requested ?
> > - * @type: are we checking for MSI or MSI-X ?
> > *
> > * Look at global flags, the device itself, and its parent buses
> > * to determine if MSI/-X are supported for the device. If MSI/-X is
> > * supported return 0, else return an error code.
> > **/
> > -static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> > +static int msi_check_device(struct pci_dev *dev, int nvec)
> > {
> > struct pci_bus *bus;
> > - int ret;
> >
> > /* MSI must be globally enabled and supported by the device */
> > - if (!pci_msi_enable || !dev || dev->no_msi)
> > + if (!pci_msi_enable)
> > + return -EINVAL;
> > +
> > + if (!dev || dev->no_msi || dev->current_state != PCI_D0)
> > return -EINVAL;
> >
> > /*
> > @@ -846,10 +837,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
> > if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
> > return -EINVAL;
> >
> > - ret = arch_msi_check_device(dev, nvec, type);
> > - if (ret)
> > - return ret;
> > -
>
> Move the arch_msi_check_device() into arch_msi_setup_irq(), make we can not detect whether the device in this platform
> supports MSI or MSI-X aeap. If we delay this, maybe we will do a lot unnecessary working for MSI/MSI-X setup.
A traditional approach for a function is first to make sanity check and
then allocate resources. I do not see a reason to keep these two steps
in separate functions: arch_msi_check_device() and arch_setup_msi_irq().
Just make checks within arch_setup_msi_irq() and bail out early would be as
cheap as it is now, but more natural and would deflate the interface.
Moreover, some platforms duplicate checks in arch_msi_check_device() and
arch_setup_msi_irq(), which does not add to readability.
> Thanks!
> Yijing.
>
> > return 0;
> > }
> >
> > @@ -954,13 +941,13 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
> > int status, nr_entries;
> > int i, j;
> >
> > - if (!entries || !dev->msix_cap || dev->current_state != PCI_D0)
> > - return -EINVAL;
> > -
> > - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX);
> > + status = msi_check_device(dev, nvec);
> > if (status)
> > return status;
> >
> > + if (!entries)
> > + return -EINVAL;
> > +
> > nr_entries = pci_msix_vec_count(dev);
> > if (nr_entries < 0)
> > return nr_entries;
> > @@ -1085,8 +1072,9 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> > int nvec;
> > int rc;
> >
> > - if (dev->current_state != PCI_D0)
> > - return -EINVAL;
> > + rc = msi_check_device(dev, minvec);
> > + if (rc)
> > + return rc;
> >
> > WARN_ON(!!dev->msi_enabled);
> >
> > @@ -1109,17 +1097,6 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
> > nvec = maxvec;
> >
> > do {
> > - rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
> > - if (rc < 0) {
> > - return rc;
> > - } else if (rc > 0) {
> > - if (rc < minvec)
> > - return -ENOSPC;
> > - nvec = rc;
> > - }
> > - } while (rc);
> > -
> > - do {
> > rc = msi_capability_init(dev, nvec);
> > if (rc < 0) {
> > return rc;
> > diff --git a/include/linux/msi.h b/include/linux/msi.h
> > index 92a2f99..3b873bc 100644
> > --- a/include/linux/msi.h
> > +++ b/include/linux/msi.h
> > @@ -59,7 +59,6 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
> > void arch_teardown_msi_irq(unsigned int irq);
> > int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
> > void arch_teardown_msi_irqs(struct pci_dev *dev);
> > -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type);
> > void arch_restore_msi_irqs(struct pci_dev *dev);
> >
> > void default_teardown_msi_irqs(struct pci_dev *dev);
> > @@ -76,8 +75,6 @@ struct msi_chip {
> > int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
> > struct msi_desc *desc);
> > void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
> > - int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
> > - int nvec, int type);
> > };
> >
> > #endif /* LINUX_MSI_H */
> >
>
>
> --
> Thanks!
> Yijing
>
--
Regards,
Alexander Gordeev
agordeev@redhat.com
^ permalink raw reply
* Re: [PATCH] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Gavin Shan @ 2014-07-14 13:01 UTC (permalink / raw)
To: Mike Qiu; +Cc: benh, linuxppc-dev, gwshan
In-Reply-To: <1405325963-1664-1-git-send-email-qiudayu@linux.vnet.ibm.com>
On Mon, Jul 14, 2014 at 04:19:23AM -0400, Mike Qiu wrote:
>[ 121.133381] WARNING: at drivers/pci/search.c:223
>[ 121.133422] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
>[ 121.133424] task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
>[ 121.133425] NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
>[ 121.133427] REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
>[ 121.133428] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
>[ 121.133433] CFAR: c00000000003752c SOFTE: 0
>GPR00: c000000000037530 c000000001447220 c000000001448c30 c0000003bca1dc00
>GPR04: 0000000000000000 c000000000066064 9000000000009032 0000000000000008
>GPR08: 0000000000000007 0000000000000001 0000000000000100 000000003003d200
>GPR12: 0000000044002482 c00000000fee0000 0000000000000000 c0000000015e8830
>GPR16: c0000000015e8c30 0000000000000000 c0000000015e8430 c0000000015e8030
>GPR20: c000000001348c30 c000000001482180 0000000000000000 0000000000000000
>GPR24: 0000000000200200 c0000003bc243500 c0000003feff4070 c0000003bcec3000
>GPR28: c0000000014cac00 c0000003bca1dc00 0000000000000000 0000000000000000
>[ 121.133454] NIP [c000000000497b70] .pci_get_slot+0x40/0x110
>[ 121.133457] LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
>[ 121.133458] Call Trace:
>[ 121.133461] [c000000001447220] [c000000000721730] .of_get_property+0x30/0x60 (unreliable)
>[ 121.133464] [c0000000014472b0] [c000000000037530] .eeh_pe_loc_get+0x150/0x190
>[ 121.133466] [c000000001447340] [c000000000034684] .eeh_dev_check_failure+0x1b4/0x550
>[ 121.133468] [c0000000014473f0] [c000000000034ab0] .eeh_check_failure+0x90/0xf0
>[ 121.133493] [c000000001447490] [d000000002c03e84] .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
>[ 121.133501] [c000000001447520] [d000000002c041a4] .lpfc_poll_eratt+0x64/0x100 [lpfc]
>[ 121.133504] [c0000000014475a0] [c0000000000b45b4] .call_timer_fn+0x64/0x190
>[ 121.133506] [c000000001447650] [c0000000000b4d1c] .run_timer_softirq+0x2cc/0x3e0
>[ 121.133508] [c000000001447760] [c0000000000a90c8] .__do_softirq+0x198/0x3c0
>[ 121.133510] [c000000001447880] [c0000000000a9658] .irq_exit+0xc8/0x110
>[ 121.133513] [c000000001447900] [c00000000001e010] .timer_interrupt+0xa0/0xe0
>[ 121.133515] [c000000001447980] [c0000000000026d8] decrementer_common+0x158/0x180
>[ 121.133518] --- Exception: 901 at .arch_local_irq_restore+0x74/0x90
>
>pci_get_slot() should not be used in interrupt. But eeh subsystem do
>the error checking in interrupt in this situation.
>
>This patch is to solve this issue.
>
The commit log has been clear enough, but the following message might
be better. I'm not good at writing good commit log as well:
---
pci_get_slot() is called with hold of PCI bus semaphore and it's not
safe to be called in interrupt context. However, we possibly checks
EEH error and calls the function in interrupt context. To avoid using
pci_get_slot(), we turn into device tree for fetching location code.
Otherwise, we might run into WARN_ON() as following messages indicate:
WARNING: at drivers/pci/search.c:223
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
CFAR: c00000000003752c SOFTE: 0
:
NIP [c000000000497b70] .pci_get_slot+0x40/0x110
LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
Call Trace:
.of_get_property+0x30/0x60 (unreliable)
.eeh_pe_loc_get+0x150/0x190
.eeh_dev_check_failure+0x1b4/0x550
.eeh_check_failure+0x90/0xf0
.lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
.lpfc_poll_eratt+0x64/0x100 [lpfc]
.call_timer_fn+0x64/0x190
.run_timer_softirq+0x2cc/0x3e0
>Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>---
> arch/powerpc/kernel/eeh_pe.c | 29 ++++++++++++++++++++++++++---
> 1 file changed, 26 insertions(+), 3 deletions(-)
>
>diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
>index fbd01eb..6f4bfee 100644
>--- a/arch/powerpc/kernel/eeh_pe.c
>+++ b/arch/powerpc/kernel/eeh_pe.c
>@@ -792,6 +792,28 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
> }
>
> /**
>+ * __dn_get_pdev - Retrieve the pci_dev from device_node by bus/devfn
>+ * @dn: device_node of the pci_dev
>+ * @data: the pci device's bus/devfn
>+ *
>+ * Retrieve the pci_dev using the given device_node and bus/devfn.
>+ */
>+void *__dn_get_pdev(struct device_node *dn, void *data)
>+{
The function isn't necessarily public. "static" is enough, I think.
I don't think we need this actually. Please refer to more comments
below.
>+ struct pci_dn *pdn = PCI_DN(dn);
>+ int busno = *((int *)data) >> 8;
>+ int devfn = *((int *)data) & 0xff;
>+
>+ if (!pdn)
>+ return NULL;
>+
>+ if (pdn->busno == busno && pdn->devfn == devfn)
>+ return pdn->pcidev;
>+
>+ return NULL;
>+}
>+
>+/**
> * eeh_pe_loc_get - Retrieve location code binding to the given PE
> * @pe: EEH PE
> *
>@@ -807,6 +829,7 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
> struct pci_dev *pdev;
> struct device_node *dn;
> const char *loc;
>+ int bdevfn;
>
> if (!bus)
> return "N/A";
>@@ -823,7 +846,9 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
> if (loc)
> return loc;
>
>- pdev = pci_get_slot(bus, 0x0);
>+ /* Get the root port */
>+ bdevfn = (bus->number) << 8 || 0x0;
>+ pdev = traverse_pci_devices(hose->dn, __dn_get_pdev, &bdevfn);
We needn't search pdev from device-tree and then translate it to
device-node. Root port is the only child hooked to root bus's
device node (it's also PHB's device-node). So I guess you can
just have something:
/* Check PHB's device node */
dn = pci_bus_to_OF_node(bus);
if (unlikely(!dn)) {
loc = "N/A";
goto out;
}
loc = of_get_property(hose->dn,
"ibm,loc-code", NULL);
if (loc)
return loc;
loc = of_get_property(hose->dn,
"ibm,io-base-loc-code", NULL);
if (loc)
return loc;
/* Check root port */
dn = dn->child;
> } else {
> pdev = bus->self;
Here, we needn't grab the bridge as well:
dn = pci_bus_to_OF_node(bus);
> }
Then check the device-node of bridge (or root port):
if (unlikely(!dn)) {
loc = "N/A";
goto out;
}
loc = of_get_property(dn, "ibm,loc-code", NULL);
if (!loc)
loc = of_get_property(dn, "ibm,slot-location-code", NULL);
if (!loc)
loc = "N/A";
>@@ -846,8 +871,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
> loc = "N/A";
>
> out:
>- if (pci_is_root_bus(bus) && pdev)
>- pci_dev_put(pdev);
> return loc;
> }
Thanks,
Gavin
^ permalink raw reply
* Re: [PATCH 1/6] powerpc/powernv: Enable M64 aperatus for PHB3
From: Gavin Shan @ 2014-07-14 13:15 UTC (permalink / raw)
To: Guo Chao; +Cc: linuxppc-dev
In-Reply-To: <1405000426-1016-2-git-send-email-yan@linux.vnet.ibm.com>
On Thu, Jul 10, 2014 at 09:53:41PM +0800, Guo Chao wrote:
>This patch enable M64 aperatus for PHB3.
>
>We already had platform hook (ppc_md.pcibios_window_alignment) to affect
>the PCI resource assignment done in PCI core so that each PE's M32 resource
>was built on basis of M32 segment size. Similarly, we're using that for
>M64 assignment on basis of M64 segment size.
>
> * We're using last M64 BAR to cover M64 aperatus, and it's shared by all
> 256 PEs.
> * We don't support P7IOC yet. However, some function callbacks are added
> to (struct pnv_phb) so that we can reuse them on P7IOC in future.
> * PE, corresponding to PCI bus with large M64 BAR device attached, might
> span multiple M64 segments. We introduce "compound" PE to cover the case.
> The compound PE is a list of PEs and the master PE is used as before.
> The slave PEs are just for MMIO isolation.
>
>Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com>
>---
> arch/powerpc/include/asm/opal.h | 8 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 284 ++++++++++++++++++++++++++++--
> arch/powerpc/platforms/powernv/pci.h | 20 +++
> 3 files changed, 297 insertions(+), 15 deletions(-)
>
>diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
>index 0da1dbd..ae885cc 100644
>--- a/arch/powerpc/include/asm/opal.h
>+++ b/arch/powerpc/include/asm/opal.h
>@@ -340,6 +340,12 @@ enum OpalMveEnableAction {
> OPAL_ENABLE_MVE = 1
> };
>
>+enum OpalM64EnableAction {
>+ OPAL_DISABLE_M64 = 0,
>+ OPAL_ENABLE_M64_SPLIT = 1,
>+ OPAL_ENABLE_M64_NON_SPLIT = 2
>+};
>+
> enum OpalPciResetScope {
> OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3,
> OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5,
>@@ -768,7 +774,7 @@ int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type,
> uint16_t window_num,
> uint64_t starting_real_address,
> uint64_t starting_pci_address,
>- uint16_t segment_size);
>+ uint64_t size);
> int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number,
> uint16_t window_type, uint16_t window_num,
> uint16_t segment_num);
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index de19ede..851e615 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -36,6 +36,7 @@
> #include <asm/tce.h>
> #include <asm/xics.h>
> #include <asm/debug.h>
>+#include <asm/firmware.h>
>
> #include "powernv.h"
> #include "pci.h"
>@@ -82,6 +83,12 @@ static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
> : : "r" (val), "r" (paddr) : "memory");
> }
>
>+static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
>+{
>+ return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) ==
>+ (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
>+}
>+
> static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
> {
> unsigned long pe;
>@@ -106,6 +113,243 @@ static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
> clear_bit(pe, phb->ioda.pe_alloc);
> }
>
>+/* The default M64 BAR is shared by all PEs */
>+static int pnv_ioda2_init_m64(struct pnv_phb *phb)
>+{
>+ const char *desc;
>+ struct resource *r;
>+ s64 rc;
>+
>+ /* Configure the default M64 BAR */
>+ rc = opal_pci_set_phb_mem_window(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ phb->ioda.m64_base,
>+ 0, /* unused */
>+ phb->ioda.m64_size);
>+ if (rc != OPAL_SUCCESS) {
>+ desc = "configuring";
>+ goto fail;
>+ }
>+
>+ /* Enable the default M64 BAR */
>+ rc = opal_pci_phb_mmio_enable(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ OPAL_ENABLE_M64_SPLIT);
>+ if (rc != OPAL_SUCCESS) {
>+ desc = "enabling";
>+ goto fail;
>+ }
>+
>+ /* Mark the M64 BAR assigned */
>+ set_bit(phb->ioda.m64_bar_idx, &phb->ioda.m64_bar_alloc);
>+
>+ /*
>+ * Strip off the segment used by the reserved PE, which is
>+ * expected to be 0 or last one of PE capabicity.
>+ */
>+ r = &phb->hose->mem_resources[1];
>+ if (phb->ioda.reserved_pe == 0)
>+ r->start += phb->ioda.m64_segsize;
>+ else if (phb->ioda.reserved_pe == (phb->ioda.total_pe - 1))
>+ r->end -= phb->ioda.m64_segsize;
>+ else
>+ pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
>+ phb->ioda.reserved_pe);
>+
>+ return 0;
>+
>+fail:
>+ pr_warn(" Failure %lld %s M64 BAR#%d\n",
>+ rc, desc, phb->ioda.m64_bar_idx);
>+ opal_pci_phb_mmio_enable(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ OPAL_DISABLE_M64);
>+ return -EIO;
>+}
>+
>+static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb)
>+{
>+ resource_size_t sgsz = phb->ioda.m64_segsize;
>+ struct pci_dev *pdev;
>+ struct resource *r;
>+ int base, step, i;
>+
>+ /*
>+ * Root bus always has full M64 range and root port has
>+ * M64 range used in reality. So we're checking root port
>+ * instead of root bus.
>+ */
>+ list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) {
>+ for (i = PCI_BRIDGE_RESOURCES;
>+ i <= PCI_BRIDGE_RESOURCE_END; i++) {
>+ r = &pdev->resource[i];
>+ if (!r->parent ||
>+ !pnv_pci_is_mem_pref_64(r->flags))
>+ continue;
>+
>+ base = (r->start - phb->ioda.m64_base) / sgsz;
>+ for (step = 0; step < resource_size(r) / sgsz; step++)
>+ set_bit(base + step, phb->ioda.pe_alloc);
>+ }
>+ }
>+}
>+
>+static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb,
>+ struct pci_bus *bus, int all)
>+{
>+ resource_size_t segsz = phb->ioda.m64_segsize;
>+ struct pci_dev *pdev;
>+ struct resource *r;
>+ struct pnv_ioda_pe *master_pe, *pe;
>+ unsigned long size, *pe_alloc;
>+ bool found;
>+ int start, i, j;
>+
>+ /* Root bus shouldn't use M64 */
>+ if (pci_is_root_bus(bus))
>+ return IODA_INVALID_PE;
>+
>+ /* We support only one M64 window on each bus */
>+ found = false;
>+ pci_bus_for_each_resource(bus, r, i) {
>+ if (r && r->parent &&
>+ pnv_pci_is_mem_pref_64(r->flags)) {
>+ found = true;
>+ break;
>+ }
>+ }
>+
>+ /* No M64 window found ? */
>+ if (!found)
>+ return IODA_INVALID_PE;
>+
>+ /* Allocate bitmap */
>+ size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));
>+ pe_alloc = kzalloc(size, GFP_KERNEL);
>+ if (!pe_alloc) {
>+ pr_warn("%s: Out of memory !\n",
>+ __func__);
>+ return IODA_INVALID_PE;
>+ }
>+
>+ /*
>+ * Figure out reserved PE numbers by the PE
>+ * the its child PEs.
>+ */
>+ start = (r->start - phb->ioda.m64_base) / segsz;
>+ for (i = 0; i < resource_size(r) / segsz; i++)
>+ set_bit(start + i, pe_alloc);
>+
>+ if (all)
>+ goto done;
>+
>+ /*
>+ * If the PE doesn't cover all subordinate buses,
>+ * we need subtract from reserved PEs for children.
>+ */
>+ list_for_each_entry(pdev, &bus->devices, bus_list) {
>+ if (!pdev->subordinate)
>+ continue;
>+
>+ pci_bus_for_each_resource(pdev->subordinate, r, i) {
>+ if (!r || !r->parent ||
>+ !pnv_pci_is_mem_pref_64(r->flags))
>+ continue;
>+
>+ start = (r->start - phb->ioda.m64_base) / segsz;
>+ for (j = 0; j < resource_size(r) / segsz ; j++)
>+ clear_bit(start + j, pe_alloc);
>+ }
>+ }
>+
>+ /*
>+ * the current bus might not own M64 window and that's all
>+ * contributed by its child buses. For the case, we needn't
>+ * pick M64 dependent PE#.
>+ */
>+ if (bitmap_empty(pe_alloc, phb->ioda.total_pe)) {
>+ kfree(pe_alloc);
>+ return IODA_INVALID_PE;
>+ }
>+
>+ /*
>+ * Figure out the master PE and put all slave PEs to master
>+ * PE's list to form compound PE.
>+ */
>+done:
>+ master_pe = NULL;
>+ i = -1;
>+ while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) <
>+ phb->ioda.total_pe) {
>+ pe = &phb->ioda.pe_array[i];
>+ pe->phb = phb;
>+ pe->pe_number = i;
>+
>+ if (!master_pe) {
>+ pe->flags |= PNV_IODA_PE_MASTER;
>+ INIT_LIST_HEAD(&pe->slaves);
>+ master_pe = pe;
>+ } else {
>+ pe->flags |= PNV_IODA_PE_SLAVE;
>+ pe->master = master_pe;
>+ list_add_tail(&pe->list, &master_pe->slaves);
>+ }
>+ }
>+
>+ kfree(pe_alloc);
>+ return master_pe->pe_number;
>+}
>+
>+static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
>+{
>+ struct pci_controller *hose = phb->hose;
>+ struct device_node *dn = hose->dn;
>+ struct resource *res;
>+ const u32 *r;
>+ u64 pci_addr;
>+
>+ if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
>+ pr_info(" Firmware too old to support M64 window\n");
>+ return;
>+ }
>+
>+ r = of_get_property(dn, "ibm,opal-m64-window", NULL);
>+ if (!r) {
>+ pr_info(" No <ibm,opal-m64-window> on %s\n",
>+ dn->full_name);
>+ return;
>+ }
>+
>+ /* FIXME: Support M64 for P7IOC */
>+ if (phb->type != PNV_PHB_IODA2) {
>+ pr_info(" Not support M64 window\n");
>+ return;
>+ }
>+
>+ res = &hose->mem_resources[1];
>+ res->start = of_translate_address(dn, r + 2);
>+ res->end = res->start + of_read_number(r + 4, 2) - 1;
>+ res->flags = (IORESOURCE_MEM | IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);
>+ pci_addr = of_read_number(r, 2);
>+ hose->mem_offset[1] = res->start - pci_addr;
>+
>+ phb->ioda.m64_size = resource_size(res);
>+ phb->ioda.m64_segsize = phb->ioda.m64_size / phb->ioda.total_pe;
>+ phb->ioda.m64_base = pci_addr;
>+
>+ /* Use last M64 BAR to cover M64 window */
>+ phb->ioda.m64_bar_idx = 15;
>+ phb->init_m64 = pnv_ioda2_init_m64;
>+ phb->alloc_m64_pe = pnv_ioda2_alloc_m64_pe;
>+ phb->pick_m64_pe = pnv_ioda2_pick_m64_pe;
>+
>+ pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx Prefetchable\n",
>+ res->start, res->end, pci_addr);
>+}
>+
> /* Currently those 2 are only used when MSIs are enabled, this will change
> * but in the meantime, we need to protect them to avoid warnings
> */
>@@ -363,9 +607,16 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)
> struct pci_controller *hose = pci_bus_to_host(bus);
> struct pnv_phb *phb = hose->private_data;
> struct pnv_ioda_pe *pe;
>- int pe_num;
>+ int pe_num = IODA_INVALID_PE;
>+
>+ /* Check if PE is determined by M64 */
>+ if (phb->pick_m64_pe)
>+ pe_num = phb->pick_m64_pe(phb, bus, all);
>+
>+ /* The PE number isn't pinned by M64 */
>+ if (pe_num == IODA_INVALID_PE)
>+ pe_num = pnv_ioda_alloc_pe(phb);
>
>- pe_num = pnv_ioda_alloc_pe(phb);
> if (pe_num == IODA_INVALID_PE) {
> pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n",
> __func__, pci_domain_nr(bus), bus->number);
>@@ -441,8 +692,15 @@ static void pnv_ioda_setup_PEs(struct pci_bus *bus)
> static void pnv_pci_ioda_setup_PEs(void)
> {
> struct pci_controller *hose, *tmp;
>+ struct pnv_phb *phb;
>
> list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
>+ phb = hose->private_data;
>+
>+ /* M64 layout might affect PE allocation */
>+ if (phb->alloc_m64_pe)
>+ phb->alloc_m64_pe(phb);
>+
> pnv_ioda_setup_PEs(hose->bus);
> }
> }
>@@ -1055,9 +1313,6 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
> index++;
> }
> } else if (res->flags & IORESOURCE_MEM) {
>- /* WARNING: Assumes M32 is mem region 0 in PHB. We need to
>- * harden that algorithm when we start supporting M64
>- */
> region.start = res->start -
> hose->mem_offset[0] -
> phb->ioda.m32_pci_base;
>@@ -1178,7 +1433,8 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
> bridge = bridge->bus->self;
> }
>
>- /* We need support prefetchable memory window later */
>+ if (pnv_pci_is_mem_pref_64(type))
>+ return phb->ioda.m64_segsize;
I guess we need more conditions for P7IOC since we didn't enable M64 for P7IOC
yet. Otherwise, it's going to break P7IOC. Sorry, I should catch this a bit
early.
if (phb->ioda.m64_segsize &&
pnv_pci_is_mem_pref_64(type))
return phb->ioda.m64_segsize;
And I think one of us need run the code on P7 box to see if it breaks anything
there.
Thanks,
Gavin
> if (type & IORESOURCE_MEM)
> return phb->ioda.m32_segsize;
>
>@@ -1299,6 +1555,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL);
> if (prop32)
> phb->ioda.reserved_pe = be32_to_cpup(prop32);
>+
>+ /* Parse 64-bit MMIO range */
>+ pnv_ioda_parse_m64_window(phb);
>+
> phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
> /* FW Has already off top 64k of M32 space (MSI space) */
> phb->ioda.m32_size += 0x10000;
>@@ -1334,14 +1594,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> /* Calculate how many 32-bit TCE segments we have */
> phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28;
>
>- /* Clear unusable m64 */
>- hose->mem_resources[1].flags = 0;
>- hose->mem_resources[1].start = 0;
>- hose->mem_resources[1].end = 0;
>- hose->mem_resources[2].flags = 0;
>- hose->mem_resources[2].start = 0;
>- hose->mem_resources[2].end = 0;
>-
> #if 0 /* We should really do that ... */
> rc = opal_pci_set_phb_mem_window(opal->phb_id,
> window_type,
>@@ -1404,6 +1656,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL);
> ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET);
> }
>+
>+ /* Configure M64 window */
>+ if (phb->init_m64 && phb->init_m64(phb))
>+ hose->mem_resources[1].flags = 0;
> }
>
> void __init pnv_pci_init_ioda2_phb(struct device_node *np)
>diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
>index 676232c..def7171 100644
>--- a/arch/powerpc/platforms/powernv/pci.h
>+++ b/arch/powerpc/platforms/powernv/pci.h
>@@ -21,6 +21,8 @@ enum pnv_phb_model {
> #define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */
> #define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */
> #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */
>+#define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */
>+#define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */
>
> /* Data associated with a PE, including IOMMU tracking etc.. */
> struct pnv_phb;
>@@ -64,6 +66,10 @@ struct pnv_ioda_pe {
> */
> int mve_number;
>
>+ /* PEs in compound case */
>+ struct pnv_ioda_pe *master;
>+ struct list_head slaves;
>+
> /* Link in list of PE#s */
> struct list_head dma_link;
> struct list_head list;
>@@ -119,6 +125,9 @@ struct pnv_phb {
> void (*fixup_phb)(struct pci_controller *hose);
> u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
> void (*shutdown)(struct pnv_phb *phb);
>+ int (*init_m64)(struct pnv_phb *phb);
>+ void (*alloc_m64_pe)(struct pnv_phb *phb);
>+ int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
>
> union {
> struct {
>@@ -129,9 +138,20 @@ struct pnv_phb {
> /* Global bridge info */
> unsigned int total_pe;
> unsigned int reserved_pe;
>+
>+ /* 32-bit MMIO window */
> unsigned int m32_size;
> unsigned int m32_segsize;
> unsigned int m32_pci_base;
>+
>+ /* 64-bit MMIO window */
>+ unsigned int m64_bar_idx;
>+ unsigned long m64_size;
>+ unsigned long m64_segsize;
>+ unsigned long m64_base;
>+ unsigned long m64_bar_alloc;
>+
>+ /* IO ports */
> unsigned int io_size;
> unsigned int io_segsize;
> unsigned int io_pci_base;
>--
>1.8.3.1
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Mike Qiu @ 2014-07-14 13:35 UTC (permalink / raw)
To: Gavin Shan; +Cc: benh, linuxppc-dev
In-Reply-To: <20140714130149.GA4752@shangw>
On 07/14/2014 09:01 PM, Gavin Shan wrote:
> On Mon, Jul 14, 2014 at 04:19:23AM -0400, Mike Qiu wrote:
>> [ 121.133381] WARNING: at drivers/pci/search.c:223
>> [ 121.133422] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
>> [ 121.133424] task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
>> [ 121.133425] NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
>> [ 121.133427] REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
>> [ 121.133428] MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
>> [ 121.133433] CFAR: c00000000003752c SOFTE: 0
>> GPR00: c000000000037530 c000000001447220 c000000001448c30 c0000003bca1dc00
>> GPR04: 0000000000000000 c000000000066064 9000000000009032 0000000000000008
>> GPR08: 0000000000000007 0000000000000001 0000000000000100 000000003003d200
>> GPR12: 0000000044002482 c00000000fee0000 0000000000000000 c0000000015e8830
>> GPR16: c0000000015e8c30 0000000000000000 c0000000015e8430 c0000000015e8030
>> GPR20: c000000001348c30 c000000001482180 0000000000000000 0000000000000000
>> GPR24: 0000000000200200 c0000003bc243500 c0000003feff4070 c0000003bcec3000
>> GPR28: c0000000014cac00 c0000003bca1dc00 0000000000000000 0000000000000000
>> [ 121.133454] NIP [c000000000497b70] .pci_get_slot+0x40/0x110
>> [ 121.133457] LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
>> [ 121.133458] Call Trace:
>> [ 121.133461] [c000000001447220] [c000000000721730] .of_get_property+0x30/0x60 (unreliable)
>> [ 121.133464] [c0000000014472b0] [c000000000037530] .eeh_pe_loc_get+0x150/0x190
>> [ 121.133466] [c000000001447340] [c000000000034684] .eeh_dev_check_failure+0x1b4/0x550
>> [ 121.133468] [c0000000014473f0] [c000000000034ab0] .eeh_check_failure+0x90/0xf0
>> [ 121.133493] [c000000001447490] [d000000002c03e84] .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
>> [ 121.133501] [c000000001447520] [d000000002c041a4] .lpfc_poll_eratt+0x64/0x100 [lpfc]
>> [ 121.133504] [c0000000014475a0] [c0000000000b45b4] .call_timer_fn+0x64/0x190
>> [ 121.133506] [c000000001447650] [c0000000000b4d1c] .run_timer_softirq+0x2cc/0x3e0
>> [ 121.133508] [c000000001447760] [c0000000000a90c8] .__do_softirq+0x198/0x3c0
>> [ 121.133510] [c000000001447880] [c0000000000a9658] .irq_exit+0xc8/0x110
>> [ 121.133513] [c000000001447900] [c00000000001e010] .timer_interrupt+0xa0/0xe0
>> [ 121.133515] [c000000001447980] [c0000000000026d8] decrementer_common+0x158/0x180
>> [ 121.133518] --- Exception: 901 at .arch_local_irq_restore+0x74/0x90
>>
>> pci_get_slot() should not be used in interrupt. But eeh subsystem do
>> the error checking in interrupt in this situation.
>>
>> This patch is to solve this issue.
>>
> The commit log has been clear enough, but the following message might
> be better. I'm not good at writing good commit log as well:
>
> ---
>
> pci_get_slot() is called with hold of PCI bus semaphore and it's not
> safe to be called in interrupt context. However, we possibly checks
> EEH error and calls the function in interrupt context. To avoid using
> pci_get_slot(), we turn into device tree for fetching location code.
> Otherwise, we might run into WARN_ON() as following messages indicate:
>
> WARNING: at drivers/pci/search.c:223
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
> task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
> NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
> REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
> MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
> CFAR: c00000000003752c SOFTE: 0
> :
> NIP [c000000000497b70] .pci_get_slot+0x40/0x110
> LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
> Call Trace:
> .of_get_property+0x30/0x60 (unreliable)
> .eeh_pe_loc_get+0x150/0x190
> .eeh_dev_check_failure+0x1b4/0x550
> .eeh_check_failure+0x90/0xf0
> .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
> .lpfc_poll_eratt+0x64/0x100 [lpfc]
> .call_timer_fn+0x64/0x190
> .run_timer_softirq+0x2cc/0x3e0
>
Yes, it's better enough.
>> Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/kernel/eeh_pe.c | 29 ++++++++++++++++++++++++++---
>> 1 file changed, 26 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
>> index fbd01eb..6f4bfee 100644
>> --- a/arch/powerpc/kernel/eeh_pe.c
>> +++ b/arch/powerpc/kernel/eeh_pe.c
>> @@ -792,6 +792,28 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
>> }
>>
>> /**
>> + * __dn_get_pdev - Retrieve the pci_dev from device_node by bus/devfn
>> + * @dn: device_node of the pci_dev
>> + * @data: the pci device's bus/devfn
>> + *
>> + * Retrieve the pci_dev using the given device_node and bus/devfn.
>> + */
>> +void *__dn_get_pdev(struct device_node *dn, void *data)
>> +{
> The function isn't necessarily public. "static" is enough, I think.
> I don't think we need this actually. Please refer to more comments
> below.
>
>> + struct pci_dn *pdn = PCI_DN(dn);
>> + int busno = *((int *)data) >> 8;
>> + int devfn = *((int *)data) & 0xff;
>> +
>> + if (!pdn)
>> + return NULL;
>> +
>> + if (pdn->busno == busno && pdn->devfn == devfn)
>> + return pdn->pcidev;
>> +
>> + return NULL;
>> +}
>> +
>> +/**
>> * eeh_pe_loc_get - Retrieve location code binding to the given PE
>> * @pe: EEH PE
>> *
>> @@ -807,6 +829,7 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> struct pci_dev *pdev;
>> struct device_node *dn;
>> const char *loc;
>> + int bdevfn;
>>
>> if (!bus)
>> return "N/A";
>> @@ -823,7 +846,9 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> if (loc)
>> return loc;
>>
>> - pdev = pci_get_slot(bus, 0x0);
>> + /* Get the root port */
>> + bdevfn = (bus->number) << 8 || 0x0;
>> + pdev = traverse_pci_devices(hose->dn, __dn_get_pdev, &bdevfn);
> We needn't search pdev from device-tree and then translate it to
> device-node. Root port is the only child hooked to root bus's
> device node (it's also PHB's device-node). So I guess you can
So here you mean, child hooked device node(root port) can be
hose->dn->child?
> just have something:
>
> /* Check PHB's device node */
> dn = pci_bus_to_OF_node(bus);
> if (unlikely(!dn)) {
> loc = "N/A";
> goto out;
> }
> loc = of_get_property(hose->dn,
> "ibm,loc-code", NULL);
> if (loc)
> return loc;
> loc = of_get_property(hose->dn,
> "ibm,io-base-loc-code", NULL);
> if (loc)
> return loc;
>
> /* Check root port */
> dn = dn->child;
>> } else {
>> pdev = bus->self;
> Here, we needn't grab the bridge as well:
>
> dn = pci_bus_to_OF_node(bus);
>> }
> Then check the device-node of bridge (or root port):
>
> if (unlikely(!dn)) {
> loc = "N/A";
> goto out;
> }
>
> loc = of_get_property(dn, "ibm,loc-code", NULL);
> if (!loc)
> loc = of_get_property(dn, "ibm,slot-location-code", NULL);
> if (!loc)
> loc = "N/A";
>
>> @@ -846,8 +871,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> loc = "N/A";
>>
>> out:
>> - if (pci_is_root_bus(bus) && pdev)
>> - pci_dev_put(pdev);
>> return loc;
>> }
I will make a new patch, after tested, I will resend it out
Thanks
Mike
> Thanks,
> Gavin
>
^ permalink raw reply
* Re: [PATCH v5 0/3] DMA: Freescale: driver cleanups and enhancements
From: Vinod Koul @ 2014-07-14 16:05 UTC (permalink / raw)
To: hongbo.zhang
Cc: leo.li, vkoul, linux-kernel, scottwood, dmaengine, dan.j.williams,
linuxppc-dev
In-Reply-To: <1400659383-6555-1-git-send-email-hongbo.zhang@freescale.com>
On Wed, May 21, 2014 at 04:03:00PM +0800, hongbo.zhang@freescale.com wrote:
> From: Hongbo Zhang <hongbo.zhang@freescale.com>
>
> Hi Dan,
> Please have a look at this 3/3 as Vinod mentioned.
>
> Hi Vinod Koul,
> Please have a look at the v5 patch set.
I dont see any objection, so applying all 3 with subject changed to reflect
correct subsystem name
--
~Vinod
>
> v4 -> v5 changes:
> - since previous 5 of 8 patches have been merged by Vinod, this iteration oly
> inludes the last 3 patches of v4.
> - patches order is changed for being reviewed and merged easier.
> - remove the .prepare functions, and use the suspend_late and resume_early in
> the suspend-and-resume patch.
>
> v3 -> v4 changes:
> - Fixed a typo in [2/8] commit message.
> - There was a potential double call of list_del() when apply [4/8] only,
> although this defect is removed again in later [6/8]. This version
> eliminates this problem by updating [4/8] and [6/8] slightly.
> - Updated [8/8] to use register access method introduced by [2/8]
>
> v2 -> v3 change:
> Only add "chan->pm_state = RUNNING" for patch[8/8].
>
> v1 -> v2 change:
> The only one change is introducing a new patch[1/7] to remove the unnecessary
> macro FSL_DMA_LD_DEBUG, thus the total patches number is 8 now (was 7)
>
> v1 notes:
> Note that patch 2~6 had beed sent out for upstream before, but were together
> with other storage patches at that time, that was not easy for being reviewed
> and merged, so I send them separately this time.
>
> Hongbo Zhang (3):
> DMA: Freescale: use spin_lock_bh instead of spin_lock_irqsave
> DMA: Freescale: add suspend resume functions for DMA driver
> DMA: Freescale: change descriptor release process for supporting
> async_tx
>
> drivers/dma/fsldma.c | 297 ++++++++++++++++++++++++++++++++++++++------------
> drivers/dma/fsldma.h | 32 +++++-
> 2 files changed, 260 insertions(+), 69 deletions(-)
>
> --
> 1.7.9.5
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
^ permalink raw reply
* Re: [PATCH v5 2/2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64
From: Tony Luck @ 2014-07-14 17:17 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Jeremy Fitzhardinge, linux-ia64@vger.kernel.org, sparse,
Paul Mackerras, H. Peter Anvin, akataria, linux-tip-commits,
anil.s.keshavamurthy, Ingo Molnar, Suzuki K. Poulose, Fenghua Yu,
Arnd Bergmann, Rusty Russell, Chris Wright, yrl.pp-manager.tt,
Thomas Gleixner, Kevin Hao, Linus Torvalds, rdunlap,
Linux Kernel Mailing List, dl9pf, Andrew Morton, linuxppc-dev,
David S. Miller
In-Reply-To: <53BBDEE6.1080800@hitachi.com>
On Tue, Jul 8, 2014 at 5:07 AM, Masami Hiramatsu
<masami.hiramatsu.pt@hitachi.com> wrote:
> Ping?
>
> This patch can be applied without 1/2, and will fix ia64/ppc64 problem.
Is somebody going to push this upstream? Another week has gone by,
we are at -rc5, and I'm still seeing the
Failed to find blacklist a00000010133b150
messages on ia64.
-Tony
^ permalink raw reply
* Re: [PATCH] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Gavin Shan @ 2014-07-14 23:24 UTC (permalink / raw)
To: Mike Qiu; +Cc: benh, linuxppc-dev, Gavin Shan
In-Reply-To: <53C3DC96.70505@linux.vnet.ibm.com>
On Mon, Jul 14, 2014 at 09:35:18PM +0800, Mike Qiu wrote:
>On 07/14/2014 09:01 PM, Gavin Shan wrote:
>>On Mon, Jul 14, 2014 at 04:19:23AM -0400, Mike Qiu wrote:
.../...
>>>Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>>>---
>>>arch/powerpc/kernel/eeh_pe.c | 29 ++++++++++++++++++++++++++---
>>>1 file changed, 26 insertions(+), 3 deletions(-)
>>>
>>>diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
>>>index fbd01eb..6f4bfee 100644
>>>--- a/arch/powerpc/kernel/eeh_pe.c
>>>+++ b/arch/powerpc/kernel/eeh_pe.c
>>>@@ -792,6 +792,28 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
>>>}
>>>
>>>/**
>>>+ * __dn_get_pdev - Retrieve the pci_dev from device_node by bus/devfn
>>>+ * @dn: device_node of the pci_dev
>>>+ * @data: the pci device's bus/devfn
>>>+ *
>>>+ * Retrieve the pci_dev using the given device_node and bus/devfn.
>>>+ */
>>>+void *__dn_get_pdev(struct device_node *dn, void *data)
>>>+{
>>The function isn't necessarily public. "static" is enough, I think.
>>I don't think we need this actually. Please refer to more comments
>>below.
>>
>>>+ struct pci_dn *pdn = PCI_DN(dn);
>>>+ int busno = *((int *)data) >> 8;
>>>+ int devfn = *((int *)data) & 0xff;
>>>+
>>>+ if (!pdn)
>>>+ return NULL;
>>>+
>>>+ if (pdn->busno == busno && pdn->devfn == devfn)
>>>+ return pdn->pcidev;
>>>+
>>>+ return NULL;
>>>+}
>>>+
>>>+/**
>>> * eeh_pe_loc_get - Retrieve location code binding to the given PE
>>> * @pe: EEH PE
>>> *
>>>@@ -807,6 +829,7 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>>> struct pci_dev *pdev;
>>> struct device_node *dn;
>>> const char *loc;
>>>+ int bdevfn;
>>>
>>> if (!bus)
>>> return "N/A";
>>>@@ -823,7 +846,9 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>>> if (loc)
>>> return loc;
>>>
>>>- pdev = pci_get_slot(bus, 0x0);
>>>+ /* Get the root port */
>>>+ bdevfn = (bus->number) << 8 || 0x0;
>>>+ pdev = traverse_pci_devices(hose->dn, __dn_get_pdev, &bdevfn);
>>We needn't search pdev from device-tree and then translate it to
>>device-node. Root port is the only child hooked to root bus's
>>device node (it's also PHB's device-node). So I guess you can
>
>So here you mean, child hooked device node(root port) can be
>hose->dn->child?
>
Yes, I think so.
>>just have something:
>>
>> /* Check PHB's device node */
>> dn = pci_bus_to_OF_node(bus);
>> if (unlikely(!dn)) {
>> loc = "N/A";
>> goto out;
>> }
>> loc = of_get_property(hose->dn,
>> "ibm,loc-code", NULL);
>> if (loc)
>> return loc;
>> loc = of_get_property(hose->dn,
>> "ibm,io-base-loc-code", NULL);
>> if (loc)
>> return loc;
>>
>> /* Check root port */
>> dn = dn->child;
>>> } else {
>>> pdev = bus->self;
>>Here, we needn't grab the bridge as well:
>>
>> dn = pci_bus_to_OF_node(bus);
>>> }
>>Then check the device-node of bridge (or root port):
>>
>> if (unlikely(!dn)) {
>> loc = "N/A";
>> goto out;
>> }
>>
>> loc = of_get_property(dn, "ibm,loc-code", NULL);
>> if (!loc)
>> loc = of_get_property(dn, "ibm,slot-location-code", NULL);
>> if (!loc)
>> loc = "N/A";
>>
>>>@@ -846,8 +871,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>>> loc = "N/A";
>>>
>>>out:
>>>- if (pci_is_root_bus(bus) && pdev)
>>>- pci_dev_put(pdev);
>>> return loc;
>>>}
>
>I will make a new patch, after tested, I will resend it out
>
Thanks, Mike.
Thanks,
Gavin
^ permalink raw reply
* [PATCH] powerpc: Revert removing of _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
From: Steven Rostedt @ 2014-07-15 0:12 UTC (permalink / raw)
To: LKML, linuxppc-dev, Benjamin Herrenschmidt, Anton Blanchard,
Olof Johansson
I wanted to test some new ftrace code on my PASemi electra powerpc box.
But unfortunately it failed to build. It failed with this:
LD init/built-in.o
arch/powerpc/kernel/head_64.o:arch/powerpc/kernel/exceptions-64s.S:874:
relocation truncated to fit: R_PPC64_REL14 against `.text'+1c90
Makefile:864: recipe for target 'vmlinux' failed
Bisecting it lead me down to this commit:
commit 6a3bab90cf78bc579638525cb76ac240f8253803
Author: Anton Blanchard <anton@samba.org>
Date: Tue Feb 4 16:06:11 2014 +1100
powerpc: Remove some unnecessary uses of _GLOBAL() and _STATIC()
There is no need to create a function descriptor for functions
called locally out of assembly.
And by reverting this and:
commit a0e971ffb9d9dae3b9892fb548bd2497db758f60
Author: Anton Blanchard <anton@samba.org>
Date: Tue Feb 4 16:06:25 2014 +1100
powerpc: Remove _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
Now there are no users of _INIT_GLOBAL(), _STATIC() and
_INIT_STATIC() we can remove them.
My box builds and boots again.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 9ea266e..1baf197 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -217,6 +217,20 @@ name: \
addi r2,r2,(.TOC.-0b)@l; \
.localentry name,.-name
+#define _INIT_GLOBAL(name) \
+ __REF; \
+ .align 2 ; \
+ .globl name; \
+ .globl GLUE(.,name); \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
#define _KPROBE(name) \
.section ".kprobes.text","a"; \
.align 2 ; \
@@ -265,6 +279,30 @@ GLUE(.,name):
#endif
+#define _STATIC(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _INIT_STATIC(name) \
+ __REF; \
+ .align 2 ; \
+ .section ".opd","aw"; \
+name: \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
+ .previous; \
+ .type GLUE(.,name),@function; \
+GLUE(.,name):
+
#else /* 32-bit */
#define _ENTRY(n) \
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index bb9cac6..ce0c55d 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -1580,14 +1580,14 @@ _GLOBAL(book3e_secondary_thread_init)
mflr r28
b 3b
-init_core_book3e:
+_STATIC(init_core_book3e)
/* Establish the interrupt vector base */
LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
mtspr SPRN_IVPR,r3
sync
blr
-init_thread_book3e:
+_STATIC(init_thread_book3e)
lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
mtspr SPRN_EPCR,r3
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a7d36b1..220c5a9 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1586,7 +1586,7 @@ power4_fixup_nap:
* Hash table stuff
*/
.align 7
-do_hash_page:
+_STATIC(do_hash_page)
std r3,_DAR(r1)
std r4,_DSISR(r1)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index a95145d..b8986af 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -299,7 +299,7 @@ generic_secondary_common_init:
* Assumes we're mapped EA == RA if the MMU is on.
*/
#ifdef CONFIG_PPC_BOOK3S
-__mmu_off:
+_STATIC(__mmu_off)
mfmsr r3
andi. r0,r3,MSR_IR|MSR_DR
beqlr
@@ -324,7 +324,7 @@ __mmu_off:
* DT block, r4 is a physical pointer to the kernel itself
*
*/
-__start_initialization_multiplatform:
+_GLOBAL(__start_initialization_multiplatform)
/* Make sure we are running in 64 bits mode */
bl enable_64b_mode
@@ -376,7 +376,7 @@ __start_initialization_multiplatform:
b __after_prom_start
#endif /* CONFIG_PPC_BOOK3E */
-__boot_from_prom:
+_INIT_STATIC(__boot_from_prom)
#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
/* Save parameters */
mr r31,r3
@@ -414,7 +414,7 @@ __boot_from_prom:
* from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
trap
-__after_prom_start:
+_STATIC(__after_prom_start)
#ifdef CONFIG_RELOCATABLE
/* process relocations for the final address of the kernel */
lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
@@ -674,7 +674,7 @@ _GLOBAL(start_secondary_resume)
/*
* This subroutine clobbers r11 and r12
*/
-enable_64b_mode:
+_GLOBAL(enable_64b_mode)
mfmsr r11 /* grab the current MSR */
#ifdef CONFIG_PPC_BOOK3E
oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */
@@ -715,7 +715,7 @@ p_toc: .llong __toc_start + 0x8000 - 0b
/*
* This is where the main kernel code starts.
*/
-start_here_multiplatform:
+_INIT_STATIC(start_here_multiplatform)
/* set up the TOC */
bl relative_toc
tovirt(r2,r2)
^ permalink raw reply related
* Re: [PATCH] powerpc: Revert removing of _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
From: Benjamin Herrenschmidt @ 2014-07-15 2:05 UTC (permalink / raw)
To: Steven Rostedt; +Cc: Olof Johansson, linuxppc-dev, LKML, Anton Blanchard
In-Reply-To: <20140714201204.7b6fcd8e@gandalf.local.home>
On Mon, 2014-07-14 at 20:12 -0400, Steven Rostedt wrote:
> I wanted to test some new ftrace code on my PASemi electra powerpc box.
> But unfortunately it failed to build. It failed with this:
>
> LD init/built-in.o
> arch/powerpc/kernel/head_64.o:arch/powerpc/kernel/exceptions-64s.S:874:
> relocation truncated to fit: R_PPC64_REL14 against `.text'+1c90
> Makefile:864: recipe for target 'vmlinux' failed
Weird ... what are your gcc and binutils versions ? Smells like a
toolchain issue to me but I need to dig a bit more. Doesn't hit any
of my test configs here.
Cheers,
Ben.
> Bisecting it lead me down to this commit:
>
> commit 6a3bab90cf78bc579638525cb76ac240f8253803
> Author: Anton Blanchard <anton@samba.org>
> Date: Tue Feb 4 16:06:11 2014 +1100
>
> powerpc: Remove some unnecessary uses of _GLOBAL() and _STATIC()
>
> There is no need to create a function descriptor for functions
> called locally out of assembly.
>
>
> And by reverting this and:
>
> commit a0e971ffb9d9dae3b9892fb548bd2497db758f60
> Author: Anton Blanchard <anton@samba.org>
> Date: Tue Feb 4 16:06:25 2014 +1100
>
> powerpc: Remove _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
>
> Now there are no users of _INIT_GLOBAL(), _STATIC() and
> _INIT_STATIC() we can remove them.
>
> My box builds and boots again.
>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> ---
> diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
> index 9ea266e..1baf197 100644
> --- a/arch/powerpc/include/asm/ppc_asm.h
> +++ b/arch/powerpc/include/asm/ppc_asm.h
> @@ -217,6 +217,20 @@ name: \
> addi r2,r2,(.TOC.-0b)@l; \
> .localentry name,.-name
>
> +#define _INIT_GLOBAL(name) \
> + __REF; \
> + .align 2 ; \
> + .globl name; \
> + .globl GLUE(.,name); \
> + .section ".opd","aw"; \
> +name: \
> + .quad GLUE(.,name); \
> + .quad .TOC.@tocbase; \
> + .quad 0; \
> + .previous; \
> + .type GLUE(.,name),@function; \
> +GLUE(.,name):
> +
> #define _KPROBE(name) \
> .section ".kprobes.text","a"; \
> .align 2 ; \
> @@ -265,6 +279,30 @@ GLUE(.,name):
>
> #endif
>
> +#define _STATIC(name) \
> + .section ".text"; \
> + .align 2 ; \
> + .section ".opd","aw"; \
> +name: \
> + .quad GLUE(.,name); \
> + .quad .TOC.@tocbase; \
> + .quad 0; \
> + .previous; \
> + .type GLUE(.,name),@function; \
> +GLUE(.,name):
> +
> +#define _INIT_STATIC(name) \
> + __REF; \
> + .align 2 ; \
> + .section ".opd","aw"; \
> +name: \
> + .quad GLUE(.,name); \
> + .quad .TOC.@tocbase; \
> + .quad 0; \
> + .previous; \
> + .type GLUE(.,name),@function; \
> +GLUE(.,name):
> +
> #else /* 32-bit */
>
> #define _ENTRY(n) \
> diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
> index bb9cac6..ce0c55d 100644
> --- a/arch/powerpc/kernel/exceptions-64e.S
> +++ b/arch/powerpc/kernel/exceptions-64e.S
> @@ -1580,14 +1580,14 @@ _GLOBAL(book3e_secondary_thread_init)
> mflr r28
> b 3b
>
> -init_core_book3e:
> +_STATIC(init_core_book3e)
> /* Establish the interrupt vector base */
> LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
> mtspr SPRN_IVPR,r3
> sync
> blr
>
> -init_thread_book3e:
> +_STATIC(init_thread_book3e)
> lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
> mtspr SPRN_EPCR,r3
>
> diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
> index a7d36b1..220c5a9 100644
> --- a/arch/powerpc/kernel/exceptions-64s.S
> +++ b/arch/powerpc/kernel/exceptions-64s.S
> @@ -1586,7 +1586,7 @@ power4_fixup_nap:
> * Hash table stuff
> */
> .align 7
> -do_hash_page:
> +_STATIC(do_hash_page)
> std r3,_DAR(r1)
> std r4,_DSISR(r1)
>
> diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
> index a95145d..b8986af 100644
> --- a/arch/powerpc/kernel/head_64.S
> +++ b/arch/powerpc/kernel/head_64.S
> @@ -299,7 +299,7 @@ generic_secondary_common_init:
> * Assumes we're mapped EA == RA if the MMU is on.
> */
> #ifdef CONFIG_PPC_BOOK3S
> -__mmu_off:
> +_STATIC(__mmu_off)
> mfmsr r3
> andi. r0,r3,MSR_IR|MSR_DR
> beqlr
> @@ -324,7 +324,7 @@ __mmu_off:
> * DT block, r4 is a physical pointer to the kernel itself
> *
> */
> -__start_initialization_multiplatform:
> +_GLOBAL(__start_initialization_multiplatform)
> /* Make sure we are running in 64 bits mode */
> bl enable_64b_mode
>
> @@ -376,7 +376,7 @@ __start_initialization_multiplatform:
> b __after_prom_start
> #endif /* CONFIG_PPC_BOOK3E */
>
> -__boot_from_prom:
> +_INIT_STATIC(__boot_from_prom)
> #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
> /* Save parameters */
> mr r31,r3
> @@ -414,7 +414,7 @@ __boot_from_prom:
> * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
> trap
>
> -__after_prom_start:
> +_STATIC(__after_prom_start)
> #ifdef CONFIG_RELOCATABLE
> /* process relocations for the final address of the kernel */
> lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
> @@ -674,7 +674,7 @@ _GLOBAL(start_secondary_resume)
> /*
> * This subroutine clobbers r11 and r12
> */
> -enable_64b_mode:
> +_GLOBAL(enable_64b_mode)
> mfmsr r11 /* grab the current MSR */
> #ifdef CONFIG_PPC_BOOK3E
> oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */
> @@ -715,7 +715,7 @@ p_toc: .llong __toc_start + 0x8000 - 0b
> /*
> * This is where the main kernel code starts.
> */
> -start_here_multiplatform:
> +_INIT_STATIC(start_here_multiplatform)
> /* set up the TOC */
> bl relative_toc
> tovirt(r2,r2)
^ permalink raw reply
* Re: [PATCH v5 2/2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64
From: Michael Ellerman @ 2014-07-15 2:11 UTC (permalink / raw)
To: Tony Luck
Cc: Jeremy Fitzhardinge, linux-ia64@vger.kernel.org, sparse,
Paul Mackerras, H. Peter Anvin, Masami Hiramatsu, akataria,
linux-tip-commits, anil.s.keshavamurthy, Ingo Molnar,
Suzuki K. Poulose, Fenghua Yu, Arnd Bergmann, Rusty Russell,
Chris Wright, yrl.pp-manager.tt, Thomas Gleixner, Kevin Hao,
Linus Torvalds, rdunlap, Linux Kernel Mailing List, dl9pf,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <CA+8MBbJH3EfiGctxLpXScGEtvBNXkNVYEnyahihnCie1FgO+9Q@mail.gmail.com>
On Mon, 2014-07-14 at 10:17 -0700, Tony Luck wrote:
> On Tue, Jul 8, 2014 at 5:07 AM, Masami Hiramatsu
> <masami.hiramatsu.pt@hitachi.com> wrote:
> > Ping?
> >
> > This patch can be applied without 1/2, and will fix ia64/ppc64 problem.
>
> Is somebody going to push this upstream? Another week has gone by,
> we are at -rc5, and I'm still seeing the
>
> Failed to find blacklist a00000010133b150
>
> messages on ia64.
I don't see those messages on ppc64, I don't know where the original report
that it was broken on ppc64 came from. So I'm a bit lukewarm on the patch.
cheers
^ permalink raw reply
* Re: [PATCH] powerpc: Revert removing of _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
From: Steven Rostedt @ 2014-07-15 2:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Olof Johansson, linuxppc-dev, LKML, Anton Blanchard
In-Reply-To: <1405389955.9343.48.camel@pasglop>
On Tue, 15 Jul 2014 12:05:55 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> On Mon, 2014-07-14 at 20:12 -0400, Steven Rostedt wrote:
> > I wanted to test some new ftrace code on my PASemi electra powerpc box.
> > But unfortunately it failed to build. It failed with this:
> >
> > LD init/built-in.o
> > arch/powerpc/kernel/head_64.o:arch/powerpc/kernel/exceptions-64s.S:874:
> > relocation truncated to fit: R_PPC64_REL14 against `.text'+1c90
> > Makefile:864: recipe for target 'vmlinux' failed
>
> Weird ... what are your gcc and binutils versions ? Smells like a
> toolchain issue to me but I need to dig a bit more. Doesn't hit any
> of my test configs here.
>
I built it from scratch from the mainline source repos.
dist-ppc-gcc (GCC) 4.6.0
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU assembler (GNU Binutils) 2.21
Copyright 2010 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `powerpc64-unknown-linux'.
-- Steve
^ permalink raw reply
* Re: [PATCH] powerpc: Revert removing of _INIT_GLOBAL(), _STATIC() and _INIT_STATIC()
From: Steven Rostedt @ 2014-07-15 2:16 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Olof Johansson, linuxppc-dev, LKML, Anton Blanchard
In-Reply-To: <1405389955.9343.48.camel@pasglop>
On Tue, 15 Jul 2014 12:05:55 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> Cheers,
> Ben.
>
While I got your attention, could you please ack my patch with subject:
[RFA][PATCH 09/27] powerpc/ftrace: Add call to ftrace_graph_is_dead() in function graph code
so that I can push it through my tree.
Thanks!
-- Steve
^ permalink raw reply
* Re: Re: [PATCH v5 2/2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64
From: Masami Hiramatsu @ 2014-07-15 2:24 UTC (permalink / raw)
To: Michael Ellerman
Cc: Jeremy Fitzhardinge, linux-ia64@vger.kernel.org, sparse,
Linux Kernel Mailing List, Paul Mackerras, H. Peter Anvin,
akataria, linux-tip-commits, anil.s.keshavamurthy, Ingo Molnar,
Suzuki K. Poulose, Fenghua Yu, Arnd Bergmann, Rusty Russell,
Chris Wright, yrl.pp-manager.tt, Thomas Gleixner, Kevin Hao,
Linus Torvalds, rdunlap, Tony Luck, dl9pf, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <1405390262.17767.5.camel@concordia>
(2014/07/15 11:11), Michael Ellerman wrote:
> On Mon, 2014-07-14 at 10:17 -0700, Tony Luck wrote:
>> On Tue, Jul 8, 2014 at 5:07 AM, Masami Hiramatsu
>> <masami.hiramatsu.pt@hitachi.com> wrote:
>>> Ping?
>>>
>>> This patch can be applied without 1/2, and will fix ia64/ppc64 problem.
>>
>> Is somebody going to push this upstream? Another week has gone by,
>> we are at -rc5, and I'm still seeing the
>>
>> Failed to find blacklist a00000010133b150
>>
>> messages on ia64.
>
> I don't see those messages on ppc64, I don't know where the original report
> that it was broken on ppc64 came from. So I'm a bit lukewarm on the patch.
Right, on ppc64(ABIv1) it may be silently failed. Because each function
descriptor has another entry on kallsyms, original code can't detect
that. On the other hand, ia64's function descriptors have no entries,
so it can detect the failure on boot.
This patch adds new detection code using kernel_text_address() and
translates function descriptor to function entry.
Thank you,
--
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com
^ permalink raw reply
* [PATCH v2] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Mike Qiu @ 2014-07-15 2:33 UTC (permalink / raw)
To: linuxppc-dev; +Cc: benh, Mike Qiu, gwshan
pci_get_slot() is called with hold of PCI bus semaphore and it's not
safe to be called in interrupt context. However, we possibly checks
EEH error and calls the function in interrupt context. To avoid using
pci_get_slot(), we turn into device tree for fetching location code.
Otherwise, we might run into WARN_ON() as following messages indicate:
WARNING: at drivers/pci/search.c:223
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
CFAR: c00000000003752c SOFTE: 0
:
NIP [c000000000497b70] .pci_get_slot+0x40/0x110
LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
Call Trace:
.of_get_property+0x30/0x60 (unreliable)
.eeh_pe_loc_get+0x150/0x190
.eeh_dev_check_failure+0x1b4/0x550
.eeh_check_failure+0x90/0xf0
.lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
.lpfc_poll_eratt+0x64/0x100 [lpfc]
.call_timer_fn+0x64/0x190
.run_timer_softirq+0x2cc/0x3e0
Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
---
Changelog[v2]:
Check the child device_node of root bus for root port
directly instead of search pdev from device-tree and
then translate it to device-node
arch/powerpc/kernel/eeh_pe.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eb..f96c10f 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -802,7 +802,6 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
*/
const char *eeh_pe_loc_get(struct eeh_pe *pe)
{
- struct pci_controller *hose;
struct pci_bus *bus = eeh_pe_bus_get(pe);
struct pci_dev *pdev;
struct device_node *dn;
@@ -811,29 +810,20 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
if (!bus)
return "N/A";
+ dn = pci_bus_to_OF_node(bus);
/* PHB PE or root PE ? */
- if (pci_is_root_bus(bus)) {
- hose = pci_bus_to_host(bus);
- loc = of_get_property(hose->dn,
- "ibm,loc-code", NULL);
+ if (dn && pci_is_root_bus(bus)) {
+ loc = of_get_property(dn, "ibm,loc-code", NULL);
if (loc)
return loc;
- loc = of_get_property(hose->dn,
- "ibm,io-base-loc-code", NULL);
+ loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
if (loc)
return loc;
- pdev = pci_get_slot(bus, 0x0);
- } else {
- pdev = bus->self;
- }
-
- if (!pdev) {
- loc = "N/A";
- goto out;
+ /* Check the root port */
+ dn = dn->child;
}
- dn = pci_device_to_OF_node(pdev);
if (!dn) {
loc = "N/A";
goto out;
@@ -846,8 +836,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
loc = "N/A";
out:
- if (pci_is_root_bus(bus) && pdev)
- pci_dev_put(pdev);
return loc;
}
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH 1/6] powerpc/powernv: Enable M64 aperatus for PHB3
From: Wei Yang @ 2014-07-15 2:55 UTC (permalink / raw)
To: Guo Chao; +Cc: linuxppc-dev
In-Reply-To: <1405000426-1016-2-git-send-email-yan@linux.vnet.ibm.com>
On Thu, Jul 10, 2014 at 09:53:41PM +0800, Guo Chao wrote:
>This patch enable M64 aperatus for PHB3.
>
>We already had platform hook (ppc_md.pcibios_window_alignment) to affect
>the PCI resource assignment done in PCI core so that each PE's M32 resource
>was built on basis of M32 segment size. Similarly, we're using that for
>M64 assignment on basis of M64 segment size.
>
> * We're using last M64 BAR to cover M64 aperatus, and it's shared by all
> 256 PEs.
> * We don't support P7IOC yet. However, some function callbacks are added
> to (struct pnv_phb) so that we can reuse them on P7IOC in future.
> * PE, corresponding to PCI bus with large M64 BAR device attached, might
> span multiple M64 segments. We introduce "compound" PE to cover the case.
> The compound PE is a list of PEs and the master PE is used as before.
> The slave PEs are just for MMIO isolation.
>
>Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com>
>---
> arch/powerpc/include/asm/opal.h | 8 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 284 ++++++++++++++++++++++++++++--
> arch/powerpc/platforms/powernv/pci.h | 20 +++
> 3 files changed, 297 insertions(+), 15 deletions(-)
>
>diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
>index 0da1dbd..ae885cc 100644
>--- a/arch/powerpc/include/asm/opal.h
>+++ b/arch/powerpc/include/asm/opal.h
>@@ -340,6 +340,12 @@ enum OpalMveEnableAction {
> OPAL_ENABLE_MVE = 1
> };
>
>+enum OpalM64EnableAction {
>+ OPAL_DISABLE_M64 = 0,
>+ OPAL_ENABLE_M64_SPLIT = 1,
>+ OPAL_ENABLE_M64_NON_SPLIT = 2
>+};
>+
> enum OpalPciResetScope {
> OPAL_PHB_COMPLETE = 1, OPAL_PCI_LINK = 2, OPAL_PHB_ERROR = 3,
> OPAL_PCI_HOT_RESET = 4, OPAL_PCI_FUNDAMENTAL_RESET = 5,
>@@ -768,7 +774,7 @@ int64_t opal_pci_set_phb_mem_window(uint64_t phb_id, uint16_t window_type,
> uint16_t window_num,
> uint64_t starting_real_address,
> uint64_t starting_pci_address,
>- uint16_t segment_size);
>+ uint64_t size);
> int64_t opal_pci_map_pe_mmio_window(uint64_t phb_id, uint16_t pe_number,
> uint16_t window_type, uint16_t window_num,
> uint16_t segment_num);
>diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
>index de19ede..851e615 100644
>--- a/arch/powerpc/platforms/powernv/pci-ioda.c
>+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>@@ -36,6 +36,7 @@
> #include <asm/tce.h>
> #include <asm/xics.h>
> #include <asm/debug.h>
>+#include <asm/firmware.h>
>
> #include "powernv.h"
> #include "pci.h"
>@@ -82,6 +83,12 @@ static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
> : : "r" (val), "r" (paddr) : "memory");
> }
>
>+static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
>+{
>+ return ((flags & (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)) ==
>+ (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
>+}
>+
> static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
> {
> unsigned long pe;
>@@ -106,6 +113,243 @@ static void pnv_ioda_free_pe(struct pnv_phb *phb, int pe)
> clear_bit(pe, phb->ioda.pe_alloc);
> }
>
>+/* The default M64 BAR is shared by all PEs */
>+static int pnv_ioda2_init_m64(struct pnv_phb *phb)
>+{
>+ const char *desc;
>+ struct resource *r;
>+ s64 rc;
>+
>+ /* Configure the default M64 BAR */
>+ rc = opal_pci_set_phb_mem_window(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ phb->ioda.m64_base,
>+ 0, /* unused */
>+ phb->ioda.m64_size);
>+ if (rc != OPAL_SUCCESS) {
>+ desc = "configuring";
>+ goto fail;
>+ }
>+
>+ /* Enable the default M64 BAR */
>+ rc = opal_pci_phb_mmio_enable(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ OPAL_ENABLE_M64_SPLIT);
>+ if (rc != OPAL_SUCCESS) {
>+ desc = "enabling";
>+ goto fail;
>+ }
>+
>+ /* Mark the M64 BAR assigned */
>+ set_bit(phb->ioda.m64_bar_idx, &phb->ioda.m64_bar_alloc);
>+
>+ /*
>+ * Strip off the segment used by the reserved PE, which is
>+ * expected to be 0 or last one of PE capabicity.
>+ */
>+ r = &phb->hose->mem_resources[1];
>+ if (phb->ioda.reserved_pe == 0)
>+ r->start += phb->ioda.m64_segsize;
>+ else if (phb->ioda.reserved_pe == (phb->ioda.total_pe - 1))
>+ r->end -= phb->ioda.m64_segsize;
>+ else
>+ pr_warn(" Cannot strip M64 segment for reserved PE#%d\n",
>+ phb->ioda.reserved_pe);
>+
>+ return 0;
>+
>+fail:
>+ pr_warn(" Failure %lld %s M64 BAR#%d\n",
>+ rc, desc, phb->ioda.m64_bar_idx);
>+ opal_pci_phb_mmio_enable(phb->opal_id,
>+ OPAL_M64_WINDOW_TYPE,
>+ phb->ioda.m64_bar_idx,
>+ OPAL_DISABLE_M64);
>+ return -EIO;
>+}
>+
>+static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb)
>+{
>+ resource_size_t sgsz = phb->ioda.m64_segsize;
>+ struct pci_dev *pdev;
>+ struct resource *r;
>+ int base, step, i;
>+
>+ /*
>+ * Root bus always has full M64 range and root port has
>+ * M64 range used in reality. So we're checking root port
>+ * instead of root bus.
>+ */
>+ list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) {
>+ for (i = PCI_BRIDGE_RESOURCES;
>+ i <= PCI_BRIDGE_RESOURCE_END; i++) {
>+ r = &pdev->resource[i];
>+ if (!r->parent ||
>+ !pnv_pci_is_mem_pref_64(r->flags))
>+ continue;
>+
>+ base = (r->start - phb->ioda.m64_base) / sgsz;
>+ for (step = 0; step < resource_size(r) / sgsz; step++)
>+ set_bit(base + step, phb->ioda.pe_alloc);
>+ }
>+ }
>+}
>+
>+static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb,
>+ struct pci_bus *bus, int all)
>+{
>+ resource_size_t segsz = phb->ioda.m64_segsize;
>+ struct pci_dev *pdev;
>+ struct resource *r;
>+ struct pnv_ioda_pe *master_pe, *pe;
>+ unsigned long size, *pe_alloc;
>+ bool found;
>+ int start, i, j;
>+
>+ /* Root bus shouldn't use M64 */
>+ if (pci_is_root_bus(bus))
>+ return IODA_INVALID_PE;
>+
>+ /* We support only one M64 window on each bus */
>+ found = false;
>+ pci_bus_for_each_resource(bus, r, i) {
>+ if (r && r->parent &&
>+ pnv_pci_is_mem_pref_64(r->flags)) {
>+ found = true;
>+ break;
>+ }
>+ }
>+
>+ /* No M64 window found ? */
>+ if (!found)
>+ return IODA_INVALID_PE;
>+
>+ /* Allocate bitmap */
>+ size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));
>+ pe_alloc = kzalloc(size, GFP_KERNEL);
>+ if (!pe_alloc) {
>+ pr_warn("%s: Out of memory !\n",
>+ __func__);
>+ return IODA_INVALID_PE;
>+ }
>+
>+ /*
>+ * Figure out reserved PE numbers by the PE
>+ * the its child PEs.
>+ */
>+ start = (r->start - phb->ioda.m64_base) / segsz;
>+ for (i = 0; i < resource_size(r) / segsz; i++)
>+ set_bit(start + i, pe_alloc);
>+
>+ if (all)
>+ goto done;
>+
>+ /*
>+ * If the PE doesn't cover all subordinate buses,
>+ * we need subtract from reserved PEs for children.
>+ */
>+ list_for_each_entry(pdev, &bus->devices, bus_list) {
>+ if (!pdev->subordinate)
>+ continue;
>+
>+ pci_bus_for_each_resource(pdev->subordinate, r, i) {
>+ if (!r || !r->parent ||
>+ !pnv_pci_is_mem_pref_64(r->flags))
>+ continue;
>+
>+ start = (r->start - phb->ioda.m64_base) / segsz;
>+ for (j = 0; j < resource_size(r) / segsz ; j++)
>+ clear_bit(start + j, pe_alloc);
>+ }
>+ }
>+
>+ /*
>+ * the current bus might not own M64 window and that's all
>+ * contributed by its child buses. For the case, we needn't
>+ * pick M64 dependent PE#.
>+ */
>+ if (bitmap_empty(pe_alloc, phb->ioda.total_pe)) {
>+ kfree(pe_alloc);
>+ return IODA_INVALID_PE;
>+ }
>+
>+ /*
>+ * Figure out the master PE and put all slave PEs to master
>+ * PE's list to form compound PE.
>+ */
>+done:
>+ master_pe = NULL;
>+ i = -1;
>+ while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) <
>+ phb->ioda.total_pe) {
>+ pe = &phb->ioda.pe_array[i];
>+ pe->phb = phb;
>+ pe->pe_number = i;
>+
>+ if (!master_pe) {
>+ pe->flags |= PNV_IODA_PE_MASTER;
>+ INIT_LIST_HEAD(&pe->slaves);
>+ master_pe = pe;
>+ } else {
>+ pe->flags |= PNV_IODA_PE_SLAVE;
>+ pe->master = master_pe;
>+ list_add_tail(&pe->list, &master_pe->slaves);
>+ }
>+ }
>+
>+ kfree(pe_alloc);
>+ return master_pe->pe_number;
>+}
>+
>+static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
>+{
>+ struct pci_controller *hose = phb->hose;
>+ struct device_node *dn = hose->dn;
>+ struct resource *res;
>+ const u32 *r;
>+ u64 pci_addr;
>+
>+ if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
>+ pr_info(" Firmware too old to support M64 window\n");
>+ return;
>+ }
>+
>+ r = of_get_property(dn, "ibm,opal-m64-window", NULL);
>+ if (!r) {
>+ pr_info(" No <ibm,opal-m64-window> on %s\n",
>+ dn->full_name);
>+ return;
>+ }
>+
>+ /* FIXME: Support M64 for P7IOC */
>+ if (phb->type != PNV_PHB_IODA2) {
>+ pr_info(" Not support M64 window\n");
>+ return;
>+ }
>+
>+ res = &hose->mem_resources[1];
>+ res->start = of_translate_address(dn, r + 2);
>+ res->end = res->start + of_read_number(r + 4, 2) - 1;
>+ res->flags = (IORESOURCE_MEM | IORESOURCE_MEM_64 | IORESOURCE_PREFETCH);
>+ pci_addr = of_read_number(r, 2);
>+ hose->mem_offset[1] = res->start - pci_addr;
>+
>+ phb->ioda.m64_size = resource_size(res);
>+ phb->ioda.m64_segsize = phb->ioda.m64_size / phb->ioda.total_pe;
>+ phb->ioda.m64_base = pci_addr;
>+
>+ /* Use last M64 BAR to cover M64 window */
>+ phb->ioda.m64_bar_idx = 15;
>+ phb->init_m64 = pnv_ioda2_init_m64;
>+ phb->alloc_m64_pe = pnv_ioda2_alloc_m64_pe;
>+ phb->pick_m64_pe = pnv_ioda2_pick_m64_pe;
>+
>+ pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx Prefetchable\n",
>+ res->start, res->end, pci_addr);
In pnv_pci_init_ioda_phb(), we have following code to print the M32
information.
pr_info(" %d (%d) PE's M32: 0x%x [segment=0x%x]"
" IO: 0x%x [segment=0x%x]\n",
phb->ioda.total_pe,
phb->ioda.reserved_pe,
phb->ioda.m32_size, phb->ioda.m32_segsize,
phb->ioda.io_size, phb->ioda.io_segsize);
Suggest to have similar one for M64.
>+}
>+
> /* Currently those 2 are only used when MSIs are enabled, this will change
> * but in the meantime, we need to protect them to avoid warnings
> */
>@@ -363,9 +607,16 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)
> struct pci_controller *hose = pci_bus_to_host(bus);
> struct pnv_phb *phb = hose->private_data;
> struct pnv_ioda_pe *pe;
>- int pe_num;
>+ int pe_num = IODA_INVALID_PE;
>+
>+ /* Check if PE is determined by M64 */
>+ if (phb->pick_m64_pe)
>+ pe_num = phb->pick_m64_pe(phb, bus, all);
>+
>+ /* The PE number isn't pinned by M64 */
>+ if (pe_num == IODA_INVALID_PE)
>+ pe_num = pnv_ioda_alloc_pe(phb);
>
>- pe_num = pnv_ioda_alloc_pe(phb);
> if (pe_num == IODA_INVALID_PE) {
> pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n",
> __func__, pci_domain_nr(bus), bus->number);
>@@ -441,8 +692,15 @@ static void pnv_ioda_setup_PEs(struct pci_bus *bus)
> static void pnv_pci_ioda_setup_PEs(void)
> {
> struct pci_controller *hose, *tmp;
>+ struct pnv_phb *phb;
>
> list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
>+ phb = hose->private_data;
>+
>+ /* M64 layout might affect PE allocation */
>+ if (phb->alloc_m64_pe)
>+ phb->alloc_m64_pe(phb);
>+
> pnv_ioda_setup_PEs(hose->bus);
> }
> }
>@@ -1055,9 +1313,6 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
> index++;
> }
> } else if (res->flags & IORESOURCE_MEM) {
>- /* WARNING: Assumes M32 is mem region 0 in PHB. We need to
>- * harden that algorithm when we start supporting M64
>- */
> region.start = res->start -
> hose->mem_offset[0] -
> phb->ioda.m32_pci_base;
>@@ -1178,7 +1433,8 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
> bridge = bridge->bus->self;
> }
>
>- /* We need support prefetchable memory window later */
>+ if (pnv_pci_is_mem_pref_64(type))
>+ return phb->ioda.m64_segsize;
> if (type & IORESOURCE_MEM)
> return phb->ioda.m32_segsize;
>
>@@ -1299,6 +1555,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL);
> if (prop32)
> phb->ioda.reserved_pe = be32_to_cpup(prop32);
>+
>+ /* Parse 64-bit MMIO range */
>+ pnv_ioda_parse_m64_window(phb);
>+
> phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
> /* FW Has already off top 64k of M32 space (MSI space) */
> phb->ioda.m32_size += 0x10000;
>@@ -1334,14 +1594,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> /* Calculate how many 32-bit TCE segments we have */
> phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28;
>
>- /* Clear unusable m64 */
>- hose->mem_resources[1].flags = 0;
>- hose->mem_resources[1].start = 0;
>- hose->mem_resources[1].end = 0;
>- hose->mem_resources[2].flags = 0;
>- hose->mem_resources[2].start = 0;
>- hose->mem_resources[2].end = 0;
>-
> #if 0 /* We should really do that ... */
> rc = opal_pci_set_phb_mem_window(opal->phb_id,
> window_type,
>@@ -1404,6 +1656,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
> ioda_eeh_phb_reset(hose, EEH_RESET_FUNDAMENTAL);
> ioda_eeh_phb_reset(hose, OPAL_DEASSERT_RESET);
> }
>+
>+ /* Configure M64 window */
>+ if (phb->init_m64 && phb->init_m64(phb))
>+ hose->mem_resources[1].flags = 0;
> }
>
> void __init pnv_pci_init_ioda2_phb(struct device_node *np)
>diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
>index 676232c..def7171 100644
>--- a/arch/powerpc/platforms/powernv/pci.h
>+++ b/arch/powerpc/platforms/powernv/pci.h
>@@ -21,6 +21,8 @@ enum pnv_phb_model {
> #define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */
> #define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */
> #define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */
>+#define PNV_IODA_PE_MASTER (1 << 3) /* Master PE in compound case */
>+#define PNV_IODA_PE_SLAVE (1 << 4) /* Slave PE in compound case */
>
> /* Data associated with a PE, including IOMMU tracking etc.. */
> struct pnv_phb;
>@@ -64,6 +66,10 @@ struct pnv_ioda_pe {
> */
> int mve_number;
>
>+ /* PEs in compound case */
>+ struct pnv_ioda_pe *master;
>+ struct list_head slaves;
>+
> /* Link in list of PE#s */
> struct list_head dma_link;
> struct list_head list;
>@@ -119,6 +125,9 @@ struct pnv_phb {
> void (*fixup_phb)(struct pci_controller *hose);
> u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
> void (*shutdown)(struct pnv_phb *phb);
>+ int (*init_m64)(struct pnv_phb *phb);
>+ void (*alloc_m64_pe)(struct pnv_phb *phb);
>+ int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
>
> union {
> struct {
>@@ -129,9 +138,20 @@ struct pnv_phb {
> /* Global bridge info */
> unsigned int total_pe;
> unsigned int reserved_pe;
>+
>+ /* 32-bit MMIO window */
> unsigned int m32_size;
> unsigned int m32_segsize;
> unsigned int m32_pci_base;
>+
>+ /* 64-bit MMIO window */
>+ unsigned int m64_bar_idx;
idx is the abbreviation of index, which will move from the beginning to the
end for some calculation. While the m64_bar_idx in your patch is set to a
fixed value to mark the last(15th) M64 BAR is used.
My suggestion is to rename it to m64_bar_num, which we may retrieve it from
firmware. Then we could use this value not only to mark the last M64 BAR, but
also could be used to track the usage of M64 BARs in later.
>+ unsigned long m64_size;
>+ unsigned long m64_segsize;
>+ unsigned long m64_base;
>+ unsigned long m64_bar_alloc;
>+
>+ /* IO ports */
> unsigned int io_size;
> unsigned int io_segsize;
> unsigned int io_pci_base;
>--
>1.8.3.1
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev
--
Richard Yang
Help you, Help me
^ permalink raw reply
* Re: Re: [PATCH v5 2/2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64
From: Michael Ellerman @ 2014-07-15 3:16 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Jeremy Fitzhardinge, linux-ia64@vger.kernel.org, sparse,
Linux Kernel Mailing List, Paul Mackerras, H. Peter Anvin,
akataria, linux-tip-commits, anil.s.keshavamurthy, Ingo Molnar,
Suzuki K. Poulose, Fenghua Yu, Arnd Bergmann, Rusty Russell,
Chris Wright, yrl.pp-manager.tt, Thomas Gleixner, Kevin Hao,
Linus Torvalds, rdunlap, Tony Luck, dl9pf, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <53C490F1.4020402@hitachi.com>
On Tue, 2014-07-15 at 11:24 +0900, Masami Hiramatsu wrote:
> (2014/07/15 11:11), Michael Ellerman wrote:
> > On Mon, 2014-07-14 at 10:17 -0700, Tony Luck wrote:
> >> On Tue, Jul 8, 2014 at 5:07 AM, Masami Hiramatsu
> >> <masami.hiramatsu.pt@hitachi.com> wrote:
> >>> Ping?
> >>>
> >>> This patch can be applied without 1/2, and will fix ia64/ppc64 problem.
> >>
> >> Is somebody going to push this upstream? Another week has gone by,
> >> we are at -rc5, and I'm still seeing the
> >>
> >> Failed to find blacklist a00000010133b150
> >>
> >> messages on ia64.
> >
> > I don't see those messages on ppc64, I don't know where the original report
> > that it was broken on ppc64 came from. So I'm a bit lukewarm on the patch.
>
> Right, on ppc64(ABIv1) it may be silently failed. Because each function
> descriptor has another entry on kallsyms, original code can't detect
> that.
OK, that would have been good to know :)
It's actually much worse than you describe. On ppc64 (ABIv1) we are
successfully blacklisting the function descriptors. But that doesn't prevent
you from probing the text address. So basically NOKPROBE_SYMBOL() does nothing
useful for us.
$ head -2 ../kprobes/blacklist
0xc000000000d4cff8-0xc000000000d4d010 notify_die
0xc000000000d4cf80-0xc000000000d4cf98 atomic_notifier_call_chain
$ echo "p:atomic_notifier_call_chain .atomic_notifier_call_chain" > kprobe_events
$ echo 1 > events/kprobes/enable
$ ls
available_events instances saved_cmdlines trace_options
available_tracers kprobe_events saved_cmdlines_size trace_pipe
buffer_size_kb kprobe_profile set_event tracing_cpumask
buffer_total_size_kb options snapshot tracing_max_latency
current_tracer per_cpu trace tracing_on
events printk_formats trace_clock tracing_thresh
free_buffer README trace_marker
$ Dumping ftrace buffer:
cpu 0x2: Vector: 400 (Instruction Access) at [c0000001defaf830]
pc: 0000000000000000
lr: 0000000000000001
sp: c0000001defafab0
msr: 8000000140009032
current = 0xc0000001def57e40
paca = 0xc00000000fe00800 softe: 0 irq_happened: 0x01
pid = 1, comm = swapper/2
cpu 0x3: Vector: 400 (Instruction Access) at [c0000001ddbcc640]
pc: 0000000000000000
lr: 0000000000000000
sp: c0000001ddbcc8c0
msr: 8000000040001032
current = 0xc0000001def5a100
paca = 0xc00000000fe00c00 softe: 0 irq_happened: 0x01
pid = -554326528, comm =
Dead machine.
With your patch:
$ head -2 kprobes/blacklist
0xc0000000000bf860-0xc0000000000bf8b0 .notify_die
0xc0000000000bf750-0xc0000000000bf780 .atomic_notifier_call_chain
$ echo "p:notify_die .notify_die" > tracing/kprobe_events
-bash: echo: write error: Invalid argument
So that is much better.
cheers
^ permalink raw reply
* Re: [PATCH v5 2/2] [BUGFIX] kprobes: Fix "Failed to find blacklist" error on ia64 and ppc64
From: Michael Ellerman @ 2014-07-15 3:19 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Jeremy Fitzhardinge, linux-ia64, sparse,
Linux Kernel Mailing List, Paul Mackerras, H. Peter Anvin,
akataria, linux-tip-commits, anil.s.keshavamurthy, Ingo Molnar,
Suzuki K. Poulose, Fenghua Yu, Arnd Bergmann, Rusty Russell,
Chris Wright, yrl.pp-manager.tt, Thomas Gleixner, Tony Luck,
Kevin Hao, Linus Torvalds, rdunlap, Tony Luck, dl9pf,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20140702070029.14689.18485.stgit@kbuild-fedora.novalocal>
On Wed, 2014-07-02 at 07:00 +0000, Masami Hiramatsu wrote:
> On ia64 and ppc64, the function pointer does not point the
> entry address of the function, but the address of function
> discriptor (which contains the entry address and misc
> data.) Since the kprobes passes the function pointer stored
> by NOKPROBE_SYMBOL() to kallsyms_lookup_size_offset() for
> initalizing its blacklist, it fails and reports many errors
> as below.
>
> Failed to find blacklist 0001013168300000
> Failed to find blacklist 0001013000f0a000
> Failed to find blacklist 000101315f70a000
> Failed to find blacklist 000101324c80a000
> Failed to find blacklist 0001013063f0a000
> Failed to find blacklist 000101327800a000
> Failed to find blacklist 0001013277f0a000
> Failed to find blacklist 000101315a70a000
> Failed to find blacklist 0001013277e0a000
> Failed to find blacklist 000101305a20a000
> Failed to find blacklist 0001013277d0a000
> Failed to find blacklist 00010130bdc0a000
> Failed to find blacklist 00010130dc20a000
> Failed to find blacklist 000101309a00a000
> Failed to find blacklist 0001013277c0a000
> Failed to find blacklist 0001013277b0a000
> Failed to find blacklist 0001013277a0a000
> Failed to find blacklist 000101327790a000
> Failed to find blacklist 000101303140a000
> Failed to find blacklist 0001013a3280a000
>
> To fix this bug, this introduces function_entry() macro to
> retrieve the entry address from the given function pointer,
> and uses for kallsyms_lookup_size_offset() while initializing
> blacklist.
>
> Changes in v5:
> - Use arch_deref_entry_point() instead of function_entry().
>
> Changes in v4:
> - Add kernel_text_address() check for verifying the address.
> - Moved on the latest linus tree.
>
> Changes in v3:
> - Fix a bug to get blacklist address based on function entry
> instead of function descriptor. (Suzuki's work, Thanks!)
>
> Changes in V2:
> - Use function_entry() macro when lookin up symbols instead
> of storing it.
> - Update for the latest -next.
>
> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Reported-by: Tony Luck <tony.luck@gmail.com>
> Tested-by: Tony Luck <tony.luck@intel.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
Tested-by: Michael Ellerman <mpe@ellerman.id.au>
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (for powerpc)
Ben, can you take this in your tree?
cheers
^ permalink raw reply
* Re: [PATCH v2] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Gavin Shan @ 2014-07-15 5:07 UTC (permalink / raw)
To: Mike Qiu; +Cc: benh, linuxppc-dev, gwshan
In-Reply-To: <1405391628-1680-1-git-send-email-qiudayu@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 3311 bytes --]
On Mon, Jul 14, 2014 at 10:33:48PM -0400, Mike Qiu wrote:
>pci_get_slot() is called with hold of PCI bus semaphore and it's not
>safe to be called in interrupt context. However, we possibly checks
>EEH error and calls the function in interrupt context. To avoid using
>pci_get_slot(), we turn into device tree for fetching location code.
>Otherwise, we might run into WARN_ON() as following messages indicate:
>
> WARNING: at drivers/pci/search.c:223
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
> task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
> NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
> REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
> MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
> CFAR: c00000000003752c SOFTE: 0
> :
> NIP [c000000000497b70] .pci_get_slot+0x40/0x110
> LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
> Call Trace:
> .of_get_property+0x30/0x60 (unreliable)
> .eeh_pe_loc_get+0x150/0x190
> .eeh_dev_check_failure+0x1b4/0x550
> .eeh_check_failure+0x90/0xf0
> .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
> .lpfc_poll_eratt+0x64/0x100 [lpfc]
> .call_timer_fn+0x64/0x190
> .run_timer_softirq+0x2cc/0x3e0
>
>Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>---
> Changelog[v2]:
> Check the child device_node of root bus for root port
> directly instead of search pdev from device-tree and
> then translate it to device-node
>
I run into following warning with your patch. Please test the attached
one. If no problem found, send that one please.
arch/powerpc/kernel/eeh_pe.c: In function 'eeh_pe_loc_get':
arch/powerpc/kernel/eeh_pe.c:806:18: warning: unused variable 'pdev'
Thanks,
Gavin
> arch/powerpc/kernel/eeh_pe.c | 24 ++++++------------------
> 1 file changed, 6 insertions(+), 18 deletions(-)
>
>diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
>index fbd01eb..f96c10f 100644
>--- a/arch/powerpc/kernel/eeh_pe.c
>+++ b/arch/powerpc/kernel/eeh_pe.c
>@@ -802,7 +802,6 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
> */
> const char *eeh_pe_loc_get(struct eeh_pe *pe)
> {
>- struct pci_controller *hose;
> struct pci_bus *bus = eeh_pe_bus_get(pe);
> struct pci_dev *pdev;
> struct device_node *dn;
>@@ -811,29 +810,20 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
> if (!bus)
> return "N/A";
>
>+ dn = pci_bus_to_OF_node(bus);
> /* PHB PE or root PE ? */
>- if (pci_is_root_bus(bus)) {
>- hose = pci_bus_to_host(bus);
>- loc = of_get_property(hose->dn,
>- "ibm,loc-code", NULL);
>+ if (dn && pci_is_root_bus(bus)) {
>+ loc = of_get_property(dn, "ibm,loc-code", NULL);
> if (loc)
> return loc;
>- loc = of_get_property(hose->dn,
>- "ibm,io-base-loc-code", NULL);
>+ loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
> if (loc)
> return loc;
>
>- pdev = pci_get_slot(bus, 0x0);
>- } else {
>- pdev = bus->self;
>- }
>-
>- if (!pdev) {
>- loc = "N/A";
>- goto out;
>+ /* Check the root port */
>+ dn = dn->child;
> }
>
>- dn = pci_device_to_OF_node(pdev);
> if (!dn) {
> loc = "N/A";
> goto out;
>@@ -846,8 +836,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
> loc = "N/A";
>
> out:
>- if (pci_is_root_bus(bus) && pdev)
>- pci_dev_put(pdev);
> return loc;
> }
>
>--
>1.8.1.4
>
[-- Attachment #2: 0001-powerpc-eeh-Wrong-place-to-call-pci_get_slot.patch --]
[-- Type: text/x-diff, Size: 3199 bytes --]
>From 14e45dbe5cd8732ad824f66d576e3642ec338f76 Mon Sep 17 00:00:00 2001
From: Mike Qiu <qiudayu@linux.vnet.ibm.com>
Date: Mon, 14 Jul 2014 22:33:48 -0400
Subject: [PATCH] powerpc/eeh: Wrong place to call pci_get_slot()
pci_get_slot() is called with hold of PCI bus semaphore and it's not
safe to be called in interrupt context. However, we possibly checks
EEH error and calls the function in interrupt context. To avoid using
pci_get_slot(), we turn into device tree for fetching location code.
Otherwise, we might run into WARN_ON() as following messages indicate:
WARNING: at drivers/pci/search.c:223
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
CFAR: c00000000003752c SOFTE: 0
:
NIP [c000000000497b70] .pci_get_slot+0x40/0x110
LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
Call Trace:
.of_get_property+0x30/0x60 (unreliable)
.eeh_pe_loc_get+0x150/0x190
.eeh_dev_check_failure+0x1b4/0x550
.eeh_check_failure+0x90/0xf0
.lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
.lpfc_poll_eratt+0x64/0x100 [lpfc]
.call_timer_fn+0x64/0x190
.run_timer_softirq+0x2cc/0x3e0
Cc: Stable@vger.kernel.org
Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
Acked-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/kernel/eeh_pe.c | 45 +++++++++++++-------------------------------
1 file changed, 13 insertions(+), 32 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eb..920c9dc 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -802,53 +802,34 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
*/
const char *eeh_pe_loc_get(struct eeh_pe *pe)
{
- struct pci_controller *hose;
struct pci_bus *bus = eeh_pe_bus_get(pe);
- struct pci_dev *pdev;
struct device_node *dn;
- const char *loc;
+ const char *loc = NULL;
- if (!bus)
- return "N/A";
+ dn = bus ? pci_bus_to_OF_node(bus) : NULL;
+ if (!dn)
+ goto out;
/* PHB PE or root PE ? */
if (pci_is_root_bus(bus)) {
- hose = pci_bus_to_host(bus);
- loc = of_get_property(hose->dn,
- "ibm,loc-code", NULL);
+ loc = of_get_property(dn, "ibm,loc-code", NULL);
+ if (!loc)
+ loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
if (loc)
- return loc;
- loc = of_get_property(hose->dn,
- "ibm,io-base-loc-code", NULL);
- if (loc)
- return loc;
-
- pdev = pci_get_slot(bus, 0x0);
- } else {
- pdev = bus->self;
- }
-
- if (!pdev) {
- loc = "N/A";
- goto out;
- }
+ goto out;
- dn = pci_device_to_OF_node(pdev);
- if (!dn) {
- loc = "N/A";
- goto out;
+ /* Check the root port */
+ dn = dn->child;
+ if (!dn)
+ goto out;
}
loc = of_get_property(dn, "ibm,loc-code", NULL);
if (!loc)
loc = of_get_property(dn, "ibm,slot-location-code", NULL);
- if (!loc)
- loc = "N/A";
out:
- if (pci_is_root_bus(bus) && pdev)
- pci_dev_put(pdev);
- return loc;
+ return loc ? loc : "N/A";
}
/**
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2] Bugfix: powerpc/eeh: Wrong place to call pci_get_slot()
From: Mike Qiu @ 2014-07-15 5:15 UTC (permalink / raw)
To: Gavin Shan; +Cc: benh, linuxppc-dev
In-Reply-To: <20140715050707.GA17089@shangw>
On 07/15/2014 01:07 PM, Gavin Shan wrote:
> On Mon, Jul 14, 2014 at 10:33:48PM -0400, Mike Qiu wrote:
>> pci_get_slot() is called with hold of PCI bus semaphore and it's not
>> safe to be called in interrupt context. However, we possibly checks
>> EEH error and calls the function in interrupt context. To avoid using
>> pci_get_slot(), we turn into device tree for fetching location code.
>> Otherwise, we might run into WARN_ON() as following messages indicate:
>>
>> WARNING: at drivers/pci/search.c:223
>> CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
>> task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
>> NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
>> REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
>> MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
>> CFAR: c00000000003752c SOFTE: 0
>> :
>> NIP [c000000000497b70] .pci_get_slot+0x40/0x110
>> LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
>> Call Trace:
>> .of_get_property+0x30/0x60 (unreliable)
>> .eeh_pe_loc_get+0x150/0x190
>> .eeh_dev_check_failure+0x1b4/0x550
>> .eeh_check_failure+0x90/0xf0
>> .lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
>> .lpfc_poll_eratt+0x64/0x100 [lpfc]
>> .call_timer_fn+0x64/0x190
>> .run_timer_softirq+0x2cc/0x3e0
>>
>> Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>> ---
>> Changelog[v2]:
>> Check the child device_node of root bus for root port
>> directly instead of search pdev from device-tree and
>> then translate it to device-node
>>
> I run into following warning with your patch. Please test the attached
> one. If no problem found, send that one please.
>
> arch/powerpc/kernel/eeh_pe.c: In function 'eeh_pe_loc_get':
> arch/powerpc/kernel/eeh_pe.c:806:18: warning: unused variable 'pdev'
OK, I will remove unused variable.
Thanks,
Mike
> Thanks,
> Gavin
>
>> arch/powerpc/kernel/eeh_pe.c | 24 ++++++------------------
>> 1 file changed, 6 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
>> index fbd01eb..f96c10f 100644
>> --- a/arch/powerpc/kernel/eeh_pe.c
>> +++ b/arch/powerpc/kernel/eeh_pe.c
>> @@ -802,7 +802,6 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
>> */
>> const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> {
>> - struct pci_controller *hose;
>> struct pci_bus *bus = eeh_pe_bus_get(pe);
>> struct pci_dev *pdev;
>> struct device_node *dn;
>> @@ -811,29 +810,20 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> if (!bus)
>> return "N/A";
>>
>> + dn = pci_bus_to_OF_node(bus);
>> /* PHB PE or root PE ? */
>> - if (pci_is_root_bus(bus)) {
>> - hose = pci_bus_to_host(bus);
>> - loc = of_get_property(hose->dn,
>> - "ibm,loc-code", NULL);
>> + if (dn && pci_is_root_bus(bus)) {
>> + loc = of_get_property(dn, "ibm,loc-code", NULL);
>> if (loc)
>> return loc;
>> - loc = of_get_property(hose->dn,
>> - "ibm,io-base-loc-code", NULL);
>> + loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
>> if (loc)
>> return loc;
>>
>> - pdev = pci_get_slot(bus, 0x0);
>> - } else {
>> - pdev = bus->self;
>> - }
>> -
>> - if (!pdev) {
>> - loc = "N/A";
>> - goto out;
>> + /* Check the root port */
>> + dn = dn->child;
>> }
>>
>> - dn = pci_device_to_OF_node(pdev);
>> if (!dn) {
>> loc = "N/A";
>> goto out;
>> @@ -846,8 +836,6 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
>> loc = "N/A";
>>
>> out:
>> - if (pci_is_root_bus(bus) && pdev)
>> - pci_dev_put(pdev);
>> return loc;
>> }
>>
>> --
>> 1.8.1.4
>>
^ permalink raw reply
* [PATCH v3] powerpc/eeh: Wrong place to call pci_get_slot()
From: Mike Qiu @ 2014-07-15 5:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: benh, Mike Qiu, gwshan, Stable
pci_get_slot() is called with hold of PCI bus semaphore and it's not
safe to be called in interrupt context. However, we possibly checks
EEH error and calls the function in interrupt context. To avoid using
pci_get_slot(), we turn into device tree for fetching location code.
Otherwise, we might run into WARN_ON() as following messages indicate:
WARNING: at drivers/pci/search.c:223
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.16.0-rc3+ #72
task: c000000001367af0 ti: c000000001444000 task.ti: c000000001444000
NIP: c000000000497b70 LR: c000000000037530 CTR: 000000003003d114
REGS: c000000001446fa0 TRAP: 0700 Not tainted (3.16.0-rc3+)
MSR: 9000000000029032 <SF,HV,EE,ME,IR,DR,RI> CR: 48002422 XER: 20000000
CFAR: c00000000003752c SOFTE: 0
:
NIP [c000000000497b70] .pci_get_slot+0x40/0x110
LR [c000000000037530] .eeh_pe_loc_get+0x150/0x190
Call Trace:
.of_get_property+0x30/0x60 (unreliable)
.eeh_pe_loc_get+0x150/0x190
.eeh_dev_check_failure+0x1b4/0x550
.eeh_check_failure+0x90/0xf0
.lpfc_sli_check_eratt+0x504/0x7c0 [lpfc]
.lpfc_poll_eratt+0x64/0x100 [lpfc]
.call_timer_fn+0x64/0x190
.run_timer_softirq+0x2cc/0x3e0
Cc: Stable@vger.kernel.org
Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
Acked-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
Changelog[v3]:
Remove unused variables
Code refactoring for eeh_pe_loc_get()
Changelog[v2]:
Check the child device_node of root bus for root port
directly instead of search pdev from device-tree and
then translate it to device-node
arch/powerpc/kernel/eeh_pe.c | 46 +++++++++++++-------------------------------
1 file changed, 13 insertions(+), 33 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index fbd01eb..94802d2 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -802,53 +802,33 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
*/
const char *eeh_pe_loc_get(struct eeh_pe *pe)
{
- struct pci_controller *hose;
struct pci_bus *bus = eeh_pe_bus_get(pe);
- struct pci_dev *pdev;
- struct device_node *dn;
- const char *loc;
+ struct device_node *dn = pci_bus_to_OF_node(bus);
+ const char *loc = NULL;
- if (!bus)
- return "N/A";
+ if (!dn)
+ goto out;
/* PHB PE or root PE ? */
if (pci_is_root_bus(bus)) {
- hose = pci_bus_to_host(bus);
- loc = of_get_property(hose->dn,
- "ibm,loc-code", NULL);
- if (loc)
- return loc;
- loc = of_get_property(hose->dn,
- "ibm,io-base-loc-code", NULL);
+ loc = of_get_property(dn, "ibm,loc-code", NULL);
+ if (!loc)
+ loc = of_get_property(dn, "ibm,io-base-loc-code", NULL);
if (loc)
- return loc;
-
- pdev = pci_get_slot(bus, 0x0);
- } else {
- pdev = bus->self;
- }
-
- if (!pdev) {
- loc = "N/A";
- goto out;
- }
+ goto out;
- dn = pci_device_to_OF_node(pdev);
- if (!dn) {
- loc = "N/A";
- goto out;
+ /* Check the root port */
+ dn = dn->child;
+ if (!dn)
+ goto out;
}
loc = of_get_property(dn, "ibm,loc-code", NULL);
if (!loc)
loc = of_get_property(dn, "ibm,slot-location-code", NULL);
- if (!loc)
- loc = "N/A";
out:
- if (pci_is_root_bus(bus) && pdev)
- pci_dev_put(pdev);
- return loc;
+ return loc ? loc : "N/A";
}
/**
--
1.8.1.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox