Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/xen Add a vm_prot_t parameter to pmap_remap_pages()...



details:   https://anonhg.NetBSD.org/src/rev/b2704a3ed724
branches:  trunk
changeset: 584168:b2704a3ed724
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Sep 10 18:00:49 2005 +0000

description:
Add a vm_prot_t parameter to pmap_remap_pages(), and use it for the new PTE
instead to always trying PG_RW and falling back to PG_RO if this fails.
Use uvm_map_checkprot() in IOCTL_PRIVCMD_MMAP and IOCTL_PRIVCMD_MMAP_BATCH
to compute the appropriate vm_prot_t for pmap_remap_pages().
Thanks to Jed Davis for pointing out uvm_map_checkprot().

diffstat:

 sys/arch/xen/i386/pmap.c      |  30 +++++++-----------------
 sys/arch/xen/include/pmap.h   |   4 +-
 sys/arch/xen/xen/privcmd.c    |  51 ++++++++++++++++++++++++++++++++++++------
 sys/arch/xen/xen/xbdback.c    |   5 ++-
 sys/arch/xen/xen/xennetback.c |  10 ++++----
 5 files changed, 62 insertions(+), 38 deletions(-)

diffs (239 lines):

diff -r 92e725fa5fca -r b2704a3ed724 sys/arch/xen/i386/pmap.c
--- a/sys/arch/xen/i386/pmap.c  Sat Sep 10 17:33:45 2005 +0000
+++ b/sys/arch/xen/i386/pmap.c  Sat Sep 10 18:00:49 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.13 2005/09/10 15:46:04 bouyer Exp $ */
+/*     $NetBSD: pmap.c,v 1.14 2005/09/10 18:00:49 bouyer Exp $ */
 /*     NetBSD: pmap.c,v 1.179 2004/10/10 09:55:24 yamt Exp             */
 
 /*
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.13 2005/09/10 15:46:04 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.14 2005/09/10 18:00:49 bouyer Exp $");
 
 #include "opt_cputype.h"
 #include "opt_user_ldt.h"
@@ -4050,11 +4050,12 @@
  */
 
 int
-pmap_remap_pages(pmap, va, pa, npages, flags, dom)
+pmap_remap_pages(pmap, va, pa, npages, prot, flags, dom)
        struct pmap *pmap;
        vaddr_t va;
        paddr_t pa;
        int npages;
+       vm_prot_t prot;
        int flags;
        int dom;
 {
@@ -4138,11 +4139,11 @@
            pmap->pm_stats.wired_count));
        //printf("npte %p opte %p ptes %p idx %03x\n", (void *)npte, (void *)opte, ptes, x86_btop(va));
        //printf("pmap_remap_pages pa %08lx va %08lx opte %08x npte %08x count %ld\n", pa, va, opte, npte, pmap->pm_stats.wired_count);
-#if 0
-       npte |= (opte & (PG_M | PG_RW));
-#else
-       npte |= (PG_M | PG_RW);
-#endif
+
+       if (prot & VM_PROT_WRITE)
+               npte |= (PG_M | PG_RW);
+       else 
+               npte |= PG_RO;
 
        /*
         * is there currently a valid mapping at our VA and does it
@@ -4240,21 +4241,8 @@
 
        //printf("pmap initial setup");
        maptp = (pt_entry_t *)vtomach((vaddr_t)&ptes[x86_btop(va)]);
- change_pte:
        error = xpq_update_foreign(maptp, npte, dom);
        if (error) {
-               if (npte & PG_RW) {
-                       /* 
-                        * XXXjld%panix.com@localhost: Some things cannot be
-                        * mapped read/write, even by a privileged
-                        * domain.  This wouldn't be necessary if
-                        * pmap_remap_pages had a "prot" parameter
-                        * like pmap_enter does.
-                        */
-                       npte &= ~(PG_RW | PG_M);
-                       //printf("pmap_remap_pages: losing write bit npte=%lx\n", (unsigned long)npte);
-                       goto change_pte;
-               }
                printf("pmap_remap_pages: xpq_update_foreign failed va=%lx"
                    " npte=%lx error=%d dptpwire=%d\n",
                    va, (unsigned long)npte, error, dptpwire);
diff -r 92e725fa5fca -r b2704a3ed724 sys/arch/xen/include/pmap.h
--- a/sys/arch/xen/include/pmap.h       Sat Sep 10 17:33:45 2005 +0000
+++ b/sys/arch/xen/include/pmap.h       Sat Sep 10 18:00:49 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.4 2005/03/09 22:39:20 bouyer Exp $  */
+/*     $NetBSD: pmap.h,v 1.5 2005/09/10 18:00:49 bouyer Exp $  */
 /*     NetBSD: pmap.h,v 1.82 2004/02/20 17:35:01 yamt Exp      */
 
 /*
@@ -359,7 +359,7 @@
                    int);
 boolean_t      pmap_extract_ma(pmap_t, vaddr_t, paddr_t *);
 int            pmap_remap_pages(struct pmap *, vaddr_t, paddr_t, int,
-                   int, int);
+                   vm_prot_t, int, int);
 
 vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
 
diff -r 92e725fa5fca -r b2704a3ed724 sys/arch/xen/xen/privcmd.c
--- a/sys/arch/xen/xen/privcmd.c        Sat Sep 10 17:33:45 2005 +0000
+++ b/sys/arch/xen/xen/privcmd.c        Sat Sep 10 18:00:49 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: privcmd.c,v 1.5 2005/09/10 15:48:10 bouyer Exp $ */
+/* $NetBSD: privcmd.c,v 1.6 2005/09/10 18:00:49 bouyer Exp $ */
 
 /*
  *
@@ -33,7 +33,7 @@
 
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: privcmd.c,v 1.5 2005/09/10 15:48:10 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: privcmd.c,v 1.6 2005/09/10 18:00:49 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -104,6 +104,7 @@
                privcmd_mmap_entry_t mentry;
                vaddr_t va;
                u_long ma;
+               vm_prot_t prot;
                //printf("IOCTL_PRIVCMD_MMAP: %d entries\n", mcmd->num);
 
                pmap_t pmap = vm_map_pmap(&ap->a_p->p_vmspace->vm_map);
@@ -121,14 +122,29 @@
 #endif
                        va = mentry.va & ~PAGE_MASK;
                        ma = mentry.mfn <<  PGSHIFT; /* XXX ??? */
+                       vm_map_lock_read(&ap->a_p->p_vmspace->vm_map);
+                       if (uvm_map_checkprot(&ap->a_p->p_vmspace->vm_map,
+                           va, va + (mentry.npages << PGSHIFT) - 1,
+                           VM_PROT_WRITE))
+                               prot = VM_PROT_READ | VM_PROT_WRITE;
+                       else if (uvm_map_checkprot(&ap->a_p->p_vmspace->vm_map,
+                           va, va + (mentry.npages << PGSHIFT) - 1,
+                           VM_PROT_READ))
+                               prot = VM_PROT_READ;
+                       else {
+                               printf("uvm_map_checkprot 0x%lx -> 0x%lx "
+                                   "failed\n",
+                                   va, va + (mentry.npages << PGSHIFT) - 1);
+                               vm_map_unlock_read(&ap->a_p->p_vmspace->vm_map);
+                               return EINVAL;
+                       }
+                       vm_map_unlock_read(&ap->a_p->p_vmspace->vm_map);
+
                        for (j = 0; j < mentry.npages; j++) {
                                //printf("remap va 0x%lx to 0x%lx\n", va, ma);
-#if 0
-                               if (!pmap_extract(pmap, va, NULL))
-                                       return EINVAL; /* XXX */
-#endif
                                if ((error = pmap_remap_pages(pmap, va, ma, 1,
-                                   PMAP_WIRED | PMAP_CANFAIL, mcmd->dom)))
+                                   prot, PMAP_WIRED | PMAP_CANFAIL,
+                                   mcmd->dom)))
                                        return error;
                                va += PAGE_SIZE;
                                ma += PAGE_SIZE;
@@ -143,6 +159,7 @@
                vaddr_t va0, va;
                u_long mfn, ma;
                struct vm_map *vmm;
+               vm_prot_t prot;
                pmap_t pmap;
 
                vmm = &ap->a_p->p_vmspace->vm_map;
@@ -155,6 +172,24 @@
                        return EINVAL;
                
                //printf("mmapbatch: va0=%lx num=%d dom=%d\n", va0, pmb->num, pmb->dom);
+               vm_map_lock_read(vmm);
+               if (uvm_map_checkprot(vmm,
+                   va0, va0 + (pmb->num << PGSHIFT) - 1,
+                   VM_PROT_WRITE))
+                       prot = VM_PROT_READ | VM_PROT_WRITE;
+               else if (uvm_map_checkprot(vmm,
+                   va0, va0 + (pmb->num << PGSHIFT) - 1,
+                   VM_PROT_READ))
+                       prot = VM_PROT_READ;
+               else {
+                       printf("uvm_map_checkprot2 0x%lx -> 0x%lx "
+                           "failed\n",
+                           va0, va0 + (pmb->num << PGSHIFT) - 1);
+                       vm_map_unlock_read(vmm);
+                       return EINVAL;
+               }
+               vm_map_unlock_read(vmm);
+
                for(i = 0; i < pmb->num; ++i) {
                        va = va0 + (i * PAGE_SIZE);
                        error = copyin(&pmb->arr[i], &mfn, sizeof(mfn));
@@ -167,7 +202,7 @@
                         * these into fewer hypercalls.
                         */
                        //printf("mmapbatch: va=%lx ma=%lx dom=%d\n", va, ma, pmb->dom);
-                       error = pmap_remap_pages(pmap, va, ma, 1,
+                       error = pmap_remap_pages(pmap, va, ma, 1, prot,
                            PMAP_WIRED | PMAP_CANFAIL, pmb->dom);
                        if (error != 0) {
                                printf("mmapbatch: remap error %d!\n", error);
diff -r 92e725fa5fca -r b2704a3ed724 sys/arch/xen/xen/xbdback.c
--- a/sys/arch/xen/xen/xbdback.c        Sat Sep 10 17:33:45 2005 +0000
+++ b/sys/arch/xen/xen/xbdback.c        Sat Sep 10 18:00:49 2005 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xbdback.c,v 1.14 2005/07/19 12:20:29 yamt Exp $      */
+/*      $NetBSD: xbdback.c,v 1.15 2005/09/10 18:00:49 bouyer Exp $      */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -368,7 +368,8 @@
 
                xbdi->ma_ring = req->shmem_frame << PAGE_SHIFT;
                error = pmap_remap_pages(pmap_kernel(), ring_addr,
-                   xbdi->ma_ring, 1, PMAP_WIRED | PMAP_CANFAIL, req->domid);
+                   xbdi->ma_ring, 1, VM_PROT_READ | VM_PROT_WRITE,
+                   PMAP_WIRED | PMAP_CANFAIL, req->domid);
                if (error) {
                        uvm_km_free(kernel_map, ring_addr, PAGE_SIZE,
                            UVM_KMF_VAONLY);
diff -r 92e725fa5fca -r b2704a3ed724 sys/arch/xen/xen/xennetback.c
--- a/sys/arch/xen/xen/xennetback.c     Sat Sep 10 17:33:45 2005 +0000
+++ b/sys/arch/xen/xen/xennetback.c     Sat Sep 10 18:00:49 2005 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xennetback.c,v 1.11 2005/05/18 16:19:23 bouyer Exp $      */
+/*      $NetBSD: xennetback.c,v 1.12 2005/09/10 18:00:49 bouyer Exp $      */
 
 /*
  * Copyright (c) 2005 Manuel Bouyer.
@@ -318,14 +318,14 @@
                xneti->xni_ma_rxring = req->rx_shmem_frame << PAGE_SHIFT;
                xneti->xni_ma_txring = req->tx_shmem_frame << PAGE_SHIFT;
                error = pmap_remap_pages(pmap_kernel(), ring_rxaddr,
-                  xneti->xni_ma_rxring, 1, PMAP_WIRED | PMAP_CANFAIL,
-                  req->domid);
+                  xneti->xni_ma_rxring, 1, VM_PROT_READ | VM_PROT_WRITE,
+                  PMAP_WIRED | PMAP_CANFAIL, req->domid);
                if (error) {
                        goto fail_1;
                }
                error = pmap_remap_pages(pmap_kernel(), ring_txaddr,
-                  xneti->xni_ma_txring, 1, PMAP_WIRED | PMAP_CANFAIL,
-                  req->domid);
+                  xneti->xni_ma_txring, 1, VM_PROT_READ | VM_PROT_WRITE,
+                  PMAP_WIRED | PMAP_CANFAIL, req->domid);
                if (error) {
                        pmap_remove(pmap_kernel(), ring_rxaddr,
                            ring_rxaddr + PAGE_SIZE);



Home | Main Index | Thread Index | Old Index