Date: Wed, 29 Sep 2010 23:12:21 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: Matthew Fleming <mdf356@gmail.com> Cc: freebsd-hackers@freebsd.org Subject: Re: Adding a V=R mapping for amd64? Message-ID: <20100929201221.GG43070@deviant.kiev.zoral.com.ua> In-Reply-To: <AANLkTinUCXES2UhLHPQD7YCjt5Sx4X5%2BgERJZNjsR-ho@mail.gmail.com> References: <AANLkTinUCXES2UhLHPQD7YCjt5Sx4X5%2BgERJZNjsR-ho@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--rPFbv4B2w2tcwGo5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
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.
>=20
> 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.
>=20
> 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
>=20
> cpuid =3D 0
> Panic occurred in module kernel loaded at 0xffffffff80100000:
>=20
> 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 =3D 0; apic id =3D 00
> fault virtual address =3D 0x7000
> fault code =3D supervisor write data, page not present
> stack pointer =3D 0x10:0xffffff8059e07670
> frame pointer =3D 0x10:0xffffff8059e07780
>=20
> 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.
>=20
> void
> pmap_kenter_VR(vm_paddr_t pa)
> {
> pmap_t pmap =3D kernel_pmap;
> vm_page_t mpte;
> pd_entry_t *pde;
> pt_entry_t *pte;
>=20
> vm_page_lock_queues();
> PMAP_LOCK(pmap);
> mpte =3D pmap_allocpte(pmap, pa, M_WAITOK);
>=20
> pde =3D pmap_pde(pmap, pa);
> if (pde =3D=3D NULL || (*pde & PG_V) =3D=3D 0)
> panic("%s: invalid page directory va=3D%#lx", __func__, pa);
> if ((*pde & PG_PS) !=3D 0)
> panic("%s: attempted pmap_enter on 2MB page", __func__);
> pte =3D pmap_pde_to_pte(pde, pa);
> if (pte =3D=3D NULL)
> panic("%s: no pte va=3D%#lx", __func__, pa);
>=20
> if (*pte !=3D 0) {
> /* Remove extra pte reference. */
> mpte->wire_count--;
> }
> pte_store(pte, pa | PG_RW | PG_V | PG_G | pg_nx);
> =09
> vm_page_unlock_queues();
> PMAP_UNLOCK(pmap);
> }
>=20
> Then in cpu_reset():
>=20
> /*
> * Establish a V=3DR 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 =3D (uintptr_t)xxx_reset_end - (uintptr_t)xxx_reset_real;
> if (to_copy > mbaddr - trunc_page(mbaddr))
> to_copy =3D 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);
>=20
>=20
> My first attempt was a call to
> pmap_kenter(trunc_page(0x7c00), trunc_page(0x7c00));
> which failed trying to dereference the non-existent PDE.
>=20
> 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().
>=20
> 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().
--rPFbv4B2w2tcwGo5
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (FreeBSD)
iEYEARECAAYFAkyjnaUACgkQC3+MBN1Mb4gTmQCcCEQFXgRtClu9NDwO6wA8KpoV
37sAoN5LaB1RquPFkER/F4KGmIza+GfE
=YNMd
-----END PGP SIGNATURE-----
--rPFbv4B2w2tcwGo5--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100929201221.GG43070>
