/** * map frontend ring page * bind event channel * init **/ static int chrif_map(struct xen_chrif *chrif, unsigned long ring_ref, unsigned int evtchn) { int err; chrif_sring_t *sring; chrif->comms_area = alloc_vm_area(PAGE_SIZE, NULL); if(chrif->comms_area == NULL){ free_vm_area(chrif->comms_area); printk("\nxen: dom0: could not allocate shared_page"); return -ENOMEM; } err = map_frontend_pages(chrif, ring_ref); if(err){ free_vm_area(chrif->comms_area); printk("\nxen: dom0: map frontend page fail"); return err; } sring = (chrif_sring_t *)chrif->comms_area->addr; BACK_RING_INIT(&chrif->chr_ring, sring, PAGE_SIZE); err = bind_interdomain_evtchn_to_irqhandler(chrif->domid, evtchn, chrif_int, 0, "domtest2", chrif); if (err < 0) { printk(KERN_DEBUG "\nxen: dom0: chrif_int failed binding to evtchn"); unmap_frontend_pages(chrif); return -EFAULT; } chrif->irq = err; printk(KERN_DEBUG "\nxen: dom0:bind event channel fineshed: irq = %d\n", chrif->irq); printk("\nxen: dom0: chrif map finished, otherend_id"); return 0; }
int netif_map(netif_t *netif, unsigned long tx_ring_ref, unsigned long rx_ring_ref, unsigned int evtchn) { int err = -ENOMEM; netif_tx_sring_t *txs; netif_rx_sring_t *rxs; struct evtchn_bind_interdomain bind_interdomain; /* Already connected through? */ if (netif->irq) return 0; netif->tx_comms_area = alloc_vm_area(PAGE_SIZE); if (netif->tx_comms_area == NULL) return -ENOMEM; netif->rx_comms_area = alloc_vm_area(PAGE_SIZE); if (netif->rx_comms_area == NULL) goto err_rx; err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref); if (err) goto err_map; bind_interdomain.remote_dom = netif->domid; bind_interdomain.remote_port = evtchn; err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &bind_interdomain); if (err) goto err_hypervisor; netif->evtchn = bind_interdomain.local_port; netif->irq = bind_evtchn_to_irqhandler( netif->evtchn, netif_be_int, 0, netif->dev->name, netif); disable_irq(netif->irq); txs = (netif_tx_sring_t *)netif->tx_comms_area->addr; BACK_RING_INIT(&netif->tx, txs, PAGE_SIZE); rxs = (netif_rx_sring_t *) ((char *)netif->rx_comms_area->addr); BACK_RING_INIT(&netif->rx, rxs, PAGE_SIZE); netif->rx_req_cons_peek = 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(); return 0; err_hypervisor: unmap_frontend_pages(netif); err_map: free_vm_area(netif->rx_comms_area); err_rx: free_vm_area(netif->tx_comms_area); return err; }