From owner-freebsd-hackers@FreeBSD.ORG Wed Sep 29 19:40:59 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3248D106566C for ; Wed, 29 Sep 2010 19:40:59 +0000 (UTC) (envelope-from mdf356@gmail.com) Received: from mail-iw0-f182.google.com (mail-iw0-f182.google.com [209.85.214.182]) by mx1.freebsd.org (Postfix) with ESMTP id F1AD08FC16 for ; Wed, 29 Sep 2010 19:40:58 +0000 (UTC) Received: by iwn34 with SMTP id 34so1751724iwn.13 for ; Wed, 29 Sep 2010 12:40:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type; bh=UDaFUmNsTFMGJzc5Ssz39fuXHT5g3w9QwHN9ulTruy0=; b=A3Rf8pLpJHvBlcRWMRs3XI9iU7Q5cUOYGGKpQlfENqH8+XApcMogr6WZBxGulfuJVO wu0FASSWFwhMZMhTVDC6KL8NRpJbyWzFvQKqQMSvBF0p9SzVFipspik6Xog73BuyGo7h 856JFJArqSKpWw+lRJO8V2f5Z2lCVUJ5hWwqU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=VN+lAWgPDy0MLXHhFePN8j02BqUnp6XjILxMUCM58sAyKqNkgGEBxvje1LGUbuLnXb wcX9/MEzMYrJVuLe39wG6iaeRGfXIfxwLa2Fgsm/nTo97JveDGcSQSTxOoOBYAeXKEV8 d/PZA1TN8Cs3pzNh+6m6bYHhMyjV1wqxdNxmk= MIME-Version: 1.0 Received: by 10.231.34.139 with SMTP id l11mr2265643ibd.141.1285789257249; Wed, 29 Sep 2010 12:40:57 -0700 (PDT) Received: by 10.231.167.140 with HTTP; Wed, 29 Sep 2010 12:40:57 -0700 (PDT) Date: Wed, 29 Sep 2010 12:40:57 -0700 Message-ID: From: Matthew Fleming To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Subject: Adding a V=R mapping for amd64? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Sep 2010 19:40:59 -0000 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? Thanks, matthew