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

[Xen-changelog] A more comprehensive fix for mapping shared-ring grant



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 8dbcf407a680f80e60ceabe0383297821a39e7cd
# Parent  52eb8504be717c1ee7371234696bf8fa45b2aea6
A more comprehensive fix for mapping shared-ring grant
references in back-end drivers.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Thu Sep 22 11:46:17 2005
@@ -17,6 +17,7 @@
 #include <asm-xen/xen-public/io/blkif.h>
 #include <asm-xen/xen-public/io/ring.h>
 #include <asm-xen/gnttab.h>
+#include <asm-xen/driver_util.h>
 
 #if 0
 #define ASSERT(_p) \
@@ -42,11 +43,11 @@
     domid_t           domid;
     unsigned int      handle;
     /* Physical parameters of the comms window. */
-    unsigned long     shmem_frame;
     unsigned int      evtchn;
     unsigned int      remote_evtchn;
     /* Comms information. */
     blkif_back_ring_t blk_ring;
+    struct vm_struct *blk_ring_area;
     /* VBDs attached to this interface. */
     struct vbd        vbd;
     /* Private fields. */
@@ -60,8 +61,8 @@
     atomic_t         refcnt;
 
     struct work_struct free_work;
-    u16 shmem_handle;
-    unsigned long shmem_vaddr;
+
+    u16         shmem_handle;
     grant_ref_t shmem_ref;
 } blkif_t;
 
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Thu Sep 22 
11:46:17 2005
@@ -8,7 +8,6 @@
 
 #include "common.h"
 #include <asm-xen/evtchn.h>
-#include <asm-xen/driver_util.h>
 
 static kmem_cache_t *blkif_cachep;
 
@@ -29,16 +28,18 @@
     return blkif;
 }
 
-static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
-                            unsigned long shared_page)
+static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
     struct gnttab_map_grant_ref op;
-    op.host_addr = localaddr;
-    op.flags = GNTMAP_host_map;
-    op.ref = shared_page;
-    op.dom = blkif->domid;
 
-    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+    op.host_addr = (unsigned long)blkif->blk_ring_area->addr;
+    op.flags     = GNTMAP_host_map;
+    op.ref       = shared_page;
+    op.dom       = blkif->domid;
+
+    lock_vm_area(blkif->blk_ring_area);
+    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+    unlock_vm_area(blkif->blk_ring_area);
 
     if (op.handle < 0) {
        DPRINTK(" Grant table operation failure !\n");
@@ -47,7 +48,7 @@
 
     blkif->shmem_ref = shared_page;
     blkif->shmem_handle = op.handle;
-    blkif->shmem_vaddr = localaddr;
+
     return 0;
 }
 
@@ -55,27 +56,29 @@
 {
     struct gnttab_unmap_grant_ref op;
 
-    op.host_addr = blkif->shmem_vaddr;
-    op.handle = blkif->shmem_handle;
+    op.host_addr    = (unsigned long)blkif->blk_ring_area->addr;
+    op.handle       = blkif->shmem_handle;
     op.dev_bus_addr = 0;
+
+    lock_vm_area(blkif->blk_ring_area);
     BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+    unlock_vm_area(blkif->blk_ring_area);
 }
 
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
-    struct vm_struct *vma;
     blkif_sring_t *sring;
     evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
     int err;
 
     BUG_ON(blkif->remote_evtchn);
 
-    if ( (vma = prepare_vm_area(PAGE_SIZE)) == NULL )
+    if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
        return -ENOMEM;
 
-    err = map_frontend_page(blkif, (unsigned long)vma->addr, shared_page);
+    err = map_frontend_page(blkif, shared_page);
     if (err) {
-        vunmap(vma->addr);
+        free_vm_area(blkif->blk_ring_area);
        return err;
     }
 
@@ -86,21 +89,20 @@
     err = HYPERVISOR_event_channel_op(&op);
     if (err) {
        unmap_frontend_page(blkif);
-       vunmap(vma->addr);
+        free_vm_area(blkif->blk_ring_area);
        return err;
     }
 
     blkif->evtchn = op.u.bind_interdomain.port1;
     blkif->remote_evtchn = evtchn;
 
-    sring = (blkif_sring_t *)vma->addr;
+    sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
     SHARED_RING_INIT(sring);
     BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
     bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
                              blkif);
-    blkif->status        = CONNECTED;
-    blkif->shmem_frame   = shared_page;
+    blkif->status = CONNECTED;
 
     return 0;
 }
@@ -124,7 +126,7 @@
 
     if (blkif->blk_ring.sring) {
        unmap_frontend_page(blkif);
-       vunmap(blkif->blk_ring.sring);
+        free_vm_area(blkif->blk_ring_area);
        blkif->blk_ring.sring = NULL;
     }
 
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/common.h  Thu Sep 22 11:46:17 2005
@@ -17,6 +17,7 @@
 #include <asm-xen/xen-public/io/blkif.h>
 #include <asm-xen/xen-public/io/ring.h>
 #include <asm-xen/gnttab.h>
+#include <asm-xen/driver_util.h>
 
 #if 0
 #define ASSERT(_p) \
@@ -44,11 +45,11 @@
     domid_t           domid;
     unsigned int      handle;
     /* Physical parameters of the comms window. */
-    unsigned long     shmem_frame;
     unsigned int      evtchn;
     unsigned int      remote_evtchn;
     /* Comms information. */
     blkif_back_ring_t blk_ring;
+    struct vm_struct *blk_ring_area;
     /* VBDs attached to this interface. */
     struct vbd        vbd;
     /* Private fields. */
@@ -62,9 +63,9 @@
     atomic_t         refcnt;
 
     struct work_struct free_work;
-    u16 shmem_handle;
-    unsigned long shmem_vaddr;
-    grant_ref_t shmem_ref;
+
+    u16              shmem_handle;
+    grant_ref_t      shmem_ref;
 } blkif_t;
 
 blkif_t *alloc_blkif(domid_t domid);
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Thu Sep 22 
11:46:17 2005
@@ -8,135 +8,148 @@
 
 #include "common.h"
 #include <asm-xen/evtchn.h>
-#include <asm-xen/driver_util.h>
 
 static kmem_cache_t *blkif_cachep;
 
 blkif_t *alloc_blkif(domid_t domid)
 {
-    blkif_t *blkif;
+       blkif_t *blkif;
 
-    blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
-    if (!blkif)
-           return ERR_PTR(-ENOMEM);
+       blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL);
+       if (!blkif)
+               return ERR_PTR(-ENOMEM);
 
-    memset(blkif, 0, sizeof(*blkif));
-    blkif->domid = domid;
-    blkif->status = DISCONNECTED;
-    spin_lock_init(&blkif->blk_ring_lock);
-    atomic_set(&blkif->refcnt, 1);
+       memset(blkif, 0, sizeof(*blkif));
+       blkif->domid = domid;
+       blkif->status = DISCONNECTED;
+       spin_lock_init(&blkif->blk_ring_lock);
+       atomic_set(&blkif->refcnt, 1);
 
-    return blkif;
+       return blkif;
 }
 
-static int map_frontend_page(blkif_t *blkif, unsigned long localaddr,
-                            unsigned long shared_page)
+static int map_frontend_page(blkif_t *blkif, unsigned long shared_page)
 {
-    struct gnttab_map_grant_ref op;
-    op.host_addr = localaddr;
-    op.flags = GNTMAP_host_map;
-    op.ref = shared_page;
-    op.dom = blkif->domid;
+       struct gnttab_map_grant_ref op;
 
-    BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+       op.host_addr = (unsigned long)blkif->blk_ring_area->addr;
+       op.flags     = GNTMAP_host_map;
+       op.ref       = shared_page;
+       op.dom       = blkif->domid;
 
-    if (op.handle < 0) {
-       DPRINTK(" Grant table operation failure !\n");
-       return op.handle;
-    }
+       lock_vm_area(blkif->blk_ring_area);
+       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       unlock_vm_area(blkif->blk_ring_area);
 
-    blkif->shmem_ref = shared_page;
-    blkif->shmem_handle = op.handle;
-    blkif->shmem_vaddr = localaddr;
-    return 0;
+       if (op.handle < 0) {
+               DPRINTK(" Grant table operation failure !\n");
+               return op.handle;
+       }
+
+       blkif->shmem_ref    = shared_page;
+       blkif->shmem_handle = op.handle;
+
+       return 0;
 }
 
 static void unmap_frontend_page(blkif_t *blkif)
 {
-    struct gnttab_unmap_grant_ref op;
+       struct gnttab_unmap_grant_ref op;
 
-    op.host_addr = blkif->shmem_vaddr;
-    op.handle = blkif->shmem_handle;
-    op.dev_bus_addr = 0;
-    BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+       op.host_addr    = (unsigned long)blkif->blk_ring_area->addr;
+       op.handle       = blkif->shmem_handle;
+       op.dev_bus_addr = 0;
+
+       lock_vm_area(blkif->blk_ring_area);
+       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+       unlock_vm_area(blkif->blk_ring_area);
 }
 
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
-    struct vm_struct *vma;
-    blkif_sring_t *sring;
-    evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
-    int err;
+       blkif_sring_t *sring;
+       evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
+       int err;
 
-    BUG_ON(blkif->remote_evtchn);
+       BUG_ON(blkif->remote_evtchn);
 
-    if ( (vma = prepare_vm_area(PAGE_SIZE)) == NULL )
-       return -ENOMEM;
+       if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
+               return -ENOMEM;
 
-    err = map_frontend_page(blkif, (unsigned long)vma->addr, shared_page);
-    if (err) {
-        vunmap(vma->addr);
-       return err;
-    }
+       err = map_frontend_page(blkif, shared_page);
+       if (err) {
+               free_vm_area(blkif->blk_ring_area);
+               return err;
+       }
 
-    op.u.bind_interdomain.dom1 = DOMID_SELF;
-    op.u.bind_interdomain.dom2 = blkif->domid;
-    op.u.bind_interdomain.port1 = 0;
-    op.u.bind_interdomain.port2 = evtchn;
-    err = HYPERVISOR_event_channel_op(&op);
-    if (err) {
-       unmap_frontend_page(blkif);
-       vunmap(vma->addr);
-       return err;
-    }
+       op.u.bind_interdomain.dom1 = DOMID_SELF;
+       op.u.bind_interdomain.dom2 = blkif->domid;
+       op.u.bind_interdomain.port1 = 0;
+       op.u.bind_interdomain.port2 = evtchn;
+       err = HYPERVISOR_event_channel_op(&op);
+       if (err) {
+               unmap_frontend_page(blkif);
+               free_vm_area(blkif->blk_ring_area);
+               return err;
+       }
 
-    blkif->evtchn = op.u.bind_interdomain.port1;
-    blkif->remote_evtchn = evtchn;
 
-    sring = (blkif_sring_t *)vma->addr;
-    SHARED_RING_INIT(sring);
-    BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
+       blkif->evtchn = op.u.bind_interdomain.port1;
+       blkif->remote_evtchn = evtchn;
 
-    bind_evtchn_to_irqhandler(blkif->evtchn, blkif_be_int, 0, "blkif-backend",
-                             blkif);
-    blkif->status        = CONNECTED;
-    blkif->shmem_frame   = shared_page;
+       sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
+       SHARED_RING_INIT(sring);
+       BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-    return 0;
+       bind_evtchn_to_irqhandler(
+               blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
+       blkif->status        = CONNECTED;
+
+       return 0;
 }
 
 static void free_blkif(void *arg)
 {
-    evtchn_op_t op = { .cmd = EVTCHNOP_close };
-    blkif_t *blkif = (blkif_t *)arg;
+       evtchn_op_t op = { .cmd = EVTCHNOP_close };
+       blkif_t *blkif = (blkif_t *)arg;
 
-    op.u.close.port = blkif->evtchn;
-    op.u.close.dom = DOMID_SELF;
-    HYPERVISOR_event_channel_op(&op);
-    op.u.close.port = blkif->remote_evtchn;
-    op.u.close.dom = blkif->domid;
-    HYPERVISOR_event_channel_op(&op);
+       op.u.close.port = blkif->evtchn;
+       op.u.close.dom = DOMID_SELF;
+       HYPERVISOR_event_channel_op(&op);
+       op.u.close.port = blkif->remote_evtchn;
+       op.u.close.dom = blkif->domid;
+       HYPERVISOR_event_channel_op(&op);
 
-    if (blkif->evtchn)
-        unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
+       if (blkif->evtchn)
+               unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
 
-    if (blkif->blk_ring.sring) {
-       unmap_frontend_page(blkif);
-       vunmap(blkif->blk_ring.sring);
-       blkif->blk_ring.sring = NULL;
-    }
+       if (blkif->blk_ring.sring) {
+               unmap_frontend_page(blkif);
+               free_vm_area(blkif->blk_ring_area);
+               blkif->blk_ring.sring = NULL;
+       }
 
-    kmem_cache_free(blkif_cachep, blkif);
+       kmem_cache_free(blkif_cachep, blkif);
 }
 
 void free_blkif_callback(blkif_t *blkif)
 {
-    INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
-    schedule_work(&blkif->free_work);
+       INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
+       schedule_work(&blkif->free_work);
 }
 
 void __init blkif_interface_init(void)
 {
-    blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
-                                     0, 0, NULL, NULL);
+       blkif_cachep = kmem_cache_create(
+               "blkif_cache", sizeof(blkif_t), 0, 0, NULL, NULL);
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Sep 22 11:46:17 2005
@@ -20,6 +20,7 @@
 #include <asm/pgalloc.h>
 #include <asm-xen/xen-public/grant_table.h>
 #include <asm-xen/gnttab.h>
+#include <asm-xen/driver_util.h>
 
 #define GRANT_INVALID_REF (0xFFFF)
 
@@ -46,24 +47,17 @@
        u8               fe_dev_addr[6];
 
        /* Physical parameters of the comms window. */
-       unsigned long    tx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT
        u16              tx_shmem_handle;
-       unsigned long    tx_shmem_vaddr; 
        grant_ref_t      tx_shmem_ref; 
-#endif
-       unsigned long    rx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT
        u16              rx_shmem_handle;
-       unsigned long    rx_shmem_vaddr; 
        grant_ref_t      rx_shmem_ref; 
-#endif
        unsigned int     evtchn;
        unsigned int     remote_evtchn;
 
        /* The shared rings and indexes. */
        netif_tx_interface_t *tx;
        netif_rx_interface_t *rx;
+       struct vm_struct *comms_area;
 
        /* Private indexes into shared ring. */
        NETIF_RING_IDX rx_req_cons;
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Thu Sep 22 
11:46:17 2005
@@ -8,7 +8,6 @@
 
 #include "common.h"
 #include <linux/rtnetlink.h>
-#include <asm-xen/driver_util.h>
 
 static void __netif_up(netif_t *netif)
 {
@@ -113,20 +112,20 @@
        return netif;
 }
 
-static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
-                              unsigned long tx_ring_ref, 
-                              unsigned long rx_ring_ref)
-{
-#ifdef CONFIG_XEN_NETDEV_GRANT
+static int map_frontend_pages(
+       netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref)
+{
        struct gnttab_map_grant_ref op;
 
-       /* Map: Use the Grant table reference */
-       op.host_addr = localaddr;
+       op.host_addr = (unsigned long)netif->comms_area->addr;
        op.flags     = GNTMAP_host_map;
        op.ref       = tx_ring_ref;
        op.dom       = netif->domid;
     
-       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+       lock_vm_area(netif->comms_area);
+       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       unlock_vm_area(netif->comms_area);
+
        if (op.handle < 0) { 
                DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
                return op.handle;
@@ -134,15 +133,16 @@
 
        netif->tx_shmem_ref    = tx_ring_ref;
        netif->tx_shmem_handle = op.handle;
-       netif->tx_shmem_vaddr  = localaddr;
-
-       /* Map: Use the Grant table reference */
-       op.host_addr = localaddr + PAGE_SIZE;
+
+       op.host_addr = (unsigned long)netif->comms_area->addr + PAGE_SIZE;
        op.flags     = GNTMAP_host_map;
        op.ref       = rx_ring_ref;
        op.dom       = netif->domid;
 
-       BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+       lock_vm_area(netif->comms_area);
+       BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       unlock_vm_area(netif->comms_area);
+
        if (op.handle < 0) { 
                DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
                return op.handle;
@@ -150,63 +150,44 @@
 
        netif->rx_shmem_ref    = rx_ring_ref;
        netif->rx_shmem_handle = op.handle;
-       netif->rx_shmem_vaddr  = localaddr + PAGE_SIZE;
-
-#else
-       pgprot_t prot = __pgprot(_KERNPG_TABLE);
-       int      err;
-
-       err = direct_remap_pfn_range(
-               &init_mm, localaddr,
-               tx_ring_ref, PAGE_SIZE,
-               prot, netif->domid); 
-    
-       err |= direct_remap_pfn_range(
-               &init_mm, localaddr + PAGE_SIZE,
-               rx_ring_ref, PAGE_SIZE,
-               prot, netif->domid);
-
-       if (err)
-               return err;
-#endif
 
        return 0;
 }
 
 static void unmap_frontend_pages(netif_t *netif)
 {
-#ifdef CONFIG_XEN_NETDEV_GRANT
        struct gnttab_unmap_grant_ref op;
 
-       op.host_addr    = netif->tx_shmem_vaddr;
+       op.host_addr    = (unsigned long)netif->comms_area->addr;
        op.handle       = netif->tx_shmem_handle;
        op.dev_bus_addr = 0;
+
+       lock_vm_area(netif->comms_area);
        BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-
-       op.host_addr    = netif->rx_shmem_vaddr;
+       unlock_vm_area(netif->comms_area);
+
+       op.host_addr    = (unsigned long)netif->comms_area->addr + PAGE_SIZE;
        op.handle       = netif->rx_shmem_handle;
        op.dev_bus_addr = 0;
+
+       lock_vm_area(netif->comms_area);
        BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-       return; 
+       unlock_vm_area(netif->comms_area);
 }
 
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
              unsigned long rx_ring_ref, unsigned int evtchn)
 {
-       struct vm_struct *vma;
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
        int err;
 
-       vma = prepare_vm_area(2*PAGE_SIZE);
-       if (vma == NULL)
+       netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
+       if (netif->comms_area == NULL)
                return -ENOMEM;
 
-       err = map_frontend_pages(
-               netif, (unsigned long)vma->addr, tx_ring_ref, rx_ring_ref);
+       err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
        if (err) {
-               vunmap(vma->addr);
+               free_vm_area(netif->comms_area);
                return err;
        }
 
@@ -217,15 +198,16 @@
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_pages(netif);
-               vunmap(vma->addr);
+               free_vm_area(netif->comms_area);
                return err;
        }
 
        netif->evtchn = op.u.bind_interdomain.port1;
        netif->remote_evtchn = evtchn;
 
-       netif->tx = (netif_tx_interface_t *)vma->addr;
-       netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE);
+       netif->tx = (netif_tx_interface_t *)netif->comms_area->addr;
+       netif->rx = (netif_rx_interface_t *)
+               ((char *)netif->comms_area->addr + PAGE_SIZE);
        netif->tx->resp_prod = netif->rx->resp_prod = 0;
        netif_get(netif);
        wmb(); /* Other CPUs see new state before interface is started. */
@@ -262,7 +244,7 @@
 
        if (netif->tx) {
                unmap_frontend_pages(netif);
-               vunmap(netif->tx); /* Frees netif->rx as well. */
+               free_vm_area(netif->comms_area);
        }
 
        free_netdev(netif->dev);
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/common.h Thu Sep 22 11:46:17 2005
@@ -11,6 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <asm-xen/evtchn.h>
+#include <asm-xen/driver_util.h>
 #include <asm-xen/xen-public/io/tpmif.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
@@ -33,12 +34,12 @@
        unsigned int handle;
 
        /* Physical parameters of the comms window. */
-       unsigned long tx_shmem_frame;
        unsigned int evtchn;
        unsigned int remote_evtchn;
 
        /* The shared rings and indexes. */
        tpmif_tx_interface_t *tx;
+       struct vm_struct *tx_area;
 
        /* Miscellaneous private stuff. */
        enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
@@ -54,9 +55,7 @@
        struct work_struct work;
 
        u16 shmem_handle;
-       unsigned long shmem_vaddr;
        grant_ref_t shmem_ref;
-
 } tpmif_t;
 
 void tpmif_disconnect_complete(tpmif_t * tpmif);
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Thu Sep 22 
11:46:17 2005
@@ -13,9 +13,6 @@
 
 #include "common.h"
 #include <asm-xen/balloon.h>
-#include <asm-xen/driver_util.h>
-
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
 
 #define TPMIF_HASHSZ (2 << 5)
 #define TPMIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(TPMIF_HASHSZ-1))
@@ -79,17 +76,18 @@
 }
 
 static int
-map_frontend_page(tpmif_t * tpmif, unsigned long localaddr,
-                 unsigned long shared_page)
+map_frontend_page(tpmif_t *tpmif, unsigned long shared_page)
 {
        struct gnttab_map_grant_ref op = {
-               .host_addr = localaddr,
+               .host_addr = (unsigned long)tpmif->tx_area->addr,
                .flags = GNTMAP_host_map,
                .ref = shared_page,
                .dom = tpmif->domid,
        };
 
+       lock_vm_area(tpmif->tx_area);
        BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
+       unlock_vm_area(tpmif->tx_area);
 
        if (op.handle < 0) {
                DPRINTK(" Grant table operation failure !\n");
@@ -98,37 +96,38 @@
 
        tpmif->shmem_ref = shared_page;
        tpmif->shmem_handle = op.handle;
-       tpmif->shmem_vaddr = localaddr;
+
        return 0;
 }
 
 static void
-unmap_frontend_page(tpmif_t * tpmif)
+unmap_frontend_page(tpmif_t *tpmif)
 {
        struct gnttab_unmap_grant_ref op;
 
-       op.host_addr = tpmif->shmem_vaddr;
-       op.handle = tpmif->shmem_handle;
+       op.host_addr    = (unsigned long)tpmif->tx_area->addr;
+       op.handle       = tpmif->shmem_handle;
        op.dev_bus_addr = 0;
 
+       lock_vm_area(tpmif->tx_area);
        BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
+       unlock_vm_area(tpmif->tx_area);
 }
 
 int
-tpmif_map(tpmif_t * tpmif, unsigned long shared_page, unsigned int evtchn)
-{
-       struct vm_struct *vma;
+tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
+{
        evtchn_op_t op = {.cmd = EVTCHNOP_bind_interdomain };
        int err;
 
        BUG_ON(tpmif->remote_evtchn);
 
-       if ((vma = prepare_vm_area(PAGE_SIZE)) == NULL)
+       if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
 
-       err = map_frontend_page(tpmif, VMALLOC_VMADDR(vma->addr), shared_page);
+       err = map_frontend_page(tpmif, shared_page);
        if (err) {
-               vunmap(vma->addr);
+               free_vm_area(tpmif->tx_area);
                return err;
        }
 
@@ -139,14 +138,14 @@
        err = HYPERVISOR_event_channel_op(&op);
        if (err) {
                unmap_frontend_page(tpmif);
-               vunmap(vma->addr);
+               free_vm_area(tpmif->tx_area);
                return err;
        }
 
        tpmif->evtchn = op.u.bind_interdomain.port1;
        tpmif->remote_evtchn = evtchn;
 
-       tpmif->tx = (tpmif_tx_interface_t *) vma->addr;
+       tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
        bind_evtchn_to_irqhandler(tpmif->evtchn,
                                  tpmif_be_int, 0, "tpmif-backend", tpmif);
@@ -175,7 +174,7 @@
 
        if (tpmif->tx) {
                unmap_frontend_page(tpmif);
-               vunmap(tpmif->tx);
+               free_vm_area(tpmif->tx_area);
        }
 
        free_tpmif(tpmif);
@@ -194,3 +193,13 @@
        tpmif_cachep = kmem_cache_create("tpmif_cache", sizeof (tpmif_t),
                                         0, 0, NULL, NULL);
 }
+
+/*
+ * Local variables:
+ *  c-file-style: "linux"
+ *  indent-tabs-mode: t
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/usbback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/usbback/common.h Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/usbback/common.h Thu Sep 22 11:46:17 2005
@@ -13,7 +13,7 @@
 #include <asm/setup.h>
 #include <asm/pgalloc.h>
 #include <asm/hypervisor.h>
-
+#include <asm-xen/driver_util.h>
 #include <asm-xen/xen-public/io/usbif.h>
 
 #if 0
@@ -38,6 +38,7 @@
     unsigned int     evtchn;
     /* Comms Information */
     usbif_back_ring_t usb_ring;
+    struct vm_struct *usb_ring_area;
     /* Private fields. */
     enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
     /*
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/usbback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c      Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/usbback/interface.c      Thu Sep 22 
11:46:17 2005
@@ -7,7 +7,6 @@
  */
 
 #include "common.h"
-#include <asm-xen/driver_util.h>
 
 #define USBIF_HASHSZ 1024
 #define USBIF_HASH(_d) (((int)(_d))&(USBIF_HASHSZ-1))
@@ -34,7 +33,7 @@
      * may be outstanding requests at the device whose asynchronous responses
      * must still be notified to the remote driver.
      */
-    vunmap(usbif->usb_ring.sring);
+    free_vm_area(usbif->usb_ring_area);
 
     /* Construct the deferred response message. */
     cmsg.type         = CMSG_USBIF_BE;
@@ -140,7 +139,6 @@
     domid_t       domid  = connect->domid;
     unsigned int  evtchn = connect->evtchn;
     unsigned long shmem_frame = connect->shmem_frame;
-    struct vm_struct *vma;
     pgprot_t      prot;
     int           error;
     usbif_priv_t *up;
@@ -155,14 +153,14 @@
         return;
     }
 
-    if ( (vma = prepare_vm_area(PAGE_SIZE)) == NULL )
+    if ( (up->usb_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
     {
         connect->status = USBIF_BE_STATUS_OUT_OF_MEMORY;
         return;
     }
 
     prot = __pgprot(_KERNPG_TABLE);
-    error = direct_remap_pfn_range(&init_mm, VMALLOC_VMADDR(vma->addr),
+    error = direct_remap_pfn_range(&init_mm, AREALLOC_AREADDR(area->addr),
                                     shmem_frame, PAGE_SIZE,
                                     prot, domid);
     if ( error != 0 )
@@ -173,18 +171,18 @@
             connect->status = USBIF_BE_STATUS_MAPPING_ERROR;
         else
             connect->status = USBIF_BE_STATUS_ERROR;
-        vunmap(vma->addr);
+        free_vm_area(up->usb_ring_area);
         return;
     }
 
     if ( up->status != DISCONNECTED )
     {
         connect->status = USBIF_BE_STATUS_INTERFACE_CONNECTED;
-        vunmap(vma->addr);
-        return;
-    }
-
-    sring = (usbif_sring_t *)vma->addr;
+        free_vm_area(up->usb_ring_area);
+        return;
+    }
+
+    sring = (usbif_sring_t *)area->addr;
     SHARED_RING_INIT(sring);
     BACK_RING_INIT(&up->usb_ring, sring, PAGE_SIZE);
 
diff -r 52eb8504be71 -r 8dbcf407a680 linux-2.6-xen-sparse/drivers/xen/util.c
--- a/linux-2.6-xen-sparse/drivers/xen/util.c   Thu Sep 22 10:04:30 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/util.c   Thu Sep 22 11:46:17 2005
@@ -3,16 +3,15 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <asm/uaccess.h>
+#include <asm-xen/driver_util.h>
 
-static int touch_fn(
-       pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
+static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
 {
-       char c;
-       BUG_ON(!__get_user(c, (char *)addr));
+       /* generic_page_range() does all the hard work. */
        return 0;
 }
 
-struct vm_struct *prepare_vm_area(unsigned long size)
+struct vm_struct *alloc_vm_area(unsigned long size)
 {
        struct vm_struct *area;
 
@@ -21,18 +20,46 @@
                return NULL;
 
        /*
-         * This ensures that page tables are constructed for this region
-         * of kernel virtual address space. Furthermore, by touching each
-         * memory page (in touch_fn()) we ensure that the page tables are
-         * mapped into the current mm as well as init_mm.
-         */
+        * This ensures that page tables are constructed for this region
+        * of kernel virtual address space and mapped into init_mm.
+        */
        if (generic_page_range(&init_mm, (unsigned long)area->addr,
-                              area->size, touch_fn, NULL)) {
-               vunmap(area->addr);
+                              area->size, f, NULL)) {
+               free_vm_area(area);
                return NULL;
        }
 
        return area;
+}
+
+void free_vm_area(struct vm_struct *area)
+{
+       BUG_ON(remove_vm_area(area->addr) != area);
+       kfree(area);
+}
+
+void lock_vm_area(struct vm_struct *area)
+{
+       unsigned long i;
+       char c;
+
+       /*
+        * Prevent context switch to a lazy mm that doesn't have this area
+        * mapped into its page tables.
+        */
+       preempt_disable();
+
+       /*
+        * Ensure that the page tables are mapped into the current mm. The
+        * page-fault path will copy the page directory pointers from init_mm.
+        */
+       for (i = 0; i < area->size; i += PAGE_SIZE)
+               (void)__get_user(c, (char *)area->addr + i);
+}
+
+void unlock_vm_area(struct vm_struct *area)
+{
+       preempt_enable();
 }
 
 /*
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/include/asm-xen/driver_util.h
--- a/linux-2.6-xen-sparse/include/asm-xen/driver_util.h        Thu Sep 22 
10:04:30 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/driver_util.h        Thu Sep 22 
11:46:17 2005
@@ -5,6 +5,12 @@
 #include <linux/config.h>
 #include <linux/vmalloc.h>
 
-extern struct vm_struct *prepare_vm_area(unsigned long size);
+/* Allocate/destroy a 'vmalloc' VM area. */
+extern struct vm_struct *alloc_vm_area(unsigned long size);
+extern void free_vm_area(struct vm_struct *area);
+
+/* Lock an area so that PTEs are accessible in the current address space. */
+extern void lock_vm_area(struct vm_struct *area);
+extern void unlock_vm_area(struct vm_struct *area);
 
 #endif /* __ASM_XEN_DRIVER_UTIL_H__ */
diff -r 52eb8504be71 -r 8dbcf407a680 
linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.h  Thu Sep 22 10:04:30 2005
+++ /dev/null   Thu Sep 22 11:46:17 2005
@@ -1,229 +0,0 @@
-/*
- * blktap.h
- * 
- * Interfaces for the Xen block tap driver.
- * 
- * (c) 2004, Andrew Warfield, University of Cambridge
- * 
- */
-
-#ifndef __BLKTAP_H__
-#define __BLKTAP_H__
-
-#include <linux/version.h>
-#include <linux/blkdev.h>
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/blkdev.h>
-#include <asm/io.h>
-#include <asm/setup.h>
-#include <asm/pgalloc.h>
-#include <asm/hypervisor.h>
-#include <asm-xen/xen-public/io/blkif.h>
-#include <asm-xen/xen-public/io/ring.h>
-
-/* Used to signal to the backend that this is a tap domain. */
-#define BLKTAP_COOKIE 0xbeadfeed
-
-/* -------[ debug / pretty printing ]--------------------------------- */
-
-#define PRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#if 0
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
-                           __FILE__ , __LINE__ , ## _a )
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
-
-#if 1
-#define ASSERT(_p) \
-    if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
-    __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p) ((void)0)
-#endif
-
-#define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
-
-
-/* -------[ state descriptors ]--------------------------------------- */
-
-#define BLKIF_STATE_CLOSED       0
-#define BLKIF_STATE_DISCONNECTED 1
-#define BLKIF_STATE_CONNECTED    2
-
-/* -------[ connection tracking ]------------------------------------- */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#endif
-
-extern spinlock_t blkif_io_lock;
-
-typedef struct blkif_st {
-    /* Unique identifier for this interface. */
-    domid_t             domid;
-    unsigned int        handle;
-    /* Physical parameters of the comms window. */
-    unsigned long       shmem_frame;
-    unsigned int        evtchn;
-    /* Comms information. */
-    blkif_back_ring_t   blk_ring;
-    
-    enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
-    /*
-     * DISCONNECT response is deferred until pending requests are ack'ed.
-     * We therefore need to store the id from the original request.
-     */    
-    u8                  disconnect_rspid;
-    struct blkif_st    *hash_next;
-    struct list_head    blkdev_list;
-    spinlock_t          blk_ring_lock;
-    atomic_t            refcnt;
-    struct work_struct work;
-#ifdef CONFIG_XEN_BLKDEV_GRANT
-    u16 shmem_handle;
-    unsigned long shmem_vaddr;
-    grant_ref_t shmem_ref;
-#endif
-} blkif_t;
-
-blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
-void blkif_disconnect_complete(blkif_t *blkif);
-#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
-#define blkif_put(_b)                             \
-    do {                                          \
-        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            blkif_disconnect_complete(_b);        \
-    } while (0)
-
-
-/* -------[ active request tracking ]--------------------------------- */
-
-typedef struct {
-    blkif_t       *blkif;
-    unsigned long  id;
-    int            nr_pages;
-    int            next_free;
-} active_req_t;
-
-typedef unsigned int ACTIVE_RING_IDX;
-
-active_req_t *lookup_active_req(ACTIVE_RING_IDX idx);
-
-extern inline unsigned int ID_TO_IDX(unsigned long id) 
-{ 
-    return ( id & 0x0000ffff );
-}
-
-extern inline domid_t ID_TO_DOM(unsigned long id) 
-{ 
-    return (id >> 16); 
-}
-
-void active_reqs_init(void);
-
-/* -------[ interposition -> character device interface ]------------- */
-
-/* /dev/xen/blktap resides at device number major=10, minor=200        */ 
-#define BLKTAP_MINOR 202
-
-/* size of the extra VMA area to map in attached pages. */
-#define BLKTAP_VMA_PAGES BLKIF_RING_SIZE
-
-/* blktap IOCTLs:                                                      */
-#define BLKTAP_IOCTL_KICK_FE         1
-#define BLKTAP_IOCTL_KICK_BE         2
-#define BLKTAP_IOCTL_SETMODE         3
-#define BLKTAP_IOCTL_PRINT_IDXS      100  
-
-/* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
-#define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
-#define BLKTAP_MODE_INTERCEPT_FE     0x00000001
-#define BLKTAP_MODE_INTERCEPT_BE     0x00000002
-#define BLKTAP_MODE_COPY_FE          0x00000004
-#define BLKTAP_MODE_COPY_BE          0x00000008
-#define BLKTAP_MODE_COPY_FE_PAGES    0x00000010
-#define BLKTAP_MODE_COPY_BE_PAGES    0x00000020
-
-#define BLKTAP_MODE_INTERPOSE \
-           (BLKTAP_MODE_INTERCEPT_FE | BLKTAP_MODE_INTERCEPT_BE)
-
-#define BLKTAP_MODE_COPY_BOTH \
-           (BLKTAP_MODE_COPY_FE | BLKTAP_MODE_COPY_BE)
-
-#define BLKTAP_MODE_COPY_BOTH_PAGES \
-           (BLKTAP_MODE_COPY_FE_PAGES | BLKTAP_MODE_COPY_BE_PAGES)
-
-static inline int BLKTAP_MODE_VALID(unsigned long arg)
-{
-    return (
-        ( arg == BLKTAP_MODE_PASSTHROUGH  ) ||
-        ( arg == BLKTAP_MODE_INTERCEPT_FE ) ||
-        ( arg == BLKTAP_MODE_INTERCEPT_BE ) ||
-        ( arg == BLKTAP_MODE_INTERPOSE    ) ||
-        ( (arg & ~BLKTAP_MODE_COPY_FE_PAGES) == BLKTAP_MODE_COPY_FE ) ||
-        ( (arg & ~BLKTAP_MODE_COPY_BE_PAGES) == BLKTAP_MODE_COPY_BE ) ||
-        ( (arg & ~BLKTAP_MODE_COPY_BOTH_PAGES) == BLKTAP_MODE_COPY_BOTH )
-        );
-}
-
-
-
-/* -------[ Mappings to User VMA ]------------------------------------ */
-#define BATCH_PER_DOMAIN 16
-
-/* -------[ Here be globals ]----------------------------------------- */
-extern unsigned long blktap_mode;
-
-/* Connection to a single backend domain. */
-extern blkif_front_ring_t blktap_be_ring;
-extern unsigned int blktap_be_evtchn;
-extern unsigned int blktap_be_state;
-
-/* User ring status. */
-extern unsigned long blktap_ring_ok;
-
-/* -------[ ...and function prototypes. ]----------------------------- */
-
-/* init function for character device interface.                       */
-int blktap_init(void);
-
-/* init function for the blkif cache. */
-void __init blkif_interface_init(void);
-void __init blkdev_schedule_init(void);
-void blkif_deschedule(blkif_t *blkif);
-
-/* interfaces to the char driver, passing messages to and from apps.   */
-void blktap_kick_user(void);
-
-/* user ring access functions: */
-int blktap_write_fe_ring(blkif_request_t *req);
-int blktap_write_be_ring(blkif_response_t *rsp);
-int blktap_write_ctrl_ring(ctrl_msg_t *msg);
-
-/* fe/be ring access functions: */
-int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp);
-int write_req_to_be_ring(blkif_request_t *req);
-
-/* event notification functions */
-void kick_fe_domain(blkif_t *blkif);
-void kick_be_domain(void);
-
-/* Interrupt handlers. */
-irqreturn_t blkif_ptbe_int(int irq, void *dev_id, 
-                                  struct pt_regs *ptregs);
-irqreturn_t blkif_ptfe_int(int irq, void *dev_id, struct pt_regs *regs);
-
-/* Control message receiver. */
-extern void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id);
-
-/* debug */
-void print_fe_ring_idxs(void);
-void print_be_ring_idxs(void);
-        
-#define __BLKINT_H__
-#endif

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.