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(&region, gdt, NGDT * sizeof(gdt[0]) - 1);
        lgdt(&region);
 #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