diff options
-rw-r--r-- | linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 | 4 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 | 4 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 | 4 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 | 4 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/netback/common.h | 17 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 111 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 18 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c | 78 | ||||
-rw-r--r-- | tools/python/xen/lowlevel/xu/xu.c | 8 | ||||
-rw-r--r-- | tools/python/xen/xend/XendDomainInfo.py | 2 | ||||
-rwxr-xr-x | tools/python/xen/xend/server/netif.py | 4 | ||||
-rw-r--r-- | xen/common/grant_table.c | 187 | ||||
-rw-r--r-- | xen/include/public/io/domain_controller.h | 6 |
13 files changed, 301 insertions, 146 deletions
diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 index 2fd6798e7d..7274d10780 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 @@ -18,8 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_NETDEV_GRANT_TX is not set -# CONFIG_XEN_NETDEV_GRANT_RX is not set +CONFIG_XEN_NETDEV_GRANT_TX=y +CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 index 6c8a39f999..84bc803069 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 @@ -18,8 +18,8 @@ CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_NETDEV_GRANT_TX is not set -# CONFIG_XEN_NETDEV_GRANT_RX is not set +CONFIG_XEN_NETDEV_GRANT_TX=y +CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 index 7cf0b62e43..18a5217794 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 @@ -15,8 +15,8 @@ CONFIG_NO_IDLE_HZ=y CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_NETDEV_GRANT_TX is not set -# CONFIG_XEN_NETDEV_GRANT_RX is not set +CONFIG_XEN_NETDEV_GRANT_TX=y +CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 index b06dd5cad5..f238787d18 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 @@ -15,8 +15,8 @@ CONFIG_NO_IDLE_HZ=y CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_NETDEV_GRANT_TX is not set -# CONFIG_XEN_NETDEV_GRANT_RX is not set +CONFIG_XEN_NETDEV_GRANT_TX=y +CONFIG_XEN_NETDEV_GRANT_RX=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set # CONFIG_XEN_BLKDEV_TAP is not set # CONFIG_XEN_SHADOW_MODE is not set diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/common.h b/linux-2.6-xen-sparse/drivers/xen/netback/common.h index a1f9146511..c3c877ce6c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h @@ -20,6 +20,13 @@ #include <asm/io.h> #include <asm/pgalloc.h> +#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) +#include <asm-xen/xen-public/grant_table.h> +#include <asm-xen/gnttab.h> +#endif + + + #if 0 #define ASSERT(_p) \ if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \ @@ -40,7 +47,17 @@ typedef struct netif_st { /* Physical parameters of the comms window. */ unsigned long tx_shmem_frame; +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + u16 tx_shmem_handle; + memory_t tx_shmem_vaddr; + grant_ref_t tx_shmem_ref; +#endif unsigned long rx_shmem_frame; +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + u16 rx_shmem_handle; + memory_t rx_shmem_vaddr; + grant_ref_t rx_shmem_ref; +#endif unsigned int evtchn; /* The shared rings and indexes. */ diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index df0f43b3b2..8326915220 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -71,12 +71,31 @@ static void __netif_disconnect_complete(void *arg) netif_t *netif = (netif_t *)arg; ctrl_msg_t cmsg; netif_be_disconnect_t disc; +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) + struct gnttab_unmap_grant_ref op; +#endif /* * These can't be done in netif_disconnect() because at that point there * may be outstanding requests in the network stack whose asynchronous * responses must still be notified to the remote driver. */ + +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + op.host_addr = netif->tx_shmem_vaddr; + op.handle = netif->tx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); +#endif + +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + op.host_addr = netif->rx_shmem_vaddr; + op.handle = netif->rx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); +#endif + + vfree(netif->tx); /* Frees netif->rx as well. */ /* Construct the deferred response message. */ @@ -275,37 +294,101 @@ void netif_connect(netif_be_connect_t *connect) unsigned long tx_shmem_frame = connect->tx_shmem_frame; unsigned long rx_shmem_frame = connect->rx_shmem_frame; struct vm_struct *vma; - pgprot_t prot; +#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) + pgprot_t prot = __pgprot(_KERNPG_TABLE); int error; +#endif netif_t *netif; netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { + if ( unlikely(netif == NULL) ) { DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", connect->domid, connect->netif_handle); connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; return; } - if ( netif->status != DISCONNECTED ) - { + if ( netif->status != DISCONNECTED ) { connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; return; } - if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) - { + if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) { connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; return; } - prot = __pgprot(_KERNPG_TABLE); - error = direct_remap_area_pages(&init_mm, - VMALLOC_VMADDR(vma->addr), - tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, - prot, domid); - error |= direct_remap_area_pages(&init_mm, + +#if defined(CONFIG_XEN_NETDEV_GRANT_TX) + { + struct gnttab_map_grant_ref op; + int tx_ref = connect->tx_shmem_ref; + + /* Map: Use the Grant table reference */ + op.host_addr = VMALLOC_VMADDR(vma->addr); + op.flags = GNTMAP_host_map; + op.ref = tx_ref; + op.dom = domid; + + if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || + (op.handle < 0)) { + DPRINTK(" Grant table operation failure !\n"); + connect->status = NETIF_BE_STATUS_MAPPING_ERROR; + vfree(vma->addr); + return; + } + + netif->tx_shmem_ref = tx_ref; + netif->tx_shmem_handle = op.handle; + netif->tx_shmem_vaddr = VMALLOC_VMADDR(vma->addr); + } + + +#else + error = direct_remap_area_pages(&init_mm, + VMALLOC_VMADDR(vma->addr), + tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, + prot, domid); + if ( error != 0 ) + { + if ( error == -ENOMEM ) + connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; + else if ( error == -EFAULT ) + connect->status = NETIF_BE_STATUS_MAPPING_ERROR; + else + connect->status = NETIF_BE_STATUS_ERROR; + vfree(vma->addr); + return; + } +#endif + + +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) + { + struct gnttab_map_grant_ref op; + int rx_ref = connect->rx_shmem_ref; + + + /* Map: Use the Grant table reference */ + op.host_addr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; + op.flags = GNTMAP_host_map; + op.ref = rx_ref; + op.dom = domid; + + if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || + (op.handle < 0)) { + DPRINTK(" Grant table operation failure !\n"); + connect->status = NETIF_BE_STATUS_MAPPING_ERROR; + vfree(vma->addr); + return; + } + + netif->rx_shmem_ref = rx_ref; + netif->rx_shmem_handle = handle; + netif->rx_shmem_vaddr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; + } +#else + error = direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(vma->addr) + PAGE_SIZE, rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, prot, domid); @@ -321,6 +404,8 @@ void netif_connect(netif_be_connect_t *connect) return; } +#endif + netif->evtchn = evtchn; netif->tx_shmem_frame = tx_shmem_frame; netif->rx_shmem_frame = rx_shmem_frame; diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index d2ede06e72..0de0b0b064 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -55,6 +55,8 @@ static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0); static struct timer_list net_timer; +#define MAX_PENDING_REQS 256 + static struct sk_buff_head rx_queue; static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1]; static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE]; @@ -68,7 +70,6 @@ static unsigned char rx_notify[NR_EVENT_CHANNELS]; /* Don't currently gate addition of an interface to the tx scheduling list. */ #define tx_work_exists(_if) (1) -#define MAX_PENDING_REQS 256 static unsigned long mmap_vstart; #define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE)) @@ -518,7 +519,7 @@ inline static void net_tx_action_dealloc(void) gop++; } BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); #else mcl = tx_mcl; while ( dc != dp ) @@ -697,9 +698,9 @@ static void net_tx_action(unsigned long unused) skb_reserve(skb, 16); #ifdef CONFIG_XEN_NETDEV_GRANT_TX mop->host_addr = MMAP_VADDR(pending_idx); - mop->dom = netif->domid; - mop->ref = txreq.addr >> PAGE_SHIFT; - mop->flags = GNTMAP_host_map | GNTMAP_readonly; + mop->dom = netif->domid; + mop->ref = txreq.addr >> PAGE_SHIFT; + mop->flags = GNTMAP_host_map | GNTMAP_readonly; mop++; #else MULTI_update_va_mapping_otherdomain( @@ -752,7 +753,12 @@ static void net_tx_action(unsigned long unused) /* Check the remap error code. */ #ifdef CONFIG_XEN_NETDEV_GRANT_TX - if ( unlikely(mop->dev_bus_addr == 0) ) + /* + XXX SMH: error returns from grant operations are pretty poorly + specified/thought out, but the below at least conforms with + what the rest of the code uses. + */ + if ( unlikely(mop->handle < 0) ) { printk(KERN_ALERT "#### netback grant fails\n"); make_tx_response(netif, txreq.id, NETIF_RSP_ERROR); diff --git a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c index b118313143..742c3fd46c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c @@ -59,7 +59,7 @@ #include <asm-xen/gnttab.h> #ifdef GRANT_DEBUG static void -dump_packet(int tag, u32 addr, u32 ap) +dump_packet(int tag, void *addr, u32 ap) { unsigned char *p = (unsigned char *)ap; int i; @@ -200,7 +200,7 @@ static char *be_state_name[] = { [BEST_CONNECTED] = "connected", }; -#if DEBUG +#ifdef DEBUG #define DPRINTK(fmt, args...) \ printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args) #else @@ -356,8 +356,12 @@ static void network_tx_buf_gc(struct net_device *dev) id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; skb = np->tx_skbs[id]; #ifdef CONFIG_XEN_NETDEV_GRANT_TX - if (gnttab_query_foreign_access(grant_tx_ref[id]) != 0) { - printk(KERN_ALERT "netfront: query foreign access\n"); + if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) { + /* other domain is still using this grant - shouldn't happen + but if it does, we'll try to reclaim the grant later */ + printk(KERN_ALERT "network_tx_buf_gc: warning -- grant " + "still in use by backend domain.\n"); + goto out; } gnttab_end_foreign_access(grant_tx_ref[id], GNTMAP_readonly); gnttab_release_grant_reference(&gref_tx_head, grant_tx_ref[id]); @@ -382,6 +386,7 @@ static void network_tx_buf_gc(struct net_device *dev) mb(); } while (prod != np->tx->resp_prod); + out: if (np->tx_full && ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE)) { np->tx_full = 0; if (np->user_state == UST_OPEN) @@ -433,13 +438,15 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id; #ifdef CONFIG_XEN_NETDEV_GRANT_RX - if ((ref = gnttab_claim_grant_reference(&gref_rx_head, gref_rx_terminal)) < 0) { + if (unlikely((ref = gnttab_claim_grant_reference(&gref_rx_head, + gref_rx_terminal)) < 0)) { printk(KERN_ALERT "#### netfront can't claim rx reference\n"); BUG(); } grant_rx_ref[id] = ref; gnttab_grant_foreign_transfer_ref(ref, rdomid, - virt_to_machine(skb->head) >> PAGE_SHIFT); + virt_to_machine( + skb->head) >> PAGE_SHIFT); np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref; #endif rx_pfn_array[i] = virt_to_machine(skb->head) >> PAGE_SHIFT; @@ -528,7 +535,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) tx->id = id; #ifdef CONFIG_XEN_NETDEV_GRANT_TX - if ((ref = gnttab_claim_grant_reference(&gref_tx_head, gref_tx_terminal)) < 0) { + if (unlikely((ref = gnttab_claim_grant_reference(&gref_tx_head, + gref_tx_terminal)) < 0)) { printk(KERN_ALERT "#### netfront can't claim tx grant reference\n"); BUG(); } @@ -638,7 +646,6 @@ static int netif_poll(struct net_device *dev, int *pbudget) #ifdef CONFIG_XEN_NETDEV_GRANT_RX ref = grant_rx_ref[rx->id]; grant_rx_ref[rx->id] = GRANT_INVALID_REF; - mfn = gnttab_end_foreign_transfer(ref); gnttab_release_grant_reference(&gref_rx_head, ref); #endif @@ -674,18 +681,20 @@ static int netif_poll(struct net_device *dev, int *pbudget) pfn_pte_ma(mfn, PAGE_KERNEL), 0); #else MULTI_update_va_mapping(mcl, (unsigned long)skb->head, - pfn_pte_ma(rx->addr >> PAGE_SHIFT, PAGE_KERNEL), 0); + pfn_pte_ma(rx->addr >> PAGE_SHIFT, + PAGE_KERNEL), 0); #endif mcl++; - phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = #ifdef CONFIG_XEN_NETDEV_GRANT_RX - mfn; + phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn; #else + phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = rx->addr >> PAGE_SHIFT; #endif + #ifdef GRANT_DEBUG - printk(KERN_ALERT "#### rx_poll enqueue vdata=%08x mfn=%08x ref=%04x\n", + printk(KERN_ALERT "#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n", skb->data, mfn, ref); #endif __skb_queue_tail(&rxq, skb); @@ -707,9 +716,9 @@ static int netif_poll(struct net_device *dev, int *pbudget) while ((skb = __skb_dequeue(&rxq)) != NULL) { #ifdef GRANT_DEBUG - printk(KERN_ALERT "#### rx_poll dequeue vdata=%08x mfn=%08x\n", - skb->data, virt_to_machine(skb->data)>>PAGE_SHIFT); - dump_packet('d', skb->data, (unsigned long)skb->data); + printk(KERN_ALERT "#### rx_poll dequeue vdata=%p mfn=%lu\n", + skb->data, virt_to_machine(skb->data)>>PAGE_SHIFT); + dump_packet('d', skb->data, (unsigned long)skb->data); #endif /* * Enough room in skbuff for the data we were passed? Also, Linux @@ -884,7 +893,7 @@ static void network_connect(struct net_device *dev, static void vif_show(struct net_private *np) { -#if DEBUG +#ifdef DEBUG if (np) { IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", np->handle, @@ -911,8 +920,29 @@ static void send_interface_connect(struct net_private *np) msg->handle = np->handle; msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT); +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + msg->tx_shmem_ref = (u32)gnttab_claim_grant_reference(&gref_tx_head, + gref_tx_terminal); + if(msg->tx_shmem_ref < 0) { + printk(KERN_ALERT "#### netfront can't claim tx_shmem reference\n"); + BUG(); + } + gnttab_grant_foreign_access_ref (msg->tx_shmem_ref, rdomid, + msg->tx_shmem_frame, 0); +#endif + msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT); - +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + msg->rx_shmem_ref = (u32)gnttab_claim_grant_reference(&gref_rx_head, + gref_rx_terminal); + if(msg->rx_shmem_ref < 0) { + printk(KERN_ALERT "#### netfront can't claim rx_shmem reference\n"); + BUG(); + } + gnttab_grant_foreign_access_ref (msg->rx_shmem_ref, rdomid, + msg->rx_shmem_frame, 0); +#endif + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); } @@ -1380,20 +1410,22 @@ static int __init netif_init(void) if (xen_start_info.flags & SIF_INITDOMAIN) return 0; #ifdef CONFIG_XEN_NETDEV_GRANT_TX - if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, + /* A grant for every ring slot, plus one for the ring itself */ + if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE + 1, &gref_tx_head, &gref_tx_terminal) < 0) { printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); return 1; } - printk(KERN_ALERT "#### netfront tx using grant tables\n"); + printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); #endif #ifdef CONFIG_XEN_NETDEV_GRANT_RX - if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE, + /* A grant for every ring slot, plus one for the ring itself */ + if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE + 1, &gref_rx_head, &gref_rx_terminal) < 0) { printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); return 1; } - printk(KERN_ALERT "#### netfront rx using grant tables\n"); + printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); #endif if ((err = xennet_proc_init()) != 0) @@ -1417,10 +1449,10 @@ static int __init netif_init(void) static void netif_exit(void) { #ifdef CONFIG_XEN_NETDEV_GRANT_TX - gnttab_free_grant_references(NETIF_TX_RING_SIZE, gref_tx_head); + gnttab_free_grant_references(NETIF_TX_RING_SIZE + 1, gref_tx_head); #endif #ifdef CONFIG_XEN_NETDEV_GRANT_RX - gnttab_free_grant_references(NETIF_RX_RING_SIZE, gref_rx_head); + gnttab_free_grant_references(NETIF_RX_RING_SIZE + 1, gref_rx_head); #endif } diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index f81dd722a4..832630e057 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -655,7 +655,9 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_CONNECT): C2P(netif_fe_interface_connect_t, handle, Int, Long); C2P(netif_fe_interface_connect_t, tx_shmem_frame, Int, Long); + C2P(netif_fe_interface_connect_t, tx_shmem_ref, Int, Long); C2P(netif_fe_interface_connect_t, rx_shmem_frame, Int, Long); + C2P(netif_fe_interface_connect_t, rx_shmem_ref, Int, Long); return dict; case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_DISCONNECT): C2P(netif_fe_interface_disconnect_t, handle, Int, Long); @@ -681,7 +683,9 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) C2P(netif_be_connect_t, domid, Int, Long); C2P(netif_be_connect_t, netif_handle, Int, Long); C2P(netif_be_connect_t, tx_shmem_frame, Int, Long); + C2P(netif_be_connect_t, tx_shmem_ref, Int, Long); C2P(netif_be_connect_t, rx_shmem_frame, Int, Long); + C2P(netif_be_connect_t, rx_shmem_ref, Int, Long); C2P(netif_be_connect_t, evtchn, Int, Long); C2P(netif_be_connect_t, status, Int, Long); return dict; @@ -903,8 +907,10 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args) P2C(netif_be_connect_t, domid, u32); P2C(netif_be_connect_t, netif_handle, u32); P2C(netif_be_connect_t, tx_shmem_frame, memory_t); + P2C(netif_be_connect_t, tx_shmem_ref, u32); P2C(netif_be_connect_t, rx_shmem_frame, memory_t); - P2C(netif_be_connect_t, evtchn, u16); + P2C(netif_be_connect_t, rx_shmem_ref, u32); + P2C(netif_be_connect_t, evtchn, u16); break; case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DISCONNECT): P2C(netif_be_disconnect_t, domid, u32); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 029021f13e..5fe20c499a 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -593,7 +593,7 @@ class XendDomainInfo: def delete(self): """Delete the vm's db. """ - if self.dom_get(self.id): + if dom_get(self.id): return self.id = None self.saveToDB(sync=True) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 9e42098f27..1163459ac0 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -421,7 +421,9 @@ class NetDev(Dev): 'netif_handle' : self.vif, 'evtchn' : self.getEventChannelBackend(), 'tx_shmem_frame' : val['tx_shmem_frame'], - 'rx_shmem_frame' : val['rx_shmem_frame'] }) + 'tx_shmem_ref' : val['tx_shmem_ref'], + 'rx_shmem_frame' : val['rx_shmem_frame'], + 'rx_shmem_ref' : val['rx_shmem_ref'] }) msg = self.backendChannel.requestResponse(msg) #todo: check return status self.status = NETIF_INTERFACE_STATUS_CONNECTED diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 785cfa97a0..b6af8d17d9 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -771,9 +771,8 @@ gnttab_dump_table(gnttab_dump_table_t *uop) if ( sha_copy.flags ) { DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) " - "dom:(%hu) frame:(%lx)\n", - op.dom, i, sha_copy.flags, sha_copy.domid, - (unsigned long) sha_copy.frame); + "dom:(%hu) frame:(%x)\n", + op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame); } } @@ -826,18 +825,20 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) for (i = 0; i < count; i++) { gnttab_donate_t *gop = &uop[i]; #if GRANT_DEBUG - printk("gnttab_donate: i=%d mfn=%08x domid=%d gref=%08x\n", - i, (unsigned int)gop->mfn, gop->domid, gop->handle); + printk("gnttab_donate: i=%d mfn=%lx domid=%d gref=%08x\n", + i, gop->mfn, gop->domid, gop->handle); #endif page = &frame_table[gop->mfn]; - + if (unlikely(IS_XEN_HEAP_FRAME(page))) { - printk("gnttab_donate: xen heap frame mfn=%lx\n", (unsigned long) gop->mfn); + printk("gnttab_donate: xen heap frame mfn=%lx\n", + (unsigned long) gop->mfn); gop->status = GNTST_bad_virt_addr; continue; } if (unlikely(!pfn_valid(page_to_pfn(page)))) { - printk("gnttab_donate: invalid pfn for mfn=%lx\n", (unsigned long) gop->mfn); + printk("gnttab_donate: invalid pfn for mfn=%lx\n", + (unsigned long) gop->mfn); gop->status = GNTST_bad_virt_addr; continue; } @@ -863,7 +864,8 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) if (unlikely((x & (PGC_count_mask|PGC_allocated)) != (1 | PGC_allocated)) || unlikely(_nd != _d)) { printk("gnttab_donate: Bad page values %p: ed=%p(%u), sd=%p," - " caf=%08x, taf=%" PRtype_info "\n", (void *) page_to_pfn(page), + " caf=%08x, taf=%" PRtype_info "\n", + (void *) page_to_pfn(page), d, d->domain_id, unpickle_domptr(_nd), x, page->u.inuse.type_info); spin_unlock(&d->page_alloc_lock); @@ -922,9 +924,9 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags)) || unlikely(e->tot_pages == e->max_pages) || unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) { - printk("gnttab_donate: Transferee has no reservation headroom (%d,%d), or " - "provided a bad grant ref (%08x), or is dying (%p).\n", - e->tot_pages, e->max_pages, gop->handle, e->d_flags); + printk("gnttab_donate: Transferee has no reservation headroom (%d," + "%d) or provided a bad grant ref (%08x) or is dying (%p)\n", + e->tot_pages, e->max_pages, gop->handle, e->d_flags); spin_unlock(&e->page_alloc_lock); put_domain(e); result = GNTST_general_error; @@ -937,9 +939,9 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) } list_add_tail(&page->list, &e->page_list); page_set_owner(page, e); - + spin_unlock(&e->page_alloc_lock); - + /* * Transfer is all done: tell the guest about its new page * frame. @@ -947,7 +949,7 @@ gnttab_donate(gnttab_donate_t *uop, unsigned int count) gnttab_notify_transfer(e, d, gop->handle, gop->mfn); put_domain(e); - + gop->status = GNTST_okay; } return result; @@ -959,50 +961,52 @@ do_grant_table_op( { long rc; struct domain *d = current->domain; - + if ( count > 512 ) return -EINVAL; - + LOCK_BIGLOCK(d); - + sync_pagetable_state(d); - + rc = -EFAULT; switch ( cmd ) - { - case GNTTABOP_map_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_map_grant_ref_t))) ) - goto out; - rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); - break; - case GNTTABOP_unmap_grant_ref: - if ( unlikely(!array_access_ok( - uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) - goto out; - rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, count); - break; - case GNTTABOP_setup_table: - rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); - break; + { + case GNTTABOP_map_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_map_grant_ref_t))) ) + goto out; + rc = gnttab_map_grant_ref((gnttab_map_grant_ref_t *)uop, count); + break; + case GNTTABOP_unmap_grant_ref: + if ( unlikely(!array_access_ok( + uop, count, sizeof(gnttab_unmap_grant_ref_t))) ) + goto out; + rc = gnttab_unmap_grant_ref((gnttab_unmap_grant_ref_t *)uop, + count); + break; + case GNTTABOP_setup_table: + rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count); + break; #if GRANT_DEBUG - case GNTTABOP_dump_table: - rc = gnttab_dump_table((gnttab_dump_table_t *)uop); - break; + case GNTTABOP_dump_table: + rc = gnttab_dump_table((gnttab_dump_table_t *)uop); + break; #endif - case GNTTABOP_donate: - if (unlikely(!array_access_ok(uop, count, sizeof(gnttab_donate_t)))) - goto out; - rc = gnttab_donate(uop, count); - break; - default: - rc = -ENOSYS; - break; - } - -out: + case GNTTABOP_donate: + if (unlikely(!array_access_ok(uop, count, + sizeof(gnttab_donate_t)))) + goto out; + rc = gnttab_donate(uop, count); + break; + default: + rc = -ENOSYS; + break; + } + + out: UNLOCK_BIGLOCK(d); - + return rc; } @@ -1016,106 +1020,101 @@ gnttab_check_unmap( * Called a _lot_ at domain creation because pages mapped by priv domains * also traverse this. */ - + /* Note: If the same frame is mapped multiple times, and then one of * the ptes is overwritten, which maptrack handle gets invalidated? * Advice: Don't do it. Explicitly unmap. */ - + unsigned int handle, ref, refcount; grant_table_t *lgt, *rgt; active_grant_entry_t *act; grant_mapping_t *map; int found = 0; - + lgt = ld->grant_table; - + #if GRANT_DEBUG_VERBOSE - if ( ld->domain_id != 0 ) - { - DPRINTK("Foreign unref rd(%d) ld(%d) frm(%x) flgs(%x).\n", - rd->domain_id, ld->domain_id, (unsigned int)frame, readonly); - } + if ( ld->domain_ id != 0 ) { + DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", + rd->domain_id, ld->domain_id, frame, readonly); + } #endif - + /* Fast exit if we're not mapping anything using grant tables */ if ( lgt->map_count == 0 ) return 0; - - if ( get_domain(rd) == 0 ) - { + + if ( get_domain(rd) == 0 ) { DPRINTK("gnttab_check_unmap: couldn't get_domain rd(%d)\n", rd->domain_id); return 0; } - + rgt = rd->grant_table; + + for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) { - for ( handle = 0; handle < lgt->maptrack_limit; handle++ ) - { map = &lgt->maptrack[handle]; - + if ( map->domid != rd->domain_id ) continue; - + if ( ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK ) && - ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) - { + ( readonly ? 1 : (!(map->ref_and_flags & GNTMAP_readonly)))) { + ref = (map->ref_and_flags >> MAPTRACK_REF_SHIFT); act = &rgt->active[ref]; - + spin_lock(&rgt->lock); - - if ( act->frame != frame ) - { + + if ( act->frame != frame ) { spin_unlock(&rgt->lock); continue; } - + refcount = act->pin & ( readonly ? GNTPIN_hstr_mask - : GNTPIN_hstw_mask ); - if ( refcount == 0 ) - { + : GNTPIN_hstw_mask ); + + if ( refcount == 0 ) { spin_unlock(&rgt->lock); continue; } - + /* gotcha */ DPRINTK("Grant unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n", rd->domain_id, ld->domain_id, frame, readonly); - + if ( readonly ) act->pin -= GNTPIN_hstr_inc; - else - { + else { act->pin -= GNTPIN_hstw_inc; - + /* any more granted writable mappings? */ - if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) - { + if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 ) { clear_bit(_GTF_writing, &rgt->shared[ref].flags); put_page_type(&frame_table[frame]); } } - - if ( act->pin == 0 ) - { + + if ( act->pin == 0 ) { clear_bit(_GTF_reading, &rgt->shared[ref].flags); put_page(&frame_table[frame]); } - spin_unlock(&rgt->lock); + spin_unlock(&rgt->lock); + clear_bit(GNTMAP_host_map, &map->ref_and_flags); - + if ( !(map->ref_and_flags & GNTMAP_device_map) ) put_maptrack_handle(lgt, handle); - + found = 1; break; } } put_domain(rd); - + return found; } @@ -1131,8 +1130,10 @@ gnttab_prepare_for_transfer( int retries = 0; unsigned long target_pfn; +#ifdef GRANT_DEBUG_VERBOSE DPRINTK("gnttab_prepare_for_transfer rd(%hu) ld(%hu) ref(%hu).\n", rd->domain_id, ld->domain_id, ref); +#endif if ( unlikely((rgt = rd->grant_table) == NULL) || unlikely(ref >= NR_GRANT_ENTRIES) ) @@ -1210,8 +1211,10 @@ gnttab_notify_transfer( grant_entry_t *sha; unsigned long pfn; +#ifdef GRANT_DEBUG_VERBOSE DPRINTK("gnttab_notify_transfer rd(%hu) ld(%hu) ref(%hu).\n", rd->domain_id, ld->domain_id, ref); +#endif sha = &rd->grant_table->shared[ref]; diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index 4df634c9d7..1ff5f123cf 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -365,8 +365,10 @@ typedef struct netif_fe_driver_status { */ typedef struct netif_fe_interface_connect { u32 handle; - memory_t tx_shmem_frame; + memory_t tx_shmem_frame; + int tx_shmem_ref; memory_t rx_shmem_frame; + int rx_shmem_ref; } netif_fe_interface_connect_t; /* @@ -487,7 +489,9 @@ typedef struct netif_be_connect { domid_t domid; /* Domain attached to new interface. */ u32 netif_handle; /* Domain-specific interface handle. */ memory_t tx_shmem_frame; /* Page cont. tx shared comms window. */ + int tx_shmem_ref; /* Grant reference for above */ memory_t rx_shmem_frame; /* Page cont. rx shared comms window. */ + int rx_shmem_ref; /* Grant reference for above */ u16 evtchn; /* Event channel for notifications. */ /* OUT */ u32 status; |