[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |