Adding a V=R mapping for amd64?
Kostik Belousov
kostikbel at gmail.com
Wed Sep 29 20:12:27 UTC 2010
On Wed, Sep 29, 2010 at 12:40:57PM -0700, Matthew Fleming wrote:
> I'm hacking around with making a "fast reboot" that puts a copy of the
> MBR from disk into address 0x7c00 and, after disabling various
> translation bits and stopping other CPUs, branches to it, to skip the
> hardware self test that normally happens on boot.
>
> I haven't gotten to the point of attempting to run the code at 0x7c00
> because I'm first hitting a different error. Despite my attempts to
> enter a translation into the hardware page table, I get a panic trying
> to write to address 0x7000, where I intended to put the trampoline
> code that turns off translation.
>
> Rebooting...
> Attempt to reset to MBR...
> XXX attempting pmap_kenter()...
> XXX copying bootstrap code...
> panic @ time 1285760103.939, thread 0xffffff000775d960: Fatal trap 12:
> page fault while in kernel mode
>
> cpuid = 0
> Panic occurred in module kernel loaded at 0xffffffff80100000:
>
> Stack: --------------------------------------------------
> kernel:trap_fatal+0xac
> kernel:trap_pfault+0x24c
> kernel:trap+0x42e
> kernel:bcopy+0x16
> kernel:shutdown_reset+0x48
> kernel:boot+0x317
> kernel:reboot+0x60
> kernel:ia32_syscall+0x1cd
> --------------------------------------------------
> cpuid = 0; apic id = 00
> fault virtual address = 0x7000
> fault code = supervisor write data, page not present
> stack pointer = 0x10:0xffffff8059e07670
> frame pointer = 0x10:0xffffff8059e07780
>
> Here's what I think is the relevant snippets of code. Note that I
> reserved the vm_page_t for physical page 7 as mbr_page early in boot,
> so I know the memory is free.
>
> void
> pmap_kenter_VR(vm_paddr_t pa)
> {
> pmap_t pmap = kernel_pmap;
> vm_page_t mpte;
> pd_entry_t *pde;
> pt_entry_t *pte;
>
> vm_page_lock_queues();
> PMAP_LOCK(pmap);
> mpte = pmap_allocpte(pmap, pa, M_WAITOK);
>
> pde = pmap_pde(pmap, pa);
> if (pde == NULL || (*pde & PG_V) == 0)
> panic("%s: invalid page directory va=%#lx", __func__, pa);
> if ((*pde & PG_PS) != 0)
> panic("%s: attempted pmap_enter on 2MB page", __func__);
> pte = pmap_pde_to_pte(pde, pa);
> if (pte == NULL)
> panic("%s: no pte va=%#lx", __func__, pa);
>
> if (*pte != 0) {
> /* Remove extra pte reference. */
> mpte->wire_count--;
> }
> pte_store(pte, pa | PG_RW | PG_V | PG_G | pg_nx);
>
> vm_page_unlock_queues();
> PMAP_UNLOCK(pmap);
> }
>
> Then in cpu_reset():
>
> /*
> * Establish a V=R mapping for the MBR page, and copy a
> * reasonable guess at the size of the bootstrap code into the
> * beginning of the page.
> */
> printf("XXX attempting pmap_kenter()...\n");
> pmap_kenter_VR(trunc_page(mbaddr));
> printf("XXX copying bootstrap code...\n");
> to_copy = (uintptr_t)xxx_reset_end - (uintptr_t)xxx_reset_real;
> if (to_copy > mbaddr - trunc_page(mbaddr))
> to_copy = mbaddr - trunc_page(mbaddr);
> bcopy(xxx_reset_real, (void *)trunc_page(mbaddr), to_copy); /* die here */
> printf("XXX attempting to turn off xlation and re-run MBR...\n");
> xxx_reset_real(mbaddr);
>
>
> My first attempt was a call to
> pmap_kenter(trunc_page(0x7c00), trunc_page(0x7c00));
> which failed trying to dereference the non-existent PDE.
>
> My second attempt called
> pmap_enter(kernel_pmap, trunc_page(0x7c00), VM_PROT_WRITE, mbr_page,
> VM_PROT_ALL, 0);
> That failed with the same crash as the attempt using pmap_kenter_VR().
>
> So... any thoughts as to why, after an apparently successful
> installation of an xlation, I still get a panic as though there were
> no xlation?
Weird formatting of backtrace. Is this some proprietary code ?
Why do you try to create 1-1 mapping at all ? The MBR code should be
executing in real mode anyway, and the mapping address at the moment of
bcopy does not matter at all. I think that the use of PHYS_TO_DMAP()
should give you direct mapping.
About the #pf that you see. I think that this is due to the fact that
you are modifying kernel pmap, while the active one is the pmap of
the user process which context issued reboot().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20100929/ad12c901/attachment.pgp
More information about the freebsd-hackers
mailing list