浏览代码

[pcbios] Restrict external memory allocations to the low 4GB

When running the 64-bit BIOS version of iPXE, restrict external memory
allocations to the low 4GB to ensure that allocations (such as for
initrds) fall within our identity-mapped memory region, and will be
accessible to the potentially 32-bit operating system.

Move largest_memblock() back to memtop_umalloc.c, since this change
imposes a restriction that applies only to BIOS builds.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 年前
父节点
当前提交
d3db00ecf9
共有 2 个文件被更改,包括 53 次插入85 次删除
  1. 53
    0
      src/arch/x86/interface/pcbios/memtop_umalloc.c
  2. 0
    85
      src/core/memblock.c

+ 53
- 0
src/arch/x86/interface/pcbios/memtop_umalloc.c 查看文件

@@ -38,6 +38,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
38 38
 #include <ipxe/memblock.h>
39 39
 #include <ipxe/umalloc.h>
40 40
 
41
+/** Maximum usable address for external allocated memory */
42
+#define EM_MAX_ADDRESS 0xffffffffUL
43
+
41 44
 /** Alignment of external allocated memory */
42 45
 #define EM_ALIGN ( 4 * 1024 )
43 46
 
@@ -61,6 +64,56 @@ static userptr_t bottom = UNULL;
61 64
 /** Remaining space on heap */
62 65
 static size_t heap_size;
63 66
 
67
+/**
68
+ * Find largest usable memory region
69
+ *
70
+ * @ret start		Start of region
71
+ * @ret len		Length of region
72
+ */
73
+size_t largest_memblock ( userptr_t *start ) {
74
+	struct memory_map memmap;
75
+	struct memory_region *region;
76
+	physaddr_t max = EM_MAX_ADDRESS;
77
+	physaddr_t region_start;
78
+	physaddr_t region_end;
79
+	size_t region_len;
80
+	unsigned int i;
81
+	size_t len = 0;
82
+
83
+	/* Avoid returning uninitialised data on error */
84
+	*start = UNULL;
85
+
86
+	/* Scan through all memory regions */
87
+	get_memmap ( &memmap );
88
+	for ( i = 0 ; i < memmap.count ; i++ ) {
89
+		region = &memmap.regions[i];
90
+		DBG ( "Considering [%llx,%llx)\n", region->start, region->end );
91
+
92
+		/* Truncate block to maximum physical address */
93
+		if ( region->start > max ) {
94
+			DBG ( "...starts after maximum address %lx\n", max );
95
+			continue;
96
+		}
97
+		region_start = region->start;
98
+		if ( region->end > max ) {
99
+			DBG ( "...end truncated to maximum address %lx\n", max);
100
+			region_end = 0; /* =max, given the wraparound */
101
+		} else {
102
+			region_end = region->end;
103
+		}
104
+		region_len = ( region_end - region_start );
105
+
106
+		/* Use largest block */
107
+		if ( region_len > len ) {
108
+			DBG ( "...new best block found\n" );
109
+			*start = phys_to_user ( region_start );
110
+			len = region_len;
111
+		}
112
+	}
113
+
114
+	return len;
115
+}
116
+
64 117
 /**
65 118
  * Initialise external heap
66 119
  *

+ 0
- 85
src/core/memblock.c 查看文件

@@ -1,85 +0,0 @@
1
-/*
2
- * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2 of the
7
- * License, or (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
- * General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
- * 02110-1301, USA.
18
- *
19
- * You can also choose to distribute this program under the terms of
20
- * the Unmodified Binary Distribution Licence (as given in the file
21
- * COPYING.UBDL), provided that you have satisfied its requirements.
22
- */
23
-
24
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
-
26
-/** @file
27
- *
28
- * Largest memory block
29
- *
30
- */
31
-
32
-#include <stdint.h>
33
-#include <ipxe/uaccess.h>
34
-#include <ipxe/io.h>
35
-#include <ipxe/memblock.h>
36
-
37
-/**
38
- * Find largest usable memory region
39
- *
40
- * @ret start		Start of region
41
- * @ret len		Length of region
42
- */
43
-size_t largest_memblock ( userptr_t *start ) {
44
-	struct memory_map memmap;
45
-	struct memory_region *region;
46
-	physaddr_t max = ~( ( physaddr_t ) 0 );
47
-	physaddr_t region_start;
48
-	physaddr_t region_end;
49
-	size_t region_len;
50
-	unsigned int i;
51
-	size_t len = 0;
52
-
53
-	/* Avoid returning uninitialised data on error */
54
-	*start = UNULL;
55
-
56
-	/* Scan through all memory regions */
57
-	get_memmap ( &memmap );
58
-	for ( i = 0 ; i < memmap.count ; i++ ) {
59
-		region = &memmap.regions[i];
60
-		DBG ( "Considering [%llx,%llx)\n", region->start, region->end );
61
-
62
-		/* Truncate block to maximum physical address */
63
-		if ( region->start > max ) {
64
-			DBG ( "...starts after maximum address %lx\n", max );
65
-			continue;
66
-		}
67
-		region_start = region->start;
68
-		if ( region->end > max ) {
69
-			DBG ( "...end truncated to maximum address %lx\n", max);
70
-			region_end = 0; /* =max, given the wraparound */
71
-		} else {
72
-			region_end = region->end;
73
-		}
74
-		region_len = ( region_end - region_start );
75
-
76
-		/* Use largest block */
77
-		if ( region_len > len ) {
78
-			DBG ( "...new best block found\n" );
79
-			*start = phys_to_user ( region_start );
80
-			len = region_len;
81
-		}
82
-	}
83
-
84
-	return len;
85
-}

正在加载...
取消
保存