summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-07-25 10:00:22 +0100
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2020-07-25 10:00:22 +0100
commit7f28286f5cb1ca682e3ba0a8706d8884f12bc49e (patch)
tree1761cca1493e83038539afe178d81420fddad686
parent75fbb41d2857d93208c74a8e0228b29fd7bf04c0 (diff)
downloadqemu-openbios-7f28286f5cb1ca682e3ba0a8706d8884f12bc49e.tar.gz
PPC: mark first 4 pages of physical and virtual memory as unavailable
The Debian ports images have now switched from using yaboot to grub as their bootloader. Recent versions of these images will hang rather than boot under QEMU despite there being no obvious changes to the boot process. Further investigation reveals that the second stage grub bootloader appears to use low memory whilst loading the kernel/initrd from disk: unfortunately the OpenBIOS vector table lives within the first few pages of physical RAM and so grub writes over the vector table (in particular overwriting the MMU fault handlers) causing them to fail next time they are executed which causes the hang. Fortunately just before this stage of the bootloader executes, it uses the CIF to request the contents of the /memory node "available" property. It seems that the low memory locations used by grub are taken from the start of the available range, so we can simply increase the number of RAM pages reserved at the bottom of RAM to ensure that the area chosen by the bootloader doesn't conflict with the vector table. This patch raises the start of available memory from 0x1000 to 0x4000 which allows grub to boot successfully in my tests. According to dumps of device trees taken from real PPC Macs there are already several examples where the start of available memory is set to 0x3000 or 0x4000, so as this is already present on real hardware it should not cause any regressions. Finally it is worth noting that even in the earlier grub images I could see write accesses to low memory that would overwrite the vector table: I think that until recently we were lucky that they happened to avoid anything that was critical to allow the kernel to load and boot. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
-rw-r--r--arch/ppc/qemu/ofmem.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c
index 7a78a1e3..4ff0803a 100644
--- a/arch/ppc/qemu/ofmem.c
+++ b/arch/ppc/qemu/ofmem.c
@@ -571,9 +571,9 @@ ofmem_init(void)
{
ofmem_t *ofmem = ofmem_arch_get_private();
- /* Mark the first page as non-free */
- ofmem_claim_phys(0, PAGE_SIZE, 0);
- ofmem_claim_virt(0, PAGE_SIZE, 0);
+ /* Mark the first 4 pages as non-free */
+ ofmem_claim_phys(0, 4 * PAGE_SIZE, 0);
+ ofmem_claim_virt(0, 4 * PAGE_SIZE, 0);
/* Map everything at the top of physical RAM 1:1, minus the OpenBIOS ROM in RAM copy */
ofmem_claim_phys(get_ram_top(), get_hash_base() + HASH_SIZE - get_ram_top(), 0);