@@ -1459,64 +1459,133 @@ static void __init kmap_init(void)
1459
1459
1460
1460
static void __init map_lowmem (void )
1461
1461
{
1462
- phys_addr_t kernel_x_start = round_down (__pa (KERNEL_START ), SECTION_SIZE );
1463
- phys_addr_t kernel_x_end = round_up (__pa (__init_end ), SECTION_SIZE );
1464
1462
phys_addr_t start , end ;
1465
1463
u64 i ;
1466
1464
1467
1465
/* Map all the lowmem memory banks. */
1468
1466
for_each_mem_range (i , & start , & end ) {
1469
1467
struct map_desc map ;
1470
1468
1469
+ pr_debug ("map lowmem start: 0x%08llx, end: 0x%08llx\n" ,
1470
+ (long long )start , (long long )end );
1471
1471
if (end > arm_lowmem_limit )
1472
1472
end = arm_lowmem_limit ;
1473
1473
if (start >= end )
1474
1474
break ;
1475
1475
1476
- if (end < kernel_x_start ) {
1477
- map .pfn = __phys_to_pfn (start );
1478
- map .virtual = __phys_to_virt (start );
1479
- map .length = end - start ;
1480
- map .type = MT_MEMORY_RWX ;
1476
+ /*
1477
+ * If our kernel image is in the VMALLOC area we need to remove
1478
+ * the kernel physical memory from lowmem since the kernel will
1479
+ * be mapped separately.
1480
+ *
1481
+ * The kernel will typically be at the very start of lowmem,
1482
+ * but any placement relative to memory ranges is possible.
1483
+ *
1484
+ * If the memblock contains the kernel, we have to chisel out
1485
+ * the kernel memory from it and map each part separately. We
1486
+ * get 6 different theoretical cases:
1487
+ *
1488
+ * +--------+ +--------+
1489
+ * +-- start --+ +--------+ | Kernel | | Kernel |
1490
+ * | | | Kernel | | case 2 | | case 5 |
1491
+ * | | | case 1 | +--------+ | | +--------+
1492
+ * | Memory | +--------+ | | | Kernel |
1493
+ * | range | +--------+ | | | case 6 |
1494
+ * | | | Kernel | +--------+ | | +--------+
1495
+ * | | | case 3 | | Kernel | | |
1496
+ * +-- end ----+ +--------+ | case 4 | | |
1497
+ * +--------+ +--------+
1498
+ */
1481
1499
1482
- create_mapping (& map );
1483
- } else if (start >= kernel_x_end ) {
1484
- map .pfn = __phys_to_pfn (start );
1485
- map .virtual = __phys_to_virt (start );
1486
- map .length = end - start ;
1487
- map .type = MT_MEMORY_RW ;
1500
+ /* Case 5: kernel covers range, don't map anything, should be rare */
1501
+ if ((start > kernel_sec_start ) && (end < kernel_sec_end ))
1502
+ break ;
1488
1503
1489
- create_mapping (& map );
1490
- } else {
1491
- /* This better cover the entire kernel */
1492
- if (start < kernel_x_start ) {
1504
+ /* Cases where the kernel is starting inside the range */
1505
+ if ((kernel_sec_start >= start ) && (kernel_sec_start <= end )) {
1506
+ /* Case 6: kernel is embedded in the range, we need two mappings */
1507
+ if ((start < kernel_sec_start ) && (end > kernel_sec_end )) {
1508
+ /* Map memory below the kernel */
1493
1509
map .pfn = __phys_to_pfn (start );
1494
1510
map .virtual = __phys_to_virt (start );
1495
- map .length = kernel_x_start - start ;
1511
+ map .length = kernel_sec_start - start ;
1496
1512
map .type = MT_MEMORY_RW ;
1497
-
1498
1513
create_mapping (& map );
1499
- }
1500
-
1501
- map .pfn = __phys_to_pfn (kernel_x_start );
1502
- map .virtual = __phys_to_virt (kernel_x_start );
1503
- map .length = kernel_x_end - kernel_x_start ;
1504
- map .type = MT_MEMORY_RWX ;
1505
-
1506
- create_mapping (& map );
1507
-
1508
- if (kernel_x_end < end ) {
1509
- map .pfn = __phys_to_pfn (kernel_x_end );
1510
- map .virtual = __phys_to_virt (kernel_x_end );
1511
- map .length = end - kernel_x_end ;
1514
+ /* Map memory above the kernel */
1515
+ map .pfn = __phys_to_pfn (kernel_sec_end );
1516
+ map .virtual = __phys_to_virt (kernel_sec_end );
1517
+ map .length = end - kernel_sec_end ;
1512
1518
map .type = MT_MEMORY_RW ;
1513
-
1514
1519
create_mapping (& map );
1520
+ break ;
1515
1521
}
1522
+ /* Case 1: kernel and range start at the same address, should be common */
1523
+ if (kernel_sec_start == start )
1524
+ start = kernel_sec_end ;
1525
+ /* Case 3: kernel and range end at the same address, should be rare */
1526
+ if (kernel_sec_end == end )
1527
+ end = kernel_sec_start ;
1528
+ } else if ((kernel_sec_start < start ) && (kernel_sec_end > start ) && (kernel_sec_end < end )) {
1529
+ /* Case 2: kernel ends inside range, starts below it */
1530
+ start = kernel_sec_end ;
1531
+ } else if ((kernel_sec_start > start ) && (kernel_sec_start < end ) && (kernel_sec_end > end )) {
1532
+ /* Case 4: kernel starts inside range, ends above it */
1533
+ end = kernel_sec_start ;
1516
1534
}
1535
+ map .pfn = __phys_to_pfn (start );
1536
+ map .virtual = __phys_to_virt (start );
1537
+ map .length = end - start ;
1538
+ map .type = MT_MEMORY_RW ;
1539
+ create_mapping (& map );
1517
1540
}
1518
1541
}
1519
1542
1543
+ static void __init map_kernel (void )
1544
+ {
1545
+ /*
1546
+ * We use the well known kernel section start and end and split the area in the
1547
+ * middle like this:
1548
+ * . .
1549
+ * | RW memory |
1550
+ * +----------------+ kernel_x_start
1551
+ * | Executable |
1552
+ * | kernel memory |
1553
+ * +----------------+ kernel_x_end / kernel_nx_start
1554
+ * | Non-executable |
1555
+ * | kernel memory |
1556
+ * +----------------+ kernel_nx_end
1557
+ * | RW memory |
1558
+ * . .
1559
+ *
1560
+ * Notice that we are dealing with section sized mappings here so all of this
1561
+ * will be bumped to the closest section boundary. This means that some of the
1562
+ * non-executable part of the kernel memory is actually mapped as executable.
1563
+ * This will only persist until we turn on proper memory management later on
1564
+ * and we remap the whole kernel with page granularity.
1565
+ */
1566
+ phys_addr_t kernel_x_start = kernel_sec_start ;
1567
+ phys_addr_t kernel_x_end = round_up (__pa (__init_end ), SECTION_SIZE );
1568
+ phys_addr_t kernel_nx_start = kernel_x_end ;
1569
+ phys_addr_t kernel_nx_end = kernel_sec_end ;
1570
+ struct map_desc map ;
1571
+
1572
+ map .pfn = __phys_to_pfn (kernel_x_start );
1573
+ map .virtual = __phys_to_virt (kernel_x_start );
1574
+ map .length = kernel_x_end - kernel_x_start ;
1575
+ map .type = MT_MEMORY_RWX ;
1576
+ create_mapping (& map );
1577
+
1578
+ /* If the nx part is small it may end up covered by the tail of the RWX section */
1579
+ if (kernel_x_end == kernel_nx_end )
1580
+ return ;
1581
+
1582
+ map .pfn = __phys_to_pfn (kernel_nx_start );
1583
+ map .virtual = __phys_to_virt (kernel_nx_start );
1584
+ map .length = kernel_nx_end - kernel_nx_start ;
1585
+ map .type = MT_MEMORY_RW ;
1586
+ create_mapping (& map );
1587
+ }
1588
+
1520
1589
#ifdef CONFIG_ARM_PV_FIXUP
1521
1590
typedef void pgtables_remap (long long offset , unsigned long pgd );
1522
1591
pgtables_remap lpae_pgtables_remap_asm ;
@@ -1647,9 +1716,18 @@ void __init paging_init(const struct machine_desc *mdesc)
1647
1716
{
1648
1717
void * zero_page ;
1649
1718
1719
+ pr_debug ("physical kernel sections: 0x%08x-0x%08x\n" ,
1720
+ kernel_sec_start , kernel_sec_end );
1721
+
1650
1722
prepare_page_table ();
1651
1723
map_lowmem ();
1652
1724
memblock_set_current_limit (arm_lowmem_limit );
1725
+ pr_debug ("lowmem limit is %08llx\n" , (long long )arm_lowmem_limit );
1726
+ /*
1727
+ * After this point early_alloc(), i.e. the memblock allocator, can
1728
+ * be used
1729
+ */
1730
+ map_kernel ();
1653
1731
dma_contiguous_remap ();
1654
1732
early_fixmap_shutdown ();
1655
1733
devicemaps_init (mdesc );
0 commit comments