DF-5588 / fix.diff
--- sys/platform/pc64/acpica/acpi_sdt.c +++ sys/platform/pc64/acpica/acpi_sdt.c @@ -68,12 +68,30 @@ uint8_t *ptr; u_long rsdp_paddr; - if (kgetenv_ulong("hint.acpi.0.rsdp", &rsdp_paddr) == 1) { - SDT_VPRINTF("RSDP in kenv hint\n"); + /* + * The hinted RSDP address must refer to physical memory + * (mapping an address with reserved PTE bits faults the + * moment the mapping is read), and the bytes it points at + * must actually look like an RSDP with a revision we + * understand before it is installed as the ACPI table root. + * Otherwise fall back to the firmware scan below. + */ + if (kgetenv_ulong("hint.acpi.0.rsdp", &rsdp_paddr) == 1 && + rsdp_paddr < ptoa(Maxmem)) { mapsz = PAGE_SIZE; ptr = pmap_mapdev(rsdp_paddr, mapsz); rsdp = (const ACPI_TABLE_RSDP *)ptr; - goto found_rsdp; + if (memcmp(rsdp->Signature, ACPI_SIG_RSDP, + sizeof(rsdp->Signature)) == 0 && + rsdp->Revision <= 2) { + SDT_VPRINTF("RSDP in kenv hint\n"); + goto found_rsdp; + } + kprintf("sdt_probe: kenv RSDP failed validation, " + "falling back to firmware scan\n"); + pmap_unmapdev((vm_offset_t)ptr, mapsz); + ptr = NULL; + mapsz = 0; } if (ebda_addr != 0) { |