Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymund Will <rw@suse.de>2011-08-01 15:04:27 +0200
committerRaymund Will <rw@suse.de>2011-08-01 15:04:27 +0200
commit4af36a922230b73b068295c066fa0cab10a1bdc9 (patch)
tree82ece92b88020fab53a28692ad95f69daed69aa0
parentc266a183b8f2703c0e484c57f2580a457dd1e2ee (diff)
- patches.arch/x86-efi-07-introduce-e820-check_early:rpm-2.6.32.43-0.13
double MAX_EARLY_RES and improve 'check_early()'. - patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE: Refresh. - patches.arch/x86-efi-10-merge-contiguous-early-reservations: x86, efi: Merge contiguous early reservations. (bnc#681242)
-rw-r--r--kernel-source.changes9
-rw-r--r--patches.arch/x86-efi-07-introduce-e820-check_early31
-rw-r--r--patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE2
-rw-r--r--patches.arch/x86-efi-10-merge-contiguous-early-reservations93
-rw-r--r--series.conf1
5 files changed, 123 insertions, 13 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index 8513ba86ee..b11e0fbea7 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -1,4 +1,13 @@
-------------------------------------------------------------------
+Mon Aug 1 14:59:20 CEST 2011 - rw@suse.de
+
+- patches.arch/x86-efi-07-introduce-e820-check_early:
+ double MAX_EARLY_RES and improve 'check_early()'.
+- patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE: Refresh.
+- patches.arch/x86-efi-10-merge-contiguous-early-reservations:
+ x86, efi: Merge contiguous early reservations. (bnc#681242)
+
+-------------------------------------------------------------------
Mon Aug 1 14:51:58 CEST 2011 - mmarek@suse.cz
- rpm/modversions: Support for new genksyms format with E# tags for enum
diff --git a/patches.arch/x86-efi-07-introduce-e820-check_early b/patches.arch/x86-efi-07-introduce-e820-check_early
index ecc18da1ab..1894900df5 100644
--- a/patches.arch/x86-efi-07-introduce-e820-check_early
+++ b/patches.arch/x86-efi-07-introduce-e820-check_early
@@ -12,16 +12,21 @@ This 'check_early()' is needed by the backport of
as we're lacking the migration of 'lib/lmb.c' to 'mm/memblock.c' with
all subsequent fixes & improvements.
+[v2]
+- double MAX_EARLY_RES as a first machine hit 35 early reservations
+- don't open-code check_early() and adapt (i.e. invert) return values
+ to match expectations (clarified by comment)
+
Signed-off-by: Raymund Will <rw@suse.de>
---
arch/x86/include/asm/e820.h | 1 +
- arch/x86/kernel/e820.c | 15 ++++++++++++++-
- 2 files changed, 15 insertions(+), 1 deletion(-)
+ arch/x86/kernel/e820.c | 17 ++++++++++++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
-@@ -113,6 +113,7 @@ extern u64 find_e820_area(u64 start, u64
+@@ -108,6 +108,7 @@ extern u64 find_e820_area(u64 start, u64
extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align);
extern void reserve_early(u64 start, u64 end, char *name);
extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
@@ -31,30 +36,32 @@ Signed-off-by: Raymund Will <rw@suse.de>
extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align);
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
-@@ -730,7 +730,7 @@ core_initcall(e820_mark_nvs_memory);
+@@ -729,7 +729,7 @@ core_initcall(e820_mark_nvs_memory);
/*
* Early reserved memory areas.
*/
-#define MAX_EARLY_RES 20
-+#define MAX_EARLY_RES 32
++#define MAX_EARLY_RES 64
struct early_res {
u64 start, end;
-@@ -906,6 +906,19 @@ void __init reserve_early(u64 start, u64
+@@ -905,6 +905,21 @@ void __init reserve_early(u64 start, u64
__reserve_early(start, end, name, 0);
}
++/*
++ * Check whether given range would be early reservable.
++ */
+int __init check_early(u64 start, u64 end)
+{
+ int i;
+ struct early_res *r;
+
-+ for (i = 0; i < MAX_EARLY_RES && early_res[i].end; i++) {
-+ r = &early_res[i];
-+ if (start >= r->start && end <= r->end)
-+ return 1;
-+ }
-+ return 0;
++ i = find_overlapped_early(start, end);
++ r = &early_res[i];
++ if (i >= MAX_EARLY_RES || r->end)
++ return 0;
++ return 1;
+}
+
void __init free_early(u64 start, u64 end)
diff --git a/patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE b/patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE
index c74e1905b3..64b7064332 100644
--- a/patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE
+++ b/patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE
@@ -27,7 +27,7 @@ Signed-off-by: Raymund Will <rw@suse.de>
set_memory_uc(addr, npages);
+ } else if (md->type == EFI_RESERVED_TYPE) {
+ printk(KERN_INFO PFX "skip EFI_RESERVED_TYPE: 0x%llX "
-+ "attr=%d!\n", md->phys_addr, md->attribute);
++ "attr=0x%llx!\n", md->phys_addr, md->attribute);
}
systab = (u64) (unsigned long) efi_phys.systab;
diff --git a/patches.arch/x86-efi-10-merge-contiguous-early-reservations b/patches.arch/x86-efi-10-merge-contiguous-early-reservations
new file mode 100644
index 0000000000..8c9c2bde6b
--- /dev/null
+++ b/patches.arch/x86-efi-10-merge-contiguous-early-reservations
@@ -0,0 +1,93 @@
+From: Raymund Will <rw@suse.de>
+Subject: x86, efi: Merge contiguous early reservations
+Patch-mainline: N/A
+References: bnc#655434, bnc#681242
+
+Some firmware implementations deliver an insane amount (>140) of tiny
+snippets of EFI_BOOT_SERVICES_CODE and DATA, which are individually
+preserved by commit 916f676f8dc016103f983c7ec54c18ecdbb6e349.
+
+Unfortunately SLE11SP2 kernels do not have the memblock interface yet,
+and worse, e820.c provides only 20 (or 32 or so) entries for early
+reservations.
+
+This patch works around this mess, by merging all contigous regions
+of EFI_BOOT_SERVICES_{CODE,DATA} into one reservation, which brings
+the number down to 29-35 on said machine.
+
+Signed-off-by: Raymund Will <rw@suse.de>
+
+---
+ arch/x86/kernel/efi.c | 48 ++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 36 insertions(+), 12 deletions(-)
+
+--- a/arch/x86/kernel/efi.c
++++ b/arch/x86/kernel/efi.c
+@@ -304,31 +304,55 @@ static void __init print_efi_memmap(void
+ }
+ #endif /* EFI_DEBUG */
+
++static int __init efi_early_reservable(u64 start, u64 size) {
++ /* Only reserve where possible:
++ * - Not within any already allocated areas
++ * - Not over any memory area (really needed, if above?)
++ * - Not within any part of the kernel
++ * - Not the bios reserved area
++ */
++ if ((start+size >= virt_to_phys(_text)
++ && start <= virt_to_phys(_end)) ||
++ !e820_all_mapped(start, start+size, E820_RAM) ||
++ !check_early(start, start+size-1))
++ return 0;
++ return 1;
++}
++
+ void __init efi_reserve_boot_services(void)
+ {
+ void *p;
+
+ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+ efi_memory_desc_t *md = p;
++ void *n = p + memmap.desc_size;
+ u64 start = md->phys_addr;
+ u64 size = md->num_pages << EFI_PAGE_SHIFT;
+
+ if (md->type != EFI_BOOT_SERVICES_CODE &&
+ md->type != EFI_BOOT_SERVICES_DATA)
+ continue;
+- /* Only reserve where possible:
+- * - Not within any already allocated areas
+- * - Not over any memory area (really needed, if above?)
+- * - Not within any part of the kernel
+- * - Not the bios reserved area
+- */
+- if ((start+size >= virt_to_phys(_text)
+- && start <= virt_to_phys(_end)) ||
+- !e820_all_mapped(start, start+size, E820_RAM) ||
+- check_early(start, start+size)) {
+- /* Could not reserve, skip it */
++
++ /* Merge contiguous regions to avoid overflowing
++ * MAX_EARLY_RES (max observed has been >140!)
++ */
++ while (n < memmap.map_end) {
++ efi_memory_desc_t *nd = n;
++ u64 n_size = size + (nd->num_pages << EFI_PAGE_SHIFT);
++ if ((nd->type != EFI_BOOT_SERVICES_CODE &&
++ nd->type != EFI_BOOT_SERVICES_DATA) ||
++ nd->phys_addr != (start + size) ||
++ !efi_early_reservable(start, n_size))
++ break;
++ size = n_size;
++ p = nd;
++ n += memmap.desc_size;
++ }
++
++ if (!efi_early_reservable(start, size)) {
++ /* Reserve will fail, skip it */
+ md->num_pages = 0;
+- printk(KERN_INFO PFX "Could not reserve boot range "
++ printk(KERN_INFO PFX "Skip reserving boot range "
+ "[0x%010llx-0x%010llx]\n",
+ start, start+size-1);
+ } else
diff --git a/series.conf b/series.conf
index fbf9456681..2eb4babff1 100644
--- a/series.conf
+++ b/series.conf
@@ -517,6 +517,7 @@
patches.arch/x86-efi-07-introduce-e820-check_early
patches.arch/x86-efi-08-reserve_early-only-unreserved-regions
patches.arch/x86-efi-09-ignore-EFI_RESERVED_TYPE
+ patches.arch/x86-efi-10-merge-contiguous-early-reservations
# for KMS
patches.arch/x86-Add-array-variants-for-setting-memory-to-wc