Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/xen Rework the physical<->machine memory mapping: ...
details: https://anonhg.NetBSD.org/src/rev/66108462e759
branches: trunk
changeset: 566062:66108462e759
user: cl <cl%NetBSD.org@localhost>
date: Mon Apr 26 22:05:04 2004 +0000
description:
Rework the physical<->machine memory mapping: offset physical addresses
by 0x100000 (above the I/O Memory "hole") leaving all physical addresses
below unused, don't perform phys<->mach mapping for addresses below 0x100000
or beyond the real hardware's physical memory.
-> /dev/mem works now as expected and X works in domain0.
diffstat:
sys/arch/xen/i386/locore.S | 4 +-
sys/arch/xen/i386/machdep.c | 22 ++-
sys/arch/xen/i386/pmap.c | 186 +++++++++++++++++++++++++++++++++----
sys/arch/xen/i386/xen_machdep.c | 65 +++++++++++--
sys/arch/xen/include/cpu.h | 6 +-
sys/arch/xen/include/hypervisor.h | 13 ++-
sys/arch/xen/include/xenpmap.h | 32 +++++-
sys/arch/xen/x86/bus_space.c | 6 +-
sys/arch/xen/xen/if_xennet.c | 6 +-
sys/arch/xen/xen/xbd.c | 7 +-
10 files changed, 283 insertions(+), 64 deletions(-)
diffs (truncated from 792 to 300 lines):
diff -r 45210ec34aa0 -r 66108462e759 sys/arch/xen/i386/locore.S
--- a/sys/arch/xen/i386/locore.S Mon Apr 26 21:06:55 2004 +0000
+++ b/sys/arch/xen/i386/locore.S Mon Apr 26 22:05:04 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.4 2004/04/25 19:01:27 cl Exp $ */
+/* $NetBSD: locore.S,v 1.5 2004/04/26 22:05:04 cl Exp $ */
/* NetBSD: locore.S,v 1.26 2004/04/12 13:17:46 yamt Exp */
/*-
@@ -449,7 +449,7 @@
leal (PROC0STACK)(%esi),%eax
movl %eax,_C_LABEL(proc0paddr)
leal (USPACE-FRAMESIZE)(%eax),%esp
- subl $KERNTEXTOFF,%esi
+ subl $KERNBASE_LOCORE,%esi
movl %esi,PCB_CR3(%eax) # pcb->pcb_cr3
xorl %ebp,%ebp # mark end of frames
diff -r 45210ec34aa0 -r 66108462e759 sys/arch/xen/i386/machdep.c
--- a/sys/arch/xen/i386/machdep.c Mon Apr 26 21:06:55 2004 +0000
+++ b/sys/arch/xen/i386/machdep.c Mon Apr 26 22:05:04 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.6 2004/04/25 23:46:07 cl Exp $ */
+/* $NetBSD: machdep.c,v 1.7 2004/04/26 22:05:04 cl Exp $ */
/* NetBSD: machdep.c,v 1.552 2004/03/24 15:34:49 atatat Exp */
/*-
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.6 2004/04/25 23:46:07 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.7 2004/04/26 22:05:04 cl Exp $");
#include "opt_beep.h"
#include "opt_compat_ibcs2.h"
@@ -280,6 +280,7 @@
struct vm_map *phys_map = NULL;
extern paddr_t avail_start, avail_end;
+extern paddr_t pmap_pa_start, pmap_pa_end;
#ifdef ISA_CLOCK
void (*delay_func)(int) = i8254_delay;
@@ -1413,9 +1414,9 @@
setregion(®ion, gdt, NGDT * sizeof(gdt[0]) - 1);
lgdt(®ion);
#else
- frames[0] = xpmap_ptom((uint32_t)gdt - KERNTEXTOFF) >> PAGE_SHIFT;
+ frames[0] = xpmap_ptom((uint32_t)gdt - KERNBASE) >> PAGE_SHIFT;
/* pmap_kremove((vaddr_t)gdt, PAGE_SIZE); */
- pmap_kenter_pa((vaddr_t)gdt, (uint32_t)gdt - KERNTEXTOFF,
+ pmap_kenter_pa((vaddr_t)gdt, (uint32_t)gdt - KERNBASE,
VM_PROT_READ);
XENPRINTK(("loading gdt %lx, %d entries\n", frames[0] << PAGE_SHIFT,
LAST_RESERVED_GDT_ENTRY + 1));
@@ -1506,8 +1507,11 @@
#else
/* Make sure the end of the space used by the kernel is rounded. */
first_avail = round_page(first_avail);
- avail_start = first_avail - KERNTEXTOFF;
- avail_end = ptoa(xen_start_info.nr_pages);
+ avail_start = first_avail - KERNBASE;
+ avail_end = ptoa(xen_start_info.nr_pages) +
+ (KERNTEXTOFF - KERNBASE_LOCORE);
+ pmap_pa_start = (KERNTEXTOFF - KERNBASE_LOCORE);
+ pmap_pa_end = avail_end;
mem_clusters[0].start = avail_start;
mem_clusters[0].size = avail_end - avail_start;
mem_cluster_cnt++;
@@ -1696,9 +1700,9 @@
XENPRINTK(("load the memory cluster %p(%d) - %p(%ld)\n",
(void *)avail_start, (int)atop(avail_start),
- (void *)ptoa(xen_start_info.nr_pages), xen_start_info.nr_pages));
- uvm_page_physload(atop(avail_start), xen_start_info.nr_pages,
- atop(avail_start), xen_start_info.nr_pages,
+ (void *)avail_end, (int)atop(avail_end)));
+ uvm_page_physload(atop(avail_start), atop(avail_end),
+ atop(avail_start), atop(avail_end),
VM_FREELIST_DEFAULT);
#if !defined(XEN)
diff -r 45210ec34aa0 -r 66108462e759 sys/arch/xen/i386/pmap.c
--- a/sys/arch/xen/i386/pmap.c Mon Apr 26 21:06:55 2004 +0000
+++ b/sys/arch/xen/i386/pmap.c Mon Apr 26 22:05:04 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.4 2004/04/24 19:18:01 cl Exp $ */
+/* $NetBSD: pmap.c,v 1.5 2004/04/26 22:05:04 cl Exp $ */
/* NetBSD: pmap.c,v 1.172 2004/04/12 13:17:46 yamt Exp */
/*
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.4 2004/04/24 19:18:01 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.5 2004/04/26 22:05:04 cl Exp $");
#include "opt_cputype.h"
#include "opt_user_ldt.h"
@@ -376,6 +376,12 @@
paddr_t avail_start; /* PA of first available physical page */
paddr_t avail_end; /* PA of last available physical page */
+paddr_t pmap_pa_start; /* PA of first physical page for this domain */
+paddr_t pmap_pa_end; /* PA of last physical page for this domain */
+
+ /* MA of last physical page of the machine */
+paddr_t pmap_mem_end = HYPERVISOR_VIRT_START; /* updated for domain-0 */
+
/*
* other data structures
*/
@@ -805,6 +811,79 @@
}
}
+__inline static pt_entry_t
+pte_mtop(pt_entry_t pte)
+{
+ pt_entry_t ppte;
+
+ KDASSERT(pmap_valid_entry(pte));
+ ppte = xpmap_mtop(pte);
+ if ((ppte & PG_FRAME) == (KERNTEXTOFF - KERNBASE_LOCORE)) {
+ XENPRINTF(("pte_mtop: null page %08x -> %08x\n",
+ ppte, pte));
+ ppte = pte;
+ }
+
+ return ppte;
+}
+
+__inline static pt_entry_t
+pte_get_ma(pt_entry_t *pte)
+{
+
+ return *pte;
+}
+
+__inline static pt_entry_t
+pte_get(pt_entry_t *pte)
+{
+
+ if (pmap_valid_entry(*pte))
+ return pte_mtop(*pte);
+ return *pte;
+}
+
+__inline static pt_entry_t
+pte_atomic_update_ma(pt_entry_t *pte, pt_entry_t npte)
+{
+ pt_entry_t opte;
+
+ opte = PTE_GET_MA(pte);
+ if (opte > pmap_mem_end) {
+ /* must remove opte unchecked */
+ if (npte > pmap_mem_end)
+ /* must set npte unchecked */
+ xpq_queue_unchecked_pte_update(pte, npte);
+ else {
+ /* must set npte checked */
+ xpq_queue_unchecked_pte_update(pte, 0);
+ xpq_queue_pte_update(pte, npte);
+ }
+ } else {
+ /* must remove opte checked */
+ if (npte > pmap_mem_end) {
+ /* must set npte unchecked */
+ xpq_queue_pte_update(pte, 0);
+ xpq_queue_unchecked_pte_update(pte, npte);
+ } else
+ /* must set npte checked */
+ xpq_queue_pte_update(pte, npte);
+ }
+ xpq_flush_queue();
+
+ return opte;
+}
+
+__inline static pt_entry_t
+pte_atomic_update(pt_entry_t *pte, pt_entry_t npte)
+{
+ pt_entry_t opte;
+
+ opte = pte_atomic_update_ma(pte, npte);
+
+ return pte_mtop(opte);
+}
+
/*
* Fixup the code segment to cover all potential executable mappings.
* returns 0 if no changes to the code segment were made.
@@ -870,10 +949,18 @@
else
pte = kvtopte(va);
- npte = pa | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) |
+ npte = ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) |
PG_V | pmap_pg_g;
- PTE_ATOMIC_SET(pte, npte, opte); /* zap! */
+ if (pa >= pmap_pa_start && pa < pmap_pa_end) {
+ npte |= xpmap_ptom(pa);
+ } else {
+ XENPRINTF(("pmap_kenter: va %08lx outside pa range %08lx\n",
+ va, pa));
+ npte |= pa;
+ }
+
+ opte = pte_atomic_update_ma(pte, npte); /* zap! */
XENPRINTK(("pmap_kenter_pa(%p,%p) %p, was %08x\n", (void *)va,
(void *)pa, pte, opte));
#ifdef LARGEPAGES
@@ -917,7 +1004,7 @@
npte = ma | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) |
PG_V | pmap_pg_g;
- PTE_ATOMIC_SET_MA(pte, npte, opte); /* zap! */
+ opte = pte_atomic_update_ma(pte, npte); /* zap! */
XENPRINTK(("pmap_kenter_ma(%p,%p) %p, was %08x\n", (void *)va,
(void *)ma, pte, opte));
#ifdef LARGEPAGES
@@ -964,7 +1051,7 @@
pte = vtopte(va);
else
pte = kvtopte(va);
- PTE_ATOMIC_CLEAR(pte, opte); /* zap! */
+ opte = pte_atomic_update_ma(pte, 0); /* zap! */
XENPRINTK(("pmap_kremove pte %p, was %08x\n", pte, opte));
#ifdef LARGEPAGES
/* XXX For now... */
@@ -1018,6 +1105,13 @@
virtual_end = VM_MAX_KERNEL_ADDRESS; /* last KVA */
/*
+ * find out where physical memory ends on the real hardware.
+ */
+
+ if (xen_start_info.flags & SIF_PRIVILEGED)
+ pmap_mem_end = find_pmap_mem_end(kva_start);
+
+ /*
* set up protection_codes: we need to be able to convert from
* a MI protection code (some combo of VM_PROT...) to something
* we can jam into a i386 PTE.
@@ -1050,7 +1144,7 @@
kpm->pm_obj.uo_npages = 0;
kpm->pm_obj.uo_refs = 1;
memset(&kpm->pm_list, 0, sizeof(kpm->pm_list)); /* pm_list not used */
- kpm->pm_pdir = (pd_entry_t *)(lwp0.l_addr->u_pcb.pcb_cr3 + KERNTEXTOFF);
+ kpm->pm_pdir = (pd_entry_t *)(lwp0.l_addr->u_pcb.pcb_cr3 + KERNBASE);
XENPRINTF(("pm_pdirpa %p PTDpaddr %p\n",
(void *)lwp0.l_addr->u_pcb.pcb_cr3, (void *)PTDpaddr));
kpm->pm_pdirpa = (u_int32_t) lwp0.l_addr->u_pcb.pcb_cr3;
@@ -2534,7 +2628,7 @@
}
/* atomically save the old PTE and zap! it */
- PTE_ATOMIC_CLEAR(pte, opte);
+ opte = pte_atomic_update(pte, 0);
pmap_exec_account(pmap, startva, opte, 0);
if (opte & PG_W)
@@ -2623,7 +2717,8 @@
}
/* atomically save the old PTE and zap! it */
- PTE_ATOMIC_CLEAR(pte, opte);
+ opte = pte_atomic_update(pte, 0);
+
XENPRINTK(("pmap_remove_pte %p, was %08x\n", pte, opte));
pmap_exec_account(pmap, va, opte, 0);
@@ -2963,7 +3058,7 @@
#endif
/* atomically save the old PTE and zap! it */
- PTE_ATOMIC_CLEAR(&ptes[x86_btop(pve->pv_va)], opte);
+ opte = pte_atomic_update(&ptes[x86_btop(pve->pv_va)], 0);
if (opte & PG_W)
pve->pv_pmap->pm_stats.wired_count--;
@@ -3411,7 +3506,16 @@
panic("pmap_enter: missing kernel PTP!");
#endif
- npte = pa | protection_codes[prot] | PG_V;
+ npte = protection_codes[prot] | PG_V;
+
+ if (pa >= pmap_pa_start && pa < pmap_pa_end)
+ npte |= xpmap_ptom(pa);
+ else {
+ XENPRINTF(("pmap_enter: va %08lx outside pa range %08lx\n",
+ va, pa));
+ npte |= pa;
+ }
+
/* XENPRINTK(("npte %p\n", npte)); */
Home |
Main Index |
Thread Index |
Old Index