50a9ff6df4
The kernel is moved ahead to version 3.10.0-693.21.1.el7 To summarize: CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1' This is fixed by load fences and is "baked in" and cannot be turned off. CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2' This is fixed by a combination of retpolines and IBPB, or IBRS+IBPB if on skylake. This requires a microcode change in the processors. This feature, if on, has a significant performance impact. It is assumed on unless turned off via the "nospectre_v2" bootarg. CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3' This is fixed by page table isolation using the Kaiser patches. This feature is assumed on unless turned off via the "nopti" bootarg. As of the commit date, we have changed the installer kickstarts to issue both "nopti nospectre_v2" bootargs to minimize realtime impacts by default. The customer will be able to optionally sacrifice performance for extra security at datafill time. Change-Id: Id7c99923f2ee2ee91f77c7bd9940e684eff8b476 Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
225 lines
8.1 KiB
Diff
225 lines
8.1 KiB
Diff
From f51db02e07e1bad6c6ddf2cfd8b9091bc40950f0 Mon Sep 17 00:00:00 2001
|
|
Message-Id: <f51db02e07e1bad6c6ddf2cfd8b9091bc40950f0.1522097754.git.Jim.Somerville@windriver.com>
|
|
In-Reply-To: <f4706beaf86081b0890ea616082913f8f51823ff.1522097754.git.Jim.Somerville@windriver.com>
|
|
References: <f4706beaf86081b0890ea616082913f8f51823ff.1522097754.git.Jim.Somerville@windriver.com>
|
|
From: Akinobu Mita <akinobu.mita@gmail.com>
|
|
Date: Tue, 31 May 2016 16:09:04 -0400
|
|
Subject: [PATCH 10/27] cma: add placement specifier for "cma=" kernel
|
|
parameter
|
|
|
|
Commit 5ea3b1b2f8ad9162684431ce6188102ca4c64b7a upstream
|
|
Backported-by: Nam Ninh <nam.ninh@windriver.com>
|
|
|
|
Currently, "cma=" kernel parameter is used to specify the size of CMA,
|
|
but we can't specify where it is located. We want to locate CMA below
|
|
4GB for devices only supporting 32-bit addressing on 64-bit systems
|
|
without iommu.
|
|
|
|
This enables to specify the placement of CMA by extending "cma=" kernel
|
|
parameter.
|
|
|
|
Examples:
|
|
1. locate 64MB CMA below 4GB by "cma=64M@0-4G"
|
|
2. locate 64MB CMA exact at 512MB by "cma=64M@512M"
|
|
|
|
Note that the DMA contiguous memory allocator on x86 assumes that
|
|
page_address() works for the pages to allocate. So this change requires
|
|
to limit end address of contiguous memory area upto max_pfn_mapped to
|
|
prevent from locating it on highmem area by the argument of
|
|
dma_contiguous_reserve().
|
|
|
|
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
|
|
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
|
|
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
|
Cc: David Woodhouse <dwmw2@infradead.org>
|
|
Cc: Don Dutile <ddutile@redhat.com>
|
|
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
Cc: Ingo Molnar <mingo@redhat.com>
|
|
Cc: "H. Peter Anvin" <hpa@zytor.com>
|
|
Cc: Andi Kleen <andi@firstfloor.org>
|
|
Cc: Yinghai Lu <yinghai@kernel.org>
|
|
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
|
|
---
|
|
Documentation/kernel-parameters.txt | 7 +++++--
|
|
arch/x86/kernel/setup.c | 2 +-
|
|
drivers/base/dma-contiguous.c | 42 ++++++++++++++++++++++++++++---------
|
|
include/linux/dma-contiguous.h | 9 +++++---
|
|
4 files changed, 44 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
|
|
index b06a8fb..c116178 100644
|
|
--- a/Documentation/kernel-parameters.txt
|
|
+++ b/Documentation/kernel-parameters.txt
|
|
@@ -560,8 +560,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|
Also note the kernel might malfunction if you disable
|
|
some critical bits.
|
|
|
|
- cma=nn[MG] [ARM,KNL]
|
|
- Sets the size of kernel global memory area for contiguous
|
|
+ cma=nn[MG]@[start[MG][-end[MG]]]
|
|
+ [ARM,X86,KNL]
|
|
+ Sets the size of kernel global memory area for
|
|
+ contiguous memory allocations and optionally the
|
|
+ placement constraint by the physical address range of
|
|
memory allocations. For more information, see
|
|
include/linux/dma-contiguous.h
|
|
|
|
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
|
|
index dcb7e8a..ab7c0c3 100644
|
|
--- a/arch/x86/kernel/setup.c
|
|
+++ b/arch/x86/kernel/setup.c
|
|
@@ -1252,7 +1252,7 @@ void __init setup_arch(char **cmdline_p)
|
|
setup_real_mode();
|
|
|
|
memblock_set_current_limit(get_max_mapped());
|
|
- dma_contiguous_reserve(0);
|
|
+ dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
|
|
|
|
/*
|
|
* NOTE: On x86-32, only from this point on, fixmaps are ready for use.
|
|
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
|
|
index 99802d6..8f50513 100644
|
|
--- a/drivers/base/dma-contiguous.c
|
|
+++ b/drivers/base/dma-contiguous.c
|
|
@@ -59,11 +59,22 @@ struct cma *dma_contiguous_default_area;
|
|
*/
|
|
static const phys_addr_t size_bytes = CMA_SIZE_MBYTES * SZ_1M;
|
|
static phys_addr_t size_cmdline = -1;
|
|
+static phys_addr_t base_cmdline;
|
|
+static phys_addr_t limit_cmdline;
|
|
|
|
static int __init early_cma(char *p)
|
|
{
|
|
pr_debug("%s(%s)\n", __func__, p);
|
|
size_cmdline = memparse(p, &p);
|
|
+ if (*p != '@')
|
|
+ return 0;
|
|
+ base_cmdline = memparse(p + 1, &p);
|
|
+ if (*p != '-') {
|
|
+ limit_cmdline = base_cmdline + size_cmdline;
|
|
+ return 0;
|
|
+ }
|
|
+ limit_cmdline = memparse(p + 1, &p);
|
|
+
|
|
return 0;
|
|
}
|
|
early_param("cma", early_cma);
|
|
@@ -107,11 +118,18 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void)
|
|
void __init dma_contiguous_reserve(phys_addr_t limit)
|
|
{
|
|
phys_addr_t selected_size = 0;
|
|
+ phys_addr_t selected_base = 0;
|
|
+ phys_addr_t selected_limit = limit;
|
|
+ bool fixed = false;
|
|
|
|
pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
|
|
|
|
if (size_cmdline != -1) {
|
|
selected_size = size_cmdline;
|
|
+ selected_base = base_cmdline;
|
|
+ selected_limit = min_not_zero(limit_cmdline, limit);
|
|
+ if (base_cmdline + size_cmdline == limit_cmdline)
|
|
+ fixed = true;
|
|
} else {
|
|
#ifdef CONFIG_CMA_SIZE_SEL_MBYTES
|
|
selected_size = size_bytes;
|
|
@@ -128,10 +146,12 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
|
|
pr_debug("%s: reserving %ld MiB for global area\n", __func__,
|
|
(unsigned long)selected_size / SZ_1M);
|
|
|
|
- dma_contiguous_reserve_area(selected_size, 0, limit,
|
|
- &dma_contiguous_default_area);
|
|
+ dma_contiguous_reserve_area(selected_size, selected_base,
|
|
+ selected_limit,
|
|
+ &dma_contiguous_default_area,
|
|
+ fixed);
|
|
}
|
|
-};
|
|
+}
|
|
|
|
static DEFINE_MUTEX(cma_mutex);
|
|
|
|
@@ -187,15 +207,20 @@ core_initcall(cma_init_reserved_areas);
|
|
* @base: Base address of the reserved area optional, use 0 for any
|
|
* @limit: End address of the reserved memory (optional, 0 for any).
|
|
* @res_cma: Pointer to store the created cma region.
|
|
+ * @fixed: hint about where to place the reserved area
|
|
*
|
|
* This function reserves memory from early allocator. It should be
|
|
* called by arch specific code once the early allocator (memblock or bootmem)
|
|
* has been activated and all other subsystems have already allocated/reserved
|
|
* memory. This function allows to create custom reserved areas for specific
|
|
* devices.
|
|
+ *
|
|
+ * If @fixed is true, reserve contiguous area at exactly @base. If false,
|
|
+ * reserve in range from @base to @limit.
|
|
*/
|
|
int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
|
|
- phys_addr_t limit, struct cma **res_cma)
|
|
+ phys_addr_t limit, struct cma **res_cma,
|
|
+ bool fixed)
|
|
{
|
|
struct cma *cma = &cma_areas[cma_area_count];
|
|
phys_addr_t alignment;
|
|
@@ -221,18 +246,15 @@ int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
|
|
limit &= ~(alignment - 1);
|
|
|
|
/* Reserve memory */
|
|
- if (base) {
|
|
+ if (base && fixed) {
|
|
if (memblock_is_region_reserved(base, size) ||
|
|
memblock_reserve(base, size) < 0) {
|
|
ret = -EBUSY;
|
|
goto err;
|
|
}
|
|
} else {
|
|
- /*
|
|
- * Use __memblock_alloc_base() since
|
|
- * memblock_alloc_base() panic()s.
|
|
- */
|
|
- phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
|
|
+ phys_addr_t addr = memblock_alloc_range(size, alignment, base,
|
|
+ limit);
|
|
if (!addr) {
|
|
ret = -ENOMEM;
|
|
goto err;
|
|
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
|
|
index 3b28f93..772eab5 100644
|
|
--- a/include/linux/dma-contiguous.h
|
|
+++ b/include/linux/dma-contiguous.h
|
|
@@ -88,7 +88,8 @@ static inline void dma_contiguous_set_default(struct cma *cma)
|
|
void dma_contiguous_reserve(phys_addr_t addr_limit);
|
|
|
|
int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
|
|
- phys_addr_t limit, struct cma **res_cma);
|
|
+ phys_addr_t limit, struct cma **res_cma,
|
|
+ bool fixed);
|
|
|
|
/**
|
|
* dma_declare_contiguous() - reserve area for contiguous memory handling
|
|
@@ -108,7 +109,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
|
|
{
|
|
struct cma *cma;
|
|
int ret;
|
|
- ret = dma_contiguous_reserve_area(size, base, limit, &cma);
|
|
+ ret = dma_contiguous_reserve_area(size, base, limit, &cma, true);
|
|
if (ret == 0)
|
|
dev_set_cma_area(dev, cma);
|
|
|
|
@@ -136,7 +137,9 @@ static inline void dma_contiguous_set_default(struct cma *cma) { }
|
|
static inline void dma_contiguous_reserve(phys_addr_t limit) { }
|
|
|
|
static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
|
|
- phys_addr_t limit, struct cma **res_cma) {
|
|
+ phys_addr_t limit, struct cma **res_cma,
|
|
+ bool fixed)
|
|
+{
|
|
return -ENOSYS;
|
|
}
|
|
|
|
--
|
|
1.8.3.1
|
|
|