mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
merge?
This commit is contained in:
commit
2952ccaa5d
11 files changed
+1653
-1622
No files matched your search
@@ -45,12 +45,12 @@ static int direct_remap_area_pte_fn(pte_t *pte,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int direct_remap_pfn_range(struct mm_struct *mm,
|
||||
unsigned long address,
|
||||
unsigned long mfn,
|
||||
unsigned long size,
|
||||
pgprot_t prot,
|
||||
domid_t domid)
|
||||
static int __direct_remap_pfn_range(struct mm_struct *mm,
|
||||
unsigned long address,
|
||||
unsigned long mfn,
|
||||
unsigned long size,
|
||||
pgprot_t prot,
|
||||
domid_t domid)
|
||||
{
|
||||
int i;
|
||||
unsigned long start_address;
|
||||
@@ -98,6 +98,20 @@ int direct_remap_pfn_range(struct mm_struct *mm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int direct_remap_pfn_range(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
unsigned long mfn,
|
||||
unsigned long size,
|
||||
pgprot_t prot,
|
||||
domid_t domid)
|
||||
{
|
||||
/* Same as remap_pfn_range(). */
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED;
|
||||
|
||||
return __direct_remap_pfn_range(
|
||||
vma->vm_mm, address, mfn, size, prot, domid);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(direct_remap_pfn_range);
|
||||
|
||||
|
||||
@@ -221,8 +235,9 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
|
||||
#ifdef __x86_64__
|
||||
flags |= _PAGE_USER;
|
||||
#endif
|
||||
if (direct_remap_pfn_range(&init_mm, (unsigned long) addr, phys_addr>>PAGE_SHIFT,
|
||||
size, __pgprot(flags), domid)) {
|
||||
if (__direct_remap_pfn_range(&init_mm, (unsigned long)addr,
|
||||
phys_addr>>PAGE_SHIFT,
|
||||
size, __pgprot(flags), domid)) {
|
||||
vunmap((void __force *) addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
/* Write-combine setting is ignored, it is changed via the mtrr
|
||||
* interfaces on this platform.
|
||||
*/
|
||||
if (direct_remap_pfn_range(vma->vm_mm, vma->vm_start, vma->vm_pgoff,
|
||||
if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot, DOMID_IO))
|
||||
return -EAGAIN;
|
||||
|
||||
@@ -90,22 +90,10 @@ out:
|
||||
|
||||
static int mmap_mem(struct file * file, struct vm_area_struct * vma)
|
||||
{
|
||||
int uncached;
|
||||
|
||||
uncached = uncached_access(file);
|
||||
if (uncached)
|
||||
if (uncached_access(file))
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
|
||||
/* Don't try to swap out physical pages.. */
|
||||
vma->vm_flags |= VM_RESERVED;
|
||||
|
||||
/*
|
||||
* Don't dump addresses that are not real memory to a core file.
|
||||
*/
|
||||
if (uncached)
|
||||
vma->vm_flags |= VM_IO;
|
||||
|
||||
if (direct_remap_pfn_range(vma->vm_mm, vma->vm_start, vma->vm_pgoff,
|
||||
if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot, DOMID_IO))
|
||||
return -EAGAIN;
|
||||
|
||||
@@ -18,17 +18,11 @@
|
||||
#include <asm-xen/xen-public/io/netif.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
||||
#ifdef CONFIG_XEN_NETDEV_GRANT
|
||||
#include <asm-xen/xen-public/grant_table.h>
|
||||
#include <asm-xen/gnttab.h>
|
||||
|
||||
#define GRANT_INVALID_REF (0xFFFF)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
#define ASSERT(_p) \
|
||||
if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
|
||||
@@ -44,74 +38,73 @@
|
||||
#define WPRINTK(fmt, args...) \
|
||||
printk(KERN_WARNING "xen_net: " fmt, ##args)
|
||||
|
||||
|
||||
typedef struct netif_st {
|
||||
/* Unique identifier for this interface. */
|
||||
domid_t domid;
|
||||
unsigned int handle;
|
||||
/* Unique identifier for this interface. */
|
||||
domid_t domid;
|
||||
unsigned int handle;
|
||||
|
||||
u8 fe_dev_addr[6];
|
||||
u8 fe_dev_addr[6];
|
||||
|
||||
/* Physical parameters of the comms window. */
|
||||
unsigned long tx_shmem_frame;
|
||||
/* 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;
|
||||
u16 tx_shmem_handle;
|
||||
unsigned long tx_shmem_vaddr;
|
||||
grant_ref_t tx_shmem_ref;
|
||||
#endif
|
||||
unsigned long rx_shmem_frame;
|
||||
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;
|
||||
u16 rx_shmem_handle;
|
||||
unsigned long rx_shmem_vaddr;
|
||||
grant_ref_t rx_shmem_ref;
|
||||
#endif
|
||||
unsigned int evtchn;
|
||||
unsigned int remote_evtchn;
|
||||
unsigned int evtchn;
|
||||
unsigned int remote_evtchn;
|
||||
|
||||
/* The shared rings and indexes. */
|
||||
netif_tx_interface_t *tx;
|
||||
netif_rx_interface_t *rx;
|
||||
/* The shared rings and indexes. */
|
||||
netif_tx_interface_t *tx;
|
||||
netif_rx_interface_t *rx;
|
||||
|
||||
/* Private indexes into shared ring. */
|
||||
NETIF_RING_IDX rx_req_cons;
|
||||
NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
|
||||
/* Private indexes into shared ring. */
|
||||
NETIF_RING_IDX rx_req_cons;
|
||||
NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
|
||||
#ifdef CONFIG_XEN_NETDEV_GRANT
|
||||
NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */
|
||||
NETIF_RING_IDX rx_resp_prod_copy;
|
||||
#endif
|
||||
NETIF_RING_IDX tx_req_cons;
|
||||
NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
|
||||
NETIF_RING_IDX tx_req_cons;
|
||||
NETIF_RING_IDX tx_resp_prod; /* private version of shared variable */
|
||||
|
||||
/* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
|
||||
unsigned long credit_bytes;
|
||||
unsigned long credit_usec;
|
||||
unsigned long remaining_credit;
|
||||
struct timer_list credit_timeout;
|
||||
/* Transmit shaping: allow 'credit_bytes' every 'credit_usec'. */
|
||||
unsigned long credit_bytes;
|
||||
unsigned long credit_usec;
|
||||
unsigned long remaining_credit;
|
||||
struct timer_list credit_timeout;
|
||||
|
||||
/* Miscellaneous private stuff. */
|
||||
enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
|
||||
int active;
|
||||
struct list_head list; /* scheduling list */
|
||||
atomic_t refcnt;
|
||||
struct net_device *dev;
|
||||
struct net_device_stats stats;
|
||||
/* Miscellaneous private stuff. */
|
||||
enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
|
||||
int active;
|
||||
struct list_head list; /* scheduling list */
|
||||
atomic_t refcnt;
|
||||
struct net_device *dev;
|
||||
struct net_device_stats stats;
|
||||
|
||||
struct work_struct free_work;
|
||||
struct work_struct free_work;
|
||||
} netif_t;
|
||||
|
||||
void netif_creditlimit(netif_t *netif);
|
||||
int netif_disconnect(netif_t *netif);
|
||||
|
||||
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
|
||||
void free_netif_callback(netif_t *netif);
|
||||
void free_netif(netif_t *netif);
|
||||
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
|
||||
unsigned long rx_ring_ref, unsigned int evtchn);
|
||||
|
||||
#define netif_get(_b) (atomic_inc(&(_b)->refcnt))
|
||||
#define netif_put(_b) \
|
||||
do { \
|
||||
if ( atomic_dec_and_test(&(_b)->refcnt) ) \
|
||||
free_netif_callback(_b); \
|
||||
} while (0)
|
||||
#define netif_put(_b) \
|
||||
do { \
|
||||
if ( atomic_dec_and_test(&(_b)->refcnt) ) \
|
||||
free_netif(_b); \
|
||||
} while (0)
|
||||
|
||||
void netif_xenbus_init(void);
|
||||
|
||||
@@ -123,3 +116,13 @@ struct net_device_stats *netif_be_get_stats(struct net_device *dev);
|
||||
irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);
|
||||
|
||||
#endif /* __NETIF__BACKEND__COMMON_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* indent-tabs-mode: t
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
||||
@@ -11,104 +11,105 @@
|
||||
|
||||
static void __netif_up(netif_t *netif)
|
||||
{
|
||||
struct net_device *dev = netif->dev;
|
||||
spin_lock_bh(&dev->xmit_lock);
|
||||
netif->active = 1;
|
||||
spin_unlock_bh(&dev->xmit_lock);
|
||||
(void)bind_evtchn_to_irqhandler(
|
||||
netif->evtchn, netif_be_int, 0, dev->name, netif);
|
||||
netif_schedule_work(netif);
|
||||
struct net_device *dev = netif->dev;
|
||||
spin_lock_bh(&dev->xmit_lock);
|
||||
netif->active = 1;
|
||||
spin_unlock_bh(&dev->xmit_lock);
|
||||
(void)bind_evtchn_to_irqhandler(
|
||||
netif->evtchn, netif_be_int, 0, dev->name, netif);
|
||||
netif_schedule_work(netif);
|
||||
}
|
||||
|
||||
static void __netif_down(netif_t *netif)
|
||||
{
|
||||
struct net_device *dev = netif->dev;
|
||||
spin_lock_bh(&dev->xmit_lock);
|
||||
netif->active = 0;
|
||||
spin_unlock_bh(&dev->xmit_lock);
|
||||
unbind_evtchn_from_irqhandler(netif->evtchn, netif);
|
||||
netif_deschedule_work(netif);
|
||||
struct net_device *dev = netif->dev;
|
||||
spin_lock_bh(&dev->xmit_lock);
|
||||
netif->active = 0;
|
||||
spin_unlock_bh(&dev->xmit_lock);
|
||||
unbind_evtchn_from_irqhandler(netif->evtchn, netif);
|
||||
netif_deschedule_work(netif);
|
||||
}
|
||||
|
||||
static int net_open(struct net_device *dev)
|
||||
{
|
||||
netif_t *netif = netdev_priv(dev);
|
||||
if (netif->status == CONNECTED)
|
||||
__netif_up(netif);
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
netif_t *netif = netdev_priv(dev);
|
||||
if (netif->status == CONNECTED)
|
||||
__netif_up(netif);
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int net_close(struct net_device *dev)
|
||||
{
|
||||
netif_t *netif = netdev_priv(dev);
|
||||
netif_stop_queue(dev);
|
||||
if (netif->status == CONNECTED)
|
||||
__netif_down(netif);
|
||||
return 0;
|
||||
netif_t *netif = netdev_priv(dev);
|
||||
netif_stop_queue(dev);
|
||||
if (netif->status == CONNECTED)
|
||||
__netif_down(netif);
|
||||
return 0;
|
||||
}
|
||||
|
||||
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
|
||||
{
|
||||
int err = 0, i;
|
||||
struct net_device *dev;
|
||||
netif_t *netif;
|
||||
char name[IFNAMSIZ] = {};
|
||||
int err = 0, i;
|
||||
struct net_device *dev;
|
||||
netif_t *netif;
|
||||
char name[IFNAMSIZ] = {};
|
||||
|
||||
snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
|
||||
dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
|
||||
if (dev == NULL) {
|
||||
DPRINTK("Could not create netif: out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle);
|
||||
dev = alloc_netdev(sizeof(netif_t), name, ether_setup);
|
||||
if (dev == NULL) {
|
||||
DPRINTK("Could not create netif: out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
netif = netdev_priv(dev);
|
||||
memset(netif, 0, sizeof(*netif));
|
||||
netif->domid = domid;
|
||||
netif->handle = handle;
|
||||
netif->status = DISCONNECTED;
|
||||
atomic_set(&netif->refcnt, 0);
|
||||
netif->dev = dev;
|
||||
netif = netdev_priv(dev);
|
||||
memset(netif, 0, sizeof(*netif));
|
||||
netif->domid = domid;
|
||||
netif->handle = handle;
|
||||
netif->status = DISCONNECTED;
|
||||
atomic_set(&netif->refcnt, 0);
|
||||
netif->dev = dev;
|
||||
|
||||
netif->credit_bytes = netif->remaining_credit = ~0UL;
|
||||
netif->credit_usec = 0UL;
|
||||
init_timer(&netif->credit_timeout);
|
||||
netif->credit_bytes = netif->remaining_credit = ~0UL;
|
||||
netif->credit_usec = 0UL;
|
||||
init_timer(&netif->credit_timeout);
|
||||
|
||||
dev->hard_start_xmit = netif_be_start_xmit;
|
||||
dev->get_stats = netif_be_get_stats;
|
||||
dev->open = net_open;
|
||||
dev->stop = net_close;
|
||||
dev->features = NETIF_F_NO_CSUM;
|
||||
dev->hard_start_xmit = netif_be_start_xmit;
|
||||
dev->get_stats = netif_be_get_stats;
|
||||
dev->open = net_open;
|
||||
dev->stop = net_close;
|
||||
dev->features = NETIF_F_NO_CSUM;
|
||||
|
||||
/* Disable queuing. */
|
||||
dev->tx_queue_len = 0;
|
||||
/* Disable queuing. */
|
||||
dev->tx_queue_len = 0;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
if (be_mac[i] != 0)
|
||||
break;
|
||||
if (i == ETH_ALEN) {
|
||||
/*
|
||||
* Initialise a dummy MAC address. We choose the numerically largest
|
||||
* non-broadcast address to prevent the address getting stolen by an
|
||||
* Ethernet bridge for STP purposes. (FE:FF:FF:FF:FF:FF)
|
||||
*/
|
||||
memset(dev->dev_addr, 0xFF, ETH_ALEN);
|
||||
dev->dev_addr[0] &= ~0x01;
|
||||
} else
|
||||
memcpy(dev->dev_addr, be_mac, ETH_ALEN);
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
if (be_mac[i] != 0)
|
||||
break;
|
||||
if (i == ETH_ALEN) {
|
||||
/*
|
||||
* Initialise a dummy MAC address. We choose the numerically
|
||||
* largest non-broadcast address to prevent the address getting
|
||||
* stolen by an Ethernet bridge for STP purposes.
|
||||
* (FE:FF:FF:FF:FF:FF)
|
||||
*/
|
||||
memset(dev->dev_addr, 0xFF, ETH_ALEN);
|
||||
dev->dev_addr[0] &= ~0x01;
|
||||
} else
|
||||
memcpy(dev->dev_addr, be_mac, ETH_ALEN);
|
||||
|
||||
rtnl_lock();
|
||||
err = register_netdevice(dev);
|
||||
rtnl_unlock();
|
||||
if (err) {
|
||||
DPRINTK("Could not register new net device %s: err=%d\n",
|
||||
dev->name, err);
|
||||
free_netdev(dev);
|
||||
return NULL;
|
||||
}
|
||||
rtnl_lock();
|
||||
err = register_netdevice(dev);
|
||||
rtnl_unlock();
|
||||
if (err) {
|
||||
DPRINTK("Could not register new net device %s: err=%d\n",
|
||||
dev->name, err);
|
||||
free_netdev(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DPRINTK("Successfully created netif\n");
|
||||
return netif;
|
||||
DPRINTK("Successfully created netif\n");
|
||||
return netif;
|
||||
}
|
||||
|
||||
static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
|
||||
@@ -116,191 +117,204 @@ static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
|
||||
unsigned long rx_ring_ref)
|
||||
{
|
||||
#ifdef CONFIG_XEN_NETDEV_GRANT
|
||||
struct gnttab_map_grant_ref op;
|
||||
struct gnttab_map_grant_ref op;
|
||||
|
||||
/* Map: Use the Grant table reference */
|
||||
op.host_addr = localaddr;
|
||||
op.flags = GNTMAP_host_map;
|
||||
op.ref = tx_ring_ref;
|
||||
op.dom = netif->domid;
|
||||
/* Map: Use the Grant table reference */
|
||||
op.host_addr = localaddr;
|
||||
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) );
|
||||
if (op.handle < 0) {
|
||||
DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n");
|
||||
return op.handle;
|
||||
}
|
||||
BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
|
||||
if (op.handle < 0) {
|
||||
DPRINTK(" Gnttab failure mapping tx_ring_ref!\n");
|
||||
return op.handle;
|
||||
}
|
||||
|
||||
netif->tx_shmem_ref = tx_ring_ref;
|
||||
netif->tx_shmem_handle = op.handle;
|
||||
netif->tx_shmem_vaddr = localaddr;
|
||||
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.flags = GNTMAP_host_map;
|
||||
op.ref = rx_ring_ref;
|
||||
op.dom = netif->domid;
|
||||
/* Map: Use the Grant table reference */
|
||||
op.host_addr = localaddr + 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) );
|
||||
if (op.handle < 0) {
|
||||
DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n");
|
||||
return op.handle;
|
||||
}
|
||||
BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
|
||||
if (op.handle < 0) {
|
||||
DPRINTK(" Gnttab failure mapping rx_ring_ref!\n");
|
||||
return op.handle;
|
||||
}
|
||||
|
||||
netif->rx_shmem_ref = rx_ring_ref;
|
||||
netif->rx_shmem_handle = op.handle;
|
||||
netif->rx_shmem_vaddr = localaddr + PAGE_SIZE;
|
||||
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;
|
||||
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,
|
||||
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);
|
||||
err |= direct_remap_pfn_range(
|
||||
&init_mm, localaddr + PAGE_SIZE,
|
||||
rx_ring_ref, PAGE_SIZE,
|
||||
prot, netif->domid);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
if (err)
|
||||
return err;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void unmap_frontend_pages(netif_t *netif)
|
||||
{
|
||||
#ifdef CONFIG_XEN_NETDEV_GRANT
|
||||
struct gnttab_unmap_grant_ref op;
|
||||
struct gnttab_unmap_grant_ref op;
|
||||
|
||||
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));
|
||||
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));
|
||||
|
||||
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));
|
||||
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
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
struct vm_struct *vma;
|
||||
evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain };
|
||||
int err;
|
||||
|
||||
vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
|
||||
if (vma == NULL)
|
||||
return -ENOMEM;
|
||||
vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP);
|
||||
if (vma == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref,
|
||||
rx_ring_ref);
|
||||
if (err) {
|
||||
vfree(vma->addr);
|
||||
return err;
|
||||
}
|
||||
err = map_frontend_pages(
|
||||
netif, (unsigned long)vma->addr, tx_ring_ref, rx_ring_ref);
|
||||
if (err) {
|
||||
vfree(vma->addr);
|
||||
return err;
|
||||
}
|
||||
|
||||
op.u.bind_interdomain.dom1 = DOMID_SELF;
|
||||
op.u.bind_interdomain.dom2 = netif->domid;
|
||||
op.u.bind_interdomain.port1 = 0;
|
||||
op.u.bind_interdomain.port2 = evtchn;
|
||||
err = HYPERVISOR_event_channel_op(&op);
|
||||
if (err) {
|
||||
unmap_frontend_pages(netif);
|
||||
vfree(vma->addr);
|
||||
return err;
|
||||
}
|
||||
op.u.bind_interdomain.dom1 = DOMID_SELF;
|
||||
op.u.bind_interdomain.dom2 = netif->domid;
|
||||
op.u.bind_interdomain.port1 = 0;
|
||||
op.u.bind_interdomain.port2 = evtchn;
|
||||
err = HYPERVISOR_event_channel_op(&op);
|
||||
if (err) {
|
||||
unmap_frontend_pages(netif);
|
||||
vfree(vma->addr);
|
||||
return err;
|
||||
}
|
||||
|
||||
netif->evtchn = op.u.bind_interdomain.port1;
|
||||
netif->remote_evtchn = evtchn;
|
||||
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->resp_prod = netif->rx->resp_prod = 0;
|
||||
netif_get(netif);
|
||||
wmb(); /* Other CPUs see new state before interface is started. */
|
||||
netif->tx = (netif_tx_interface_t *)vma->addr;
|
||||
netif->rx = (netif_rx_interface_t *)((char *)vma->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. */
|
||||
|
||||
rtnl_lock();
|
||||
netif->status = CONNECTED;
|
||||
wmb();
|
||||
if (netif_running(netif->dev))
|
||||
__netif_up(netif);
|
||||
rtnl_unlock();
|
||||
rtnl_lock();
|
||||
netif->status = CONNECTED;
|
||||
wmb();
|
||||
if (netif_running(netif->dev))
|
||||
__netif_up(netif);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_netif(void *arg)
|
||||
static void free_netif_callback(void *arg)
|
||||
{
|
||||
evtchn_op_t op = { .cmd = EVTCHNOP_close };
|
||||
netif_t *netif = (netif_t *)arg;
|
||||
evtchn_op_t op = { .cmd = EVTCHNOP_close };
|
||||
netif_t *netif = (netif_t *)arg;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
op.u.close.port = netif->evtchn;
|
||||
op.u.close.dom = DOMID_SELF;
|
||||
HYPERVISOR_event_channel_op(&op);
|
||||
op.u.close.port = netif->remote_evtchn;
|
||||
op.u.close.dom = netif->domid;
|
||||
HYPERVISOR_event_channel_op(&op);
|
||||
op.u.close.port = netif->evtchn;
|
||||
op.u.close.dom = DOMID_SELF;
|
||||
HYPERVISOR_event_channel_op(&op);
|
||||
op.u.close.port = netif->remote_evtchn;
|
||||
op.u.close.dom = netif->domid;
|
||||
HYPERVISOR_event_channel_op(&op);
|
||||
|
||||
unregister_netdev(netif->dev);
|
||||
unregister_netdev(netif->dev);
|
||||
|
||||
if (netif->tx) {
|
||||
unmap_frontend_pages(netif);
|
||||
vfree(netif->tx); /* Frees netif->rx as well. */
|
||||
}
|
||||
if (netif->tx) {
|
||||
unmap_frontend_pages(netif);
|
||||
vfree(netif->tx); /* Frees netif->rx as well. */
|
||||
}
|
||||
|
||||
free_netdev(netif->dev);
|
||||
free_netdev(netif->dev);
|
||||
}
|
||||
|
||||
void free_netif_callback(netif_t *netif)
|
||||
void free_netif(netif_t *netif)
|
||||
{
|
||||
INIT_WORK(&netif->free_work, free_netif, (void *)netif);
|
||||
schedule_work(&netif->free_work);
|
||||
INIT_WORK(&netif->free_work, free_netif_callback, (void *)netif);
|
||||
schedule_work(&netif->free_work);
|
||||
}
|
||||
|
||||
void netif_creditlimit(netif_t *netif)
|
||||
{
|
||||
#if 0
|
||||
/* Set the credit limit (reset remaining credit to new limit). */
|
||||
netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes;
|
||||
netif->credit_usec = creditlimit->period_usec;
|
||||
/* Set the credit limit (reset remaining credit to new limit). */
|
||||
netif->credit_bytes = creditlimit->credit_bytes;
|
||||
netif->remaining_credit = creditlimit->credit_bytes;
|
||||
netif->credit_usec = creditlimit->period_usec;
|
||||
|
||||
if (netif->status == CONNECTED) {
|
||||
/*
|
||||
* Schedule work so that any packets waiting under previous credit
|
||||
* limit are dealt with (acts like a replenishment point).
|
||||
*/
|
||||
netif->credit_timeout.expires = jiffies;
|
||||
netif_schedule_work(netif);
|
||||
}
|
||||
if (netif->status == CONNECTED) {
|
||||
/*
|
||||
* Schedule work so that any packets waiting under previous
|
||||
* credit limit are dealt with (acts as a replenishment point).
|
||||
*/
|
||||
netif->credit_timeout.expires = jiffies;
|
||||
netif_schedule_work(netif);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int netif_disconnect(netif_t *netif)
|
||||
{
|
||||
|
||||
if (netif->status == CONNECTED) {
|
||||
rtnl_lock();
|
||||
netif->status = DISCONNECTING;
|
||||
wmb();
|
||||
if (netif_running(netif->dev))
|
||||
__netif_down(netif);
|
||||
rtnl_unlock();
|
||||
netif_put(netif);
|
||||
return 0; /* Caller should not send response message. */
|
||||
}
|
||||
if (netif->status == CONNECTED) {
|
||||
rtnl_lock();
|
||||
netif->status = DISCONNECTING;
|
||||
wmb();
|
||||
if (netif_running(netif->dev))
|
||||
__netif_down(netif);
|
||||
rtnl_unlock();
|
||||
netif_put(netif);
|
||||
return 0; /* Caller should not send response message. */
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* indent-tabs-mode: t
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -294,3 +294,13 @@ void netif_xenbus_init(void)
|
||||
{
|
||||
xenbus_register_backend(&netback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* indent-tabs-mode: t
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
||||
File diff suppressed because it is too large.
Load diff
@@ -130,12 +130,12 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
|
||||
if ( (msg[j].va + (msg[j].npages<<PAGE_SHIFT)) > vma->vm_end )
|
||||
return -EINVAL;
|
||||
|
||||
if ( (rc = direct_remap_pfn_range(vma->vm_mm,
|
||||
msg[j].va&PAGE_MASK,
|
||||
msg[j].mfn,
|
||||
msg[j].npages<<PAGE_SHIFT,
|
||||
vma->vm_page_prot,
|
||||
mmapcmd.dom)) < 0 )
|
||||
if ( (rc = direct_remap_pfn_range(vma,
|
||||
msg[j].va&PAGE_MASK,
|
||||
msg[j].mfn,
|
||||
msg[j].npages<<PAGE_SHIFT,
|
||||
vma->vm_page_prot,
|
||||
mmapcmd.dom)) < 0 )
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ void make_pages_writable(void *va, unsigned int nr);
|
||||
#define kern_addr_valid(addr) (1)
|
||||
#endif /* !CONFIG_DISCONTIGMEM */
|
||||
|
||||
int direct_remap_pfn_range(struct mm_struct *mm,
|
||||
int direct_remap_pfn_range(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
unsigned long mfn,
|
||||
unsigned long size,
|
||||
@@ -474,10 +474,10 @@ int touch_pte_range(struct mm_struct *mm,
|
||||
unsigned long size);
|
||||
|
||||
#define io_remap_page_range(vma,from,phys,size,prot) \
|
||||
direct_remap_pfn_range(vma->vm_mm,from,phys>>PAGE_SHIFT,size,prot,DOMID_IO)
|
||||
direct_remap_pfn_range(vma,from,(phys)>>PAGE_SHIFT,size,prot,DOMID_IO)
|
||||
|
||||
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
|
||||
direct_remap_pfn_range(vma->vm_mm,from,pfn,size,prot,DOMID_IO)
|
||||
direct_remap_pfn_range(vma,from,pfn,size,prot,DOMID_IO)
|
||||
|
||||
#define MK_IOSPACE_PFN(space, pfn) (pfn)
|
||||
#define GET_IOSPACE(pfn) 0
|
||||
|
||||
@@ -526,7 +526,7 @@ extern int kern_addr_valid(unsigned long addr);
|
||||
|
||||
#define DOMID_LOCAL (0xFFFFU)
|
||||
|
||||
int direct_remap_pfn_range(struct mm_struct *mm,
|
||||
int direct_remap_pfn_range(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
unsigned long mfn,
|
||||
unsigned long size,
|
||||
@@ -542,10 +542,10 @@ int touch_pte_range(struct mm_struct *mm,
|
||||
unsigned long size);
|
||||
|
||||
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
|
||||
direct_remap_pfn_range((vma)->vm_mm,vaddr,paddr>>PAGE_SHIFT,size,prot,DOMID_IO)
|
||||
direct_remap_pfn_range(vma,vaddr,(paddr)>>PAGE_SHIFT,size,prot,DOMID_IO)
|
||||
|
||||
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
|
||||
direct_remap_pfn_range((vma)->vm_mm,vaddr,pfn,size,prot,DOMID_IO)
|
||||
direct_remap_pfn_range(vma,vaddr,pfn,size,prot,DOMID_IO)
|
||||
|
||||
#define MK_IOSPACE_PFN(space, pfn) (pfn)
|
||||
#define GET_IOSPACE(pfn) 0
|
||||
|
||||