* [PATCH 1/6] unicore32: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/unicore32/include/asm/pgtable.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/unicore32/include/asm/pgtable.h b/arch/unicore32/include/asm/pgtable.h
index 9492aa304f03..126e961a8cb0 100644
--- a/arch/unicore32/include/asm/pgtable.h
+++ b/arch/unicore32/include/asm/pgtable.h
@@ -198,8 +198,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pgprot_writecombine(prot) \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
-#define pgprot_dmacoherent(prot) \
- __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd) & PMD_PRESENT)
--
2.20.1
^ permalink raw reply related
* [PATCH 2/6] arm-nommu: remove the unused pgprot_dmacoherent define
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/pgtable-nommu.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 0b1f6799a32e..d0de24f06724 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -62,7 +62,6 @@ typedef pte_t *pte_addr_t;
*/
#define pgprot_noncached(prot) (prot)
#define pgprot_writecombine(prot) (prot)
-#define pgprot_dmacoherent(prot) (prot)
#define pgprot_device(prot) (prot)
--
2.20.1
^ permalink raw reply related
* [PATCH 3/6] dma-mapping: remove arch_dma_mmap_pgprot
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
arch_dma_mmap_pgprot is used for two things:
1) to override the "normal" uncached page attributes for mapping
memory coherent to devices that can't snoop the CPU caches
2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
arm systems and some mips platforms
Replace one with the pgprot_dmacoherent macro that is already provided
by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
handling to common code with an explicit arch opt-in.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
arch/arm/Kconfig | 2 +-
arch/arm/mm/dma-mapping.c | 6 ------
arch/arm64/Kconfig | 1 -
arch/arm64/include/asm/pgtable.h | 4 ++++
arch/arm64/mm/dma-mapping.c | 6 ------
arch/m68k/Kconfig | 1 -
arch/m68k/include/asm/pgtable_mm.h | 3 +++
arch/m68k/kernel/dma.c | 3 +--
arch/mips/Kconfig | 2 +-
arch/mips/mm/dma-noncoherent.c | 8 --------
include/linux/dma-noncoherent.h | 13 +++++++++++--
kernel/dma/Kconfig | 12 +++++++++---
kernel/dma/mapping.c | 8 +++++---
13 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24360211534a..217083caeabd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,7 +8,7 @@ config ARM
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
- select ARCH_HAS_DMA_MMAP_PGPROT if SWIOTLB
+ select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..d27b12f61737 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return dma_to_pfn(dev, dma_addr);
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return __get_dma_pgprot(attrs, prot);
-}
-
void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsigned long attrs)
{
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..dab9dda34206 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -13,7 +13,6 @@ config ARM64
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN
- select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e09760ece844..6700371227d1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, \
+ PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..676efcda51e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -11,12 +11,6 @@
#include <asm/cacheflush.h>
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- return pgprot_writecombine(prot);
-}
-
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
size_t size, enum dma_data_direction dir)
{
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..a9e564306d3e 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,7 +4,6 @@ config M68K
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT
- select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h
index fe3ddd73a0cc..fde4534b974f 100644
--- a/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.h
@@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
: (prot)))
+pgprot_t pgprot_dmacoherent(pgprot_t prot);
+#define pgprot_dmacoherent(prot) pgprot_dmacoherent(prot)
+
#endif /* CONFIG_COLDFIRE */
#include <asm-generic/pgtable.h>
#endif /* !__ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 30cd59caf037..35064150e348 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -23,8 +23,7 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
cache_push(page_to_phys(page), size);
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
+pgprot_t pgprot_dmacoherent(pgprot_t prot)
{
if (CPU_IS_040_OR_060) {
pgprot_val(prot) &= ~_PAGE_CACHE040;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d50fafd7bf3a..fc88f68ea1ee 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,7 +1119,7 @@ config DMA_PERDEV_COHERENT
config DMA_NONCOHERENT
bool
- select ARCH_HAS_DMA_MMAP_PGPROT
+ select ARCH_HAS_DMA_WRITE_COMBINE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_UNCACHED_SEGMENT
select NEED_DMA_MAP_STATE
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index ed56c6fa7be2..1d4d57dd9acf 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -65,14 +65,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
return page_to_pfn(virt_to_page(cached_kernel_address(cpu_addr)));
}
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs)
-{
- if (attrs & DMA_ATTR_WRITE_COMBINE)
- return pgprot_writecombine(prot);
- return pgprot_noncached(prot);
-}
-
static inline void dma_sync_virt(void *addr, size_t size,
enum dma_data_direction dir)
{
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
index 0bff3d7fac92..dd3de6d88fc0 100644
--- a/include/linux/dma-noncoherent.h
+++ b/include/linux/dma-noncoherent.h
@@ -3,6 +3,7 @@
#define _LINUX_DMA_NONCOHERENT_H 1
#include <linux/dma-mapping.h>
+#include <asm/pgtable.h>
#ifdef CONFIG_ARCH_HAS_DMA_COHERENCE_H
#include <asm/dma-coherence.h>
@@ -42,10 +43,18 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs);
long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
dma_addr_t dma_addr);
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
- unsigned long attrs);
#ifdef CONFIG_MMU
+/*
+ * Page protection so that devices that can't snoop CPU caches can use the
+ * memory coherently. We default to pgprot_noncached which is usually used
+ * for ioremap as a safe bet, but architectures can override this with less
+ * strict semantics if possible.
+ */
+#ifndef pgprot_dmacoherent
+#define pgprot_dmacoherent(prot) pgprot_noncached(prot)
+#endif
+
pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs);
#else
static inline pgprot_t dma_pgprot(struct device *dev, pgprot_t prot,
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 9decbba255fc..73c5c2b8e824 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -20,6 +20,15 @@ config ARCH_HAS_DMA_COHERENCE_H
config ARCH_HAS_DMA_SET_MASK
bool
+#
+# Select this option if the architecture needs special handling for
+# DMA_ATTR_WRITE_COMBINE. Normally the "uncached" mapping should be what
+# people thing of when saying write combine, so very few platforms should
+# need to enable this.
+#
+config ARCH_HAS_DMA_WRITE_COMBINE
+ bool
+
config DMA_DECLARE_COHERENT
bool
@@ -45,9 +54,6 @@ config ARCH_HAS_DMA_PREP_COHERENT
config ARCH_HAS_DMA_COHERENT_TO_PFN
bool
-config ARCH_HAS_DMA_MMAP_PGPROT
- bool
-
config ARCH_HAS_FORCE_DMA_UNENCRYPTED
bool
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..1b96616c9f20 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -161,9 +161,11 @@ pgprot_t dma_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs)
(IS_ENABLED(CONFIG_DMA_NONCOHERENT_CACHE_SYNC) &&
(attrs & DMA_ATTR_NON_CONSISTENT)))
return prot;
- if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_MMAP_PGPROT))
- return arch_dma_mmap_pgprot(dev, prot, attrs);
- return pgprot_noncached(prot);
+#ifdef CONFIG_ARCH_HAS_DMA_WRITE_COMBINE
+ if (attrs & DMA_ATTR_WRITE_COMBINE)
+ return pgprot_writecombine(prot);
+#endif
+ return pgprot_dmacoherent(prot);
}
#endif /* CONFIG_MMU */
--
2.20.1
^ permalink raw reply related
* [PATCH 4/6] dma-mapping: make dma_atomic_pool_init self-contained
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
The memory allocated for the atomic pool needs to have the same
mapping attributes that we use for remapping, so use
pgprot_dmacoherent instead of open coding it. Also deduct a
suitable zone to allocate the memory from based on the presence
of the DMA zones.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arc/mm/dma.c | 6 ------
arch/arm64/mm/dma-mapping.c | 6 ------
arch/csky/mm/dma-mapping.c | 6 ------
arch/nds32/kernel/dma.c | 6 ------
include/linux/dma-mapping.h | 1 -
kernel/dma/remap.c | 17 ++++++++++++++---
6 files changed, 14 insertions(+), 28 deletions(-)
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 62c210e7ee4c..ff4a5752f8cc 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -104,9 +104,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
dev_info(dev, "use %sncoherent DMA ops\n",
dev->dma_coherent ? "" : "non");
}
-
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 676efcda51e6..a1d05f669f67 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -28,12 +28,6 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
__dma_flush_area(page_address(page), size);
}
-static int __init arm64_dma_init(void)
-{
- return dma_atomic_pool_init(GFP_DMA32, __pgprot(PROT_NORMAL_NC));
-}
-arch_initcall(arm64_dma_init);
-
#ifdef CONFIG_IOMMU_DMA
void arch_teardown_dma_ops(struct device *dev)
{
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
index 80783bb71c5c..602a60d47a94 100644
--- a/arch/csky/mm/dma-mapping.c
+++ b/arch/csky/mm/dma-mapping.c
@@ -14,12 +14,6 @@
#include <linux/version.h>
#include <asm/cache.h>
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
-
void arch_dma_prep_coherent(struct page *page, size_t size)
{
if (PageHighMem(page)) {
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 490e3720d694..4206d4b6c8ce 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -80,9 +80,3 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
{
cache_op(page_to_phys(page), size, cpu_dma_wbinval_range);
}
-
-static int __init atomic_pool_init(void)
-{
- return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..48ebe8295987 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -624,7 +624,6 @@ void *dma_common_pages_remap(struct page **pages, size_t size,
const void *caller);
void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags);
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot);
bool dma_in_atomic_pool(void *start, size_t size);
void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags);
bool dma_free_from_pool(void *start, size_t size);
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
index ffe78f0b2fe4..838123f79639 100644
--- a/kernel/dma/remap.c
+++ b/kernel/dma/remap.c
@@ -105,7 +105,16 @@ static int __init early_coherent_pool(char *p)
}
early_param("coherent_pool", early_coherent_pool);
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
+static gfp_t dma_atomic_pool_gfp(void)
+{
+ if (IS_ENABLED(CONFIG_ZONE_DMA))
+ return GFP_DMA;
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+ return GFP_DMA32;
+ return GFP_KERNEL;
+}
+
+static int __init dma_atomic_pool_init(void)
{
unsigned int pool_size_order = get_order(atomic_pool_size);
unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
@@ -117,7 +126,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
page = dma_alloc_from_contiguous(NULL, nr_pages,
pool_size_order, false);
else
- page = alloc_pages(gfp, pool_size_order);
+ page = alloc_pages(dma_atomic_pool_gfp(), pool_size_order);
if (!page)
goto out;
@@ -128,7 +137,8 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
goto free_page;
addr = dma_common_contiguous_remap(page, atomic_pool_size, VM_USERMAP,
- prot, __builtin_return_address(0));
+ pgprot_dmacoherent(PAGE_KERNEL),
+ __builtin_return_address(0));
if (!addr)
goto destroy_genpool;
@@ -155,6 +165,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
atomic_pool_size / 1024);
return -ENOMEM;
}
+postcore_initcall(dma_atomic_pool_init);
bool dma_in_atomic_pool(void *start, size_t size)
{
--
2.20.1
^ permalink raw reply related
* [PATCH 5/6] arm64: document the choice of page attributes for pgprot_dmacoherent
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Mark Rutland, Shawn Anastasio, Will Deacon, linux-m68k,
Guan Xuetao, linuxppc-dev, linux-kernel, Russell King, linux-mips,
Paul Burton, Geert Uytterhoeven, Catalin Marinas, James Hogan,
Robin Murphy, linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
Based on an email from Will Deacon.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
arch/arm64/include/asm/pgtable.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6700371227d1..fd40fb05eb51 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
#define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
+/*
+ * DMA allocations for non-coherent devices use what the Arm architecture calls
+ * "Normal non-cacheable" memory, which permits speculation, unaligned accesses
+ * and merging of writes. This is different from "Device-nGnR[nE]" memory which
+ * is intended for MMIO and thus forbids speculation, preserves access size,
+ * requires strict alignment and can also force write responses to come from the
+ * endpoint.
+ */
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
--
2.20.1
^ permalink raw reply related
* [PATCH 6/6] MIPS: document mixing "slightly different CCAs"
From: Christoph Hellwig @ 2019-08-26 13:25 UTC (permalink / raw)
To: iommu
Cc: Shawn Anastasio, Will Deacon, linux-m68k, Guan Xuetao,
linuxppc-dev, linux-kernel, Russell King, linux-mips, Paul Burton,
Geert Uytterhoeven, Catalin Marinas, James Hogan, Robin Murphy,
linux-arm-kernel
In-Reply-To: <20190826132553.4116-1-hch@lst.de>
Based on an email from Paul Burton, quoting section 4.8 "Cacheability and
Coherency Attributes and Access Types" of "MIPS Architecture Volume 1:
Introduction to the MIPS32 Architecture" (MD00080, revision 6.01).
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/Kconfig | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index fc88f68ea1ee..aff1cadeea43 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,6 +1119,13 @@ config DMA_PERDEV_COHERENT
config DMA_NONCOHERENT
bool
+ #
+ # MIPS allows mixing "slightly different" Cacheability and Coherency
+ # Attribute bits. It is believed that the uncached access through
+ # KSEG1 and the implementation specific "uncached accelerated" used
+ # by pgprot_writcombine can be mixed, and the latter sometimes provides
+ # significant advantages.
+ #
select ARCH_HAS_DMA_WRITE_COMBINE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_UNCACHED_SEGMENT
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] powerpc/time: use feature fixup in __USE_RTC() instead of cpu feature.
From: Christophe Leroy @ 2019-08-26 13:40 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Michael Ellerman, Paul Mackerras
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <60da7620a43dc29317a062f1d58dcfde8d32b258.camel@kernel.crashing.org>
Le 26/08/2019 à 15:25, Benjamin Herrenschmidt a écrit :
> On Mon, 2019-08-26 at 21:41 +1000, Michael Ellerman wrote:
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>> sched_clock(), used by printk(), calls __USE_RTC() to know
>>> whether to use realtime clock or timebase.
>>>
>>> __USE_RTC() uses cpu_has_feature() which is initialised by
>>> machine_init(). Before machine_init(), __USE_RTC() returns true,
>>> leading to a program check exception on CPUs not having realtime
>>> clock.
>>>
>>> In order to be able to use printk() earlier, use feature fixup.
>>> Feature fixups are applies in early_init(), enabling the use of
>>> printk() earlier.
>>>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>> ---
>>> arch/powerpc/include/asm/time.h | 9 ++++++++-
>>> 1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> The other option would be just to make this a compile time decision, eg.
>> add CONFIG_PPC_601 and use that to gate whether we use RTC.
>>
>> Given how many 601 users there are, maybe 1?, I think that would be a
>> simpler option and avoids complicating the code / binary for everyone
>> else.
>
> Didn't we ditch 601 support years ago anyway ? We had workaround we
> threw out I think...
There are still workarounds for 601 in the kernel, for exemple (in
arch/powerpc/include/asm/ppc_asm.h)
/* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX
#define SYNC \
BEGIN_FTR_SECTION \
sync; \
isync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define SYNC_601 \
BEGIN_FTR_SECTION \
sync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#define ISYNC_601 \
BEGIN_FTR_SECTION \
isync; \
END_FTR_SECTION_IFSET(CPU_FTR_601)
#else
#define SYNC
#define SYNC_601
#define ISYNC_601
#endif
But if you think we can get rid of 601 completely, I'm happy with that.
Christophe
>
> Cheers,
> Ben.
>
>> cheers
>>
>>> diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
>>> index 54f4ec1f9fab..3455cb54c333 100644
>>> --- a/arch/powerpc/include/asm/time.h
>>> +++ b/arch/powerpc/include/asm/time.h
>>> @@ -42,7 +42,14 @@ struct div_result {
>>> /* Accessor functions for the timebase (RTC on 601) registers. */
>>> /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
>>> #ifdef CONFIG_PPC_BOOK3S_32
>>> -#define __USE_RTC() (cpu_has_feature(CPU_FTR_USE_RTC))
>>> +static inline bool __USE_RTC(void)
>>> +{
>>> + asm_volatile_goto(ASM_FTR_IFCLR("nop;", "b %1;", %0) ::
>>> + "i" (CPU_FTR_USE_RTC) :: l_use_rtc);
>>> + return false;
>>> +l_use_rtc:
>>> + return true;
>>> +}
>>> #else
>>> #define __USE_RTC() 0
>>> #endif
>>> --
>>> 2.13.3
^ permalink raw reply
* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 14:01 UTC (permalink / raw)
To: Nayna Jain
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <1566825818-9731-3-git-send-email-nayna@linux.ibm.com>
On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> +static struct bin_attribute update_attr = {
> + .attr = {.name = "update", .mode = 0200},
> + .size = VARIABLE_MAX_SIZE,
> + .write = update_write,
> +};
Ah, do we need a __BIN_ATTR_WO() macro for you? That would make this
more obvious, right?
Other than that minor thing (not a complaint at all) looks much better
to me, nice work:
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 14:12 UTC (permalink / raw)
To: Greg Kroah-Hartman, Nayna Jain
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <20190826140131.GA15270@kroah.com>
On 08/26/2019 10:01 AM, Greg Kroah-Hartman wrote:
> On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
>> +static struct bin_attribute update_attr = {
>> + .attr = {.name = "update", .mode = 0200},
>> + .size = VARIABLE_MAX_SIZE,
>> + .write = update_write,
>> +};
> Ah, do we need a __BIN_ATTR_WO() macro for you? That would make this
> more obvious, right?
Thanks Greg. Yes, I agree it will be good to have that.
Thanks & Regards,
- Nayna
^ permalink raw reply
* Re: [PATCH v2 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 13:25 UTC (permalink / raw)
To: Greg Kroah-Hartman, Nayna Jain
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <20190821163018.GA28571@kroah.com>
[-- Attachment #1: Type: text/plain, Size: 9104 bytes --]
On 08/21/2019 12:30 PM, Greg Kroah-Hartman wrote:
> On Wed, Aug 21, 2019 at 11:08:21AM -0400, Nayna Jain wrote:
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-secvar
>> @@ -0,0 +1,27 @@
>> +What: /sys/firmware/secvar
>> +Date: August 2019
>> +Contact: Nayna Jain<nayna@linux.ibm.com>
>> +Description:
>> + This directory exposes interfaces for interacting with
>> + the secure variables managed by OPAL firmware.
>> +
>> + This is only for the powerpc/powernv platform.
>> +
>> + Directory:
>> + vars: This directory lists all the variables that
>> + are supported by the OPAL. The variables are
>> + represented in the form of directories with
>> + their variable names. The variable name is
>> + unique and is in ASCII representation. The data
>> + and size can be determined by reading their
>> + respective attribute files.
>> +
>> + Each variable directory has the following files:
>> + name: An ASCII representation of the variable name
>> + data: A read-only file containing the value of the
>> + variable
>> + size: An integer representation of the size of the
>> + content of the variable. In other works, it
>> + represents the size of the data
>> + update: A write-only file that is used to submit the new
>> + value for the variable.
> Can you break this out into one-entry-per-file like most other entries
> are defined? That makes it easier for tools to parse (specifically the
> tool in the tree right now...)
>
>
>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 42109682b727..b4bdf77837b2 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -925,6 +925,15 @@ config PPC_SECURE_BOOT
>> allows user to enable OS Secure Boot on PowerPC systems that
>> have firmware secure boot support.
>>
>> +config SECVAR_SYSFS
>> + tristate "Enable sysfs interface for POWER secure variables"
>> + depends on PPC_SECURE_BOOT
> No depends on SYSFS?
>
>> + help
>> + POWER secure variables are managed and controlled by firmware.
>> + These variables are exposed to userspace via sysfs to enable
>> + read/write operations on these variables. Say Y if you have
>> + secure boot enabled and want to expose variables to userspace.
> Mix of tabs and spaces :(
>
>> +
>> endmenu
>>
>> config ISA_DMA_API
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index 9041563f1c74..4ea7b738c3a3 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -158,6 +158,7 @@ obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o
>> obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
>>
>> obj-$(CONFIG_PPC_SECURE_BOOT) += secboot.o ima_arch.o secvar-ops.o
>> +obj-$(CONFIG_SECVAR_SYSFS) += secvar-sysfs.o
> No tab?
>
>>
>> # Disable GCOV, KCOV & sanitizers in odd or sensitive code
>> GCOV_PROFILE_prom_init.o := n
>> diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c
>> new file mode 100644
>> index 000000000000..e46986bb29a0
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/secvar-sysfs.c
>> @@ -0,0 +1,210 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 IBM Corporation<nayna@linux.ibm.com>
>> + *
>> + * This code exposes secure variables to user via sysfs
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/compat.h>
>> +#include <linux/string.h>
>> +#include <asm/opal.h>
>> +#include <asm/secvar.h>
>> +
>> +//Approximating it for now, it is bound to change.
> " " before "A" here please.
>
>> +#define VARIABLE_MAX_SIZE 32000
>> +
>> +static struct kobject *powerpc_kobj;
>> +static struct secvar_operations *secvarops;
>> +struct kset *secvar_kset;
>> +
>> +static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr,
>> + char *buf)
>> +{
>> + return sprintf(buf, "%s", kobj->name);
>> +}
> Why do you need this entry as it is the directory name? Userspace
> already "knows" it if they can open this file.
>
>
>> +
>> +static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr,
>> + char *buf)
>> +{
>> + unsigned long dsize;
>> + int rc;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error retrieving variable size %d\n", rc);
>> + return rc;
>> + }
>> +
>> + rc = sprintf(buf, "%ld", dsize);
>> +
>> + return rc;
>> +}
>> +
>> +static ssize_t data_read(struct file *filep, struct kobject *kobj,
>> + struct bin_attribute *attr, char *buf, loff_t off,
>> + size_t count)
>> +{
>> + unsigned long dsize;
>> + int rc;
>> + char *data;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error getting variable size %d\n", rc);
>> + return rc;
>> + }
>> + pr_debug("dsize is %ld\n", dsize);
>> +
>> + data = kzalloc(dsize, GFP_KERNEL);
>> + if (!data)
>> + return -ENOMEM;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name)+1, data,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error getting variable %d\n", rc);
>> + goto data_fail;
>> + }
>> +
>> + rc = memory_read_from_buffer(buf, count, &off, data, dsize);
>> +
>> +data_fail:
>> + kfree(data);
>> + return rc;
>> +}
>> +
>> +static ssize_t update_write(struct file *filep, struct kobject *kobj,
>> + struct bin_attribute *attr, char *buf, loff_t off,
>> + size_t count)
>> +{
>> + int rc;
>> +
>> + pr_debug("count is %ld\n", count);
>> + rc = secvarops->set_variable(kobj->name, strlen(kobj->name)+1, buf,
>> + count);
>> + if (rc) {
>> + pr_err("Error setting the variable %s\n", kobj->name);
>> + return rc;
>> + }
>> +
>> + return count;
>> +}
>> +
>> +static struct kobj_attribute name_attr =
>> +__ATTR(name, 0444, name_show, NULL);
> __ATTR_RO()?
>
>> +
>> +static struct kobj_attribute size_attr =
>> +__ATTR(size, 0444, size_show, NULL);
> __ATTR_RO()?
>
>> +
>> +static struct bin_attribute data_attr = {
>> + .attr = {.name = "data", .mode = 0444},
>> + .size = VARIABLE_MAX_SIZE,
>> + .read = data_read,
>> +};
> __BIN_ATTR_RO()?
>
>> +
>> +
>> +static struct bin_attribute update_attr = {
>> + .attr = {.name = "update", .mode = 0200},
>> + .size = VARIABLE_MAX_SIZE,
>> + .write = update_write,
>> +};
> __BIN_ATTR_RO()?
>
>
>> +
>> +static struct bin_attribute *secvar_bin_attrs[] = {
>> + &data_attr,
>> + &update_attr,
>> + NULL,
>> +};
>> +
>> +static struct attribute *secvar_attrs[] = {
>> + &name_attr.attr,
>> + &size_attr.attr,
>> + NULL,
>> +};
>> +
>> +const struct attribute_group secvar_attr_group = {
>> + .attrs = secvar_attrs,
>> + .bin_attrs = secvar_bin_attrs,
>> +};
> static?
>
>> +
>> +int secvar_sysfs_load(void)
>> +{
>> +
>> + char *name;
> No blank line. You didn't run this this through checkpatch, did you :(
>
>
>> + unsigned long namesize;
>> + struct kobject *kobj;
>> + int status;
>> + int rc = 0;
>> +
>> + name = kzalloc(1024, GFP_KERNEL);
> Why 1024?
>
>> + if (!name)
>> + return -ENOMEM;
>> +
>> + do {
>> +
>> + status = secvarops->get_next_variable(name, &namesize, 1024);
>> + if (status != OPAL_SUCCESS)
>> + break;
>> +
>> + pr_info("name is %s\n", name);
> Please delete debugging messages.
>
>> + kobj = kobject_create_and_add(name, &(secvar_kset->kobj));
>> + if (kobj) {
>> + rc = sysfs_create_group(kobj, &secvar_attr_group);
> You just raced userspace and lost :(
>
> If you set your kobj_type to have the attribute group you will not race
> and loose, the core will handle it for you.
>
>
>> + if (rc)
>> + pr_err("Error creating attributes for %s variable\n",
>> + name);
>> + } else {
>> + pr_err("Error creating sysfs entry for %s variable\n",
>> + name);
>> + rc = -EINVAL;
>> + }
>> +
>> + } while ((status == OPAL_SUCCESS) && (rc == 0));
>> +
>> + kfree(name);
>> + return rc;
>> +}
>> +
>> +int secvar_sysfs_init(void)
>> +{
>> + powerpc_kobj = kobject_create_and_add("secvar", firmware_kobj);
>> + if (!powerpc_kobj) {
>> + pr_err("secvar: Failed to create firmware kobj\n");
>> + return -ENODEV;
>> + }
>> +
>> + secvar_kset = kset_create_and_add("vars", NULL, powerpc_kobj);
>> + if (!secvar_kset) {
>> + pr_err("secvar: sysfs kobject registration failed.\n");
> You juat leaked a kobject :(
>
>> + return -ENODEV;
>> + }
>> +
>> + secvarops = get_secvar_ops();
>> + if (!secvarops) {
>> + kobject_put(powerpc_kobj);
>> + pr_err("secvar: failed to retrieve secvar operations.\n");
>> + return -ENODEV;
> You just leaked 2 things from above :(
>
>> + }
>> +
>> + secvar_sysfs_load();
>> + pr_info("Secure variables sysfs initialized");
> Do not be noisy when all goes just fine. The kernel log should be quiet
> when all goes well.
>
Thanks Greg for feedback. I just posted v3 version with the fixes
suggested by you and Oliver.
Currently, the name length as 1024 is taken from examples of efivars.
Probably a smaller one is fine.
In v3 version, it is still 1024 but made it #define.
Thanks & Regards,
- Nayna
[-- Attachment #2: Type: text/html, Size: 10858 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 13:26 UTC (permalink / raw)
To: Oliver O'Halloran, Nayna Jain, linuxppc-dev, linux-efi,
linux-integrity
Cc: Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, Greg Kroah-Hartman,
Paul Mackerras, Jeremy Kerr, Elaine Palmer, George Wilson
In-Reply-To: <23135466fc524a13cd76532ec59f84de51152a1c.camel@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 8538 bytes --]
On 08/22/2019 01:18 AM, Oliver O'Halloran wrote:
> On Wed, 2019-08-21 at 11:08 -0400, Nayna Jain wrote:
>> PowerNV secure variables, which store the keys used for OS kernel
>> verification, are managed by the firmware. These secure variables need to
>> be accessed by the userspace for addition/deletion of the certificates.
>>
>> This patch adds the sysfs interface to expose secure variables for PowerNV
>> secureboot. The users shall use this interface for manipulating
>> the keys stored in the secure variables.
>>
>> Signed-off-by: Nayna Jain<nayna@linux.ibm.com>
>> ---
>> Documentation/ABI/testing/sysfs-secvar | 27 ++++
>> arch/powerpc/Kconfig | 9 ++
>> arch/powerpc/kernel/Makefile | 1 +
>> arch/powerpc/kernel/secvar-sysfs.c | 210 +++++++++++++++++++++++++
>> 4 files changed, 247 insertions(+)
>> create mode 100644 Documentation/ABI/testing/sysfs-secvar
>> create mode 100644 arch/powerpc/kernel/secvar-sysfs.c
>>
>> diff --git a/Documentation/ABI/testing/sysfs-secvar b/Documentation/ABI/testing/sysfs-secvar
>> new file mode 100644
>> index 000000000000..68f0e03d873d
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-secvar
>> @@ -0,0 +1,27 @@
>> +What: /sys/firmware/secvar
>> +Date: August 2019
>> +Contact: Nayna Jain<nayna@linux.ibm.com>
>> +Description:
>> + This directory exposes interfaces for interacting with
>> + the secure variables managed by OPAL firmware.
>> +
>> + This is only for the powerpc/powernv platform.
>> +
>> + Directory:
>> + vars: This directory lists all the variables that
>> + are supported by the OPAL. The variables are
>> + represented in the form of directories with
>> + their variable names. The variable name is
>> + unique and is in ASCII representation. The data
>> + and size can be determined by reading their
>> + respective attribute files.
>> +
>> + Each variable directory has the following files:
>> + name: An ASCII representation of the variable name
>> + data: A read-only file containing the value of the
>> + variable
>> + size: An integer representation of the size of the
>> + content of the variable. In other works, it
>> + represents the size of the data
>> + update: A write-only file that is used to submit the new
>> + value for the variable.
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 42109682b727..b4bdf77837b2 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -925,6 +925,15 @@ config PPC_SECURE_BOOT
>> allows user to enable OS Secure Boot on PowerPC systems that
>> have firmware secure boot support.
>>
>> +config SECVAR_SYSFS
>> + tristate "Enable sysfs interface for POWER secure variables"
>> + depends on PPC_SECURE_BOOT
>> + help
>> + POWER secure variables are managed and controlled by firmware.
>> + These variables are exposed to userspace via sysfs to enable
>> + read/write operations on these variables. Say Y if you have
>> + secure boot enabled and want to expose variables to userspace.
>> +
>> endmenu
>>
>> config ISA_DMA_API
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index 9041563f1c74..4ea7b738c3a3 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -158,6 +158,7 @@ obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o
>> obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
>>
>> obj-$(CONFIG_PPC_SECURE_BOOT) += secboot.o ima_arch.o secvar-ops.o
>> +obj-$(CONFIG_SECVAR_SYSFS) += secvar-sysfs.o
>>
>> # Disable GCOV, KCOV & sanitizers in odd or sensitive code
>> GCOV_PROFILE_prom_init.o := n
>> diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c
>> new file mode 100644
>> index 000000000000..e46986bb29a0
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/secvar-sysfs.c
>> @@ -0,0 +1,210 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2019 IBM Corporation<nayna@linux.ibm.com>
>> + *
>> + * This code exposes secure variables to user via sysfs
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/compat.h>
>> +#include <linux/string.h>
>> +#include <asm/opal.h>
>> +#include <asm/secvar.h>
>> +
>> +//Approximating it for now, it is bound to change.
>> +#define VARIABLE_MAX_SIZE 32000
> this needs to be communicated from the secvar backend, maybe via a
> field in the ops structure?
Thanks Oliver, I have just posted v3 version which includes yours and
Greg's feedbacks.
And giving some of the responses here.
Yes for this one, thinking of doing it via device-tree as they will be
fixed values for a particular platform
>> +
>> +static struct kobject *powerpc_kobj;
> Call it secvar_kobj or something.
>
>> +static struct secvar_operations *secvarops;
> Ah, the old I-can't-believe-it's-not-global trick.
>
>> +struct kset *secvar_kset;
> shouldn't that be static too?
>
>> +
>> +static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr,
>> + char *buf)
>> +{
>> + return sprintf(buf, "%s", kobj->name);
>> +}
>> +
>> +static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr,
>> + char *buf)
>> +{
>> + unsigned long dsize;
>> + int rc;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error retrieving variable size %d\n", rc);
>> + return rc;
>> + }
>> +
>> + rc = sprintf(buf, "%ld", dsize);
>> +
>> + return rc;
>> +}
>> +
>> +static ssize_t data_read(struct file *filep, struct kobject *kobj,
>> + struct bin_attribute *attr, char *buf, loff_t off,
>> + size_t count)
>> +{
>> + unsigned long dsize;
>> + int rc;
>> + char *data;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name) + 1, NULL,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error getting variable size %d\n", rc);
>> + return rc;
>> + }
>> + pr_debug("dsize is %ld\n", dsize);
>> +
>> + data = kzalloc(dsize, GFP_KERNEL);
>> + if (!data)
>> + return -ENOMEM;
>> +
>> + rc = secvarops->get_variable(kobj->name, strlen(kobj->name)+1, data,
>> + &dsize);
>> + if (rc) {
>> + pr_err("Error getting variable %d\n", rc);
>> + goto data_fail;
>> + }
>> +
>> + rc = memory_read_from_buffer(buf, count, &off, data, dsize);
>> +
>> +data_fail:
>> + kfree(data);
>> + return rc;
>> +}
>> +
>> +static ssize_t update_write(struct file *filep, struct kobject *kobj,
>> + struct bin_attribute *attr, char *buf, loff_t off,
>> + size_t count)
>> +{
>> + int rc;
>> +
>> + pr_debug("count is %ld\n", count);
>> + rc = secvarops->set_variable(kobj->name, strlen(kobj->name)+1, buf,
>> + count);
>> + if (rc) {
>> + pr_err("Error setting the variable %s\n", kobj->name);
>> + return rc;
>> + }
>> +
>> + return count;
>> +}
>> +
>> +static struct kobj_attribute name_attr =
>> +__ATTR(name, 0444, name_show, NULL);
>> +
>> +static struct kobj_attribute size_attr =
>> +__ATTR(size, 0444, size_show, NULL);
>> +
>> +static struct bin_attribute data_attr = {
>> + .attr = {.name = "data", .mode = 0444},
>> + .size = VARIABLE_MAX_SIZE,
>> + .read = data_read,
>> +};
> Should they be globally readable? If efivars is globally readable I'm
> happy to follow that example, but mpe might have opinions.
efivars are globally readable.
>> +
>> +
>> +static struct bin_attribute update_attr = {
>> + .attr = {.name = "update", .mode = 0200},
>> + .size = VARIABLE_MAX_SIZE,
>> + .write = update_write,
>> +};
>> +
>> +static struct bin_attribute *secvar_bin_attrs[] = {
>> + &data_attr,
>> + &update_attr,
>> + NULL,
>> +};
>> +
>> +static struct attribute *secvar_attrs[] = {
>> + &name_attr.attr,
>> + &size_attr.attr,
>> + NULL,
>> +};
>> +
>> +const struct attribute_group secvar_attr_group = {
>> + .attrs = secvar_attrs,
>> + .bin_attrs = secvar_bin_attrs,
>> +};
>> +
>> +int secvar_sysfs_load(void)
>> +{
>> +
>> + char *name;
>> + unsigned long namesize;
>> + struct kobject *kobj;
>> + int status;
>> + int rc = 0;
>> +
>> + name = kzalloc(1024, GFP_KERNEL);
>> + if (!name)
>> + return -ENOMEM;
> Where'd the 1024 restriction on the length of the variable name come
> from? is that enforced by firmware? If so, how does firmware
> communicate the limited key length?
It is not enforced by the firmware. Currently, it is sort of agreed upon
value between the firmware and the kernel, and taken from the examples
of efivars. Probably it can be reduced.
[-- Attachment #2: Type: text/html, Size: 9617 bytes --]
^ permalink raw reply
* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 14:56 UTC (permalink / raw)
To: Nayna Jain
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <1566825818-9731-3-git-send-email-nayna@linux.ibm.com>
On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> +static struct kobj_attribute size_attr = __ATTR_RO(size);
Wait, why not just normal ATTR_RO()?
> +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);
And BIN_ATTR_RO() here?
Do those not work for you somehow?
thanks,
greg k-h
^ permalink raw reply
* [PATCH] sysfs: add BIN_ATTR_WO() macro
From: Greg Kroah-Hartman @ 2019-08-26 15:01 UTC (permalink / raw)
To: Nayna
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, Nayna Jain, linux-kernel,
Mimi Zohar, Claudio Carvalho, Matthew Garret, linuxppc-dev,
Paul Mackerras, Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <ff9674e1-1b27-783a-38f3-4fd725353186@linux.vnet.ibm.com>
This variant was missing from sysfs.h, I guess no one noticed it before.
Turns out the powerpc secure variable code can use it, so add it to the
tree for it, and potentially others to take advantage of, instead of
open-coding it.
Reported-by: Nayna Jain <nayna@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
I'll queue this up to my tree for 5.4-rc1, but if you want to take this
in your tree earlier, feel free to do so.
include/linux/sysfs.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 965236795750..5420817ed317 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -196,6 +196,12 @@ struct bin_attribute {
.size = _size, \
}
+#define __BIN_ATTR_WO(_name) { \
+ .attr = { .name = __stringify(_name), .mode = 0200 }, \
+ .store = _name##_store, \
+ .size = _size, \
+}
+
#define __BIN_ATTR_RW(_name, _size) \
__BIN_ATTR(_name, 0644, _name##_read, _name##_write, _size)
@@ -208,6 +214,9 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read, \
#define BIN_ATTR_RO(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size)
+#define BIN_ATTR_WO(_name, _size) \
+struct bin_attribute bin_attr_##_name = __BIN_ATTR_WO(_name, _size)
+
#define BIN_ATTR_RW(_name, _size) \
struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
--
2.23.0
^ permalink raw reply related
* Re: [PATCH v2] btrfs: fix allocation of bitmap pages.
From: David Sterba @ 2019-08-26 15:37 UTC (permalink / raw)
To: Christophe Leroy
Cc: erhard_f, Chris Mason, Josef Bacik, stable, linux-kernel,
linux-mm, David Sterba, Andrew Morton, linuxppc-dev, linux-btrfs
In-Reply-To: <c3157c8e8e0e7588312b40c853f65c02fe6c957a.1566399731.git.christophe.leroy@c-s.fr>
On Wed, Aug 21, 2019 at 03:05:55PM +0000, Christophe Leroy wrote:
> Various notifications of type "BUG kmalloc-4096 () : Redzone
> overwritten" have been observed recently in various parts of
> the kernel. After some time, it has been made a relation with
> the use of BTRFS filesystem.
>
> [ 22.809700] BUG kmalloc-4096 (Tainted: G W ): Redzone overwritten
> [ 22.809971] -----------------------------------------------------------------------------
>
> [ 22.810286] INFO: 0xbe1a5921-0xfbfc06cd. First byte 0x0 instead of 0xcc
> [ 22.810866] INFO: Allocated in __load_free_space_cache+0x588/0x780 [btrfs] age=22 cpu=0 pid=224
> [ 22.811193] __slab_alloc.constprop.26+0x44/0x70
> [ 22.811345] kmem_cache_alloc_trace+0xf0/0x2ec
> [ 22.811588] __load_free_space_cache+0x588/0x780 [btrfs]
> [ 22.811848] load_free_space_cache+0xf4/0x1b0 [btrfs]
> [ 22.812090] cache_block_group+0x1d0/0x3d0 [btrfs]
> [ 22.812321] find_free_extent+0x680/0x12a4 [btrfs]
> [ 22.812549] btrfs_reserve_extent+0xec/0x220 [btrfs]
> [ 22.812785] btrfs_alloc_tree_block+0x178/0x5f4 [btrfs]
> [ 22.813032] __btrfs_cow_block+0x150/0x5d4 [btrfs]
> [ 22.813262] btrfs_cow_block+0x194/0x298 [btrfs]
> [ 22.813484] commit_cowonly_roots+0x44/0x294 [btrfs]
> [ 22.813718] btrfs_commit_transaction+0x63c/0xc0c [btrfs]
> [ 22.813973] close_ctree+0xf8/0x2a4 [btrfs]
> [ 22.814107] generic_shutdown_super+0x80/0x110
> [ 22.814250] kill_anon_super+0x18/0x30
> [ 22.814437] btrfs_kill_super+0x18/0x90 [btrfs]
> [ 22.814590] INFO: Freed in proc_cgroup_show+0xc0/0x248 age=41 cpu=0 pid=83
> [ 22.814841] proc_cgroup_show+0xc0/0x248
> [ 22.814967] proc_single_show+0x54/0x98
> [ 22.815086] seq_read+0x278/0x45c
> [ 22.815190] __vfs_read+0x28/0x17c
> [ 22.815289] vfs_read+0xa8/0x14c
> [ 22.815381] ksys_read+0x50/0x94
> [ 22.815475] ret_from_syscall+0x0/0x38
>
> Commit 69d2480456d1 ("btrfs: use copy_page for copying pages instead
> of memcpy") changed the way bitmap blocks are copied. But allthough
> bitmaps have the size of a page, they were allocated with kzalloc().
>
> Most of the time, kzalloc() allocates aligned blocks of memory, so
> copy_page() can be used. But when some debug options like SLAB_DEBUG
> are activated, kzalloc() may return unaligned pointer.
>
> On powerpc, memcpy(), copy_page() and other copying functions use
> 'dcbz' instruction which provides an entire zeroed cacheline to avoid
> memory read when the intention is to overwrite a full line. Functions
> like memcpy() are writen to care about partial cachelines at the start
> and end of the destination, but copy_page() assumes it gets pages. As
> pages are naturally cache aligned, copy_page() doesn't care about
> partial lines. This means that when copy_page() is called with a
> misaligned pointer, a few leading bytes are zeroed.
>
> To fix it, allocate bitmaps through kmem_cache instead of using kzalloc()
> The cache pool is created with PAGE_SIZE alignment constraint.
>
> Reported-by: Erhard F. <erhard_f@mailbox.org>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
> Fixes: 69d2480456d1 ("btrfs: use copy_page for copying pages instead of memcpy")
> Cc: stable@vger.kernel.org
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> v2: Using kmem_cache instead of get_zeroed_page() in order to benefit from SLAB debugging features like redzone.
I'll take this version, thanks. Though I'm not happy about the allocator
behaviour. The kmem cache based fix can be backported independently to
4.19 regardless of the SL*B fixes.
> +extern struct kmem_cache *btrfs_bitmap_cachep;
I've renamed the cache to btrfs_free_space_bitmap_cachep
Reviewed-by: David Sterba <dsterba@suse.com>
^ permalink raw reply
* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Nayna @ 2019-08-26 15:46 UTC (permalink / raw)
To: Greg Kroah-Hartman, Nayna Jain
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, linux-kernel, Mimi Zohar,
Claudio Carvalho, Matthew Garret, linuxppc-dev, Paul Mackerras,
Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <20190826145649.GA27342@kroah.com>
On 08/26/2019 10:56 AM, Greg Kroah-Hartman wrote:
> On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
>> +static struct kobj_attribute size_attr = __ATTR_RO(size);
> Wait, why not just normal ATTR_RO()?
Oh!! Sorry. I am not seeing this macro in sysfs.h. am I missing something ?
>
>> +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);
> And BIN_ATTR_RO() here?
This would have worked. I think I just thought to use the same way as
__ATTR_RO().
I will change this to __BIN_ATTR_RO and use __BIN_ATTR_WO from your patch.
Thanks for the patch.
Thanks & Regards,
- Nayna
^ permalink raw reply
* [PATCH 1/6] powerpc/32s: add an option to exclusively select powerpc 601
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
Powerpc 601 is rather old powerpc which as some important
limitations compared to other book3s/32 powerpcs:
- No Timebase.
- Common BATs for instruction and data.
- No execution protection in segment registers.
- No RI bit in MSR
- ...
It is starting to be difficult and cumbersome to maintain
kernels that are compatible both with 601 and other 6xx cores.
Create a compiletime option to exclusively select either powerpc 601
or other 6xx.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/platforms/Kconfig.cputype | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 56a7c814160d..68c5cc075bfc 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -6,6 +6,9 @@ config PPC64
This option selects whether a 32-bit or a 64-bit kernel
will be built.
+config PPC_BOOK3S_32
+ bool
+
menu "Processor support"
choice
prompt "Processor Type"
@@ -21,13 +24,20 @@ choice
If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
-config PPC_BOOK3S_32
- bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
+config PPC_BOOK3S_6xx
+ bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601"
+ select PPC_BOOK3S_32
select PPC_FPU
select PPC_HAVE_PMU_SUPPORT
select PPC_HAVE_KUEP
select PPC_HAVE_KUAP
+config PPC_BOOK3S_601
+ bool "PowerPC 601"
+ select PPC_BOOK3S_32
+ select PPC_FPU
+ select PPC_HAVE_KUAP
+
config PPC_85xx
bool "Freescale 85xx"
select E500
--
2.13.3
^ permalink raw reply related
* [PATCH 2/6] powerpc/32s: get rid of CPU_FTR_601 feature
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>
Now that 601 is exclusive from other 6xx, CPU_FTR_601 and
associated fixups are useless.
Drop this feature and use #ifdefs instead.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/configs/pmac32_defconfig | 1 -
arch/powerpc/include/asm/cputable.h | 14 ++++++++------
arch/powerpc/include/asm/ppc_asm.h | 28 +++++++---------------------
arch/powerpc/include/asm/ptrace.h | 6 +++++-
arch/powerpc/include/asm/timex.h | 34 +++-------------------------------
arch/powerpc/kernel/cputable.c | 6 ++++--
arch/powerpc/kernel/entry_32.S | 22 ++++++++++++++++------
arch/powerpc/mm/book3s32/mmu.c | 15 ++++++---------
arch/powerpc/mm/ptdump/bats.c | 2 +-
arch/powerpc/platforms/Kconfig | 3 ++-
10 files changed, 52 insertions(+), 79 deletions(-)
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig
index 7e6654848531..4e6e95f92646 100644
--- a/arch/powerpc/configs/pmac32_defconfig
+++ b/arch/powerpc/configs/pmac32_defconfig
@@ -20,7 +20,6 @@ CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_PMAC=y
-CONFIG_PPC601_SYNC_FIX=y
CONFIG_GEN_RTC=y
CONFIG_HIGHMEM=y
CONFIG_BINFMT_MISC=m
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index d05f0c28e515..0aad095896d6 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -145,7 +145,6 @@ static inline void cpu_feature_keys_init(void) { }
/* Definitions for features that only exist on 32-bit chips */
#ifdef CONFIG_PPC32
-#define CPU_FTR_601 ASM_CONST(0x00001000)
#define CPU_FTR_L2CR ASM_CONST(0x00002000)
#define CPU_FTR_SPEC7450 ASM_CONST(0x00004000)
#define CPU_FTR_TAU ASM_CONST(0x00008000)
@@ -167,7 +166,6 @@ static inline void cpu_feature_keys_init(void) { }
#else /* CONFIG_PPC32 */
/* Define these to 0 for the sake of tests in common code */
-#define CPU_FTR_601 (0)
#define CPU_FTR_PPC_LE (0)
#endif
@@ -294,7 +292,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_MAYBE_CAN_NAP 0
#endif
-#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | \
+#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
@@ -498,7 +496,9 @@ static inline void cpu_feature_keys_init(void) { }
#else
enum {
CPU_FTRS_POSSIBLE =
-#ifdef CONFIG_PPC_BOOK3S_32
+#ifdef CONFIG_PPC_BOOK3S_601
+ CPU_FTRS_PPC601 |
+#elif defined(CONFIG_PPC_BOOK3S_32)
CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
CPU_FTRS_750FX2 | CPU_FTRS_750FX | CPU_FTRS_750GX |
@@ -574,8 +574,10 @@ enum {
#else
enum {
CPU_FTRS_ALWAYS =
-#ifdef CONFIG_PPC_BOOK3S_32
- CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
+#ifdef CONFIG_PPC_BOOK3S_601
+ CPU_FTRS_PPC601 &
+#elif defined(CONFIG_PPC_BOOK3S_32)
+ CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
CPU_FTRS_750FX2 & CPU_FTRS_750FX & CPU_FTRS_750GX &
CPU_FTRS_7400_NOTAU & CPU_FTRS_7400 & CPU_FTRS_7450_20 &
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index e0637730a8e7..94279e611c98 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -351,19 +351,9 @@ GLUE(.,name):
/* various errata or part fixups */
#ifdef CONFIG_PPC601_SYNC_FIX
-#define SYNC \
-BEGIN_FTR_SECTION \
- sync; \
- isync; \
-END_FTR_SECTION_IFSET(CPU_FTR_601)
-#define SYNC_601 \
-BEGIN_FTR_SECTION \
- sync; \
-END_FTR_SECTION_IFSET(CPU_FTR_601)
-#define ISYNC_601 \
-BEGIN_FTR_SECTION \
- isync; \
-END_FTR_SECTION_IFSET(CPU_FTR_601)
+#define SYNC sync; isync
+#define SYNC_601 sync
+#define ISYNC_601 isync
#else
#define SYNC
#define SYNC_601
@@ -389,15 +379,11 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
#define MFTBU(dest) mfspr dest, SPRN_TBRU
#endif
-#ifndef CONFIG_SMP
-#define TLBSYNC
-#else /* CONFIG_SMP */
/* tlbsync is not implemented on 601 */
-#define TLBSYNC \
-BEGIN_FTR_SECTION \
- tlbsync; \
- sync; \
-END_FTR_SECTION_IFCLR(CPU_FTR_601)
+#if !defined(CONFIG_SMP) || defined(CONFIG_PPC_BOOK3S_601)
+#define TLBSYNC
+#else
+#define TLBSYNC tlbsync; sync
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index feee1b21bbd5..ee3ada66deb5 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -203,7 +203,11 @@ do { \
#endif /* __powerpc64__ */
#define arch_has_single_step() (1)
-#define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601))
+#ifndef CONFIG_BOOK3S_601
+#define arch_has_block_step() (true)
+#else
+#define arch_has_block_step() (false)
+#endif
#define ARCH_HAS_USER_SINGLE_STEP_REPORT
/*
diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h
index 926b9f91a3ef..d2d2c4bd8435 100644
--- a/arch/powerpc/include/asm/timex.h
+++ b/arch/powerpc/include/asm/timex.h
@@ -17,38 +17,10 @@ typedef unsigned long cycles_t;
static inline cycles_t get_cycles(void)
{
-#ifdef __powerpc64__
+ if (IS_ENABLED(CONFIG_BOOK3S_601))
+ return 0;
+
return mftb();
-#else
- cycles_t ret;
-
- /*
- * For the "cycle" counter we use the timebase lower half.
- * Currently only used on SMP.
- */
-
- ret = 0;
-
- __asm__ __volatile__(
-#ifdef CONFIG_PPC_8xx
- "97: mftb %0\n"
-#else
- "97: mfspr %0, %2\n"
-#endif
- "99:\n"
- ".section __ftr_fixup,\"a\"\n"
- ".align 2\n"
- "98:\n"
- " .long %1\n"
- " .long 0\n"
- " .long 97b-98b\n"
- " .long 99b-98b\n"
- " .long 0\n"
- " .long 0\n"
- ".previous"
- : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL));
- return ret;
-#endif
}
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index bfe5f4a2886b..e745abc5457a 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -569,7 +569,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
#endif /* CONFIG_PPC_BOOK3S_64 */
#ifdef CONFIG_PPC32
-#ifdef CONFIG_PPC_BOOK3S_32
+#ifdef CONFIG_PPC_BOOK3S_601
{ /* 601 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00010000,
@@ -583,6 +583,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_generic,
.platform = "ppc601",
},
+#endif /* CONFIG_PPC_BOOK3S_601 */
+#ifdef CONFIG_PPC_BOOK3S_6xx
{ /* 603 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00030000,
@@ -1212,7 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_generic,
.platform = "ppc603",
},
-#endif /* CONFIG_PPC_BOOK3S_32 */
+#endif /* CONFIG_PPC_BOOK3S_6xx */
#ifdef CONFIG_PPC_8xx
{ /* 8xx */
.pvr_mask = 0xffff0000,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 54fab22c9a43..0365d1afbfa5 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -777,11 +777,19 @@ fast_exception_return:
1: lis r3,exc_exit_restart_end@ha
addi r3,r3,exc_exit_restart_end@l
cmplw r12,r3
+#if CONFIG_PPC_BOOK3S_601
+ bge 2b
+#else
bge 3f
+#endif
lis r4,exc_exit_restart@ha
addi r4,r4,exc_exit_restart@l
cmplw r12,r4
+#if CONFIG_PPC_BOOK3S_601
+ blt 2b
+#else
blt 3f
+#endif
lis r3,fee_restarts@ha
tophys(r3,r3)
lwz r5,fee_restarts@l(r3)
@@ -800,9 +808,6 @@ fee_restarts:
/* aargh, we don't know which trap this is */
/* but the 601 doesn't implement the RI bit, so assume it's OK */
3:
-BEGIN_FTR_SECTION
- b 2b
-END_FTR_SECTION_IFSET(CPU_FTR_601)
li r10,-1
stw r10,_TRAP(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
@@ -1270,11 +1275,19 @@ nonrecoverable:
lis r10,exc_exit_restart_end@ha
addi r10,r10,exc_exit_restart_end@l
cmplw r12,r10
+#ifdef CONFIG_PPC_BOOK3S_601
+ bgelr
+#else
bge 3f
+#endif
lis r11,exc_exit_restart@ha
addi r11,r11,exc_exit_restart@l
cmplw r12,r11
+#ifdef CONFIG_PPC_BOOK3S_601
+ bltlr
+#else
blt 3f
+#endif
lis r10,ee_restarts@ha
lwz r12,ee_restarts@l(r10)
addi r12,r12,1
@@ -1283,9 +1296,6 @@ nonrecoverable:
blr
3: /* OK, we can't recover, kill this process */
/* but the 601 doesn't implement the RI bit, so assume it's OK */
-BEGIN_FTR_SECTION
- blr
-END_FTR_SECTION_IFSET(CPU_FTR_601)
lwz r3,_TRAP(r1)
andi. r0,r3,1
beq 5f
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 50a1991d257f..84d5fab94f8f 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -74,7 +74,7 @@ static int find_free_bat(void)
{
int b;
- if (cpu_has_feature(CPU_FTR_601)) {
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) {
for (b = 0; b < 4; b++) {
struct ppc_bat *bat = BATS[b];
@@ -106,7 +106,7 @@ static int find_free_bat(void)
*/
static unsigned int block_size(unsigned long base, unsigned long top)
{
- unsigned int max_size = (cpu_has_feature(CPU_FTR_601) ? 8 : 256) << 20;
+ unsigned int max_size = IS_ENABLED(CONFIG_PPC_BOOK3S_601) ? SZ_8M : SZ_256M;
unsigned int base_shift = (ffs(base) - 1) & 31;
unsigned int block_shift = (fls(top - base) - 1) & 31;
@@ -189,7 +189,7 @@ void mmu_mark_initmem_nx(void)
unsigned long top = (unsigned long)_etext - PAGE_OFFSET;
unsigned long size;
- if (cpu_has_feature(CPU_FTR_601))
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
return;
for (i = 0; i < nb - 1 && base < top && top - base > (128 << 10);) {
@@ -227,7 +227,7 @@ void mmu_mark_rodata_ro(void)
int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
int i;
- if (cpu_has_feature(CPU_FTR_601))
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
return;
for (i = 0; i < nb; i++) {
@@ -259,7 +259,7 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
flags &= ~_PAGE_COHERENT;
bl = (size >> 17) - 1;
- if (PVR_VER(mfspr(SPRN_PVR)) != 1) {
+ if (!IS_ENABLED(CONFIG_PPC_BOOK3S_601)) {
/* 603, 604, etc. */
/* Do DBAT first */
wimgxpp = flags & (_PAGE_WRITETHRU | _PAGE_NO_CACHE
@@ -441,7 +441,7 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
BUG_ON(first_memblock_base != 0);
/* 601 can only access 16MB at the moment */
- if (PVR_VER(mfspr(SPRN_PVR)) == 1)
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01000000));
else /* Anything else has 256M mapped */
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x10000000));
@@ -459,9 +459,6 @@ void __init setup_kuep(bool disabled)
{
pr_info("Activating Kernel Userspace Execution Prevention\n");
- if (cpu_has_feature(CPU_FTR_601))
- pr_warn("KUEP is not working on powerpc 601 (No NX bit in Seg Regs)\n");
-
if (disabled)
pr_warn("KUEP cannot be disabled yet on 6xx when compiled in\n");
}
diff --git a/arch/powerpc/mm/ptdump/bats.c b/arch/powerpc/mm/ptdump/bats.c
index a0d23e96e841..4154feac1da3 100644
--- a/arch/powerpc/mm/ptdump/bats.c
+++ b/arch/powerpc/mm/ptdump/bats.c
@@ -149,7 +149,7 @@ static int bats_show_603(struct seq_file *m, void *v)
static int bats_open(struct inode *inode, struct file *file)
{
- if (cpu_has_feature(CPU_FTR_601))
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
return single_open(file, bats_show_601, NULL);
return single_open(file, bats_show_603, NULL);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f3fb79fccc72..d82e3664ffdf 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -197,7 +197,8 @@ endmenu
config PPC601_SYNC_FIX
bool "Workarounds for PPC601 bugs"
- depends on PPC_BOOK3S_32 && PPC_PMAC
+ depends on PPC_BOOK3S_601 && PPC_PMAC
+ default y
help
Some versions of the PPC601 (the first PowerPC chip) have bugs which
mean that extra synchronization instructions are required near
--
2.13.3
^ permalink raw reply related
* [PATCH 3/6] powerpc/32s: drop CPU_FTR_USE_RTC feature
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>
CPU_FTR_USE_RTC feature only applies to powerpc601.
Drop this feature and replace it with tests on CONFIG_PPC_BOOK3S_601.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/cputable.h | 3 +--
arch/powerpc/include/asm/time.h | 6 +-----
arch/powerpc/kernel/vdso.c | 22 ----------------------
arch/powerpc/kernel/vdso32/datapage.S | 2 ++
arch/powerpc/kernel/vdso32/vdso32.lds.S | 4 +++-
5 files changed, 7 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 0aad095896d6..fac1b81bbbd9 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -149,7 +149,6 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_SPEC7450 ASM_CONST(0x00004000)
#define CPU_FTR_TAU ASM_CONST(0x00008000)
#define CPU_FTR_CAN_DOZE ASM_CONST(0x00010000)
-#define CPU_FTR_USE_RTC ASM_CONST(0x00020000)
#define CPU_FTR_L3CR ASM_CONST(0x00040000)
#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x00080000)
#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x00100000)
@@ -293,7 +292,7 @@ static inline void cpu_feature_keys_init(void) { }
#endif
#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | \
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_USE_RTC)
+ CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_PPC_LE)
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 54f4ec1f9fab..08dbe3e6831c 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -41,11 +41,7 @@ struct div_result {
/* Accessor functions for the timebase (RTC on 601) registers. */
/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
-#ifdef CONFIG_PPC_BOOK3S_32
-#define __USE_RTC() (cpu_has_feature(CPU_FTR_USE_RTC))
-#else
-#define __USE_RTC() 0
-#endif
+#define __USE_RTC() (IS_ENABLED(CONFIG_PPC_BOOK3S_601))
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index d60598113a9f..eae9ddaecbcf 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -94,28 +94,6 @@ static struct vdso_patch_def vdso_patches[] = {
CPU_FTR_COHERENT_ICACHE, CPU_FTR_COHERENT_ICACHE,
"__kernel_sync_dicache", "__kernel_sync_dicache_p5"
},
-#ifdef CONFIG_PPC32
- {
- CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
- "__kernel_gettimeofday", NULL
- },
- {
- CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
- "__kernel_clock_gettime", NULL
- },
- {
- CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
- "__kernel_clock_getres", NULL
- },
- {
- CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
- "__kernel_get_tbfreq", NULL
- },
- {
- CPU_FTR_USE_RTC, CPU_FTR_USE_RTC,
- "__kernel_time", NULL
- },
-#endif
};
/*
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 6984125b9fc0..6c7401bd284e 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -70,6 +70,7 @@ V_FUNCTION_END(__kernel_get_syscall_map)
*
* returns the timebase frequency in HZ
*/
+#ifndef CONFIG_PPC_BOOK3S_601
V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
@@ -82,3 +83,4 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
blr
.cfi_endproc
V_FUNCTION_END(__kernel_get_tbfreq)
+#endif
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 099a6db14e67..00c025ba4a92 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -144,10 +144,13 @@ VERSION
__kernel_datapage_offset;
__kernel_get_syscall_map;
+#ifndef CONFIG_PPC_BOOK3S_601
__kernel_gettimeofday;
__kernel_clock_gettime;
__kernel_clock_getres;
+ __kernel_time;
__kernel_get_tbfreq;
+#endif
__kernel_sync_dicache;
__kernel_sync_dicache_p5;
__kernel_sigtramp32;
@@ -155,7 +158,6 @@ VERSION
#ifdef CONFIG_PPC64
__kernel_getcpu;
#endif
- __kernel_time;
local: *;
};
--
2.13.3
^ permalink raw reply related
* [PATCH 4/6] powerpc/32s: use CONFIG_PPC_BOOK3S_601 instead of reading PVR
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>
Use CONFIG_PPC_BOOK3S_601 instead of reading PVR to know if
it is a 601 or not.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/head_32.S | 49 +++++++++++++++++++------------------------
arch/powerpc/kernel/misc_32.S | 6 ++----
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 9e6f01abb31e..4a24f8f026c7 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -34,7 +34,16 @@
#include "head_32.h"
-/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
+/* 601 only have IBAT */
+#ifdef CONFIG_PPC_BOOK3S_601
+#define LOAD_BAT(n, reg, RA, RB) \
+ li RA,0; \
+ mtspr SPRN_IBAT##n##U,RA; \
+ lwz RA,(n*16)+0(reg); \
+ lwz RB,(n*16)+4(reg); \
+ mtspr SPRN_IBAT##n##U,RA; \
+ mtspr SPRN_IBAT##n##L,RB
+#else
#define LOAD_BAT(n, reg, RA, RB) \
/* see the comment for clear_bats() -- Cort */ \
li RA,0; \
@@ -44,12 +53,11 @@
lwz RB,(n*16)+4(reg); \
mtspr SPRN_IBAT##n##U,RA; \
mtspr SPRN_IBAT##n##L,RB; \
- beq 1f; \
lwz RA,(n*16)+8(reg); \
lwz RB,(n*16)+12(reg); \
mtspr SPRN_DBAT##n##U,RA; \
- mtspr SPRN_DBAT##n##L,RB; \
-1:
+ mtspr SPRN_DBAT##n##L,RB
+#endif
__HEAD
.stabs "arch/powerpc/kernel/",N_SO,0,0,0f
@@ -820,9 +828,6 @@ load_up_mmu:
/* Load the BAT registers with the values set up by MMU_init.
MMU_init takes care of whether we're on a 601 or not. */
- mfpvr r3
- srwi r3,r3,16
- cmpwi r3,1
lis r3,BATS@ha
addi r3,r3,BATS@l
tophys(r3,r3)
@@ -998,11 +1003,8 @@ EXPORT_SYMBOL(switch_mmu_context)
*/
clear_bats:
li r10,0
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi r9, 1
- beq 1f
+#ifndef CONFIG_PPC_BOOK3S_601
mtspr SPRN_DBAT0U,r10
mtspr SPRN_DBAT0L,r10
mtspr SPRN_DBAT1U,r10
@@ -1011,7 +1013,7 @@ clear_bats:
mtspr SPRN_DBAT2L,r10
mtspr SPRN_DBAT3U,r10
mtspr SPRN_DBAT3L,r10
-1:
+#endif
mtspr SPRN_IBAT0U,r10
mtspr SPRN_IBAT0L,r10
mtspr SPRN_IBAT1U,r10
@@ -1106,10 +1108,7 @@ mmu_off:
*/
initial_bats:
lis r11,PAGE_OFFSET@h
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi 0,r9,1
- bne 4f
+#ifdef CONFIG_PPC_BOOK3S_601
ori r11,r11,4 /* set up BAT registers for 601 */
li r8,0x7f /* valid, block length = 8MB */
mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */
@@ -1122,10 +1121,8 @@ initial_bats:
addis r8,r8,0x800000@h
mtspr SPRN_IBAT2U,r11
mtspr SPRN_IBAT2L,r8
- isync
- blr
-
-4: tophys(r8,r11)
+#else
+ tophys(r8,r11)
#ifdef CONFIG_SMP
ori r8,r8,0x12 /* R/W access, M=1 */
#else
@@ -1137,10 +1134,10 @@ initial_bats:
mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
mtspr SPRN_IBAT0L,r8
mtspr SPRN_IBAT0U,r11
+#endif
isync
blr
-
#ifdef CONFIG_BOOTX_TEXT
setup_disp_bat:
/*
@@ -1155,15 +1152,13 @@ setup_disp_bat:
beqlr
lwz r11,0(r8)
lwz r8,4(r8)
- mfspr r9,SPRN_PVR
- rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
- cmpwi 0,r9,1
- beq 1f
+#ifndef CONFIG_PPC_BOOK3S_601
mtspr SPRN_DBAT3L,r8
mtspr SPRN_DBAT3U,r11
- blr
-1: mtspr SPRN_IBAT3L,r8
+#else
+ mtspr SPRN_IBAT3L,r8
mtspr SPRN_IBAT3U,r11
+#endif
blr
#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 02d90e1ebf65..b917641cdaa6 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -303,11 +303,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
mfspr r3,SPRN_L1CSR1
ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
mtspr SPRN_L1CSR1,r3
+#elif defined(CONFIG_PPC_BOOK3S_601)
+ blr /* for 601, do nothing */
#else
- mfspr r3,SPRN_PVR
- rlwinm r3,r3,16,16,31
- cmpwi 0,r3,1
- beqlr /* for 601, do nothing */
/* 603/604 processor - use invalidate-all bit in HID0 */
mfspr r3,SPRN_HID0
ori r3,r3,HID0_ICFI
--
2.13.3
^ permalink raw reply related
* [PATCH 5/6] powerpc/32: drop CPU_FTR_UNIFIED_ID_CACHE
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>
Only 601 and e200 have unified I/D cache.
Drop the feature and use CONFIG_PPC_BOOK3S_601 and CONFIG_E200.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/cputable.h | 5 ++---
arch/powerpc/kernel/misc_32.S | 4 ++--
arch/powerpc/kernel/setup_32.c | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index fac1b81bbbd9..a1ebcbc3931f 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -158,7 +158,6 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x01000000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x02000000)
#define CPU_FTR_PPC_LE ASM_CONST(0x04000000)
-#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x08000000)
#define CPU_FTR_SPE ASM_CONST(0x10000000)
#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x20000000)
#define CPU_FTR_INDEXED_DCR ASM_CONST(0x40000000)
@@ -292,7 +291,7 @@ static inline void cpu_feature_keys_init(void) { }
#endif
#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | \
- CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
+ CPU_FTR_COHERENT_ICACHE)
#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_PPC_LE)
@@ -383,7 +382,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTRS_47X (CPU_FTRS_440x6)
#define CPU_FTRS_E200 (CPU_FTR_SPE_COMP | \
CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
- CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \
+ CPU_FTR_NOEXECUTE | \
CPU_FTR_DEBUG_LVL_EXC)
#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | \
CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index b917641cdaa6..3d21fb110797 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -292,14 +292,14 @@ _GLOBAL(flush_instruction_cache)
iccci 0,r3
#endif
#elif defined(CONFIG_FSL_BOOKE)
-BEGIN_FTR_SECTION
+#ifdef CONFIG_E200
mfspr r3,SPRN_L1CSR0
ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
/* msync; isync recommended here */
mtspr SPRN_L1CSR0,r3
isync
blr
-END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
+#endif
mfspr r3,SPRN_L1CSR1
ori r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
mtspr SPRN_L1CSR1,r3
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 94517e4a2723..a7541edf0cdb 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -206,6 +206,6 @@ __init void initialize_cache_info(void)
dcache_bsize = cur_cpu_spec->dcache_bsize;
icache_bsize = cur_cpu_spec->icache_bsize;
ucache_bsize = 0;
- if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_601) || IS_ENABLED(CONFIG_E200))
ucache_bsize = icache_bsize = dcache_bsize;
}
--
2.13.3
^ permalink raw reply related
* [PATCH 6/6] powerpc/32: don't use CPU_FTR_COHERENT_ICACHE
From: Christophe Leroy @ 2019-08-26 15:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <d644eaf7dff8cc149260066802af230bdf34fded.1566834712.git.christophe.leroy@c-s.fr>
Only 601 and E200 have CPU_FTR_COHERENT_ICACHE.
Just use #ifdefs instead of feature fixup.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/misc_32.S | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 3d21fb110797..82df4b09e79f 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -324,10 +324,10 @@ EXPORT_SYMBOL(flush_instruction_cache)
* flush_icache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_icache_range)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
PURGE_PREFETCHED_INS
- blr /* for 601, do nothing */
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+ blr /* for 601 and e200, do nothing */
+#else
rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT
subf r4,r3,r4
addi r4,r4,L1_CACHE_BYTES - 1
@@ -353,6 +353,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
sync /* additional sync needed on g4 */
isync
blr
+#endif
_ASM_NOKPROBE_SYMBOL(flush_icache_range)
EXPORT_SYMBOL(flush_icache_range)
@@ -360,15 +361,15 @@ EXPORT_SYMBOL(flush_icache_range)
* Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
- * This is a no-op on the 601 which has a unified cache.
+ * This is a no-op on the 601 and e200 which have a unified cache.
*
* void __flush_dcache_icache(void *page)
*/
_GLOBAL(__flush_dcache_icache)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
PURGE_PREFETCHED_INS
blr
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+#else
rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */
li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */
mtctr r4
@@ -396,6 +397,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
sync
isync
blr
+#endif
#ifndef CONFIG_BOOKE
/*
@@ -407,10 +409,10 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
* void __flush_dcache_icache_phys(unsigned long physaddr)
*/
_GLOBAL(__flush_dcache_icache_phys)
-BEGIN_FTR_SECTION
+#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200)
PURGE_PREFETCHED_INS
- blr /* for 601, do nothing */
-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
+ blr /* for 601 and e200, do nothing */
+#else
mfmsr r10
rlwinm r0,r10,0,28,26 /* clear DR */
mtmsr r0
@@ -431,6 +433,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
mtmsr r10 /* restore DR */
isync
blr
+#endif
#endif /* CONFIG_BOOKE */
/*
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v3 2/4] powerpc: expose secure variables to userspace via sysfs
From: Greg Kroah-Hartman @ 2019-08-26 15:57 UTC (permalink / raw)
To: Nayna
Cc: linux-efi, Ard Biesheuvel, Eric Ricther, Nayna Jain, linux-kernel,
Mimi Zohar, Claudio Carvalho, Matthew Garret, linuxppc-dev,
Paul Mackerras, Jeremy Kerr, Elaine Palmer, Oliver O'Halloran,
linux-integrity, George Wilson
In-Reply-To: <2c5b8ba3-e5a3-5c80-a291-ea9965db2019@linux.vnet.ibm.com>
On Mon, Aug 26, 2019 at 11:46:11AM -0400, Nayna wrote:
>
>
> On 08/26/2019 10:56 AM, Greg Kroah-Hartman wrote:
> > On Mon, Aug 26, 2019 at 09:23:36AM -0400, Nayna Jain wrote:
> > > +static struct kobj_attribute size_attr = __ATTR_RO(size);
> > Wait, why not just normal ATTR_RO()?
>
> Oh!! Sorry. I am not seeing this macro in sysfs.h. am I missing something ?
Ugh, no, you are right, I thought it was there as the BIN_ATTR_RO() one
was there :)
> > > +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, VARIABLE_MAX_SIZE);
> > And BIN_ATTR_RO() here?
>
> This would have worked. I think I just thought to use the same way as
> __ATTR_RO().
Yes, that's fine to use, sorry for the noise.
greg k-h
^ permalink raw reply
* Re: [PATCH v2] btrfs: fix allocation of bitmap pages.
From: David Sterba @ 2019-08-26 16:46 UTC (permalink / raw)
To: Nikolay Borisov
Cc: erhard_f, linux-mm, linux-kernel, Josef Bacik, stable, dsterba,
Chris Mason, David Sterba, Andrew Morton, linuxppc-dev,
linux-btrfs
In-Reply-To: <a096d653-8b64-be15-3e81-581536a88e8a@suse.com>
On Mon, Aug 26, 2019 at 06:40:24PM +0300, Nikolay Borisov wrote:
> >> Link: https://bugzilla.kernel.org/show_bug.cgi?id=204371
> >> Fixes: 69d2480456d1 ("btrfs: use copy_page for copying pages instead of memcpy")
> >> Cc: stable@vger.kernel.org
> >> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> >> ---
> >> v2: Using kmem_cache instead of get_zeroed_page() in order to benefit from SLAB debugging features like redzone.
> >
> > I'll take this version, thanks. Though I'm not happy about the allocator
> > behaviour. The kmem cache based fix can be backported independently to
> > 4.19 regardless of the SL*B fixes.
> >
> >> +extern struct kmem_cache *btrfs_bitmap_cachep;
> >
> > I've renamed the cache to btrfs_free_space_bitmap_cachep
> >
> > Reviewed-by: David Sterba <dsterba@suse.com>
>
> Isn't this obsoleted by
>
> '[PATCH v2 0/2] guarantee natural alignment for kmalloc()' ?
Yeah, but this would add maybe another whole dev cycle to merge and
release. The reporters of the bug seem to care enough to identify the
problem and propose the fix so I feel like adding the btrfs-specific fix
now is a little favor we can afford.
The bug is reproduced on an architecture that's not widely tested so
from practical POV I think this adds more coverage which is desirable.
^ permalink raw reply
* Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
From: Greg Kroah-Hartman @ 2019-08-26 16:50 UTC (permalink / raw)
To: Alastair D'Silva
Cc: alastair, linux-kernel, stable, Paul Mackerras, Thomas Gleixner,
linuxppc-dev, Allison Randal
In-Reply-To: <20190821001929.4253-1-alastair@au1.ibm.com>
On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
>
> The upstream commit:
> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
> has a similar effect, but since it is a rewrite of the assembler to C, is
> too invasive for stable. This patch is a minimal fix to address the issue in
> assembler.
>
> This patch applies cleanly to v5.2, v4.19 & v4.14.
>
> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
> off the upper 32 bits, so we would incorrectly flush a range smaller
> than intended.
>
> This patch replaces the 32 bit shifts with 64 bit ones, so that
> the full size is accounted for.
>
> Changelog:
> v2
> - Add related upstream commit
>
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> ---
> arch/powerpc/kernel/misc_64.S | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
> index 1ad4089dd110..d4d096f80f4b 100644
> --- a/arch/powerpc/kernel/misc_64.S
> +++ b/arch/powerpc/kernel/misc_64.S
> @@ -130,7 +130,7 @@ _GLOBAL_TOC(flush_dcache_range)
> subf r8,r6,r4 /* compute length */
> add r8,r8,r5 /* ensure we get enough */
> lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of dcache block size */
> - srw. r8,r8,r9 /* compute line count */
> + srd. r8,r8,r9 /* compute line count */
> beqlr /* nothing to do? */
> mtctr r8
> 0: dcbst 0,r6
> @@ -148,7 +148,7 @@ _GLOBAL(flush_inval_dcache_range)
> subf r8,r6,r4 /* compute length */
> add r8,r8,r5 /* ensure we get enough */
> lwz r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */
> - srw. r8,r8,r9 /* compute line count */
> + srd. r8,r8,r9 /* compute line count */
> beqlr /* nothing to do? */
> sync
> isync
I need an ack from the powerpc maintainer(s) before I can take this.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v2] powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB
From: Christophe Leroy @ 2019-08-26 20:08 UTC (permalink / raw)
To: Greg Kroah-Hartman, Alastair D'Silva
Cc: linux-kernel, stable, Paul Mackerras, alastair, Thomas Gleixner,
linuxppc-dev, Allison Randal
In-Reply-To: <20190826165021.GB9305@kroah.com>
Le 26/08/2019 à 18:50, Greg Kroah-Hartman a écrit :
> On Wed, Aug 21, 2019 at 10:19:27AM +1000, Alastair D'Silva wrote:
>> From: Alastair D'Silva <alastair@d-silva.org>
>>
>> The upstream commit:
>> 22e9c88d486a ("powerpc/64: reuse PPC32 static inline flush_dcache_range()")
>> has a similar effect, but since it is a rewrite of the assembler to C, is
>> too invasive for stable. This patch is a minimal fix to address the issue in
>> assembler.
>>
>> This patch applies cleanly to v5.2, v4.19 & v4.14.
>>
>> When calling flush_(inval_)dcache_range with a size >4GB, we were masking
>> off the upper 32 bits, so we would incorrectly flush a range smaller
>> than intended.
>>
>> This patch replaces the 32 bit shifts with 64 bit ones, so that
>> the full size is accounted for.
>>
>> Changelog:
>> v2
>> - Add related upstream commit
>>
>> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
>> ---
>> arch/powerpc/kernel/misc_64.S | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
>> index 1ad4089dd110..d4d096f80f4b 100644
>> --- a/arch/powerpc/kernel/misc_64.S
>> +++ b/arch/powerpc/kernel/misc_64.S
>> @@ -130,7 +130,7 @@ _GLOBAL_TOC(flush_dcache_range)
>> subf r8,r6,r4 /* compute length */
>> add r8,r8,r5 /* ensure we get enough */
>> lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of dcache block size */
>> - srw. r8,r8,r9 /* compute line count */
>> + srd. r8,r8,r9 /* compute line count */
>> beqlr /* nothing to do? */
>> mtctr r8
>> 0: dcbst 0,r6
>> @@ -148,7 +148,7 @@ _GLOBAL(flush_inval_dcache_range)
>> subf r8,r6,r4 /* compute length */
>> add r8,r8,r5 /* ensure we get enough */
>> lwz r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */
>> - srw. r8,r8,r9 /* compute line count */
>> + srd. r8,r8,r9 /* compute line count */
>> beqlr /* nothing to do? */
>> sync
>> isync
>
> I need an ack from the powerpc maintainer(s) before I can take this.
I think you already got an ack (on v1). See
https://patchwork.ozlabs.org/patch/1147403/#2239663
Christophe
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox