# 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
|