[PATCH] powerpc: Add macros for the ibm_architecture_vec[] lengths

2014-08-29 Thread Michael Ellerman
The encoding of the lengths in the ibm_architecture_vec array is
interesting to say the least. It's non-obvious how the number of bytes
we provide relates to the length value.

In fact we already got it wrong once, see 11e9ed43ca8a Fix up
ibm_architecture_vec definition.

So add some macros to make it (hopefully) clearer. These at least have
the property that the integer present in the code is equal to the number
of bytes that follows it.

Signed-off-by: Michael Ellerman m...@ellerman.id.au
---
 arch/powerpc/kernel/prom_init.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 1a85d8f96739..962ac852ce0b 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -642,6 +642,15 @@ static void __init early_cmdline_parse(void)
 #define W(x)   ((x)  24)  0xff, ((x)  16)  0xff, \
((x)  8)  0xff, (x)  0xff
 
+/* Firmware expects the value to be n - 1, where n is the # of vectors */
+#define NUM_VECTORS(n) ((n) - 1)
+
+/*
+ * Firmware expects 1 + n - 2, where n is the length of the option vector in
+ * bytes. The 1 accounts for the length byte itself, the - 2 .. ?
+ */
+#define VECTOR_LENGTH(n)   (1 + (n) - 2)
+
 unsigned char ibm_architecture_vec[] = {
W(0xfffe), W(0x003a),   /* POWER5/POWER5+ */
W(0x), W(0x003e),   /* POWER6 */
@@ -652,16 +661,16 @@ unsigned char ibm_architecture_vec[] = {
W(0x), W(0x0f03),   /* all 2.06-compliant */
W(0x), W(0x0f02),   /* all 2.05-compliant */
W(0xfffe), W(0x0f01),   /* all 2.04-compliant and earlier */
-   6 - 1,  /* 6 option vectors */
+   NUM_VECTORS(6), /* 6 option vectors */
 
/* option vector 1: processor architectures supported */
-   3 - 2,  /* length */
+   VECTOR_LENGTH(2),   /* length */
0,  /* don't ignore, don't halt */
OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
 
/* option vector 2: Open Firmware options supported */
-   34 - 2, /* length */
+   VECTOR_LENGTH(33),  /* length */
OV2_REAL_MODE,
0, 0,
W(0x),  /* real_base */
@@ -675,17 +684,17 @@ unsigned char ibm_architecture_vec[] = {
48, /* max log_2(hash table size) */
 
/* option vector 3: processor options supported */
-   3 - 2,  /* length */
+   VECTOR_LENGTH(2),   /* length */
0,  /* don't ignore, don't halt */
OV3_FP | OV3_VMX | OV3_DFP,
 
/* option vector 4: IBM PAPR implementation */
-   3 - 2,  /* length */
+   VECTOR_LENGTH(2),   /* length */
0,  /* don't halt */
OV4_MIN_ENT_CAP,/* minimum VP entitled capacity */
 
/* option vector 5: PAPR/OF options */
-   19 - 2, /* length */
+   VECTOR_LENGTH(18),  /* length */
0,  /* don't ignore, don't halt */
OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |
OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) |
@@ -718,12 +727,12 @@ unsigned char ibm_architecture_vec[] = {
OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) |
OV5_FEAT(OV5_PFO_HW_842),
OV5_FEAT(OV5_SUB_PROCESSORS),
+
/* option vector 6: IBM PAPR hints */
-   4 - 2,  /* length */
+   VECTOR_LENGTH(3),   /* length */
0,
0,
OV6_LINUX,
-
 };
 
 /* Old method - ELF header with PT_NOTE sections only works on BE */
-- 
1.9.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] drivers: char: hw_random: printk replacement

2014-08-29 Thread Michael Ellerman
On Thu, 2014-08-28 at 20:32 +0530, Sudip Mukherjee wrote:
 as pr_* macros are more preffered over printk, so printk replaced with 
 corresponding pr_* macros
 
I suppose ...

  drivers/char/hw_random/pasemi-rng.c  |  2 +-
  drivers/char/hw_random/pseries-rng.c |  2 +-

These look OK to me.

cheers


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH] powerpc/eeh: Clear frozen device state in time

2014-08-29 Thread Gavin Shan
The problem was reported by Carol: In the scenario of passing mlx4
adapter to guest, EEH error could be recovered successfully. When
returning the device back to host, the driver (mlx4_core.ko)
couldn't be loaded successfully because of error number -5 (-EIO)
returned from mlx4_get_ownership(), which hits offlined PCI device.
The root cause is that we missed to put the affected devices into
normal state on clearing PE isolated state right after PE reset.

The patch fixes above issue by putting the affected devices to
normal state when clearing PE isolated state in eeh_pe_state_clear().

Cc: sta...@vger.kernel.org
Reported-by: Carol L. Soto cls...@us.ibm.com
Signed-off-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/kernel/eeh_pe.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 00e3844..eef08f0 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -584,6 +584,8 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
 {
struct eeh_pe *pe = (struct eeh_pe *)data;
int state = *((int *)flag);
+   struct eeh_dev *edev, *tmp;
+   struct pci_dev *pdev;
 
/* Keep the state of permanently removed PE intact */
if ((pe-freeze_count  EEH_MAX_ALLOWED_FREEZES) 
@@ -592,9 +594,22 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
 
pe-state = ~state;
 
-   /* Clear check count since last isolation */
-   if (state  EEH_PE_ISOLATED)
-   pe-check_count = 0;
+   /*
+* Special treatment on clearing isolated state. Clear
+* check count since last isolation and put all affected
+* devices to normal state.
+*/
+   if (!(state  EEH_PE_ISOLATED))
+   return NULL;
+
+   pe-check_count = 0;
+   eeh_pe_for_each_dev(pe, edev, tmp) {
+   pdev = eeh_dev_to_pci_dev(edev);
+   if (!pdev)
+   continue;
+
+   pdev-error_state = pci_channel_io_normal;
+   }
 
return NULL;
 }
-- 
1.8.3.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

RE: [RESEND] clk: ppc-corenet: Add Freescale ARM-based platforms CLK_OF_DECLARE support

2014-08-29 Thread Jingchang Lu
-Original Message-
From: Wood Scott-B07421
Sent: Friday, August 29, 2014 12:26 AM
To: Lu Jingchang-B35083
Cc: mturque...@linaro.org; linuxppc-dev@lists.ozlabs.org; linux-
ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
Subject: Re: [RESEND] clk: ppc-corenet: Add Freescale ARM-based platforms
CLK_OF_DECLARE support

On Thu, 2014-08-28 at 05:05 -0500, Lu Jingchang-B35083 wrote:
 -Original Message-
 From: Wood Scott-B07421
 Sent: Thursday, August 28, 2014 7:34 AM
 To: Lu Jingchang-B35083
 Cc: mturque...@linaro.org; linuxppc-dev@lists.ozlabs.org; linux-
 ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
 Subject: Re: [RESEND] clk: ppc-corenet: Add Freescale ARM-based
 platforms CLK_OF_DECLARE support
 
 On Tue, 2014-08-26 at 21:19 -0500, Lu Jingchang-B35083 wrote:
  -Original Message-
  From: Wood Scott-B07421
  Sent: Wednesday, August 27, 2014 6:51 AM
  To: Lu Jingchang-B35083
  Cc: mturque...@linaro.org; linuxppc-dev@lists.ozlabs.org; linux-
  ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org
  Subject: Re: [RESEND] clk: ppc-corenet: Add Freescale ARM-based
  platforms CLK_OF_DECLARE support
  
  On Fri, 2014-08-22 at 17:34 +0800, Jingchang Lu wrote:
   +CLK_OF_DECLARE(ppc_core_pll_v1, fsl,qoriq-core-pll-1.0,
  core_pll_init);
   +CLK_OF_DECLARE(ppc_core_pll_v2, fsl,qoriq-core-pll-2.0,
  core_pll_init);
   +CLK_OF_DECLARE(ppc_core_mux_v1, fsl,qoriq-core-mux-1.0,
  core_mux_init);
   +CLK_OF_DECLARE(ppc_core_mux_v2, fsl,qoriq-core-mux-2.0,
  core_mux_init);
  
  What does this do that the existing platform driver and match
  table don't?  Why is it needed for ARM when PPC didn't need it?
  
  -Scott
  
  Common clk init on ARM platform is initialized earlier via
  of_clk_init() instead of driver probe method, the of_clk_init will
  walk a __clk_of_table to init each clk provider in the table, the
  CLK_OF_DECLARE() macro puts a supported clk in the __clk_of_table
  for it
 initializing on starup, and the clk system has added some common clk
 such as fixed-clk
  to this table already.
  So here I add our specific clk init declaration to consist this
  framework, and the driver probe function will not be needed on ARM.
 
 OK... Is there any reason why the new method won't work on PPC?
 
 PPC has little dependence on the clock tree but frequency, it will
 work well if adopted I think.

I'm just saying it seems redundant to have both.  Even on ARM, won't this
result in the clock getting registered twice (albeit with one of those
times being too late)?

Regardless of what dependence PPC has on the clock tree, what stops this
method of enumeration from working on PPC?  Is there anything required
other than inserting a call to of_clk_init(NULL) in the arch init code?

-Scott

The of_clk_init is an alternative way to the legacy driver. 
Latest ARM standard support a default call to of_clk_init(NULL) in its 
time_init().
So this is the general way for ARM-based platform.
The clk register layer can detect the twice registration of a same clk and
avoid the duplicate registration. The dtb should select the compatible for 
either,
but not both. On LS1021A the driver probe method will not be triggered.
And for support of of_clk_init on PPC, I think just add a call to it as ARM do
in time_init()[arch/arm/kernel/time.c] would be ok.



Best Regards,
Jingchang





___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 00/13] powerpc/iommu/vfio: Enable Dynamic DMA windows

2014-08-29 Thread Alexey Kardashevskiy
This enables PAPR defined feature called Dynamic DMA windows (DDW).

Each Partitionable Endpoint (IOMMU group) has a separate DMA window on
a PCI bus where devices are allows to perform DMA. By default there is
1 or 2GB window allocated at the host boot time and these windows are
used when an IOMMU group is passed to the userspace (guest). These windows
are mapped at zero offset on a PCI bus.

Hi-speed devices may suffer from limited size of this window. On the host
side a TCE bypass mode is enabled on POWER8 CPU which implements
direct mapping of the host memory to a PCI bus at 159.

For the guest, PAPR defines a DDW RTAS API which allows the pseries guest
to query the hypervisor if it supports DDW and what are the parameters
of possible windows.

Currently POWER8 supports 2 DMA windows per PE - already mentioned and used
small 32bit window and 64bit window which can only start from 159 and
can support various page sizes.

This patchset reworks PPC IOMMU code and adds necessary structures
to extend it to support big windows.

When the guest detectes the feature and the PE is capable of 64bit DMA,
it does:
1. query to hypervisor about number of available windows and page masks;
2. creates a window with the biggest possible page size (current guests can do
64K or 16MB TCEs);
3. maps the entire guest RAM via H_PUT_TCE* hypercalls
4. switches dma_ops to direct_dma_ops on the selected PE.

Once this is done, H_PUT_TCE is not called anymore and the guest gets
maximum performance.


Please comment. Thanks!


Alexey Kardashevskiy (13):
  powerpc/iommu: Check that TCE page size is equal to it_page_size
  powerpc/powernv: Make invalidate() a callback
  powerpc/spapr: vfio: Implement spapr_tce_iommu_ops
  powerpc/powernv: Convert/move set_bypass() callback to
take_ownership()
  powerpc/iommu: Fix IOMMU ownership control functions
  powerpc/iommu: Move tce_xxx callbacks from ppc_md to iommu_table
  powerpc/powernv: Do not set read flag if direction==DMA_NONE
  powerpc/powernv: Release replaced TCE
  powerpc/pseries/lpar: Enable VFIO
  powerpc/powernv: Implement Dynamic DMA windows (DDW) for IODA
  vfio: powerpc/spapr: Move locked_vm accounting to helpers
  vfio: powerpc/spapr: Use it_page_size
  vfio: powerpc/spapr: Enable Dynamic DMA windows

 arch/powerpc/include/asm/iommu.h|  35 ++-
 arch/powerpc/include/asm/machdep.h  |  25 --
 arch/powerpc/include/asm/tce.h  |  37 +++
 arch/powerpc/kernel/iommu.c | 213 +--
 arch/powerpc/kernel/vio.c   |   5 +-
 arch/powerpc/platforms/cell/iommu.c |   9 +-
 arch/powerpc/platforms/pasemi/iommu.c   |   8 +-
 arch/powerpc/platforms/powernv/pci-ioda.c   | 233 +++--
 arch/powerpc/platforms/powernv/pci-p5ioc2.c |   4 +-
 arch/powerpc/platforms/powernv/pci.c| 113 +---
 arch/powerpc/platforms/powernv/pci.h|  15 +-
 arch/powerpc/platforms/pseries/iommu.c  |  77 --
 arch/powerpc/sysdev/dart_iommu.c|  13 +-
 drivers/vfio/vfio_iommu_spapr_tce.c | 384 +++-
 include/uapi/linux/vfio.h   |  25 +-
 15 files changed, 925 insertions(+), 271 deletions(-)

-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 01/13] powerpc/iommu: Check that TCE page size is equal to it_page_size

2014-08-29 Thread Alexey Kardashevskiy
This checks that the TCE table page size is not bigger that the size of
a page we just pinned and going to put its physical address to the table.

Otherwise the hardware gets unwanted access to physical memory between
the end of the actual page and the end of the aligned up TCE page.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/kernel/iommu.c | 28 +---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index a10642a..b378f78 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -38,6 +38,7 @@
 #include linux/pci.h
 #include linux/iommu.h
 #include linux/sched.h
+#include linux/hugetlb.h
 #include asm/io.h
 #include asm/prom.h
 #include asm/iommu.h
@@ -1059,16 +1060,37 @@ int iommu_put_tce_user_mode(struct iommu_table *tbl, 
unsigned long entry,
tce, entry  tbl-it_page_shift, ret); */
return -EFAULT;
}
+
+   /*
+* Check that the TCE table granularity is not bigger than the size of
+* a page we just found. Otherwise the hardware can get access to
+* a bigger memory chunk that it should.
+*/
+   if (PageHuge(page)) {
+   struct page *head = compound_head(page);
+   long shift = PAGE_SHIFT + compound_order(head);
+
+   if (shift  tbl-it_page_shift) {
+   ret = -EINVAL;
+   goto put_page_exit;
+   }
+
+   }
+
hwaddr = (unsigned long) page_address(page) + offset;
 
ret = iommu_tce_build(tbl, entry, hwaddr, direction);
if (ret)
-   put_page(page);
+   goto put_page_exit;
 
-   if (ret  0)
-   pr_err(iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%d\n,
+   return 0;
+
+put_page_exit:
+   pr_err(iommu_tce: %s failed ioba=%lx, tce=%lx, ret=%d\n,
__func__, entry  tbl-it_page_shift, tce, ret);
 
+   put_page(page);
+
return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_put_tce_user_mode);
-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 04/13] powerpc/powernv: Convert/move set_bypass() callback to take_ownership()

2014-08-29 Thread Alexey Kardashevskiy
At the moment the iommu_table struct has a set_bypass() which enables/
disables DMA bypass on IODA2 PHB. This is exposed to POWERPC IOMMU code
which calls this callback when external IOMMU users such as VFIO are
about to get over a PHB.

Since the set_bypass() is not really an iommu_table function but PE's
function, and we have an ops struct per IOMMU owner, let's move
set_bypass() to the spapr_tce_iommu_ops struct.

As arch/powerpc/kernel/iommu.c is more about POWERPC IOMMU tables and
has very little to do with PEs, this moves take_ownership() calls to
the VFIO SPAPR TCE driver.

This renames set_bypass() to take_ownership() as it is not necessarily
just enabling bypassing, it can be something else/more so let's give it
a generic name. The bool parameter is inverted.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Reviewed-by: Gavin Shan gws...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/iommu.h  |  1 -
 arch/powerpc/include/asm/tce.h|  2 ++
 arch/powerpc/kernel/iommu.c   | 12 
 arch/powerpc/platforms/powernv/pci-ioda.c | 20 
 drivers/vfio/vfio_iommu_spapr_tce.c   | 16 
 5 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 84ee339..2b0b01d 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -77,7 +77,6 @@ struct iommu_table {
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
-   void (*set_bypass)(struct iommu_table *tbl, bool enable);
 };
 
 /* Pure 2^n version of get_order */
diff --git a/arch/powerpc/include/asm/tce.h b/arch/powerpc/include/asm/tce.h
index 9f159eb..e6355f9 100644
--- a/arch/powerpc/include/asm/tce.h
+++ b/arch/powerpc/include/asm/tce.h
@@ -56,6 +56,8 @@ struct spapr_tce_iommu_ops {
struct iommu_table *(*get_table)(
struct spapr_tce_iommu_group *data,
int num);
+   void (*take_ownership)(struct spapr_tce_iommu_group *data,
+   bool enable);
 };
 
 struct spapr_tce_iommu_group {
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 1c5dae7..c2c8d9d 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1139,14 +1139,6 @@ int iommu_take_ownership(struct iommu_table *tbl)
memset(tbl-it_map, 0xff, sz);
iommu_clear_tces_and_put_pages(tbl, tbl-it_offset, tbl-it_size);
 
-   /*
-* Disable iommu bypass, otherwise the user can DMA to all of
-* our physical memory via the bypass window instead of just
-* the pages that has been explicitly mapped into the iommu
-*/
-   if (tbl-set_bypass)
-   tbl-set_bypass(tbl, false);
-
return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_take_ownership);
@@ -1161,10 +1153,6 @@ void iommu_release_ownership(struct iommu_table *tbl)
/* Restore bit#0 set by iommu_init_table() */
if (tbl-it_offset == 0)
set_bit(0, tbl-it_map);
-
-   /* The kernel owns the device now, we can restore the iommu bypass */
-   if (tbl-set_bypass)
-   tbl-set_bypass(tbl, true);
 }
 EXPORT_SYMBOL_GPL(iommu_release_ownership);
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 2d32a1c..8cb2f31 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1105,10 +1105,8 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb 
*phb,
__free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
 }
 
-static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
+static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable)
 {
-   struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
- tce32.table);
uint16_t window_id = (pe-pe_number  1 ) + 1;
int64_t rc;
 
@@ -1136,7 +1134,7 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table 
*tbl, bool enable)
 * host side.
 */
if (pe-pdev)
-   set_iommu_table_base(pe-pdev-dev, tbl);
+   set_iommu_table_base(pe-pdev-dev, pe-tce32.table);
else
pnv_ioda_setup_bus_dma(pe, pe-pbus, false);
}
@@ -1152,15 +1150,21 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct 
pnv_phb *phb,
/* TVE #1 is selected by PCI address bit 59 */
pe-tce_bypass_base = 1ull  59;
 
-   /* Install set_bypass callback for VFIO */
-   pe-tce32.table.set_bypass = pnv_pci_ioda2_set_bypass;
-
/* Enable bypass by default */
-   pnv_pci_ioda2_set_bypass(pe-tce32.table, true);
+   pnv_pci_ioda2_set_bypass(pe, true);
+}
+
+static void pnv_ioda2_take_ownership(struct spapr_tce_iommu_group *data,
+bool 

[PATCH 02/13] powerpc/powernv: Make invalidate() a callback

2014-08-29 Thread Alexey Kardashevskiy
At the moment pnv_pci_ioda_tce_invalidate() gets the PE pointer via
container_of(tbl). Since we are going to have to add Dynamic DMA windows
and that means having 2 IOMMU tables per PE, this is not going to work.

This implements pnv_pci_ioda(1|2)_tce_invalidate as a pnv_ioda_pe callback.

This adds a pnv_iommu_table wrapper around iommu_table and stores a pointer
to PE there. PNV's ppc_md.tce_build() call uses this to find PE and
do the invalidation. This will be used later for Dynamic DMA windows too.

This registers invalidate() callbacks for IODA1 and IODA2:
- pnv_pci_ioda1_tce_invalidate;
- pnv_pci_ioda2_tce_invalidate.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/platforms/powernv/pci-ioda.c | 35 ---
 arch/powerpc/platforms/powernv/pci.c  | 31 ---
 arch/powerpc/platforms/powernv/pci.h  | 13 +++-
 3 files changed, 48 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index df241b1..136e765 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -857,7 +857,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, 
struct pci_dev *pdev
 
pe = phb-ioda.pe_array[pdn-pe_number];
WARN_ON(get_dma_ops(pdev-dev) != dma_iommu_ops);
-   set_iommu_table_base_and_group(pdev-dev, pe-tce32_table);
+   set_iommu_table_base_and_group(pdev-dev, pe-tce32.table);
 }
 
 static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
@@ -884,7 +884,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
} else {
dev_info(pdev-dev, Using 32-bit DMA via iommu\n);
set_dma_ops(pdev-dev, dma_iommu_ops);
-   set_iommu_table_base(pdev-dev, pe-tce32_table);
+   set_iommu_table_base(pdev-dev, pe-tce32.table);
}
*pdev-dev.dma_mask = dma_mask;
return 0;
@@ -899,9 +899,9 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
list_for_each_entry(dev, bus-devices, bus_list) {
if (add_to_iommu_group)
set_iommu_table_base_and_group(dev-dev,
-  pe-tce32_table);
+  pe-tce32.table);
else
-   set_iommu_table_base(dev-dev, pe-tce32_table);
+   set_iommu_table_base(dev-dev, pe-tce32.table);
 
if (dev-subordinate)
pnv_ioda_setup_bus_dma(pe, dev-subordinate,
@@ -988,19 +988,6 @@ static void pnv_pci_ioda2_tce_invalidate(struct 
pnv_ioda_pe *pe,
}
 }
 
-void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
-__be64 *startp, __be64 *endp, bool rm)
-{
-   struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
- tce32_table);
-   struct pnv_phb *phb = pe-phb;
-
-   if (phb-type == PNV_PHB_IODA1)
-   pnv_pci_ioda1_tce_invalidate(pe, tbl, startp, endp, rm);
-   else
-   pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp, rm);
-}
-
 static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
  struct pnv_ioda_pe *pe, unsigned int base,
  unsigned int segs)
@@ -1058,9 +1045,11 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb 
*phb,
}
 
/* Setup linux iommu table */
-   tbl = pe-tce32_table;
+   tbl = pe-tce32.table;
pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs,
  base  28, IOMMU_PAGE_SHIFT_4K);
+   pe-tce32.pe = pe;
+   pe-tce32.invalidate_fn = pnv_pci_ioda1_tce_invalidate;
 
/* OPAL variant of P7IOC SW invalidated TCEs */
swinvp = of_get_property(phb-hose-dn, ibm,opal-tce-kill, NULL);
@@ -1097,7 +1086,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
 static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
 {
struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
- tce32_table);
+ tce32.table);
uint16_t window_id = (pe-pe_number  1 ) + 1;
int64_t rc;
 
@@ -1142,10 +1131,10 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct 
pnv_phb *phb,
pe-tce_bypass_base = 1ull  59;
 
/* Install set_bypass callback for VFIO */
-   pe-tce32_table.set_bypass = pnv_pci_ioda2_set_bypass;
+   pe-tce32.table.set_bypass = pnv_pci_ioda2_set_bypass;
 
/* Enable bypass by default */
-   pnv_pci_ioda2_set_bypass(pe-tce32_table, true);
+   pnv_pci_ioda2_set_bypass(pe-tce32.table, true);
 }
 
 static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
@@ -1193,9 +1182,11 @@ static void 

[PATCH 03/13] powerpc/spapr: vfio: Implement spapr_tce_iommu_ops

2014-08-29 Thread Alexey Kardashevskiy
Modern IBM POWERPC systems support multiple IOMMU tables per PE
so we need a more reliable way (compared to container_of()) to get
a PE pointer from the iommu_table struct pointer used in IOMMU functions.

At the moment IOMMU group data points to an iommu_table struct. This
introduces a spapr_tce_iommu_group struct which keeps an iommu_owner
and a spapr_tce_iommu_ops struct. For IODA, iommu_owner is a pointer to
the pnv_ioda_pe struct, for others it is still a pointer to
the iommu_table struct. The ops structs correspond to the type which
iommu_owner points to.

This defines a get_table() callback which returns an iommu_table
by its number.

As the IOMMU group data pointer points to variable type instead of
iommu_table, VFIO SPAPR TCE driver is updated to use the new type.
This changes the tce_container struct to store iommu_group instead of
iommu_table.

So, it was:
- iommu_table points to iommu_group via iommu_table::it_group;
- iommu_group points to iommu_table via iommu_group_get_iommudata();

now it is:
- iommu_table points to iommu_group via iommu_table::it_group;
- iommu_group points to spapr_tce_iommu_group via
iommu_group_get_iommudata();
- spapr_tce_iommu_group points to either (depending on .get_table()):
- iommu_table;
- pnv_ioda_pe;

This uses pnv_ioda1_iommu_get_table for both IODA12 but IODA2 will
have own pnv_ioda2_iommu_get_table soon and pnv_ioda1_iommu_get_table
will only be used for IODA1.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/include/asm/iommu.h|   6 ++
 arch/powerpc/include/asm/tce.h  |  13 +++
 arch/powerpc/kernel/iommu.c |  35 ++-
 arch/powerpc/platforms/powernv/pci-ioda.c   |  31 +-
 arch/powerpc/platforms/powernv/pci-p5ioc2.c |   1 +
 arch/powerpc/platforms/powernv/pci.c|   2 +-
 arch/powerpc/platforms/pseries/iommu.c  |  10 +-
 drivers/vfio/vfio_iommu_spapr_tce.c | 148 ++--
 8 files changed, 208 insertions(+), 38 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 42632c7..84ee339 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -108,13 +108,19 @@ extern void iommu_free_table(struct iommu_table *tbl, 
const char *node_name);
  */
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
int nid);
+
+struct spapr_tce_iommu_ops;
 #ifdef CONFIG_IOMMU_API
 extern void iommu_register_group(struct iommu_table *tbl,
+void *iommu_owner,
+struct spapr_tce_iommu_ops *ops,
 int pci_domain_number, unsigned long pe_num);
 extern int iommu_add_device(struct device *dev);
 extern void iommu_del_device(struct device *dev);
 #else
 static inline void iommu_register_group(struct iommu_table *tbl,
+   void *iommu_owner,
+   struct spapr_tce_iommu_ops *ops,
int pci_domain_number,
unsigned long pe_num)
 {
diff --git a/arch/powerpc/include/asm/tce.h b/arch/powerpc/include/asm/tce.h
index 743f36b..9f159eb 100644
--- a/arch/powerpc/include/asm/tce.h
+++ b/arch/powerpc/include/asm/tce.h
@@ -50,5 +50,18 @@
 #define TCE_PCI_READ   0x1 /* read from PCI allowed */
 #define TCE_VB_WRITE   0x1 /* write from VB allowed */
 
+struct spapr_tce_iommu_group;
+
+struct spapr_tce_iommu_ops {
+   struct iommu_table *(*get_table)(
+   struct spapr_tce_iommu_group *data,
+   int num);
+};
+
+struct spapr_tce_iommu_group {
+   void *iommu_owner;
+   struct spapr_tce_iommu_ops *ops;
+};
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_TCE_H */
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index b378f78..1c5dae7 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -878,24 +878,53 @@ void iommu_free_coherent(struct iommu_table *tbl, size_t 
size,
  */
 static void group_release(void *iommu_data)
 {
-   struct iommu_table *tbl = iommu_data;
-   tbl-it_group = NULL;
+   kfree(iommu_data);
 }
 
+static struct iommu_table *spapr_tce_default_get_table(
+   struct spapr_tce_iommu_group *data, int num)
+{
+   struct iommu_table *tbl = data-iommu_owner;
+
+   switch (num) {
+   case 0:
+   if (tbl-it_size)
+   return tbl;
+   /* fallthru */
+   default:
+   return NULL;
+   }
+}
+
+static struct spapr_tce_iommu_ops spapr_tce_default_ops = {
+   .get_table = spapr_tce_default_get_table
+};
+
 void iommu_register_group(struct iommu_table *tbl,
+   void *iommu_owner, struct spapr_tce_iommu_ops *ops,
int pci_domain_number, unsigned long 

[PATCH 06/13] powerpc/iommu: Move tce_xxx callbacks from ppc_md to iommu_table

2014-08-29 Thread Alexey Kardashevskiy
This adds a iommu_table_ops struct and puts pointer to it into
the iommu_table struct. This moves tce_build/tce_free/tce_get/tce_flush
callbacks from ppc_md to the new struct where they really belong to.

This adds an extra @ops parameter to iommu_init_table() to make sure
that we do not leave any IOMMU table without iommu_table_ops. @it_ops is
initialized in the very beginning as iommu_init_table() calls
iommu_table_clear() and the latter uses callbacks already.

This does s/tce_build/set/, s/tce_free/clear/ and removes tce_ prefixes
for better readability.

This removes tce_xxx_rm handlers from ppc_md as well but does not add
them to iommu_table_ops, this will be done later if we decide to support
TCE hypercalls in real mode.

This always uses tce_buildmulti_pSeriesLP/tce_buildmulti_pSeriesLP as
callbacks for pseries. This changes multi callbacks to fall back to
tce_build_pSeriesLP/tce_free_pSeriesLP if FW_FEATURE_MULTITCE is not
present. The reason for this is we still have to support multitce=off
boot parameter in disable_multitce() and we do not want to walk through
all IOMMU tables in the system and replace multi callbacks with single
ones.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/include/asm/iommu.h| 20 +++-
 arch/powerpc/include/asm/machdep.h  | 25 ---
 arch/powerpc/kernel/iommu.c | 50 -
 arch/powerpc/kernel/vio.c   |  5 ++-
 arch/powerpc/platforms/cell/iommu.c |  9 --
 arch/powerpc/platforms/pasemi/iommu.c   |  8 +++--
 arch/powerpc/platforms/powernv/pci-ioda.c   |  4 +--
 arch/powerpc/platforms/powernv/pci-p5ioc2.c |  3 +-
 arch/powerpc/platforms/powernv/pci.c| 24 --
 arch/powerpc/platforms/powernv/pci.h|  1 +
 arch/powerpc/platforms/pseries/iommu.c  | 42 +---
 arch/powerpc/sysdev/dart_iommu.c| 13 
 12 files changed, 102 insertions(+), 102 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 2b0b01d..c725e4a 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -43,6 +43,22 @@
 extern int iommu_is_off;
 extern int iommu_force_on;
 
+struct iommu_table_ops {
+   int (*set)(struct iommu_table *tbl,
+   long index, long npages,
+   unsigned long uaddr,
+   enum dma_data_direction direction,
+   struct dma_attrs *attrs);
+   void (*clear)(struct iommu_table *tbl,
+   long index, long npages);
+   unsigned long (*get)(struct iommu_table *tbl, long index);
+   void (*flush)(struct iommu_table *tbl);
+};
+
+/* These are used by VIO */
+extern struct iommu_table_ops iommu_table_lpar_multi_ops;
+extern struct iommu_table_ops iommu_table_pseries_ops;
+
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
@@ -77,6 +93,7 @@ struct iommu_table {
 #ifdef CONFIG_IOMMU_API
struct iommu_group *it_group;
 #endif
+   struct iommu_table_ops *it_ops;
 };
 
 /* Pure 2^n version of get_order */
@@ -106,7 +123,8 @@ extern void iommu_free_table(struct iommu_table *tbl, const 
char *node_name);
  * structure
  */
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
-   int nid);
+   int nid,
+   struct iommu_table_ops *ops);
 
 struct spapr_tce_iommu_ops;
 #ifdef CONFIG_IOMMU_API
diff --git a/arch/powerpc/include/asm/machdep.h 
b/arch/powerpc/include/asm/machdep.h
index b125cea..1fc824d 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -65,31 +65,6 @@ struct machdep_calls {
 * destroyed as well */
void(*hpte_clear_all)(void);
 
-   int (*tce_build)(struct iommu_table *tbl,
-long index,
-long npages,
-unsigned long uaddr,
-enum dma_data_direction direction,
-struct dma_attrs *attrs);
-   void(*tce_free)(struct iommu_table *tbl,
-   long index,
-   long npages);
-   unsigned long   (*tce_get)(struct iommu_table *tbl,
-   long index);
-   void(*tce_flush)(struct iommu_table *tbl);
-
-   /* _rm versions are for real mode use only */
-   int (*tce_build_rm)(struct iommu_table *tbl,
-long index,
-long npages,
-unsigned long uaddr,
-enum dma_data_direction 

[PATCH 07/13] powerpc/powernv: Do not set read flag if direction==DMA_NONE

2014-08-29 Thread Alexey Kardashevskiy
Normally a bitmap from the iommu_table is used to track what TCE entry
is in use. Since we are going to use iommu_table without its locks and
do xchg() instead, it becomes essential not to put bits which are not
implied in the direction flag.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/platforms/powernv/pci.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci.c 
b/arch/powerpc/platforms/powernv/pci.c
index deddcad..ab79e2d 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -628,10 +628,18 @@ static int pnv_tce_build(struct iommu_table *tbl, long 
index, long npages,
__be64 *tcep, *tces;
u64 rpn;
 
-   proto_tce = TCE_PCI_READ; // Read allowed
-
-   if (direction != DMA_TO_DEVICE)
-   proto_tce |= TCE_PCI_WRITE;
+   switch (direction) {
+   case DMA_BIDIRECTIONAL:
+   case DMA_FROM_DEVICE:
+   proto_tce = TCE_PCI_READ | TCE_PCI_WRITE;
+   break;
+   case DMA_TO_DEVICE:
+   proto_tce = TCE_PCI_READ;
+   break;
+   default:
+   proto_tce = 0;
+   break;
+   }
 
tces = tcep = ((__be64 *)tbl-it_base) + index - tbl-it_offset;
rpn = __pa(uaddr)  tbl-it_page_shift;
-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 05/13] powerpc/iommu: Fix IOMMU ownership control functions

2014-08-29 Thread Alexey Kardashevskiy
This adds missing locks in iommu_take_ownership()/
iommu_release_ownership().

This marks all pages busy in iommu_table::it_map in order to catch
errors if there is an attempt to use this table while ownership over it
is taken.

This only clears TCE content if there is no page marked busy in it_map.
Clearing must be done outside of the table locks as iommu_clear_tce()
called from iommu_clear_tces_and_put_pages() does this.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/kernel/iommu.c | 36 +---
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index c2c8d9d..cd80867 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1126,33 +1126,55 @@ EXPORT_SYMBOL_GPL(iommu_put_tce_user_mode);
 
 int iommu_take_ownership(struct iommu_table *tbl)
 {
-   unsigned long sz = (tbl-it_size + 7)  3;
+   unsigned long flags, i, sz = (tbl-it_size + 7)  3;
+   int ret = 0, bit0 = 0;
+
+   spin_lock_irqsave(tbl-large_pool.lock, flags);
+   for (i = 0; i  tbl-nr_pools; i++)
+   spin_lock(tbl-pools[i].lock);
 
if (tbl-it_offset == 0)
-   clear_bit(0, tbl-it_map);
+   bit0 = test_and_clear_bit(0, tbl-it_map);
 
if (!bitmap_empty(tbl-it_map, tbl-it_size)) {
pr_err(iommu_tce: it_map is not empty);
-   return -EBUSY;
+   ret = -EBUSY;
+   if (bit0)
+   set_bit(0, tbl-it_map);
+   } else {
+   memset(tbl-it_map, 0xff, sz);
}
 
-   memset(tbl-it_map, 0xff, sz);
-   iommu_clear_tces_and_put_pages(tbl, tbl-it_offset, tbl-it_size);
+   for (i = 0; i  tbl-nr_pools; i++)
+   spin_unlock(tbl-pools[i].lock);
+   spin_unlock_irqrestore(tbl-large_pool.lock, flags);
 
-   return 0;
+   if (!ret)
+   iommu_clear_tces_and_put_pages(tbl, tbl-it_offset,
+   tbl-it_size);
+   return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_take_ownership);
 
 void iommu_release_ownership(struct iommu_table *tbl)
 {
-   unsigned long sz = (tbl-it_size + 7)  3;
+   unsigned long flags, i, sz = (tbl-it_size + 7)  3;
 
iommu_clear_tces_and_put_pages(tbl, tbl-it_offset, tbl-it_size);
+
+   spin_lock_irqsave(tbl-large_pool.lock, flags);
+   for (i = 0; i  tbl-nr_pools; i++)
+   spin_lock(tbl-pools[i].lock);
+
memset(tbl-it_map, 0, sz);
 
/* Restore bit#0 set by iommu_init_table() */
if (tbl-it_offset == 0)
set_bit(0, tbl-it_map);
+
+   for (i = 0; i  tbl-nr_pools; i++)
+   spin_unlock(tbl-pools[i].lock);
+   spin_unlock_irqrestore(tbl-large_pool.lock, flags);
 }
 EXPORT_SYMBOL_GPL(iommu_release_ownership);
 
-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 08/13] powerpc/powernv: Release replaced TCE

2014-08-29 Thread Alexey Kardashevskiy
At the moment writing new TCE value to the IOMMU table fails with EBUSY
if there is a valid entry already. However PAPR specification allows
the guest to write new TCE value without clearing it first.

Another problem this patch is addressing is the use of pool locks for
external IOMMU users such as VFIO. The pool locks are to protect
DMA page allocator rather than entries and since the host kernel does
not control what pages are in use, there is no point in pool locks and
exchange()+put_page(oldtce) is sufficient to avoid possible races.

This adds an exchange() callback to iommu_table_ops which does the same
thing as set() plus it returns replaced TCE(s) so the caller can release
the pages afterwards.

This makes iommu_tce_build() put pages returned by exchange().

This replaces iommu_clear_tce() with iommu_tce_build which now
can call exchange() with TCE==NULL (i.e. clear).

This preserves permission bits in TCE in iommu_put_tce_user_mode().

This removes use of pool locks for external IOMMU uses.

This disables external IOMMU use (i.e. VFIO) for IOMMUs which do not
implement exchange() callback. Therefore the powernv platform is
the only supported one after this patch.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/include/asm/iommu.h |  8 +++--
 arch/powerpc/kernel/iommu.c  | 62 
 arch/powerpc/platforms/powernv/pci.c | 40 +++
 3 files changed, 67 insertions(+), 43 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index c725e4a..8e0537d 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -49,6 +49,12 @@ struct iommu_table_ops {
unsigned long uaddr,
enum dma_data_direction direction,
struct dma_attrs *attrs);
+   int (*exchange)(struct iommu_table *tbl,
+   long index, long npages,
+   unsigned long uaddr,
+   unsigned long *old_tces,
+   enum dma_data_direction direction,
+   struct dma_attrs *attrs);
void (*clear)(struct iommu_table *tbl,
long index, long npages);
unsigned long (*get)(struct iommu_table *tbl, long index);
@@ -209,8 +215,6 @@ extern int iommu_tce_put_param_check(struct iommu_table 
*tbl,
unsigned long ioba, unsigned long tce);
 extern int iommu_tce_build(struct iommu_table *tbl, unsigned long entry,
unsigned long hwaddr, enum dma_data_direction direction);
-extern unsigned long iommu_clear_tce(struct iommu_table *tbl,
-   unsigned long entry);
 extern int iommu_clear_tces_and_put_pages(struct iommu_table *tbl,
unsigned long entry, unsigned long pages);
 extern int iommu_put_tce_user_mode(struct iommu_table *tbl,
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 678fee8..39ccce7 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1006,43 +1006,11 @@ int iommu_tce_put_param_check(struct iommu_table *tbl,
 }
 EXPORT_SYMBOL_GPL(iommu_tce_put_param_check);
 
-unsigned long iommu_clear_tce(struct iommu_table *tbl, unsigned long entry)
-{
-   unsigned long oldtce;
-   struct iommu_pool *pool = get_pool(tbl, entry);
-
-   spin_lock((pool-lock));
-
-   oldtce = tbl-it_ops-get(tbl, entry);
-   if (oldtce  (TCE_PCI_WRITE | TCE_PCI_READ))
-   tbl-it_ops-clear(tbl, entry, 1);
-   else
-   oldtce = 0;
-
-   spin_unlock((pool-lock));
-
-   return oldtce;
-}
-EXPORT_SYMBOL_GPL(iommu_clear_tce);
-
 int iommu_clear_tces_and_put_pages(struct iommu_table *tbl,
unsigned long entry, unsigned long pages)
 {
-   unsigned long oldtce;
-   struct page *page;
-
for ( ; pages; --pages, ++entry) {
-   oldtce = iommu_clear_tce(tbl, entry);
-   if (!oldtce)
-   continue;
-
-   page = pfn_to_page(oldtce  PAGE_SHIFT);
-   WARN_ON(!page);
-   if (page) {
-   if (oldtce  TCE_PCI_WRITE)
-   SetPageDirty(page);
-   put_page(page);
-   }
+   iommu_tce_build(tbl, entry, 0, DMA_NONE);
}
 
return 0;
@@ -1056,18 +1024,19 @@ EXPORT_SYMBOL_GPL(iommu_clear_tces_and_put_pages);
 int iommu_tce_build(struct iommu_table *tbl, unsigned long entry,
unsigned long hwaddr, enum dma_data_direction direction)
 {
-   int ret = -EBUSY;
+   int ret;
unsigned long oldtce;
-   struct iommu_pool *pool = get_pool(tbl, entry);
 
-   spin_lock((pool-lock));
+   ret = tbl-it_ops-exchange(tbl, entry, 1, hwaddr, oldtce,
+   direction, NULL);
 
-   oldtce = tbl-it_ops-get(tbl, entry);
-   /* Add new entry if it is not 

[PATCH 09/13] powerpc/pseries/lpar: Enable VFIO

2014-08-29 Thread Alexey Kardashevskiy
The previous patch introduced iommu_table_ops::exchange() callback
which effectively disabled VFIO on pseries. This implements exchange()
for pseries/lpar so VFIO can work in nested guests.

Since exchaange() callback returns an old TCE, it has to call H_GET_TCE
for every TCE being put to the table so VFIO performance in guests
running under PR KVM is expected to be slower than in guests running under
HV KVM or bare metal hosts.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/platforms/pseries/iommu.c | 25 +++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c 
b/arch/powerpc/platforms/pseries/iommu.c
index 9a7364f..ae15b5a 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -138,13 +138,14 @@ static void tce_freemulti_pSeriesLP(struct iommu_table*, 
long, long);
 
 static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
long npages, unsigned long uaddr,
+   unsigned long *old_tces,
enum dma_data_direction direction,
struct dma_attrs *attrs)
 {
u64 rc = 0;
u64 proto_tce, tce;
u64 rpn;
-   int ret = 0;
+   int ret = 0, i = 0;
long tcenum_start = tcenum, npages_start = npages;
 
rpn = __pa(uaddr)  TCE_SHIFT;
@@ -154,6 +155,9 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, 
long tcenum,
 
while (npages--) {
tce = proto_tce | (rpn  TCE_RPN_MASK)  TCE_RPN_SHIFT;
+   if (old_tces)
+   plpar_tce_get((u64)tbl-it_index, (u64)tcenum  12,
+   old_tces[i++]);
rc = plpar_tce_put((u64)tbl-it_index, (u64)tcenum  12, tce);
 
if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
@@ -179,8 +183,9 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, 
long tcenum,
 
 static DEFINE_PER_CPU(__be64 *, tce_page);
 
-static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
+static int tce_xchg_pSeriesLP(struct iommu_table *tbl, long tcenum,
 long npages, unsigned long uaddr,
+unsigned long *old_tces,
 enum dma_data_direction direction,
 struct dma_attrs *attrs)
 {
@@ -195,6 +200,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table 
*tbl, long tcenum,
 
if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+  old_tces,
   direction, attrs);
}
 
@@ -211,6 +217,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table 
*tbl, long tcenum,
if (!tcep) {
local_irq_restore(flags);
return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+   old_tces,
direction, attrs);
}
__get_cpu_var(tce_page) = tcep;
@@ -232,6 +239,10 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table 
*tbl, long tcenum,
for (l = 0; l  limit; l++) {
tcep[l] = cpu_to_be64(proto_tce | (rpn  TCE_RPN_MASK) 
 TCE_RPN_SHIFT);
rpn++;
+   if (old_tces)
+   plpar_tce_get((u64)tbl-it_index,
+   (u64)(tcenum + l)  12,
+   old_tces[tcenum + l]);
}
 
rc = plpar_tce_put_indirect((u64)tbl-it_index,
@@ -262,6 +273,15 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table 
*tbl, long tcenum,
return ret;
 }
 
+static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
+long npages, unsigned long uaddr,
+enum dma_data_direction direction,
+struct dma_attrs *attrs)
+{
+   return tce_xchg_pSeriesLP(tbl, tcenum, npages, uaddr, NULL,
+   direction, attrs);
+}
+
 static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long 
npages)
 {
u64 rc;
@@ -637,6 +657,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
 
 struct iommu_table_ops iommu_table_lpar_multi_ops = {
.set = tce_buildmulti_pSeriesLP,
+   .exchange = tce_xchg_pSeriesLP,
.clear = tce_freemulti_pSeriesLP,
.get = tce_get_pSeriesLP
 };
-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 11/13] vfio: powerpc/spapr: Move locked_vm accounting to helpers

2014-08-29 Thread Alexey Kardashevskiy
There moves locked pages accounting to helpers.
Later they will be reused for Dynamic DMA windows (DDW).

While we are here, update the comment explaining why RLIMIT_MEMLOCK
might be required to be bigger than the guest RAM.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 drivers/vfio/vfio_iommu_spapr_tce.c | 71 +++--
 1 file changed, 53 insertions(+), 18 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c 
b/drivers/vfio/vfio_iommu_spapr_tce.c
index 1c1a9c4..c9fac97 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -29,6 +29,46 @@
 static void tce_iommu_detach_group(void *iommu_data,
struct iommu_group *iommu_group);
 
+static long try_increment_locked_vm(struct iommu_table *tbl)
+{
+   long ret = 0, locked, lock_limit, npages;
+
+   if (!current || !current-mm)
+   return -ESRCH; /* process exited */
+
+   npages = (tbl-it_size  IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
+
+   down_write(current-mm-mmap_sem);
+   locked = current-mm-locked_vm + npages;
+   lock_limit = rlimit(RLIMIT_MEMLOCK)  PAGE_SHIFT;
+   if (locked  lock_limit  !capable(CAP_IPC_LOCK)) {
+   pr_warn(RLIMIT_MEMLOCK (%ld) exceeded\n,
+   rlimit(RLIMIT_MEMLOCK));
+   ret = -ENOMEM;
+   } else {
+   current-mm-locked_vm += npages;
+   }
+   up_write(current-mm-mmap_sem);
+
+   return ret;
+}
+
+static void decrement_locked_vm(struct iommu_table *tbl)
+{
+   long npages;
+
+   if (!current || !current-mm)
+   return; /* process exited */
+
+   npages = (tbl-it_size  IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
+
+   down_write(current-mm-mmap_sem);
+   if (npages  current-mm-locked_vm)
+   npages = current-mm-locked_vm;
+   current-mm-locked_vm -= npages;
+   up_write(current-mm-mmap_sem);
+}
+
 /*
  * VFIO IOMMU fd for SPAPR_TCE IOMMU implementation
  *
@@ -86,7 +126,6 @@ static void tce_iommu_take_ownership_notify(struct 
spapr_tce_iommu_group *data,
 static int tce_iommu_enable(struct tce_container *container)
 {
int ret = 0;
-   unsigned long locked, lock_limit, npages;
struct iommu_table *tbl;
struct spapr_tce_iommu_group *data;
 
@@ -120,24 +159,23 @@ static int tce_iommu_enable(struct tce_container 
*container)
 * Also we don't have a nice way to fail on H_PUT_TCE due to ulimits,
 * that would effectively kill the guest at random points, much better
 * enforcing the limit based on the max that the guest can map.
+*
+* Unfortunately at the moment it counts whole tables, no matter how
+* much memory the guest has. I.e. for 4GB guest and 4 IOMMU groups
+* each with 2GB DMA window, 8GB will be counted here. The reason for
+* this is that we cannot tell here the amount of RAM used by the guest
+* as this information is only available from KVM and VFIO is
+* KVM agnostic.
 */
tbl = data-ops-get_table(data, 0);
if (!tbl)
return -ENXIO;
 
-   down_write(current-mm-mmap_sem);
-   npages = (tbl-it_size  IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
-   locked = current-mm-locked_vm + npages;
-   lock_limit = rlimit(RLIMIT_MEMLOCK)  PAGE_SHIFT;
-   if (locked  lock_limit  !capable(CAP_IPC_LOCK)) {
-   pr_warn(RLIMIT_MEMLOCK (%ld) exceeded\n,
-   rlimit(RLIMIT_MEMLOCK));
-   ret = -ENOMEM;
-   } else {
-   current-mm-locked_vm += npages;
-   container-enabled = true;
-   }
-   up_write(current-mm-mmap_sem);
+   ret = try_increment_locked_vm(tbl);
+   if (ret)
+   return ret;
+
+   container-enabled = true;
 
return ret;
 }
@@ -163,10 +201,7 @@ static void tce_iommu_disable(struct tce_container 
*container)
if (!tbl)
return;
 
-   down_write(current-mm-mmap_sem);
-   current-mm-locked_vm -= (tbl-it_size 
-   IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
-   up_write(current-mm-mmap_sem);
+   decrement_locked_vm(tbl);
 }
 
 static void *tce_iommu_open(unsigned long arg)
-- 
2.0.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH 10/13] powerpc/powernv: Implement Dynamic DMA windows (DDW) for IODA

2014-08-29 Thread Alexey Kardashevskiy
SPAPR defines an interface to create additional DMA windows dynamically.
Dynamically means that the window is not allocated before the guest
even started, the guest can request it later. In practice, existing linux
guests check for the capability and if it is there, they create and map
a DMA window as big as the entire guest RAM.

This adds 4 callbacks to the spapr_tce_iommu_ops struct:
1. query - ibm,query-pe-dma-window - returns number/size of windows
which can be created (one, any page size);

2. create - ibm,create-pe-dma-window - creates a window;

3. remove - ibm,remove-pe-dma-window - removes a window; removing
the default 32bit window is not allowed by this patch, this will be added
later if needed;

4. reset -  ibm,reset-pe-dma-window - reset the DMA windows configuration
to the default state; as the default window cannot be removed, it only
removes the additional window if it was created.

The next patch will add corresponding ioctls to VFIO SPAPR TCE driver to
provide necessary support to the userspace.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 arch/powerpc/include/asm/tce.h|  22 +
 arch/powerpc/platforms/powernv/pci-ioda.c | 159 +-
 arch/powerpc/platforms/powernv/pci.h  |   1 +
 3 files changed, 181 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/tce.h b/arch/powerpc/include/asm/tce.h
index e6355f9..23b0362 100644
--- a/arch/powerpc/include/asm/tce.h
+++ b/arch/powerpc/include/asm/tce.h
@@ -58,6 +58,28 @@ struct spapr_tce_iommu_ops {
int num);
void (*take_ownership)(struct spapr_tce_iommu_group *data,
bool enable);
+
+   /* Dynamic DMA window */
+   /* Page size flags for ibm,query-pe-dma-window */
+#define DDW_PGSIZE_4K   0x01
+#define DDW_PGSIZE_64K  0x02
+#define DDW_PGSIZE_16M  0x04
+#define DDW_PGSIZE_32M  0x08
+#define DDW_PGSIZE_64M  0x10
+#define DDW_PGSIZE_128M 0x20
+#define DDW_PGSIZE_256M 0x40
+#define DDW_PGSIZE_16G  0x80
+   long (*query)(struct spapr_tce_iommu_group *data,
+   __u32 *current_windows,
+   __u32 *windows_available,
+   __u32 *page_size_mask);
+   long (*create)(struct spapr_tce_iommu_group *data,
+   __u32 page_shift,
+   __u32 window_shift,
+   struct iommu_table **ptbl);
+   long (*remove)(struct spapr_tce_iommu_group *data,
+   struct iommu_table *tbl);
+   long (*reset)(struct spapr_tce_iommu_group *data);
 };
 
 struct spapr_tce_iommu_group {
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 296f49b..a6318cb 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1154,6 +1154,26 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct pnv_phb 
*phb,
pnv_pci_ioda2_set_bypass(pe, true);
 }
 
+static struct iommu_table *pnv_ioda2_iommu_get_table(
+   struct spapr_tce_iommu_group *data,
+   int num)
+{
+   struct pnv_ioda_pe *pe = data-iommu_owner;
+
+   switch (num) {
+   case 0:
+   if (pe-tce32.table.it_size)
+   return pe-tce32.table;
+   return NULL;
+   case 1:
+   if (pe-tce64.table.it_size)
+   return pe-tce64.table;
+   return NULL;
+   default:
+   return NULL;
+   }
+}
+
 static void pnv_ioda2_take_ownership(struct spapr_tce_iommu_group *data,
 bool enable)
 {
@@ -1162,9 +1182,146 @@ static void pnv_ioda2_take_ownership(struct 
spapr_tce_iommu_group *data,
pnv_pci_ioda2_set_bypass(pe, !enable);
 }
 
+static long pnv_pci_ioda2_ddw_query(struct spapr_tce_iommu_group *data,
+   __u32 *current_windows,
+   __u32 *windows_available, __u32 *page_size_mask)
+{
+   struct pnv_ioda_pe *pe = data-iommu_owner;
+
+   *windows_available = 2;
+   *current_windows = 0;
+   if (pe-tce32.table.it_size) {
+   --*windows_available;
+   ++*current_windows;
+   }
+   if (pe-tce64.table.it_size) {
+   --*windows_available;
+   ++*current_windows;
+   }
+   *page_size_mask =
+   DDW_PGSIZE_4K |
+   DDW_PGSIZE_64K |
+   DDW_PGSIZE_16M;
+
+   return 0;
+}
+
+static long pnv_pci_ioda2_ddw_create(struct spapr_tce_iommu_group *data,
+   __u32 page_shift, __u32 window_shift,
+   struct iommu_table **ptbl)
+{
+   struct pnv_ioda_pe *pe = data-iommu_owner;
+   struct pnv_phb *phb = pe-phb;
+   struct page *tce_mem = NULL;
+   void *addr;
+   long ret;
+   unsigned long tce_table_size =
+   (1ULL  (window_shift - page_shift)) * 8;
+   unsigned 

[PATCH 12/13] vfio: powerpc/spapr: Use it_page_size

2014-08-29 Thread Alexey Kardashevskiy
This makes use of the it_page_size from the iommu_table struct
as page size can differ.

This replaces missing IOMMU_PAGE_SHIFT macro in commented debug code
as recently introduced IOMMU_PAGE_XXX macros do not include
IOMMU_PAGE_SHIFT.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 drivers/vfio/vfio_iommu_spapr_tce.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c 
b/drivers/vfio/vfio_iommu_spapr_tce.c
index c9fac97..0dccbc4 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -36,7 +36,7 @@ static long try_increment_locked_vm(struct iommu_table *tbl)
if (!current || !current-mm)
return -ESRCH; /* process exited */
 
-   npages = (tbl-it_size  IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
+   npages = (tbl-it_size  tbl-it_page_shift)  PAGE_SHIFT;
 
down_write(current-mm-mmap_sem);
locked = current-mm-locked_vm + npages;
@@ -60,7 +60,7 @@ static void decrement_locked_vm(struct iommu_table *tbl)
if (!current || !current-mm)
return; /* process exited */
 
-   npages = (tbl-it_size  IOMMU_PAGE_SHIFT_4K)  PAGE_SHIFT;
+   npages = (tbl-it_size  tbl-it_page_shift)  PAGE_SHIFT;
 
down_write(current-mm-mmap_sem);
if (npages  current-mm-locked_vm)
@@ -284,8 +284,8 @@ static long tce_iommu_ioctl(void *iommu_data,
if (info.argsz  minsz)
return -EINVAL;
 
-   info.dma32_window_start = tbl-it_offset  IOMMU_PAGE_SHIFT_4K;
-   info.dma32_window_size = tbl-it_size  IOMMU_PAGE_SHIFT_4K;
+   info.dma32_window_start = tbl-it_offset  tbl-it_page_shift;
+   info.dma32_window_size = tbl-it_size  tbl-it_page_shift;
info.flags = 0;
 
if (copy_to_user((void __user *)arg, info, minsz))
@@ -318,10 +318,6 @@ static long tce_iommu_ioctl(void *iommu_data,
VFIO_DMA_MAP_FLAG_WRITE))
return -EINVAL;
 
-   if ((param.size  ~IOMMU_PAGE_MASK_4K) ||
-   (param.vaddr  ~IOMMU_PAGE_MASK_4K))
-   return -EINVAL;
-
/* iova is checked by the IOMMU API */
tce = param.vaddr;
if (param.flags  VFIO_DMA_MAP_FLAG_READ)
@@ -334,21 +330,25 @@ static long tce_iommu_ioctl(void *iommu_data,
return -ENXIO;
BUG_ON(!tbl-it_group);
 
+   if ((param.size  ~IOMMU_PAGE_MASK(tbl)) ||
+   (param.vaddr  ~IOMMU_PAGE_MASK(tbl)))
+   return -EINVAL;
+
ret = iommu_tce_put_param_check(tbl, param.iova, tce);
if (ret)
return ret;
 
-   for (i = 0; i  (param.size  IOMMU_PAGE_SHIFT_4K); ++i) {
+   for (i = 0; i  (param.size  tbl-it_page_shift); ++i) {
ret = iommu_put_tce_user_mode(tbl,
-   (param.iova  IOMMU_PAGE_SHIFT_4K) + i,
+   (param.iova  tbl-it_page_shift) + i,
tce);
if (ret)
break;
-   tce += IOMMU_PAGE_SIZE_4K;
+   tce += IOMMU_PAGE_SIZE(tbl);
}
if (ret)
iommu_clear_tces_and_put_pages(tbl,
-   param.iova  IOMMU_PAGE_SHIFT_4K, i);
+   param.iova  tbl-it_page_shift, i);
 
iommu_flush_tce(tbl);
 
@@ -379,23 +379,23 @@ static long tce_iommu_ioctl(void *iommu_data,
if (param.flags)
return -EINVAL;
 
-   if (param.size  ~IOMMU_PAGE_MASK_4K)
-   return -EINVAL;
-
tbl = spapr_tce_find_table(container, data, param.iova);
if (!tbl)
return -ENXIO;
 
+   if (param.size  ~IOMMU_PAGE_MASK(tbl))
+   return -EINVAL;
+
BUG_ON(!tbl-it_group);
 
ret = iommu_tce_clear_param_check(tbl, param.iova, 0,
-   param.size  IOMMU_PAGE_SHIFT_4K);
+   param.size  tbl-it_page_shift);
if (ret)
return ret;
 
ret = iommu_clear_tces_and_put_pages(tbl,
-   param.iova  IOMMU_PAGE_SHIFT_4K,
-   param.size  IOMMU_PAGE_SHIFT_4K);
+   param.iova  tbl-it_page_shift,
+   param.size  tbl-it_page_shift);
iommu_flush_tce(tbl);
 
return ret;
-- 
2.0.0

___
Linuxppc-dev mailing list

[PATCH 13/13] vfio: powerpc/spapr: Enable Dynamic DMA windows

2014-08-29 Thread Alexey Kardashevskiy
This defines and implements VFIO IOMMU API which lets the userspace
create and remove DMA windows.

This updates VFIO_IOMMU_SPAPR_TCE_GET_INFO to return the number of
available windows and page mask.

This adds VFIO_IOMMU_SPAPR_TCE_CREATE and VFIO_IOMMU_SPAPR_TCE_REMOVE
to allow the user space to create and remove window(s).

The VFIO IOMMU driver does basic sanity checks and calls corresponding
SPAPR TCE functions. At the moment only IODA2 (POWER8 PCI host bridge)
implements them.

This advertises VFIO_IOMMU_SPAPR_TCE_FLAG_DDW capability via
VFIO_IOMMU_SPAPR_TCE_GET_INFO.

This calls platform DDW reset() callback when IOMMU is being disabled
to reset the DMA configuration to its original state.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
 drivers/vfio/vfio_iommu_spapr_tce.c | 135 ++--
 include/uapi/linux/vfio.h   |  25 ++-
 2 files changed, 153 insertions(+), 7 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c 
b/drivers/vfio/vfio_iommu_spapr_tce.c
index 0dccbc4..b518891 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -190,18 +190,25 @@ static void tce_iommu_disable(struct tce_container 
*container)
 
container-enabled = false;
 
-   if (!container-grp || !current-mm)
+   if (!container-grp)
return;
 
data = iommu_group_get_iommudata(container-grp);
if (!data || !data-iommu_owner || !data-ops-get_table)
return;
 
-   tbl = data-ops-get_table(data, 0);
-   if (!tbl)
-   return;
+   if (current-mm) {
+   tbl = data-ops-get_table(data, 0);
+   if (tbl)
+   decrement_locked_vm(tbl);
 
-   decrement_locked_vm(tbl);
+   tbl = data-ops-get_table(data, 1);
+   if (tbl)
+   decrement_locked_vm(tbl);
+   }
+
+   if (data-ops-reset)
+   data-ops-reset(data);
 }
 
 static void *tce_iommu_open(unsigned long arg)
@@ -243,7 +250,7 @@ static long tce_iommu_ioctl(void *iommu_data,
 unsigned int cmd, unsigned long arg)
 {
struct tce_container *container = iommu_data;
-   unsigned long minsz;
+   unsigned long minsz, ddwsz;
long ret;
 
switch (cmd) {
@@ -288,6 +295,28 @@ static long tce_iommu_ioctl(void *iommu_data,
info.dma32_window_size = tbl-it_size  tbl-it_page_shift;
info.flags = 0;
 
+   ddwsz = offsetofend(struct vfio_iommu_spapr_tce_info,
+   page_size_mask);
+
+   if (info.argsz == ddwsz) {
+   if (data-ops-query  data-ops-create 
+   data-ops-remove) {
+   info.flags |= VFIO_IOMMU_SPAPR_TCE_FLAG_DDW;
+
+   ret = data-ops-query(data,
+   info.current_windows,
+   info.windows_available,
+   info.page_size_mask);
+   if (ret)
+   return ret;
+   } else {
+   info.current_windows = 0;
+   info.windows_available = 0;
+   info.page_size_mask = 0;
+   }
+   minsz = ddwsz;
+   }
+
if (copy_to_user((void __user *)arg, info, minsz))
return -EFAULT;
 
@@ -412,12 +441,106 @@ static long tce_iommu_ioctl(void *iommu_data,
tce_iommu_disable(container);
mutex_unlock(container-lock);
return 0;
+
case VFIO_EEH_PE_OP:
if (!container-grp)
return -ENODEV;
 
return vfio_spapr_iommu_eeh_ioctl(container-grp,
  cmd, arg);
+
+   case VFIO_IOMMU_SPAPR_TCE_CREATE: {
+   struct vfio_iommu_spapr_tce_create create;
+   struct spapr_tce_iommu_group *data;
+   struct iommu_table *tbl;
+
+   if (WARN_ON(!container-grp))
+   return -ENXIO;
+
+   data = iommu_group_get_iommudata(container-grp);
+
+   minsz = offsetofend(struct vfio_iommu_spapr_tce_create,
+   start_addr);
+
+   if (copy_from_user(create, (void __user *)arg, minsz))
+   return -EFAULT;
+
+   if (create.argsz  minsz)
+   return -EINVAL;
+
+   if (create.flags)
+   return -EINVAL;
+
+   if (!data-ops-create || !data-iommu_owner)
+   return -ENOSYS;
+
+   BUG_ON(!data || !data-ops || !data-ops-remove);
+
+   

Re: [PATCH 1/2] PCI/MSI/PPC: Remove arch_msi_check_device()

2014-08-29 Thread Michael Ellerman
On Sat, 2014-07-12 at 13:21 +0200, Alexander Gordeev wrote:
 PowerPC is the only architecture that makes use of hook
 arch_msi_check_device() and does perform some checks to
 figure out if MSI/MSI-X could be enabled for a device.
 However, there are no reasons why those checks could not
 be done within arch_setup_msi_irqs() hook.
 
 Moving MSI checks into arch_setup_msi_irqs() makes code
 more readable and allows getting rid of unnecessary hook
 arch_msi_check_device().

The intention was that this hook allowed a platform to reject the request
early, ie. before all the setup had been done. But if no one except us is using
it then fine, get rid of it.

Acked-by: Michael Ellerman m...@ellerman.id.au

cheers



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 00/19] powerpc/8xx: Optimise MMU TLB handling and add support of 16k pages

2014-08-29 Thread Christophe Leroy
This patchset:
1) provides several MMU TLB handling optimisation on MPC8xx.
2) adds support of 16k pages on MPC8xx.
All changes have been successfully tested on a custom board equipped with MPC885

The two differences with first version of the patch are:
1) I removed the patch number 10, which was implementing a 16 bit alignment of 
the
PGDIR. It is not worth potentially wasting up to 64k of memory just for 
removing one
instruction (ori).
2) I managed to preserve r11 while calculating the level 2 address, therefore
no more need to save r11 into CR.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
Tested-by: Christophe Leroy christophe.le...@c-s.fr

 arch/powerpc/Kconfig |2 +-
 arch/powerpc/include/asm/mmu-8xx.h   |2 +
 arch/powerpc/include/asm/pgtable-ppc32.h |   21 ++
 arch/powerpc/include/asm/pte-8xx.h   |7 +-
 arch/powerpc/include/asm/reg.h   |3 +-
 arch/powerpc/kernel/head_8xx.S   |  342 +++-
 6 files changed, 187 insertions(+), 190 deletions(-)
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 01/19] powerpc/8xx: Declare SPRG2 as a SCRATCH register

2014-08-29 Thread Christophe Leroy
Since coming 469d62be9263b92f2c3329540cbb1c076111f4f3, SPRG2 is used as a
scratch register just like SPRG0 and SPRG1. So Declare it as such and fix
the comment which is not valid anymore since that commit.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/include/asm/reg.h |3 ++-
 arch/powerpc/kernel/head_8xx.S |   10 +-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index cb9c174..b6a7d62 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -888,7 +888,7 @@
  * 32-bit 8xx:
  * - SPRG0 scratch for exception vectors
  * - SPRG1 scratch for exception vectors
- * - SPRG2 apparently unused but initialized
+ * - SPRG2 scratch for exception vectors
  *
  */
 #ifdef CONFIG_PPC64
@@ -994,6 +994,7 @@
 #ifdef CONFIG_8xx
 #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH2 SPRN_SPRG2
 #endif
 
 
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 55d12fb..1329c5a 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -301,7 +301,7 @@ InstructionTLBMiss:
stw r11, 4(r0)
 #else
mtspr   SPRN_DAR, r10
-   mtspr   SPRN_SPRG2, r11
+   mtspr   SPRN_SPRG_SCRATCH2, r11
 #endif
mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 #ifdef CONFIG_8xx_CPU15
@@ -363,7 +363,7 @@ InstructionTLBMiss:
mfspr   r10, SPRN_DAR
mtcrr10
mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG2
+   mfspr   r11, SPRN_SPRG_SCRATCH2
 #else
lwz r11, 0(r0)
mtcrr11
@@ -386,7 +386,7 @@ InstructionTLBMiss:
mtcrr10
li  r11, 0x00f0
mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG2
+   mfspr   r11, SPRN_SPRG_SCRATCH2
 #else
lwz r11, 0(r0)
mtcrr11
@@ -409,7 +409,7 @@ DataStoreTLBMiss:
stw r11, 4(r0)
 #else
mtspr   SPRN_DAR, r10
-   mtspr   SPRN_SPRG2, r11
+   mtspr   SPRN_SPRG_SCRATCH2, r11
 #endif
mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
@@ -487,7 +487,7 @@ DataStoreTLBMiss:
mfspr   r10, SPRN_DAR
mtcrr10
mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG2
+   mfspr   r11, SPRN_SPRG_SCRATCH2
 #else
mtspr   SPRN_DAR, r11   /* Tag DAR */
lwz r11, 0(r0)
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 02/19] powerpc/8xx: Use SCRATCH0 and SCRATCH1 also for TLB handlers

2014-08-29 Thread Christophe Leroy
SCRATCH0 and SCRATCH1 are only used in Exceptions prologs where no other
exception can happen. There is therefore no need to preserve them accross
TLB handlers, we can use them there as in other exceptions. One of the
advantages is that they do not suffer CPU6 errata unlike M_TW register.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |  104 --
 1 files changed, 36 insertions(+), 68 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 1329c5a..3af6db1 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -104,12 +104,15 @@ turn_on_mmu:
  * task's thread_struct.
  */
 #define EXCEPTION_PROLOG   \
-   mtspr   SPRN_SPRG_SCRATCH0,r10; \
-   mtspr   SPRN_SPRG_SCRATCH1,r11; \
-   mfcrr10;\
+   EXCEPTION_PROLOG_0; \
EXCEPTION_PROLOG_1; \
EXCEPTION_PROLOG_2
 
+#define EXCEPTION_PROLOG_0 \
+   mtspr   SPRN_SPRG_SCRATCH0,r10; \
+   mtspr   SPRN_SPRG_SCRATCH1,r11; \
+   mfcrr10
+
 #define EXCEPTION_PROLOG_1 \
mfspr   r11,SPRN_SRR1;  /* check whether user or kernel */ \
andi.   r11,r11,MSR_PR; \
@@ -145,6 +148,14 @@ turn_on_mmu:
SAVE_2GPRS(7, r11)
 
 /*
+ * Exception exit code.
+ */
+#define EXCEPTION_EPILOG_0 \
+   mtcrr10;\
+   mfspr   r10,SPRN_SPRG_SCRATCH0; \
+   mfspr   r11,SPRN_SPRG_SCRATCH1
+
+/*
  * Note: code which follows this uses cr0.eq (set if from kernel),
  * r11, r12 (SRR0), and r9 (SRR1).
  *
@@ -293,16 +304,8 @@ InstructionTLBMiss:
 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
 #endif
-   DO_8xx_CPU6(0x3f80, r3)
-   mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-   mfcrr10
-#ifdef CONFIG_8xx_CPU6
-   stw r10, 0(r0)
-   stw r11, 4(r0)
-#else
-   mtspr   SPRN_DAR, r10
-   mtspr   SPRN_SPRG_SCRATCH2, r11
-#endif
+   EXCEPTION_PROLOG_0
+   mtspr   SPRN_SPRG_SCRATCH2, r10
mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 #ifdef CONFIG_8xx_CPU15
addir11, r10, 0x1000
@@ -359,18 +362,11 @@ InstructionTLBMiss:
mtspr   SPRN_MI_RPN, r10/* Update TLB entry */
 
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-   mfspr   r10, SPRN_DAR
-   mtcrr10
-   mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG_SCRATCH2
-#else
-   lwz r11, 0(r0)
-   mtcrr11
-   lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
 #endif
-   mfspr   r10, SPRN_M_TW
+   mfspr   r10, SPRN_SPRG_SCRATCH2
+   EXCEPTION_EPILOG_0
rfi
 2:
mfspr   r11, SPRN_SRR1
@@ -381,19 +377,11 @@ InstructionTLBMiss:
mtspr   SPRN_SRR1, r11
 
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-   mfspr   r10, SPRN_DAR
-   mtcrr10
-   li  r11, 0x00f0
-   mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG_SCRATCH2
-#else
-   lwz r11, 0(r0)
-   mtcrr11
-   lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
 #endif
-   mfspr   r10, SPRN_M_TW
+   mfspr   r10, SPRN_SPRG_SCRATCH2
+   EXCEPTION_EPILOG_0
b   InstructionAccess
 
. = 0x1200
@@ -401,16 +389,8 @@ DataStoreTLBMiss:
 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
 #endif
-   DO_8xx_CPU6(0x3f80, r3)
-   mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-   mfcrr10
-#ifdef CONFIG_8xx_CPU6
-   stw r10, 0(r0)
-   stw r11, 4(r0)
-#else
-   mtspr   SPRN_DAR, r10
-   mtspr   SPRN_SPRG_SCRATCH2, r11
-#endif
+   EXCEPTION_PROLOG_0
+   mtspr   SPRN_SPRG_SCRATCH2, r10
mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
/* If we are faulting a kernel address, we have to use the
@@ -483,19 +463,12 @@ DataStoreTLBMiss:
mtspr   SPRN_MD_RPN, r10/* Update TLB entry */
 
/* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-   mfspr   r10, SPRN_DAR
-   mtcrr10
-   mtspr   SPRN_DAR, r11   /* Tag DAR */
-   mfspr   r11, SPRN_SPRG_SCRATCH2
-#else
-   mtspr   SPRN_DAR, r11   /* Tag DAR */
-   lwz r11, 0(r0)
-   mtcrr11
-   lwz r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
 #endif
-   mfspr   r10, SPRN_M_TW
+   mtspr   SPRN_DAR, r11   /* Tag DAR */
+   mfspr   r10, SPRN_SPRG_SCRATCH2
+   EXCEPTION_EPILOG_0
rfi
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
@@ -519,23 +492,18 @@ DataTLBError:
 #ifdef CONFIG_8xx_CPU6
stw r3, 8(r0)
 #endif
-   DO_8xx_CPU6(0x3f80, r3)
-   mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-   mfcrr10
-   stw r10, 0(r0)
-   stw r11, 4(r0)
+   EXCEPTION_PROLOG_0
+   mtspr   

[PATCH v2 03/19] powerpc/8xx: exception InstructionAccess does not exist on MPC8xx

2014-08-29 Thread Christophe Leroy
Exception InstructionAccess does not exist on MPC8xx. No need to branch there 
from somewhere else. 
Handling can be done directly in InstructionTLBError Exception.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   17 +++--
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 3af6db1..fbe5d10 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -234,15 +234,9 @@ DataAccess:
EXC_XFER_LITE(0x300, handle_page_fault)
 
 /* Instruction access exception.
- * This is never generated by the MPC8xx.  We jump to it for other
- * translation errors.
+ * This is never generated by the MPC8xx.
  */
-   . = 0x400
-InstructionAccess:
-   EXCEPTION_PROLOG
-   mr  r4,r12
-   mr  r5,r9
-   EXC_XFER_LITE(0x400, handle_page_fault)
+   EXCEPTION(0x400, InstructionAccess, unknown_exception, EXC_XFER_STD)
 
 /* External interrupt */
EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -382,7 +376,7 @@ InstructionTLBMiss:
 #endif
mfspr   r10, SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
-   b   InstructionAccess
+   b   InstructionTLBError
 
. = 0x1200
 DataStoreTLBMiss:
@@ -477,7 +471,10 @@ DataStoreTLBMiss:
  */
. = 0x1300
 InstructionTLBError:
-   b   InstructionAccess
+   EXCEPTION_PROLOG
+   mr  r4,r12
+   mr  r5,r9
+   EXC_XFER_LITE(0x1300, handle_page_fault)
 
 /* This is the data TLB error on the MPC8xx.  This could be due to
  * many reasons, including a dirty update to a pte.  We can catch that
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 05/19] powerpc/8xx: Fix comment about DIRTY update

2014-08-29 Thread Christophe Leroy
Since commit 2321f33790a6c5b80322d907a92d5739e7521a13, dirty handling is not
handled here anymore. So we fix the comment.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |8 ++--
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index e59e39e..171c6ef 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -477,12 +477,8 @@ InstructionTLBError:
EXC_XFER_LITE(0x1300, handle_page_fault)
 
 /* This is the data TLB error on the MPC8xx.  This could be due to
- * many reasons, including a dirty update to a pte.  We can catch that
- * one here, but anything else is an error.  First, we track down the
- * Linux pte.  If it is valid, write access is allowed, but the
- * page dirty bit is not set, we will set it and reload the TLB.  For
- * any other case, we bail out to a higher level function that can
- * handle it.
+ * many reasons, including a dirty update to a pte.  We bail out to
+ * a higher level function that can handle it.
  */
. = 0x1400
 DataTLBError:
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 04/19] powerpc/8xx: Remove loading of r10 at end of FixupDAR

2014-08-29 Thread Christophe Leroy
Since commit 2321f33790a6c5b80322d907a92d5739e7521a13, r10 is not used anymore
after FixupDAR. There is therefore no need to set it up with the value of DAR.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index fbe5d10..e59e39e 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -495,7 +495,7 @@ DataTLBError:
mfspr   r10, SPRN_DAR
cmpwi   cr0, r10, 0x00f0
beq-FixupDAR/* must be a buggy dcbX, icbi insn. */
-DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of 
DAR */
+DARFixed:/* Return from dcbx instruction bug workaround */
 #ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
 #endif
@@ -524,7 +524,7 @@ DARFixed:/* Return from dcbx instruction bug workaround, 
r10 holds value of DAR
 
 /* This is the procedure to calculate the data EA for buggy dcbx,dcbi 
instructions
  * by decoding the registers used by the dcbx instruction and adding them.
- * DAR is set to the calculated address and r10 also holds the EA on exit.
+ * DAR is set to the calculated address.
  */
  /* define if you don't want to use self modifying code */
 #define NO_SELF_MODIFYING_CODE
@@ -564,8 +564,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
beq+142f
cmpwi   cr0, r10, 1964  /* Is icbi? */
beq+142f
-141:   mfspr   r10, SPRN_DAR   /* r10 must hold DAR at exit */
-   b   DARFixed/* Nope, go back to normal TLB processing */
+141:   b   DARFixed/* Nope, go back to normal TLB processing */
 
 144:   mfspr   r10, SPRN_DSISR
rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 10/19] powerpc/8xx: Duplicate two insns instead of branching

2014-08-29 Thread Christophe Leroy
Branching takes two cycles on MPC8xx. Lets duplicate the two instructions
and avoid the branching.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 5037420..4a49ff3 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -638,9 +638,11 @@ modified_instr:
 
/* special handling for r10,r11 since these are modified already */
 153:   mfspr   r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
-   b   155f
+   add r10, r10, r11   /* add it */
+   mfctr   r11 /* restore r11 */
+   b   151b
 154:   mfspr   r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
-155:   add r10, r10, r11   /* add it */
+   add r10, r10, r11   /* add it */
mfctr   r11 /* restore r11 */
b   151b
 #endif
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 06/19] powerpc/8xx: No need to save r10 and r3 when not calling FixupDAR

2014-08-29 Thread Christophe Leroy
r10 and r3 are only used inside FixupDAR function. So lets save them inside
that function only.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   27 +--
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 171c6ef..845abf8 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -482,20 +482,12 @@ InstructionTLBError:
  */
. = 0x1400
 DataTLBError:
-#ifdef CONFIG_8xx_CPU6
-   stw r3, 8(r0)
-#endif
EXCEPTION_PROLOG_0
-   mtspr   SPRN_SPRG_SCRATCH2, r10
 
-   mfspr   r10, SPRN_DAR
-   cmpwi   cr0, r10, 0x00f0
+   mfspr   r11, SPRN_DAR
+   cmpwi   cr0, r11, 0x00f0
beq-FixupDAR/* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
-#ifdef CONFIG_8xx_CPU6
-   lwz r3, 8(r0)
-#endif
-   mfspr   r10,SPRN_SPRG_SCRATCH2
EXCEPTION_EPILOG_0
b   DataAccess
 
@@ -525,6 +517,10 @@ DARFixed:/* Return from dcbx instruction bug workaround */
  /* define if you don't want to use self modifying code */
 #define NO_SELF_MODIFYING_CODE
 FixupDAR:/* Entry point for dcbx workaround. */
+#ifdef CONFIG_8xx_CPU6
+   stw r3, 8(r0)
+#endif
+   mtspr   SPRN_SPRG_SCRATCH2, r10
/* fetch instruction from memory. */
mfspr   r10, SPRN_SRR0
andis.  r11, r10, 0x8000/* Address = 0x8000 */
@@ -540,6 +536,9 @@ FixupDAR:/* Entry point for dcbx workaround. */
mtspr   SPRN_MD_TWC, r11/* Load pte table base address */
mfspr   r11, SPRN_MD_TWC/* and get the pte address */
lwz r11, 0(r11) /* Get the pte */
+#ifdef CONFIG_8xx_CPU6
+   lwz r3, 8(r0)   /* restore r3 from memory */
+#endif
/* concat physical page address(r11) and page offset(r10) */
rlwimi  r11, r10, 0, 20, 31
lwz r11,0(r11)
@@ -560,15 +559,13 @@ FixupDAR:/* Entry point for dcbx workaround. */
beq+142f
cmpwi   cr0, r10, 1964  /* Is icbi? */
beq+142f
-141:   b   DARFixed/* Nope, go back to normal TLB processing */
+141:   mfspr   r10,SPRN_SPRG_SCRATCH2
+   b   DARFixed/* Nope, go back to normal TLB processing */
 
 144:   mfspr   r10, SPRN_DSISR
rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
mtspr   SPRN_DSISR, r10
 142:   /* continue, it was a dcbx, dcbi instruction. */
-#ifdef CONFIG_8xx_CPU6
-   lwz r3, 8(r0)   /* restore r3 from memory */
-#endif
 #ifndef NO_SELF_MODIFYING_CODE
andis.  r10,r11,0x1f/* test if reg RA is r0 */
li  r10,modified_instr@l
@@ -587,6 +584,7 @@ modified_instr:
bne+143f
subfr10,r0,r10  /* r10=r10-r0, only if reg RA is r0 */
 143:   mtdar   r10 /* store faulting EA in DAR */
+   mfspr   r10,SPRN_SPRG_SCRATCH2
b   DARFixed/* Go back to normal TLB handling */
 #else
mfctr   r10
@@ -640,6 +638,7 @@ modified_instr:
mfdar   r11
mtctr   r11 /* restore ctr reg from DAR */
mtdar   r10 /* save fault EA to DAR */
+   mfspr   r10,SPRN_SPRG_SCRATCH2
b   DARFixed/* Go back to normal TLB handling */
 
/* special handling for r10,r11 since these are modified already */
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 15/19] powerpc/8xx: Implement 16k pages

2014-08-29 Thread Christophe Leroy
This patch activates the handling of 16k pages on the MPC8xx.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/Kconfig   |2 +-
 arch/powerpc/include/asm/mmu-8xx.h |2 ++
 arch/powerpc/kernel/head_8xx.S |4 
 3 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5f44d3b..dc5f64e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -518,7 +518,7 @@ config PPC_4K_PAGES
bool 4k page size
 
 config PPC_16K_PAGES
-   bool 16k page size if 44x
+   bool 16k page size if 44x || PPC_8xx
 
 config PPC_64K_PAGES
bool 64k page size if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64
diff --git a/arch/powerpc/include/asm/mmu-8xx.h 
b/arch/powerpc/include/asm/mmu-8xx.h
index 3d11d3c..986b9e1 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -56,6 +56,7 @@
  * additional information from the MI_EPN, and MI_TWC registers.
  */
 #define SPRN_MI_RPN790
+#define MI_SPS16K  0x0008  /* Small page size (0 = 4k, 1 = 16k) */
 
 /* Define an RPN value for mapping kernel memory to large virtual
  * pages for boot initialization.  This has real page number of 0,
@@ -129,6 +130,7 @@
  * additional information from the MD_EPN, and MD_TWC registers.
  */
 #define SPRN_MD_RPN798
+#define MD_SPS16K  0x0008  /* Small page size (0 = 4k, 1 = 16k) */
 
 /* This is a temporary storage register that could be used to save
  * a processor working register during a tablewalk.
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 8966262..4dd6be0 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -45,7 +45,11 @@
  * Value for the bits that have fixed value in RPN entries.
  * Also used for tagging DAR for DTLBerror.
  */
+#ifdef CONFIG_PPC_16K_PAGES
+#define RPN_PATTERN(0x00f0 | MD_SPS16K)
+#else
 #define RPN_PATTERN0x00f0
+#endif
 
__HEAD
 _ENTRY(_stext);
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 18/19] powerpc/8xx: _PMD_PRESENT already set in level 1 entries

2014-08-29 Thread Christophe Leroy
When a PMD entry is valid, _PMD_PRESENT is set. Therefore, forcing that bit
during TLB loading is useless.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 48d3de8..bb7c816 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -340,7 +340,6 @@ InstructionTLBMiss:
/* We have a pte table, so load the MI_TWC with the attributes
 * for this segment.
 */
-   ori r11,r11,1   /* Set valid bit */
MTSPR_CPU6(SPRN_MI_TWC, r11, r3)/* Set segment attributes */
mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
/* Extract level 2 index */
@@ -417,7 +416,6 @@ DataStoreTLBMiss:
rlwimi  r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
lwz r10, 0(r10) /* Get the pte */
 
-   ori r11, r11, 1 /* Set valid bit in physical L2 page */
/* Insert the Guarded flag into the TWC from the Linux PTE.
 * It is bit 27 of both the Linux PTE and the TWC (at least
 * I got that right :-).  It will be better when we can put
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 09/19] powerpc/8xx: Optimize verification in FixupDAR

2014-08-29 Thread Christophe Leroy
By XORing the upper part of the instruction code, we get a value that can
directly be verified with the second test and we can remove the first test.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index e5a250c..5037420 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -542,10 +542,8 @@ FixupDAR:/* Entry point for dcbx workaround. */
 /* Check if it really is a dcbx instruction. */
 /* dcbt and dcbtst does not generate DTLB Misses/Errors,
  * no need to include them here */
-   srwir10, r11, 26/* check if major OP code is 31 */
-   cmpwi   cr0, r10, 31
-   bne-141f
-   rlwinm  r10, r11, 0, 21, 30
+   xoris   r10, r11, 0x7c00/* check if major OP code is 31 */
+   rlwinm  r10, r10, 0, 21, 5
cmpwi   cr0, r10, 2028  /* Is dcbz? */
beq+142f
cmpwi   cr0, r10, 940   /* Is dcbi? */
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 19/19] powerpc/8xx: Don't restore regs to save them again.

2014-08-29 Thread Christophe Leroy
There is not need to restore r10, r11 and cr registers at this end of ITLBmiss
handler as they are saved again to the same place in ITLBError handler we are
jumping to.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index bb7c816..e21f0b2 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -381,8 +381,7 @@ InstructionTLBMiss:
lwz r3, 8(r0)
 #endif
mfspr   r10, SPRN_SPRG_SCRATCH2
-   EXCEPTION_EPILOG_0
-   b   InstructionTLBError
+   b   InstructionTLBError1
 
. = 0x1200
 DataStoreTLBMiss:
@@ -471,7 +470,10 @@ DataStoreTLBMiss:
  */
. = 0x1300
 InstructionTLBError:
-   EXCEPTION_PROLOG
+   EXCEPTION_PROLOG_0
+InstructionTLBError1:
+   EXCEPTION_PROLOG_1
+   EXCEPTION_PROLOG_2
mr  r4,r12
mr  r5,r9
EXC_XFER_LITE(0x1300, handle_page_fault)
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 17/19] powerpc/8xx: set PTE bit 22 off TLBmiss

2014-08-29 Thread Christophe Leroy
No need to re-set this bit at each TLB miss. Let's set it in the PTE.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/include/asm/pgtable-ppc32.h |   21 +
 arch/powerpc/include/asm/pte-8xx.h   |7 +--
 arch/powerpc/kernel/head_8xx.S   |   10 ++
 3 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h 
b/arch/powerpc/include/asm/pgtable-ppc32.h
index 47edde8..c261792 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -172,6 +172,26 @@ static inline unsigned long pte_update(pte_t *p,
 #ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
 
+#ifdef CONFIG_PPC_8xx
+   unsigned long tmp2;
+
+   __asm__ __volatile__(\
+1: lwarx   %0,0,%4\n\
+   andc%1,%0,%5\n\
+   or  %1,%1,%6\n\
+   /* 0x200 == Extended encoding, bit 22 */ \
+   /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ \
+   rlwimi  %1,%1,32-2,0x200\n /* get _PAGE_USER */ \
+   rlwinm  %3,%1,32-1,0x200\n /* get _PAGE_RW */ \
+   or  %1,%3,%1\n\
+   xori%1,%1,0x200\n
+   PPC405_ERR77(0,%4)
+  stwcx.  %1,0,%4\n\
+   bne-1b
+   : =r (old), =r (tmp), =m (*p), =r (tmp2)
+   : r (p), r (clr), r (set), m (*p)
+   : cc );
+#else /* CONFIG_PPC_8xx */
__asm__ __volatile__(\
 1: lwarx   %0,0,%3\n\
andc%1,%0,%4\n\
@@ -182,6 +202,7 @@ static inline unsigned long pte_update(pte_t *p,
: =r (old), =r (tmp), =m (*p)
: r (p), r (clr), r (set), m (*p)
: cc );
+#endif /* CONFIG_PPC_8xx */
 #else /* PTE_ATOMIC_UPDATES */
unsigned long old = pte_val(*p);
*p = __pte((old  ~clr) | set);
diff --git a/arch/powerpc/include/asm/pte-8xx.h 
b/arch/powerpc/include/asm/pte-8xx.h
index d44826e..dede1e7 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -48,19 +48,22 @@
  */
 #define _PAGE_RW   0x0400  /* lsb PP bits, inverted in HW */
 #define _PAGE_USER 0x0800  /* msb PP bits */
+/* set when neither _PAGE_USER nor _PAGE_RW are set */
+#define _PAGE_KNLRO0x0200
 
 #define _PMD_PRESENT   0x0001
 #define _PMD_BAD   0x0ff0
 #define _PMD_PAGE_MASK 0x000c
 #define _PMD_PAGE_8M   0x000c
 
-#define _PTE_NONE_MASK _PAGE_ACCESSED
+#define _PTE_NONE_MASK (_PAGE_ACCESSED | _PAGE_KNLRO)
 
 /* Until my rework is finished, 8xx still needs atomic PTE updates */
 #define PTE_ATOMIC_UPDATES 1
 
 /* We need to add _PAGE_SHARED to kernel pages */
-#define _PAGE_KERNEL_RO(_PAGE_SHARED)
+#define _PAGE_KERNEL_RO(_PAGE_SHARED | _PAGE_KNLRO)
+#define _PAGE_KERNEL_ROX   (_PAGE_EXEC | _PAGE_KNLRO)
 #define _PAGE_KERNEL_RW(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index a7af26e..48d3de8 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -445,14 +445,8 @@ DataStoreTLBMiss:
and r11, r11, r10
rlwimi  r10, r11, 0, _PAGE_PRESENT
 #endif
-   /* Honour kernel RO, User NA */
-   /* 0x200 == Extended encoding, bit 22 */
-   rlwimi  r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
-   /* r11 =  (r10  _PAGE_RW)  1 */
-   rlwinm  r11, r10, 32-1, 0x200
-   or  r10, r11, r10
-   /* invert RW and 0x200 bits */
-   xorir10, r10, _PAGE_RW | 0x200
+   /* invert RW */
+   xorir10, r10, _PAGE_RW
 
/* The Linux PTE won't go exactly into the MMU TLB.
 * Software indicator bits 22 and 28 must be clear.
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 12/19] powerpc/8xx: Don't use MD_TWC for walk

2014-08-29 Thread Christophe Leroy
MD_TWC can only be used properly with 4k pages.
So lets calculate level 2 table index by ourselves.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   28 
 1 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index ad15070..0f571f5 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -297,8 +297,6 @@ InstructionTLBMiss:
addir11, r10, -0x1000
tlbie   r11
 #endif
-   DO_8xx_CPU6(0x3780, r3)
-   mtspr   SPRN_MD_EPN, r10/* Have to use MD_EPN for walk, MI_EPN 
can't */
 
/* If we are faulting a kernel address, we have to use the
 * kernel page tables.
@@ -326,10 +324,9 @@ InstructionTLBMiss:
ori r11,r11,1   /* Set valid bit */
DO_8xx_CPU6(0x2b80, r3)
mtspr   SPRN_MI_TWC, r11/* Set segment attributes */
-   DO_8xx_CPU6(0x3b80, r3)
-   mtspr   SPRN_MD_TWC, r11/* Load pte table base address */
-   mfspr   r11, SPRN_MD_TWC/* and get the pte address */
-   lwz r10, 0(r11) /* Get the pte */
+   mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
+   rlwinm  r11, r11, 22, 20, 29/* Extract level 2 index */
+   lwzxr10, r10, r11   /* Get the pte */
 
 #ifdef CONFIG_SWAP
andi.   r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
@@ -395,12 +392,13 @@ DataStoreTLBMiss:
 
/* We have a pte table, so load fetch the pte from the table.
 */
-   ori r11, r11, 1 /* Set valid bit in physical L2 page */
-   DO_8xx_CPU6(0x3b80, r3)
-   mtspr   SPRN_MD_TWC, r11/* Load pte table base address */
-   mfspr   r10, SPRN_MD_TWC/* and get the pte address */
+   mfspr   r10, SPRN_MD_EPN/* Get address of fault */
+   /* Extract level 2 index */
+   rlwinm  r10, r10, 22, 20, 29
+   rlwimi  r10, r11, 0, 0, 19  /* Add level 2 base */
lwz r10, 0(r10) /* Get the pte */
 
+   ori r11, r11, 1 /* Set valid bit in physical L2 page */
/* Insert the Guarded flag into the TWC from the Linux PTE.
 * It is bit 27 of both the Linux PTE and the TWC (at least
 * I got that right :-).  It will be better when we can put
@@ -524,18 +522,16 @@ FixupDAR:/* Entry point for dcbx workaround. */
/* fetch instruction from memory. */
mfspr   r10, SPRN_SRR0
andis.  r11, r10, 0x8000/* Address = 0x8000 */
-   DO_8xx_CPU6(0x3780, r3)
-   mtspr   SPRN_MD_EPN, r10
mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
beq-3f  /* Branch if user space */
lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3: rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
lwzxr11, r10, r11   /* Get the level 1 entry */
-   DO_8xx_CPU6(0x3b80, r3)
-   mtspr   SPRN_MD_TWC, r11/* Load pte table base address */
-   mfspr   r11, SPRN_MD_TWC/* and get the pte address */
-   lwz r11, 0(r11) /* Get the pte */
+   rlwinm  r10, r11,0,0,19 /* Extract page descriptor page address */
+   mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
+   rlwinm  r11, r11, 22, 20, 29/* Extract level 2 index */
+   lwzxr11, r10, r11   /* Get the pte */
 #ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)   /* restore r3 from memory */
 #endif
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 08/19] powerpc/8xx: No need to restore registers and save them again.

2014-08-29 Thread Christophe Leroy
In DTLBError handler there is not need to restore r10, r11 and cr registers
after fixing DAR as they are saved again to the same place just after.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 5f04d5f..e5a250c 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -478,8 +478,8 @@ DataTLBError:
cmpwi   cr0, r11, 0x00f0
beq-FixupDAR/* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
-   EXCEPTION_EPILOG_0
-   EXCEPTION_PROLOG
+   EXCEPTION_PROLOG_1
+   EXCEPTION_PROLOG_2
mfspr   r10,SPRN_DSISR
stw r10,_DSISR(r11)
mr  r5,r10
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 07/19] powerpc/8xx: DataAccess exception not generated by MPC8xx

2014-08-29 Thread Christophe Leroy
DataAccess exception is never generated by MPC8xx so do the job directly where
it is used to avoid an unnecessary branching.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   23 ++-
 1 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 845abf8..5f04d5f 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -219,19 +219,9 @@ MachineCheck:
EXC_XFER_STD(0x200, machine_check_exception)
 
 /* Data access exception.
- * This is never generated by the MPC8xx.  We jump to it for other
- * translation errors.
+ * This is never generated by the MPC8xx.
  */
-   . = 0x300
-DataAccess:
-   EXCEPTION_PROLOG
-   mfspr   r10,SPRN_DSISR
-   stw r10,_DSISR(r11)
-   mr  r5,r10
-   mfspr   r4,SPRN_DAR
-   li  r10,0x00f0
-   mtspr   SPRN_DAR,r10/* Tag DAR, to be used in DTLB Error */
-   EXC_XFER_LITE(0x300, handle_page_fault)
+   EXCEPTION(0x300, DataAccess, unknown_exception, EXC_XFER_STD)
 
 /* Instruction access exception.
  * This is never generated by the MPC8xx.
@@ -489,7 +479,14 @@ DataTLBError:
beq-FixupDAR/* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
EXCEPTION_EPILOG_0
-   b   DataAccess
+   EXCEPTION_PROLOG
+   mfspr   r10,SPRN_DSISR
+   stw r10,_DSISR(r11)
+   mr  r5,r10
+   mfspr   r4,SPRN_DAR
+   li  r10,0x00f0
+   mtspr   SPRN_DAR,r10/* Tag DAR, to be used in DTLB Error */
+   EXC_XFER_LITE(0x1400, handle_page_fault)
 
EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 13/19] powerpc/8xx: Use PAGE size related consts

2014-08-29 Thread Christophe Leroy
For PAGE size related operations, use PAGE size consts in order to be able to
use different page size in the futur.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   30 ++
 1 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 0f571f5..dcaee9f 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -292,9 +292,9 @@ InstructionTLBMiss:
mtspr   SPRN_SPRG_SCRATCH2, r10
mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 #ifdef CONFIG_8xx_CPU15
-   addir11, r10, 0x1000
+   addir11, r10, PAGE_SIZE
tlbie   r11
-   addir11, r10, -0x1000
+   addir11, r10, -PAGE_SIZE
tlbie   r11
 #endif
 
@@ -313,7 +313,8 @@ InstructionTLBMiss:
ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
 #endif
-   rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   /* Extract level 1 index */
+   rlwinm  r10, r10, 32 - ((PAGE_SHIFT - 2)  1), (PAGE_SHIFT - 2)  1, 
29
lwzxr11, r10, r11   /* Get the level 1 entry */
rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
beq 2f  /* If zero, don't try to find a pte */
@@ -325,7 +326,8 @@ InstructionTLBMiss:
DO_8xx_CPU6(0x2b80, r3)
mtspr   SPRN_MI_TWC, r11/* Set segment attributes */
mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
-   rlwinm  r11, r11, 22, 20, 29/* Extract level 2 index */
+   /* Extract level 2 index */
+   rlwinm  r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
lwzxr10, r10, r11   /* Get the pte */
 
 #ifdef CONFIG_SWAP
@@ -385,7 +387,8 @@ DataStoreTLBMiss:
lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
-   rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   /* Extract level 1 index */
+   rlwinm  r10, r10, 32 - ((PAGE_SHIFT - 2)  1), (PAGE_SHIFT - 2)  1, 
29
lwzxr11, r10, r11   /* Get the level 1 entry */
rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
beq 2f  /* If zero, don't try to find a pte */
@@ -394,8 +397,8 @@ DataStoreTLBMiss:
 */
mfspr   r10, SPRN_MD_EPN/* Get address of fault */
/* Extract level 2 index */
-   rlwinm  r10, r10, 22, 20, 29
-   rlwimi  r10, r11, 0, 0, 19  /* Add level 2 base */
+   rlwinm  r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
+   rlwimi  r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
lwz r10, 0(r10) /* Get the pte */
 
ori r11, r11, 1 /* Set valid bit in physical L2 page */
@@ -526,18 +529,20 @@ FixupDAR:/* Entry point for dcbx workaround. */
beq-3f  /* Branch if user space */
lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
-3: rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   /* Extract level 1 index */
+3: rlwinm  r10, r10, 32 - ((PAGE_SHIFT - 2)  1), (PAGE_SHIFT - 2)  1, 
29
lwzxr11, r10, r11   /* Get the level 1 entry */
rlwinm  r10, r11,0,0,19 /* Extract page descriptor page address */
mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
-   rlwinm  r11, r11, 22, 20, 29/* Extract level 2 index */
+   /* Extract level 2 index */
+   rlwinm  r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
lwzxr11, r10, r11   /* Get the pte */
 #ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)   /* restore r3 from memory */
 #endif
/* concat physical page address(r11) and page offset(r10) */
mfspr   r10, SPRN_SRR0
-   rlwimi  r11, r10, 0, 20, 31
+   rlwimi  r11, r10, 0, 32 - PAGE_SHIFT, 31
lwz r11,0(r11)
 /* Check if it really is a dcbx instruction. */
 /* dcbt and dcbtst does not generate DTLB Misses/Errors,
@@ -913,12 +918,13 @@ set_dec_cpu6:
.globl  sdata
 sdata:
.globl  empty_zero_page
+   .align  PAGE_SHIFT
 empty_zero_page:
-   .space  4096
+   .space  PAGE_SIZE
 
.globl  swapper_pg_dir
 swapper_pg_dir:
-   .space  4096
+   .space  PGD_TABLE_SIZE
 
 /* Room for two PTE table poiners, usually the kernel and current user
  * pointer to their respective root page table (pgdir).
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCHv2] clk: ppc-corenet: rename to ppc-qoriq and add CLK_OF_DECLARE support

2014-08-29 Thread Jingchang Lu
The IP is shared on PPC and ARM, this rename it to qoriq for better
represention, and this also add the CLK_OF_DECLARE support for being
initialized by of_clk_init() on ARM.

Signed-off-by: Jingchang Lu jingchang...@freescale.com
---
changes in v2:
 rename the driver name to ppc-qoriq.c for shared on PPC and ARM.

 drivers/clk/Kconfig   |   9 +-
 drivers/clk/Makefile  |   2 +-
 drivers/clk/clk-ppc-corenet.c | 307 -
 drivers/clk/clk-qoriq.c   | 312 ++
 4 files changed, 318 insertions(+), 312 deletions(-)
 delete mode 100644 drivers/clk/clk-ppc-corenet.c
 create mode 100644 drivers/clk/clk-qoriq.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index cfd3af7..d7892b9 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -81,12 +81,13 @@ config COMMON_CLK_AXI_CLKGEN
  Support for the Analog Devices axi-clkgen pcore clock generator for 
Xilinx
  FPGAs. It is commonly used in Analog Devices' reference designs.
 
-config CLK_PPC_CORENET
-   bool Clock driver for PowerPC corenet platforms
-   depends on PPC_E500MC  OF
+config CLK_QORIQ
+   bool Clock driver for PowerPC corenet and compatible ARM-based 
platforms
+   depends on (PPC_E500MC || ARM)  OF
---help---
  This adds the clock driver support for Freescale PowerPC corenet
- platforms using common clock framework.
+ platforms and compatible Freescale ARM based platforms using common
+ clock framework.
 
 config COMMON_CLK_XGENE
bool Clock driver for APM XGene SoC
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 312742c..c8f1f52 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
 obj-$(CONFIG_ARCH_NSPIRE)  += clk-nspire.o
 obj-$(CONFIG_COMMON_CLK_PALMAS)+= clk-palmas.o
-obj-$(CONFIG_CLK_PPC_CORENET)  += clk-ppc-corenet.o
+obj-$(CONFIG_CLK_QORIQ)+= clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)   += clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SI5351)+= clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c
deleted file mode 100644
index 8e58edf..000
--- a/drivers/clk/clk-ppc-corenet.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2013 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * clock driver for Freescale PowerPC corenet SoCs.
- */
-#include linux/clk-provider.h
-#include linux/io.h
-#include linux/kernel.h
-#include linux/module.h
-#include linux/of_address.h
-#include linux/of_platform.h
-#include linux/of.h
-#include linux/slab.h
-
-struct cmux_clk {
-   struct clk_hw hw;
-   void __iomem *reg;
-   u32 flags;
-};
-
-#define PLL_KILL   BIT(31)
-#defineCLKSEL_SHIFT27
-#define CLKSEL_ADJUST  BIT(0)
-#define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
-
-static unsigned int clocks_per_pll;
-
-static int cmux_set_parent(struct clk_hw *hw, u8 idx)
-{
-   struct cmux_clk *clk = to_cmux_clk(hw);
-   u32 clksel;
-
-   clksel = ((idx / clocks_per_pll)  2) + idx % clocks_per_pll;
-   if (clk-flags  CLKSEL_ADJUST)
-   clksel += 8;
-   clksel = (clksel  0xf)  CLKSEL_SHIFT;
-   iowrite32be(clksel, clk-reg);
-
-   return 0;
-}
-
-static u8 cmux_get_parent(struct clk_hw *hw)
-{
-   struct cmux_clk *clk = to_cmux_clk(hw);
-   u32 clksel;
-
-   clksel = ioread32be(clk-reg);
-   clksel = (clksel  CLKSEL_SHIFT)  0xf;
-   if (clk-flags  CLKSEL_ADJUST)
-   clksel -= 8;
-   clksel = (clksel  2) * clocks_per_pll + clksel % 4;
-
-   return clksel;
-}
-
-const struct clk_ops cmux_ops = {
-   .get_parent = cmux_get_parent,
-   .set_parent = cmux_set_parent,
-};
-
-static void __init core_mux_init(struct device_node *np)
-{
-   struct clk *clk;
-   struct clk_init_data init;
-   struct cmux_clk *cmux_clk;
-   struct device_node *node;
-   int rc, count, i;
-   u32 offset;
-   const char *clk_name;
-   const char **parent_names;
-
-   rc = of_property_read_u32(np, reg, offset);
-   if (rc) {
-   pr_err(%s: could not get reg property\n, np-name);
-   return;
-   }
-
-   /* get the input clock source count */
-   count = of_property_count_strings(np, clock-names);
-   if (count  0) {
-   pr_err(%s: get clock count error\n, np-name);
-   return;
-   }
-   parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
- 

[PATCH v2 14/19] powerpc/8xx: Const for TLB RPN forced value

2014-08-29 Thread Christophe Leroy
Value 0x00f0 is used to force bits in TLB level 2 entry. This value is linked
to the page size and will vary when we change the page size. Lets define a const
for it in order to have it at only one place.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index dcaee9f..8966262 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -40,6 +40,13 @@
 #else
 #define DO_8xx_CPU6(val, reg)
 #endif
+
+/*
+ * Value for the bits that have fixed value in RPN entries.
+ * Also used for tagging DAR for DTLBerror.
+ */
+#define RPN_PATTERN0x00f0
+
__HEAD
 _ENTRY(_stext);
 _ENTRY(_start);
@@ -211,7 +218,7 @@ MachineCheck:
EXCEPTION_PROLOG
mfspr r4,SPRN_DAR
stw r4,_DAR(r11)
-   li r5,0x00f0
+   li r5,RPN_PATTERN
mtspr SPRN_DAR,r5   /* Tag DAR, to be used in DTLB Error */
mfspr r5,SPRN_DSISR
stw r5,_DSISR(r11)
@@ -237,7 +244,7 @@ Alignment:
EXCEPTION_PROLOG
mfspr   r4,SPRN_DAR
stw r4,_DAR(r11)
-   li  r5,0x00f0
+   li  r5,RPN_PATTERN
mtspr   SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
mfspr   r5,SPRN_DSISR
stw r5,_DSISR(r11)
@@ -341,7 +348,7 @@ InstructionTLBMiss:
 * set.  All other Linux PTE bits control the behavior
 * of the MMU.
 */
-   li  r11, 0x00f0
+   li  r11, RPN_PATTERN
rlwimi  r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */
DO_8xx_CPU6(0x2d80, r3)
mtspr   SPRN_MI_RPN, r10/* Update TLB entry */
@@ -445,7 +452,7 @@ DataStoreTLBMiss:
 * set.  All other Linux PTE bits control the behavior
 * of the MMU.
 */
-2: li  r11, 0x00f0
+2: li  r11, RPN_PATTERN
rlwimi  r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x3d80, r3)
mtspr   SPRN_MD_RPN, r10/* Update TLB entry */
@@ -479,7 +486,7 @@ DataTLBError:
EXCEPTION_PROLOG_0
 
mfspr   r11, SPRN_DAR
-   cmpwi   cr0, r11, 0x00f0
+   cmpwi   cr0, r11, RPN_PATTERN
beq-FixupDAR/* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
EXCEPTION_PROLOG_1
@@ -488,7 +495,7 @@ DARFixed:/* Return from dcbx instruction bug workaround */
stw r10,_DSISR(r11)
mr  r5,r10
mfspr   r4,SPRN_DAR
-   li  r10,0x00f0
+   li  r10,RPN_PATTERN
mtspr   SPRN_DAR,r10/* Tag DAR, to be used in DTLB Error */
EXC_XFER_LITE(0x1400, handle_page_fault)
 
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[PATCH v2 11/19] powerpc/8xx: Use M_TW instead of M_TWB

2014-08-29 Thread Christophe Leroy
Use M_TW instead of M_TWB for storing Level 1 table address as M_TWB requires
4k aligned tables, which is only the case with 4k pages.
Consequently, we have to calculate the level 1 table index by ourselves.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   48 ++---
 1 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 4a49ff3..ad15070 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -276,8 +276,8 @@ SystemCall:
. = 0x1100
 /*
  * For the MPC8xx, this is a software tablewalk to load the instruction
- * TLB.  It is modelled after the example in the Motorola manual.  The task
- * switch loads the M_TWB register with the pointer to the first level table.
+ * TLB.  The task switch loads the M_TW register with the pointer to the first
+ * level table.
  * If we discover there is no second level table (value is zero) or if there
  * is an invalid pte, we load that into the TLB, which causes another fault
  * into the TLB Error interrupt where we can handle such problems.
@@ -299,7 +299,6 @@ InstructionTLBMiss:
 #endif
DO_8xx_CPU6(0x3780, r3)
mtspr   SPRN_MD_EPN, r10/* Have to use MD_EPN for walk, MI_EPN 
can't */
-   mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
/* If we are faulting a kernel address, we have to use the
 * kernel page tables.
@@ -307,14 +306,17 @@ InstructionTLBMiss:
 #ifdef CONFIG_MODULES
/* Only modules will cause ITLB Misses as we always
 * pin the first 8MB of kernel memory */
-   andi.   r11, r10, 0x0800/* Address = 0x8000 */
+   andis.  r11, r10, 0x8000/* Address = 0x8000 */
+#endif
+   mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
+#ifdef CONFIG_MODULES
beq 3f
-   lis r11, swapper_pg_dir@h
-   ori r11, r11, swapper_pg_dir@l
-   rlwimi  r10, r11, 0, 2, 19
+   lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
+   ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
 #endif
-   lwz r11, 0(r10) /* Get the level 1 entry */
+   rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   lwzxr11, r10, r11   /* Get the level 1 entry */
rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
beq 2f  /* If zero, don't try to find a pte */
 
@@ -375,18 +377,19 @@ DataStoreTLBMiss:
 #endif
EXCEPTION_PROLOG_0
mtspr   SPRN_SPRG_SCRATCH2, r10
-   mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
+   mfspr   r10, SPRN_MD_EPN
 
/* If we are faulting a kernel address, we have to use the
 * kernel page tables.
 */
-   andi.   r11, r10, 0x0800
+   andis.  r11, r10, 0x8000
+   mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
beq 3f
-   lis r11, swapper_pg_dir@h
-   ori r11, r11, swapper_pg_dir@l
-   rlwimi  r10, r11, 0, 2, 19
+   lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
+   ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
-   lwz r11, 0(r10) /* Get the level 1 entry */
+   rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   lwzxr11, r10, r11   /* Get the level 1 entry */
rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
beq 2f  /* If zero, don't try to find a pte */
 
@@ -523,12 +526,12 @@ FixupDAR:/* Entry point for dcbx workaround. */
andis.  r11, r10, 0x8000/* Address = 0x8000 */
DO_8xx_CPU6(0x3780, r3)
mtspr   SPRN_MD_EPN, r10
-   mfspr   r11, SPRN_M_TWB /* Get level 1 table entry address */
+   mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
beq-3f  /* Branch if user space */
lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
-   rlwimi  r11, r10, 32-20, 0xffc /* r11 = r11~0xffc|(r1020)0xffc */
-3: lwz r11, 0(r11) /* Get the level 1 entry */
+3: rlwinm  r10, r10, 12, 20, 29/* Extract level 1 index */
+   lwzxr11, r10, r11   /* Get the level 1 entry */
DO_8xx_CPU6(0x3b80, r3)
mtspr   SPRN_MD_TWC, r11/* Load pte table base address */
mfspr   r11, SPRN_MD_TWC/* and get the pte address */
@@ -537,6 +540,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
lwz r3, 8(r0)   /* restore r3 from memory */
 #endif
/* concat physical page address(r11) and page offset(r10) */
+   mfspr   r10, SPRN_SRR0
rlwimi  r11, r10, 0, 20, 31
lwz r11,0(r11)
 /* Check if it really is a dcbx instruction. */
@@ -692,11 +696,11 @@ start_here:
 #ifdef CONFIG_8xx_CPU6
lis r4, cpu6_errata_word@h
ori r4, r4, 

[PATCH v2 16/19] powerpc/8xx: Better readibility of ERRATA CPU6 handling

2014-08-29 Thread Christophe Leroy
This patch hiddes that SPR address needed for CPU6 ERRATA handling in the macro.
Then we don't have to worry about this address directly in the code.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr

---
 arch/powerpc/kernel/head_8xx.S |   29 -
 1 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 4dd6be0..a7af26e 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -33,12 +33,19 @@
 
 /* Macro to make the code more readable. */
 #ifdef CONFIG_8xx_CPU6
-#define DO_8xx_CPU6(val, reg)  \
-   li  reg, val;   \
-   stw reg, 12(r0);\
-   lwz reg, 12(r0);
+#define SPRN_MI_TWC_ADDR   0x2b80
+#define SPRN_MI_RPN_ADDR   0x2d80
+#define SPRN_MD_TWC_ADDR   0x3b80
+#define SPRN_MD_RPN_ADDR   0x3d80
+
+#define MTSPR_CPU6(spr, reg, treg) \
+   li  treg, spr##_ADDR;   \
+   stw treg, 12(r0);   \
+   lwz treg, 12(r0);   \
+   mtspr   spr, reg
 #else
-#define DO_8xx_CPU6(val, reg)
+#define MTSPR_CPU6(spr, reg, treg) \
+   mtspr   spr, reg
 #endif
 
 /*
@@ -334,8 +341,7 @@ InstructionTLBMiss:
 * for this segment.
 */
ori r11,r11,1   /* Set valid bit */
-   DO_8xx_CPU6(0x2b80, r3)
-   mtspr   SPRN_MI_TWC, r11/* Set segment attributes */
+   MTSPR_CPU6(SPRN_MI_TWC, r11, r3)/* Set segment attributes */
mfspr   r11, SPRN_SRR0  /* Get effective address of fault */
/* Extract level 2 index */
rlwinm  r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
@@ -354,8 +360,7 @@ InstructionTLBMiss:
 */
li  r11, RPN_PATTERN
rlwimi  r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */
-   DO_8xx_CPU6(0x2d80, r3)
-   mtspr   SPRN_MI_RPN, r10/* Update TLB entry */
+   MTSPR_CPU6(SPRN_MI_RPN, r10, r3)/* Update TLB entry */
 
/* Restore registers */
 #ifdef CONFIG_8xx_CPU6
@@ -424,8 +429,7 @@ DataStoreTLBMiss:
 * It is bit 25 in the Linux PTE and bit 30 in the TWC
 */
rlwimi  r11, r10, 32-5, 30, 30
-   DO_8xx_CPU6(0x3b80, r3)
-   mtspr   SPRN_MD_TWC, r11
+   MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
 
/* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
 * We also need to know if the insn is a load/store, so:
@@ -458,8 +462,7 @@ DataStoreTLBMiss:
 */
 2: li  r11, RPN_PATTERN
rlwimi  r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
-   DO_8xx_CPU6(0x3d80, r3)
-   mtspr   SPRN_MD_RPN, r10/* Update TLB entry */
+   MTSPR_CPU6(SPRN_MD_RPN, r10, r3)/* Update TLB entry */
 
/* Restore registers */
 #ifdef CONFIG_8xx_CPU6
-- 
1.7.1

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Check flat device tree version at boot

2014-08-29 Thread Grant Likely
On 29 Aug 2014 02:56, Michael Ellerman m...@ellerman.id.au wrote:

 On Thu, 2014-08-28 at 09:27 -0500, Rob Herring wrote:
  On Thu, Aug 28, 2014 at 3:40 AM, Michael Ellerman m...@ellerman.id.au 
  wrote:
   In commit e6a6928c3ea1 of/fdt: Convert FDT functions to use libfdt,
   the kernel stopped supporting old flat device tree formats. The minimum
   supported version is now 0x10.
 
  Ugg. Is that something which needs to be supported? Supporting it at
  this point would mean adding support to libfdt.

 Well it would have been nice to keep supporting v2, dropping it broke
 kexec-tools for example. But it's done now, so we'll just deal with the
 fallout.

Umm, so we broke userspace? That's not okay. At the very least we
should investigate how much work is needed to bring v2 support into
libfdt, or up-rev the flat tree at runtime before we parse it.

We should be able to update it in-line. IIRC, the main difference
between v2 and v0x10 is that only the leaf node name is encoded into
the node instead of the full name. We can loop over the tree and
truncate all the names while filling the unused bytes with FDT NOP
tags. Should be simple. Something like the following:

fixup_old_device_tree(blob)
{
   for (offset = fdt_next_node(blob, -1, depth);
 offset = 0  depth = 0  !rc;
 offset = fdt_next_node(blob, offset, depth)) {
char *pathp = fdt_get_name(blob, offset, NULL);
if (*pathp == '/') {
char *leaf = kbasename(pathp);
int len = strlen(pathp);
int newlen = strlen(leaf);
strcpy(pathp, leaf); /* copying in place, need
to check make sure this code is safe */
node-size = newlen /* fixme - this is just
pseudocode */
newlen = FDT_TAGALIGN(newlen);
while (newlen  len) {
*(pathp + newlen) = FDT_NOP;
newlen = FDT_TAGALIGN(newlen+1);
}
}
   }

}

There's probable some more elegance that can be put into the above
block, but you get the idea. That could be run in-place without
copying the tree to another location, and it could possibly be done in
the boot wrapper. Then we'd also be able to get rid of the v2
compatibility code elsewhere in drivers/of/fdt.c because it would
already be taken care of.

g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH] powerpc: Check flat device tree version at boot

2014-08-29 Thread Rob Herring
On Fri, Aug 29, 2014 at 6:13 AM, Grant Likely grant.lik...@linaro.org wrote:
 On 29 Aug 2014 02:56, Michael Ellerman m...@ellerman.id.au wrote:

 On Thu, 2014-08-28 at 09:27 -0500, Rob Herring wrote:
  On Thu, Aug 28, 2014 at 3:40 AM, Michael Ellerman m...@ellerman.id.au 
  wrote:
   In commit e6a6928c3ea1 of/fdt: Convert FDT functions to use libfdt,
   the kernel stopped supporting old flat device tree formats. The minimum
   supported version is now 0x10.
 
  Ugg. Is that something which needs to be supported? Supporting it at
  this point would mean adding support to libfdt.

 Well it would have been nice to keep supporting v2, dropping it broke
 kexec-tools for example. But it's done now, so we'll just deal with the
 fallout.

 Umm, so we broke userspace? That's not okay. At the very least we
 should investigate how much work is needed to bring v2 support into
 libfdt, or up-rev the flat tree at runtime before we parse it.

Would up-reving work? kexec-tools is broken or booting a new kernel
with kexec is broken?

 We should be able to update it in-line. IIRC, the main difference
 between v2 and v0x10 is that only the leaf node name is encoded into
 the node instead of the full name. We can loop over the tree and
 truncate all the names while filling the unused bytes with FDT NOP
 tags. Should be simple. Something like the following:

There is also the name property in v1-v3. I'm guessing linux ignores
that already?


 fixup_old_device_tree(blob)
 {
for (offset = fdt_next_node(blob, -1, depth);
  offset = 0  depth = 0  !rc;
  offset = fdt_next_node(blob, offset, depth)) {
 char *pathp = fdt_get_name(blob, offset, NULL);
 if (*pathp == '/') {
 char *leaf = kbasename(pathp);
 int len = strlen(pathp);
 int newlen = strlen(leaf);
 strcpy(pathp, leaf); /* copying in place, need
 to check make sure this code is safe */
 node-size = newlen /* fixme - this is just
 pseudocode */
 newlen = FDT_TAGALIGN(newlen);
 while (newlen  len) {
 *(pathp + newlen) = FDT_NOP;
 newlen = FDT_TAGALIGN(newlen+1);
 }
 }
}

 }

 There's probable some more elegance that can be put into the above
 block, but you get the idea. That could be run in-place without
 copying the tree to another location, and it could possibly be done in
 the boot wrapper. Then we'd also be able to get rid of the v2
 compatibility code elsewhere in drivers/of/fdt.c because it would
 already be taken care of.

That's what got us into this problem. ;)

Rob
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 17/19] powerpc/8xx: set PTE bit 22 off TLBmiss

2014-08-29 Thread Joakim Tjernlund
Christophe Leroy christophe.le...@c-s.fr wrote on 2014/08/29 11:14:40:
 
 No need to re-set this bit at each TLB miss. Let's set it in the PTE.
 
 Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
 
 ---
  arch/powerpc/include/asm/pgtable-ppc32.h |   21 +
  arch/powerpc/include/asm/pte-8xx.h   |7 +--
  arch/powerpc/kernel/head_8xx.S   |   10 ++
  3 files changed, 28 insertions(+), 10 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h 
b/arch/powerpc/include/asm/pgtable-ppc32.h
 index 47edde8..c261792 100644
 --- a/arch/powerpc/include/asm/pgtable-ppc32.h
 +++ b/arch/powerpc/include/asm/pgtable-ppc32.h
 @@ -172,6 +172,26 @@ static inline unsigned long pte_update(pte_t *p,
  #ifdef PTE_ATOMIC_UPDATES
 unsigned long old, tmp;
 
 +#ifdef CONFIG_PPC_8xx
 +   unsigned long tmp2;
 +
 +   __asm__ __volatile__(\
 +1:   lwarx   %0,0,%4\n\
 +   andc   %1,%0,%5\n\
 +   or   %1,%1,%6\n\
 +   /* 0x200 == Extended encoding, bit 22 */ \
 +   /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ 
\
 +   rlwimi   %1,%1,32-2,0x200\n /* get _PAGE_USER */ \
 +   rlwinm   %3,%1,32-1,0x200\n /* get _PAGE_RW */ \
 +   or   %1,%3,%1\n\
 +   xori   %1,%1,0x200\n
 +   PPC405_ERR77(0,%4)

Should above PPC405_ really be there? This is 8xx only

 +   stwcx.   %1,0,%4\n\
 +   bne-   1b
 +   : =r (old), =r (tmp), =m (*p), =r (tmp2)
 +   : r (p), r (clr), r (set), m (*p)
 +   : cc );
 +#else /* CONFIG_PPC_8xx */
 __asm__ __volatile__(\
  1:   lwarx   %0,0,%3\n\
 andc   %1,%0,%4\n\
 @@ -182,6 +202,7 @@ static inline unsigned long pte_update(pte_t *p,
 : =r (old), =r (tmp), =m (*p)
 : r (p), r (clr), r (set), m (*p)
 : cc );
 +#endif /* CONFIG_PPC_8xx */
  #else /* PTE_ATOMIC_UPDATES */
 unsigned long old = pte_val(*p);
 *p = __pte((old  ~clr) | set);
 diff --git a/arch/powerpc/include/asm/pte-8xx.h 
b/arch/powerpc/include/asm/pte-8xx.h
 index d44826e..dede1e7 100644
 --- a/arch/powerpc/include/asm/pte-8xx.h
 +++ b/arch/powerpc/include/asm/pte-8xx.h
 @@ -48,19 +48,22 @@
   */
  #define _PAGE_RW   0x0400   /* lsb PP bits, inverted in HW */
  #define _PAGE_USER   0x0800   /* msb PP bits */
 +/* set when neither _PAGE_USER nor _PAGE_RW are set */
 +#define _PAGE_KNLRO   0x0200
 
  #define _PMD_PRESENT   0x0001
  #define _PMD_BAD   0x0ff0
  #define _PMD_PAGE_MASK   0x000c
  #define _PMD_PAGE_8M   0x000c
 
 -#define _PTE_NONE_MASK _PAGE_ACCESSED
 +#define _PTE_NONE_MASK (_PAGE_ACCESSED | _PAGE_KNLRO)

_PAGE_ACCESSED can be removed from PTE_NONE_MASK as 8xx no longer cheets.
See 2.4 commit 
https://git.kernel.org/cgit/linux/kernel/git/wtarreau/linux-2.4.git/commit/?id=82582b970d04ad4bcfaa9d3f9c3c256619fd889f

 
  /* Until my rework is finished, 8xx still needs atomic PTE updates */
  #define PTE_ATOMIC_UPDATES   1
 
  /* We need to add _PAGE_SHARED to kernel pages */
 -#define _PAGE_KERNEL_RO   (_PAGE_SHARED)
 +#define _PAGE_KERNEL_RO   (_PAGE_SHARED | _PAGE_KNLRO)
 +#define _PAGE_KERNEL_ROX   (_PAGE_EXEC | _PAGE_KNLRO)
  #define _PAGE_KERNEL_RW   (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
 
  #endif /* __KERNEL__ */
 diff --git a/arch/powerpc/kernel/head_8xx.S 
b/arch/powerpc/kernel/head_8xx.S
 index a7af26e..48d3de8 100644
 --- a/arch/powerpc/kernel/head_8xx.S
 +++ b/arch/powerpc/kernel/head_8xx.S
 @@ -445,14 +445,8 @@ DataStoreTLBMiss:
 and   r11, r11, r10
 rlwimi   r10, r11, 0, _PAGE_PRESENT
  #endif
 -   /* Honour kernel RO, User NA */
 -   /* 0x200 == Extended encoding, bit 22 */
 -   rlwimi   r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
 -   /* r11 =  (r10  _PAGE_RW)  1 */
 -   rlwinm   r11, r10, 32-1, 0x200
 -   or   r10, r11, r10
 -   /* invert RW and 0x200 bits */
 -   xori   r10, r10, _PAGE_RW | 0x200
 +   /* invert RW */
 +   xori   r10, r10, _PAGE_RW
 
 /* The Linux PTE won't go exactly into the MMU TLB.
  * Software indicator bits 22 and 28 must be clear.
 -- 
 1.7.1
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 02/19] powerpc/8xx: Use SCRATCH0 and SCRATCH1 also for TLB handlers

2014-08-29 Thread Joakim Tjernlund
Christophe Leroy christophe.le...@c-s.fr wrote on 2014/08/29 11:14:37:
 
 SCRATCH0 and SCRATCH1 are only used in Exceptions prologs where no other
 exception can happen. There is therefore no need to preserve them 
accross
 TLB handlers, we can use them there as in other exceptions. One of the
 advantages is that they do not suffer CPU6 errata unlike M_TW register.

Really nice! Some comments below

 
 Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
 
 ---
  arch/powerpc/kernel/head_8xx.S |  104 
--
  1 files changed, 36 insertions(+), 68 deletions(-)
 
 diff --git a/arch/powerpc/kernel/head_8xx.S 
b/arch/powerpc/kernel/head_8xx.S
 index 1329c5a..3af6db1 100644
 --- a/arch/powerpc/kernel/head_8xx.S
 +++ b/arch/powerpc/kernel/head_8xx.S
 @@ -104,12 +104,15 @@ turn_on_mmu:
   * task's thread_struct.
   */
  #define EXCEPTION_PROLOG   \
 -   mtspr   SPRN_SPRG_SCRATCH0,r10;   \
 -   mtspr   SPRN_SPRG_SCRATCH1,r11;   \
 -   mfcr   r10;  \
 +   EXCEPTION_PROLOG_0;   \
 EXCEPTION_PROLOG_1;   \
 EXCEPTION_PROLOG_2
 
 +#define EXCEPTION_PROLOG_0   \
 +   mtspr   SPRN_SPRG_SCRATCH0,r10;   \
 +   mtspr   SPRN_SPRG_SCRATCH1,r11;   \
 +   mfcr   r10
 +
  #define EXCEPTION_PROLOG_1   \
 mfspr   r11,SPRN_SRR1;  /* check whether user or kernel */ \
 andi.   r11,r11,MSR_PR;   \
 @@ -145,6 +148,14 @@ turn_on_mmu:
 SAVE_2GPRS(7, r11)
 
  /*
 + * Exception exit code.
 + */
 +#define EXCEPTION_EPILOG_0   \
 +   mtcr   r10;  \
 +   mfspr   r10,SPRN_SPRG_SCRATCH0;   \
 +   mfspr   r11,SPRN_SPRG_SCRATCH1
 +
 +/*
   * Note: code which follows this uses cr0.eq (set if from kernel),
   * r11, r12 (SRR0), and r9 (SRR1).
   *
 @@ -293,16 +304,8 @@ InstructionTLBMiss:
  #ifdef CONFIG_8xx_CPU6
 stw   r3, 8(r0)

Perhaps you can use SPRN_DAR to stash R3 now that it is free ?

 Jocke
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 00/19] powerpc/8xx: Optimise MMU TLB handling and add support of 16k pages

2014-08-29 Thread Joakim Tjernlund
Christophe Leroy christophe.le...@c-s.fr wrote on 2014/08/29 11:13:24:
 
 This patchset:
 1) provides several MMU TLB handling optimisation on MPC8xx.
 2) adds support of 16k pages on MPC8xx.
 All changes have been successfully tested on a custom board equipped 
with MPC885
 
 The two differences with first version of the patch are:
 1) I removed the patch number 10, which was implementing a 16 bit 
alignment of the
 PGDIR. It is not worth potentially wasting up to 64k of memory just for 
removing one
 instruction (ori).
 2) I managed to preserve r11 while calculating the level 2 address, 
therefore
 no more need to save r11 into CR.
 
 Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
 Tested-by: Christophe Leroy christophe.le...@c-s.fr

This looks good but I need to look harder, some minor critique 
though(already sent)
 
As you are optimizing I think the impl.of powerpc/8xx: Invalidate non 
present TLBs 
in 2.4 is better than 3.x, compare:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/arch/powerpc/mm/fault.c?id=5efab4a02c89c252fb4cce097aafde5f8208dbfe
with
https://git.kernel.org/cgit/linux/kernel/git/wtarreau/linux-2.4.git/commit/?id=da5c5609e86fb12061f2c05a6ddd80ffc46592b2


This will free the TLB before you jump to xxx_page_fault which might need 
a TLB before invalidation
and it isolates this 8xx quirk in 8xx specific code.

 Jocke
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [PATCH v2 17/19] powerpc/8xx: set PTE bit 22 off TLBmiss

2014-08-29 Thread Scott Wood
On Fri, 2014-08-29 at 11:14 +0200, Christophe Leroy wrote:
 No need to re-set this bit at each TLB miss. Let's set it in the PTE.
 
 Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
 
 ---
  arch/powerpc/include/asm/pgtable-ppc32.h |   21 +
  arch/powerpc/include/asm/pte-8xx.h   |7 +--
  arch/powerpc/kernel/head_8xx.S   |   10 ++
  3 files changed, 28 insertions(+), 10 deletions(-)
 

When you post a vN+1 please indicate below the --- what changed sinced
vN.

-Scott

 diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h 
 b/arch/powerpc/include/asm/pgtable-ppc32.h
 index 47edde8..c261792 100644
 --- a/arch/powerpc/include/asm/pgtable-ppc32.h
 +++ b/arch/powerpc/include/asm/pgtable-ppc32.h
 @@ -172,6 +172,26 @@ static inline unsigned long pte_update(pte_t *p,
  #ifdef PTE_ATOMIC_UPDATES
   unsigned long old, tmp;
  
 +#ifdef CONFIG_PPC_8xx
 + unsigned long tmp2;
 +
 + __asm__ __volatile__(\
 +1:   lwarx   %0,0,%4\n\
 + andc%1,%0,%5\n\
 + or  %1,%1,%6\n\
 + /* 0x200 == Extended encoding, bit 22 */ \
 + /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ \
 + rlwimi  %1,%1,32-2,0x200\n /* get _PAGE_USER */ \
 + rlwinm  %3,%1,32-1,0x200\n /* get _PAGE_RW */ \
 + or  %1,%3,%1\n\
 + xori%1,%1,0x200\n
 + PPC405_ERR77(0,%4)
 +stwcx.  %1,0,%4\n\
 + bne-1b
 + : =r (old), =r (tmp), =m (*p), =r (tmp2)
 + : r (p), r (clr), r (set), m (*p)
 + : cc );
 +#else /* CONFIG_PPC_8xx */
   __asm__ __volatile__(\
  1:   lwarx   %0,0,%3\n\
   andc%1,%0,%4\n\
 @@ -182,6 +202,7 @@ static inline unsigned long pte_update(pte_t *p,
   : =r (old), =r (tmp), =m (*p)
   : r (p), r (clr), r (set), m (*p)
   : cc );
 +#endif /* CONFIG_PPC_8xx */
  #else /* PTE_ATOMIC_UPDATES */
   unsigned long old = pte_val(*p);
   *p = __pte((old  ~clr) | set);
 diff --git a/arch/powerpc/include/asm/pte-8xx.h 
 b/arch/powerpc/include/asm/pte-8xx.h
 index d44826e..dede1e7 100644
 --- a/arch/powerpc/include/asm/pte-8xx.h
 +++ b/arch/powerpc/include/asm/pte-8xx.h
 @@ -48,19 +48,22 @@
   */
  #define _PAGE_RW 0x0400  /* lsb PP bits, inverted in HW */
  #define _PAGE_USER   0x0800  /* msb PP bits */
 +/* set when neither _PAGE_USER nor _PAGE_RW are set */
 +#define _PAGE_KNLRO  0x0200
  
  #define _PMD_PRESENT 0x0001
  #define _PMD_BAD 0x0ff0
  #define _PMD_PAGE_MASK   0x000c
  #define _PMD_PAGE_8M 0x000c
  
 -#define _PTE_NONE_MASK _PAGE_ACCESSED
 +#define _PTE_NONE_MASK (_PAGE_ACCESSED | _PAGE_KNLRO)
  
  /* Until my rework is finished, 8xx still needs atomic PTE updates */
  #define PTE_ATOMIC_UPDATES   1
  
  /* We need to add _PAGE_SHARED to kernel pages */
 -#define _PAGE_KERNEL_RO  (_PAGE_SHARED)
 +#define _PAGE_KERNEL_RO  (_PAGE_SHARED | _PAGE_KNLRO)
 +#define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_KNLRO)
  #define _PAGE_KERNEL_RW  (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
  
  #endif /* __KERNEL__ */
 diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
 index a7af26e..48d3de8 100644
 --- a/arch/powerpc/kernel/head_8xx.S
 +++ b/arch/powerpc/kernel/head_8xx.S
 @@ -445,14 +445,8 @@ DataStoreTLBMiss:
   and r11, r11, r10
   rlwimi  r10, r11, 0, _PAGE_PRESENT
  #endif
 - /* Honour kernel RO, User NA */
 - /* 0x200 == Extended encoding, bit 22 */
 - rlwimi  r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
 - /* r11 =  (r10  _PAGE_RW)  1 */
 - rlwinm  r11, r10, 32-1, 0x200
 - or  r10, r11, r10
 - /* invert RW and 0x200 bits */
 - xorir10, r10, _PAGE_RW | 0x200
 + /* invert RW */
 + xorir10, r10, _PAGE_RW
  
   /* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 22 and 28 must be clear.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[RFC PATCH] powerpc: Wire up three syscalls

2014-08-29 Thread Pranith Kumar
I see that the three syscalls seccomp, getrandom and memfd_create are not wired
because of which we get a warning while compilation.

So I wired them up in this patch. What else needs to be done? I tried the
memfd_test after compiling this kernel, but it is failing. What am I missing for
this to work? Any advice is really appreciated! :)

Signed-off-by: Pranith Kumar bobby.pr...@gmail.com
---
 arch/powerpc/include/asm/systbl.h  | 3 +++
 arch/powerpc/include/asm/unistd.h  | 2 +-
 arch/powerpc/include/uapi/asm/unistd.h | 3 +++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/systbl.h 
b/arch/powerpc/include/asm/systbl.h
index 542bc0f..7d8a600 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -362,3 +362,6 @@ SYSCALL(ni_syscall) /* sys_kcmp */
 SYSCALL_SPU(sched_setattr)
 SYSCALL_SPU(sched_getattr)
 SYSCALL_SPU(renameat2)
+SYSCALL_SPU(seccomp)
+SYSCALL_SPU(getrandom)
+SYSCALL_SPU(memfd_create)
diff --git a/arch/powerpc/include/asm/unistd.h 
b/arch/powerpc/include/asm/unistd.h
index 5ce5552..4e9af3f 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,7 +12,7 @@
 #include uapi/asm/unistd.h
 
 
-#define __NR_syscalls  358
+#define __NR_syscalls  361
 
 #define __NR__exit __NR_exit
 #define NR_syscalls__NR_syscalls
diff --git a/arch/powerpc/include/uapi/asm/unistd.h 
b/arch/powerpc/include/uapi/asm/unistd.h
index 2d526f7..0688fc0 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -380,5 +380,8 @@
 #define __NR_sched_setattr 355
 #define __NR_sched_getattr 356
 #define __NR_renameat2 357
+#define __NR_seccomp   358
+#define __NR_getrandom 359
+#define __NR_memfd_create  360
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
-- 
2.1.0

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev