Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153370734
D15610.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D15610.diff
View Options
Index: head/sys/powerpc/ofw/ofw_machdep.c
===================================================================
--- head/sys/powerpc/ofw/ofw_machdep.c
+++ head/sys/powerpc/ofw/ofw_machdep.c
@@ -225,41 +225,19 @@
#ifdef FDT
static int
-excise_fdt_reserved(struct mem_region *avail, int asz)
+excise_reserved_regions(struct mem_region *avail, int asz,
+ struct mem_region *exclude, int esz)
{
- struct {
- uint64_t address;
- uint64_t size;
- } fdtmap[32];
- ssize_t fdtmapsize;
- phandle_t chosen;
int i, j, k;
- chosen = OF_finddevice("/chosen");
- fdtmapsize = OF_getprop(chosen, "fdtmemreserv", fdtmap, sizeof(fdtmap));
-
- for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
- fdtmap[j].address = be64toh(fdtmap[j].address) & ~PAGE_MASK;
- fdtmap[j].size = round_page(be64toh(fdtmap[j].size));
- }
-
- KASSERT(j*sizeof(fdtmap[0]) < sizeof(fdtmap),
- ("Exceeded number of FDT reservations"));
- /* Add a virtual entry for the FDT itself */
- if (fdt != NULL) {
- fdtmap[j].address = (vm_offset_t)fdt & ~PAGE_MASK;
- fdtmap[j].size = round_page(fdt_totalsize(fdt));
- fdtmapsize += sizeof(fdtmap[0]);
- }
-
for (i = 0; i < asz; i++) {
- for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+ for (j = 0; j < esz; j++) {
/*
* Case 1: Exclusion region encloses complete
* available entry. Drop it and move on.
*/
- if (fdtmap[j].address <= avail[i].mr_start &&
- fdtmap[j].address + fdtmap[j].size >=
+ if (exclude[j].mr_start <= avail[i].mr_start &&
+ exclude[j].mr_start + exclude[j].mr_size >=
avail[i].mr_start + avail[i].mr_size) {
for (k = i+1; k < asz; k++)
avail[k-1] = avail[k];
@@ -274,20 +252,20 @@
* a new available entry with the region after
* the excluded region, if any.
*/
- if (fdtmap[j].address >= avail[i].mr_start &&
- fdtmap[j].address < avail[i].mr_start +
+ if (exclude[j].mr_start >= avail[i].mr_start &&
+ exclude[j].mr_start < avail[i].mr_start +
avail[i].mr_size) {
- if (fdtmap[j].address + fdtmap[j].size <
+ if (exclude[j].mr_start + exclude[j].mr_size <
avail[i].mr_start + avail[i].mr_size) {
avail[asz].mr_start =
- fdtmap[j].address + fdtmap[j].size;
+ exclude[j].mr_start + exclude[j].mr_size;
avail[asz].mr_size = avail[i].mr_start +
avail[i].mr_size -
avail[asz].mr_start;
asz++;
}
- avail[i].mr_size = fdtmap[j].address -
+ avail[i].mr_size = exclude[j].mr_start -
avail[i].mr_start;
}
@@ -297,13 +275,13 @@
* The case of a contained exclusion zone has already
* been caught in case 2.
*/
- if (fdtmap[j].address + fdtmap[j].size >=
- avail[i].mr_start && fdtmap[j].address +
- fdtmap[j].size < avail[i].mr_start +
+ if (exclude[j].mr_start + exclude[j].mr_size >=
+ avail[i].mr_start && exclude[j].mr_start +
+ exclude[j].mr_size < avail[i].mr_start +
avail[i].mr_size) {
avail[i].mr_size += avail[i].mr_start;
avail[i].mr_start =
- fdtmap[j].address + fdtmap[j].size;
+ exclude[j].mr_start + exclude[j].mr_size;
avail[i].mr_size -= avail[i].mr_start;
}
}
@@ -311,6 +289,62 @@
return (asz);
}
+
+static int
+excise_initrd_region(struct mem_region *avail, int asz)
+{
+ phandle_t chosen;
+ uint64_t start, end;
+ ssize_t size;
+ struct mem_region initrdmap[1];
+
+ chosen = OF_finddevice("/chosen");
+ size = OF_getprop(chosen, "linux,initrd-start", &start, sizeof(start));
+ if (size <= 0)
+ return (asz);
+
+ size = OF_getprop(chosen, "linux,initrd-end", &end, sizeof(end));
+ if (size <= 0)
+ return (asz);
+
+ initrdmap[0].mr_start = start;
+ initrdmap[0].mr_size = end - start;
+
+ asz = excise_reserved_regions(avail, asz, initrdmap, 1);
+
+ return (asz);
+}
+
+static int
+excise_fdt_reserved(struct mem_region *avail, int asz)
+{
+ struct mem_region fdtmap[32];
+ ssize_t fdtmapsize;
+ phandle_t chosen;
+ int j, fdtentries;
+
+ chosen = OF_finddevice("/chosen");
+ fdtmapsize = OF_getprop(chosen, "fdtmemreserv", fdtmap, sizeof(fdtmap));
+
+ for (j = 0; j < fdtmapsize/sizeof(fdtmap[0]); j++) {
+ fdtmap[j].mr_start = be64toh(fdtmap[j].mr_start) & ~PAGE_MASK;
+ fdtmap[j].mr_size = round_page(be64toh(fdtmap[j].mr_size));
+ }
+
+ KASSERT(j*sizeof(fdtmap[0]) < sizeof(fdtmap),
+ ("Exceeded number of FDT reservations"));
+ /* Add a virtual entry for the FDT itself */
+ if (fdt != NULL) {
+ fdtmap[j].mr_start = (vm_offset_t)fdt & ~PAGE_MASK;
+ fdtmap[j].mr_size = round_page(fdt_totalsize(fdt));
+ fdtmapsize += sizeof(fdtmap[0]);
+ }
+
+ fdtentries = fdtmapsize/sizeof(fdtmap[0]);
+ asz = excise_reserved_regions(avail, asz, fdtmap, fdtentries);
+
+ return (asz);
+}
#endif
/*
@@ -364,6 +398,13 @@
phandle = OF_finddevice("/chosen");
if (OF_hasprop(phandle, "fdtmemreserv"))
asz = excise_fdt_reserved(availp, asz);
+
+ /* If the kernel is being loaded through kexec, initrd region is listed
+ * in /chosen but the region is not marked as reserved, so, we might exclude
+ * it here.
+ */
+ if (OF_hasprop(phandle, "linux,initrd-start"))
+ asz = excise_initrd_region(availp, asz);
#endif
*memsz = msz;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 21, 6:40 PM (2 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31926427
Default Alt Text
D15610.diff (5 KB)
Attached To
Mode
D15610: powerpc64: Avoid overwriting initrd area
Attached
Detach File
Event Timeline
Log In to Comment