# HG changeset patch # User sos22@xxxxxxxxxxxxxxxxxxxx # Date 1153175939 -3600 # Node ID aa3087ee5769d60d5ab1e368cc062233d364ec8b # Parent 7053592c928b488b0c653fb25ce6f73bc6deeb05 Frontend parts of PV-on-HVM patches. diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Jul 17 23:38:59 2006 +0100 @@ -46,6 +46,7 @@ #include #include #include +#include #define BLKIF_STATE_DISCONNECTED 0 #define BLKIF_STATE_CONNECTED 1 diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/core/gnttab.c --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Mon Jul 17 23:38:59 2006 +0100 @@ -41,6 +41,13 @@ #include #include #include +#include +#include + +#ifndef CONFIG_XEN +#include +#include +#endif /* External tools reserve first few grant table entries. */ #define NR_RESERVED_ENTRIES 8 @@ -350,6 +357,7 @@ void gnttab_cancel_free_callback(struct } EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback); +#ifdef CONFIG_XEN #ifndef __ia64__ static int map_pte_fn(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data) @@ -404,23 +412,49 @@ int gnttab_resume(void) shared = __va(frames[0] << PAGE_SHIFT); printk("grant table at %p\n", shared); #endif - - return 0; -} +} +#else /* !CONFIG_XEN */ +int +gnttab_resume(void) +{ + unsigned long frames; + int x; + struct xen_add_to_physmap xatp; + + frames = alloc_xen_mmio(PAGE_SIZE * NR_GRANT_FRAMES); + shared = ioremap(frames, PAGE_SIZE * NR_GRANT_FRAMES); + if(!shared){ + printk("error to ioremap gnttab share frames\n"); + return -1; + } + for (x = 0; x < NR_GRANT_FRAMES; x++) { + xatp.domid = DOMID_SELF; + xatp.idx = x; + xatp.space = XENMAPSPACE_grant_table; + xatp.gpfn = (frames >> PAGE_SHIFT) + x; + BUG_ON(HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)); + } + return 0; +} +#endif int gnttab_suspend(void) { #ifndef __ia64__ +#ifdef CONFIG_XEN apply_to_page_range(&init_mm, (unsigned long)shared, PAGE_SIZE * NR_GRANT_FRAMES, unmap_pte_fn, NULL); -#endif - - return 0; -} - -static int __init gnttab_init(void) +#else + iounmap(shared); +#endif +#endif + + return 0; +} + +int __init gnttab_init(void) { int i; @@ -439,4 +473,6 @@ static int __init gnttab_init(void) return 0; } +#ifdef CONFIG_XEN core_initcall(gnttab_init); +#endif diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c Mon Jul 17 23:38:59 2006 +0100 @@ -1,4 +1,5 @@ +#include #include #include #include @@ -12,6 +13,7 @@ struct proc_dir_entry *create_xen_proc_e panic("Couldn't create /proc/xen"); return create_proc_entry(name, mode, xen_base); } +EXPORT_SYMBOL(create_xen_proc_entry); void remove_xen_proc_entry(const char *name) { diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Jul 17 23:38:59 2006 +0100 @@ -61,6 +61,25 @@ #include #include #include +#include + +/* If we don't have GSO, fake things up so that we never try to use + it */ +#ifndef NETIF_F_GSO +#define netif_needs_gso(dev, skb) 0 +#define NETIF_F_GSO_ROBUST 0 +#define NETIF_F_GSO_SHIFT 16 +#else +#define HAVE_GSO +#endif + +#ifdef CONFIG_XEN +#define SKB_PROTO_DATA_VALID(skb) (skb)->proto_data_valid +#define SET_SKB_PROTO_DATA_VALID(skb, v) do { (skb)->proto_data_valid = (v); } while (0) +#else +#define SKB_PROTO_DATA_VALID(skb) 0 +#define SET_SKB_PROTO_DATA_VALID(skb, v) do {} while (0) +#endif #define GRANT_INVALID_REF 0 @@ -88,6 +107,7 @@ struct netfront_info { unsigned int handle; unsigned int evtchn, irq; + unsigned int copyall; /* Receive-ring batched refills. */ #define RX_MIN_TARGET 8 @@ -148,7 +168,7 @@ static inline unsigned short get_id_from static int talk_to_backend(struct xenbus_device *, struct netfront_info *); static int setup_device(struct xenbus_device *, struct netfront_info *); -static struct net_device *create_netdev(int, struct xenbus_device *); +static struct net_device *create_netdev(int, int, struct xenbus_device *); static void netfront_closing(struct xenbus_device *); @@ -190,14 +210,41 @@ static int __devinit netfront_probe(stru struct net_device *netdev; struct netfront_info *info; unsigned int handle; +#ifndef CONFIG_XEN + unsigned feature_rx_flags; +#endif + unsigned feature_rx_copy; err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle); if (err != 1) { xenbus_dev_fatal(dev, err, "reading handle"); return err; } - - netdev = create_netdev(handle, dev); +#ifndef CONFIG_XEN + err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flags", "%u", + &feature_rx_flags); + if (err == 1) { + err = xenbus_scanf(XBT_NIL, + dev->otherend, + "feature-rx-copy", + "%u", + &feature_rx_copy); + if (err != 1) { + feature_rx_copy = 0; + err = EINVAL; + } + } else { + feature_rx_copy = feature_rx_flags = 0; + } + if (!feature_rx_copy) { + xenbus_dev_fatal(dev, err, "need a copy-capable backend"); + return err; + } +#else + feature_rx_copy = 0; +#endif + + netdev = create_netdev(handle, feature_rx_copy, dev); if (IS_ERR(netdev)) { err = PTR_ERR(netdev); xenbus_dev_fatal(dev, err, "creating netdev"); @@ -300,6 +347,19 @@ again: "event-channel", "%u", info->evtchn); if (err) { message = "writing event-channel"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "use-rx-flags", "%u", 1); + if (err) { + message = "writing use-rx-flags"; + goto abort_transaction; + } + + err = xenbus_printf(xbt, dev->nodename, "copy-delivery-offset", "%u", + 16); + if (err) { + message = "writing copy-delivery-offset"; goto abort_transaction; } @@ -550,6 +610,8 @@ static void network_alloc_rx_buffers(str RING_IDX req_prod = np->rx.req_prod_pvt; struct xen_memory_reservation reservation; grant_ref_t ref; + netif_rx_request_t *req; + int nr_flips; if (unlikely(!netif_carrier_ok(dev))) return; @@ -592,7 +654,7 @@ static void network_alloc_rx_buffers(str np->rx_target = np->rx_max_target; refill: - for (i = 0; ; i++) { + for (nr_flips = i = 0; ; i++) { if ((skb = __skb_dequeue(&np->rx_batch)) == NULL) break; @@ -602,17 +664,78 @@ static void network_alloc_rx_buffers(str np->rx_skbs[id] = skb; - RING_GET_REQUEST(&np->rx, req_prod + i)->id = id; ref = gnttab_claim_grant_reference(&np->gref_rx_head); BUG_ON((signed short)ref < 0); np->grant_rx_ref[id] = ref; - gnttab_grant_foreign_transfer_ref(ref, - np->xbdev->otherend_id, - __pa(skb->head)>>PAGE_SHIFT); - RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref; - np->rx_pfn_array[i] = virt_to_mfn(skb->head); + + req = RING_GET_REQUEST(&np->rx, req_prod + i); + if ( !np->copyall ) { + gnttab_grant_foreign_transfer_ref(ref, + np->xbdev->otherend_id, + __pa(skb->head) >> PAGE_SHIFT); + np->rx_pfn_array[nr_flips] = virt_to_mfn(skb->head); + + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* Remove this page from map before + * passing back to Xen. */ + set_phys_to_machine(__pa(skb->head) >> + PAGE_SHIFT, + INVALID_P2M_ENTRY); + + MULTI_update_va_mapping(np->rx_mcl+nr_flips, + (unsigned long)skb->head, + __pte(0), 0); + } + nr_flips++; + req->flags = 0; + } else { + gnttab_grant_foreign_access_ref(ref, + np->xbdev->otherend_id, + virt_to_mfn(skb->head), + 0); + req->flags = NETIF_RXRF_copy_packet; + } + req->gref = ref; + req->id = id; + } + + if ( nr_flips != 0 ) { + set_xen_guest_handle(reservation.extent_start, + np->rx_pfn_array); + reservation.nr_extents = nr_flips; + reservation.extent_order = 0; + reservation.address_bits = 0; + reservation.domid = DOMID_SELF; + + /* Tell the ballon driver what is going on. */ + balloon_update_driver_allowance(nr_flips); if (!xen_feature(XENFEAT_auto_translated_physmap)) { + /* After all PTEs have been zapped, flush the + * TLB. */ + np->rx_mcl[nr_flips-1].args[MULTI_UVMFLAGS_INDEX] = + UVMF_TLB_FLUSH|UVMF_ALL; + + /* Give away a batch of pages. */ + np->rx_mcl[nr_flips].op = __HYPERVISOR_memory_op; + np->rx_mcl[nr_flips].args[0] = + XENMEM_decrease_reservation; + np->rx_mcl[nr_flips].args[1] = + (unsigned long)&reservation; + + /* Zap PTEs and give away pages in one big + * multicall. */ + (void)HYPERVISOR_multicall(np->rx_mcl, nr_flips + 1); + + /* Check return status of + * HYPERVISOR_memory_op(). */ + if (unlikely(np->rx_mcl[nr_flips].result != nr_flips)) + panic("Unable to reduce memory reservation (%ld,%d)\n", + np->rx_mcl[nr_flips].result, nr_flips); + } else { + if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation) != i) + panic("Unable to reduce memory reservation\n"); /* Remove this page before passing back to Xen. */ set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, INVALID_P2M_ENTRY); @@ -620,37 +743,9 @@ static void network_alloc_rx_buffers(str (unsigned long)skb->head, __pte(0), 0); } - } - - /* Tell the ballon driver what is going on. */ - balloon_update_driver_allowance(i); - - set_xen_guest_handle(reservation.extent_start, np->rx_pfn_array); - reservation.nr_extents = i; - reservation.extent_order = 0; - reservation.address_bits = 0; - reservation.domid = DOMID_SELF; - - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - /* After all PTEs have been zapped, flush the TLB. */ - np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = - UVMF_TLB_FLUSH|UVMF_ALL; - - /* Give away a batch of pages. */ - np->rx_mcl[i].op = __HYPERVISOR_memory_op; - np->rx_mcl[i].args[0] = XENMEM_decrease_reservation; - np->rx_mcl[i].args[1] = (unsigned long)&reservation; - - /* Zap PTEs and give away pages in one big multicall. */ - (void)HYPERVISOR_multicall(np->rx_mcl, i+1); - - /* Check return status of HYPERVISOR_memory_op(). */ - if (unlikely(np->rx_mcl[i].result != i)) - panic("Unable to reduce memory reservation\n"); - } else - if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation) != i) - panic("Unable to reduce memory reservation\n"); + } else { + wmb(); + } /* Above is a suitable barrier to ensure backend will see requests. */ np->rx.req_prod_pvt = req_prod + i; @@ -774,9 +869,10 @@ static int network_start_xmit(struct sk_ if (skb->ip_summed == CHECKSUM_HW) /* local packet? */ tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; - if (skb->proto_data_valid) /* remote but checksummed? */ + if (SKB_PROTO_DATA_VALID(skb)) /* remote but checksummed? */ tx->flags |= NETTXF_data_validated; +#ifdef HAVE_GSO if (skb_shinfo(skb)->gso_size) { struct netif_extra_info *gso = (struct netif_extra_info *) RING_GET_REQUEST(&np->tx, ++i); @@ -793,6 +889,7 @@ static int network_start_xmit(struct sk_ gso->flags = 0; extra = gso; } +#endif np->tx.req_prod_pvt = i + 1; @@ -852,6 +949,8 @@ static int netif_poll(struct net_device unsigned long flags; unsigned long mfn; grant_ref_t ref; + unsigned long ret; + netif_rx_request_t *req; spin_lock(&np->rx_lock); @@ -883,25 +982,50 @@ static int netif_poll(struct net_device continue; } - /* Memory pressure, insufficient buffer headroom, ... */ - if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) { - if (net_ratelimit()) - WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n", - rx->id, rx->status); - RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = - rx->id; - RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = - ref; - np->rx.req_prod_pvt++; - RING_PUSH_REQUESTS(&np->rx); - work_done--; - continue; + skb = np->rx_skbs[rx->id]; + + if ( !np->copyall ) { + /* Memory pressure, insufficient buffer + * headroom, ... */ + if ((mfn = gnttab_end_foreign_transfer_ref(ref)) == 0) + { + if (net_ratelimit()) + WPRINTK("Unfulfilled rx req (id=%d, st=%d).\n", + rx->id, rx->status); + req = RING_GET_REQUEST(&np->rx, + np->rx.req_prod_pvt); + req->id = rx->id; + req->gref = ref; + np->rx.req_prod_pvt++; + RING_PUSH_REQUESTS(&np->rx); + work_done--; + continue; + } + /* Remap the page. */ + if (!xen_feature(XENFEAT_auto_translated_physmap)) { + MULTI_update_va_mapping(mcl, + (unsigned long)skb->head, + pfn_pte_ma(mfn, + PAGE_KERNEL), + 0); + mcl++; + mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) + | MMU_MACHPHYS_UPDATE; + mmu->val = __pa(skb->head) >> PAGE_SHIFT; + mmu++; + + set_phys_to_machine(__pa(skb->head) + >> PAGE_SHIFT, + mfn); + } + } else { + ret = gnttab_end_foreign_access_ref(ref, 0); + BUG_ON(!ret); } gnttab_release_grant_reference(&np->gref_rx_head, ref); np->grant_rx_ref[rx->id] = GRANT_INVALID_REF; - skb = np->rx_skbs[rx->id]; add_id_to_freelist(np->rx_skbs, rx->id); /* NB. We handle skb overflow later. */ @@ -915,30 +1039,16 @@ static int netif_poll(struct net_device */ if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) { skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->proto_data_valid = 1; + SET_SKB_PROTO_DATA_VALID(skb, 1); } else { skb->ip_summed = CHECKSUM_NONE; - skb->proto_data_valid = 0; + SET_SKB_PROTO_DATA_VALID(skb, 0); } +#ifdef CONFIG_XEN skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank); - +#endif np->stats.rx_packets++; np->stats.rx_bytes += rx->status; - - if (!xen_feature(XENFEAT_auto_translated_physmap)) { - /* Remap the page. */ - MULTI_update_va_mapping(mcl, (unsigned long)skb->head, - pfn_pte_ma(mfn, PAGE_KERNEL), - 0); - mcl++; - mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) - | MMU_MACHPHYS_UPDATE; - mmu->val = __pa(skb->head) >> PAGE_SHIFT; - mmu++; - - set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, - mfn); - } __skb_queue_tail(&rxq, skb); } @@ -996,8 +1106,11 @@ static int netif_poll(struct net_device /* Copy any other fields we already set up. */ nskb->dev = skb->dev; nskb->ip_summed = skb->ip_summed; - nskb->proto_data_valid = skb->proto_data_valid; + SET_SKB_PROTO_DATA_VALID(nskb, + SKB_PROTO_DATA_VALID(skb)); +#ifdef CONFIG_XEN nskb->proto_csum_blank = skb->proto_csum_blank; +#endif } /* Reinitialise and then destroy the old skbuff. */ @@ -1126,6 +1239,8 @@ static void network_connect(struct net_d struct netfront_info *np = netdev_priv(dev); int i, requeue_idx; struct sk_buff *skb; + grant_ref_t gref; + netif_rx_request_t *req; xennet_set_features(dev); @@ -1159,13 +1274,21 @@ static void network_connect(struct net_d for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) { if ((unsigned long)np->rx_skbs[i] < PAGE_OFFSET) continue; - gnttab_grant_foreign_transfer_ref( - np->grant_rx_ref[i], np->xbdev->otherend_id, - __pa(np->rx_skbs[i]->data) >> PAGE_SHIFT); - RING_GET_REQUEST(&np->rx, requeue_idx)->gref = - np->grant_rx_ref[i]; - RING_GET_REQUEST(&np->rx, requeue_idx)->id = i; - requeue_idx++; + gref = np->grant_rx_ref[i]; + skb = np->rx_skbs[i]; + if ( !np->copyall ) { + gnttab_grant_foreign_transfer_ref( + gref, np->xbdev->otherend_id, + __pa(skb->data) >> PAGE_SHIFT); + } else { + gnttab_grant_foreign_access_ref( + gref, np->xbdev->otherend_id, + virt_to_mfn(skb->data), 0); + } + req = RING_GET_REQUEST(&np->rx, requeue_idx); + req->gref = gref; + req->id = i; + requeue_idx++; } np->rx.req_prod_pvt = requeue_idx; @@ -1348,10 +1471,13 @@ static void network_set_multicast_list(s /** Create a network device. * @param handle device handle + * @param copyall flag; 1 if every packet must be copied, 0 if every packet + * must be flipped. * @param val return parameter for created device * @return 0 on success, error code otherwise */ static struct net_device * __devinit create_netdev(int handle, + int copyall, struct xenbus_device *dev) { int i, err = 0; @@ -1368,6 +1494,7 @@ static struct net_device * __devinit cre np = netdev_priv(netdev); np->handle = handle; np->xbdev = dev; + np->copyall = copyall; netif_carrier_off(netdev); @@ -1418,7 +1545,11 @@ static struct net_device * __devinit cre netdev->uninit = netif_uninit; netdev->change_mtu = xennet_change_mtu; netdev->weight = 64; +#ifdef CONFIG_XEN netdev->features = NETIF_F_IP_CSUM; +#else + netdev->features = 0; +#endif SET_ETHTOOL_OPS(netdev, &network_ethtool_ops); SET_MODULE_OWNER(netdev); @@ -1581,8 +1712,10 @@ static int __init netif_init(void) if (!is_running_on_xen()) return -ENODEV; +#ifdef CONFIG_XEN if (xen_start_info->flags & SIF_INITDOMAIN) return 0; +#endif IPRINTK("Initialising virtual ethernet driver.\n"); diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Mon Jul 17 23:38:59 2006 +0100 @@ -39,6 +39,8 @@ #include #include "xenbus_comms.h" +void *shared_xenstore_buf; + static int xenbus_irq; extern void xenbus_probe(void *); @@ -49,7 +51,7 @@ DECLARE_WAIT_QUEUE_HEAD(xb_waitq); static inline struct xenstore_domain_interface *xenstore_domain_interface(void) { - return mfn_to_virt(xen_start_info->store_mfn); + return shared_xenstore_buf; } static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs) @@ -129,7 +131,7 @@ int xb_write(const void *data, unsigned intf->req_prod += avail; /* This implies mb() before other side sees interrupt. */ - notify_remote_via_evtchn(xen_start_info->store_evtchn); + notify_remote_via_evtchn(xen_store_evtchn); } return 0; @@ -180,7 +182,7 @@ int xb_read(void *data, unsigned len) pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); /* Implies mb(): they will see new header. */ - notify_remote_via_evtchn(xen_start_info->store_evtchn); + notify_remote_via_evtchn(xen_store_evtchn); } return 0; @@ -195,7 +197,7 @@ int xb_init_comms(void) unbind_from_irqhandler(xenbus_irq, &xb_waitq); err = bind_evtchn_to_irqhandler( - xen_start_info->store_evtchn, wake_waiting, + xen_store_evtchn, wake_waiting, 0, "xenbus", &xb_waitq); if (err <= 0) { printk(KERN_ERR "XENBUS request irq failed %i\n", err); diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.h Mon Jul 17 23:38:59 2006 +0100 @@ -39,5 +39,7 @@ int xb_read(void *data, unsigned len); int xb_read(void *data, unsigned len); int xs_input_avail(void); extern wait_queue_head_t xb_waitq; +extern void *shared_xenstore_buf; +extern int xen_store_evtchn; #endif /* _XENBUS_COMMS_H */ diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Jul 17 23:38:59 2006 +0100 @@ -48,6 +48,7 @@ #include #include #include +#include struct xenbus_dev_transaction { struct list_head list; @@ -181,7 +182,7 @@ static int xenbus_dev_open(struct inode { struct xenbus_dev_data *u; - if (xen_start_info->store_evtchn == 0) + if (xen_store_evtchn == 0) return -ENOENT; nonseekable_open(inode, filp); @@ -232,7 +233,7 @@ static struct file_operations xenbus_dev .poll = xenbus_dev_poll, }; -static int __init +int __init xenbus_dev_init(void) { xenbus_dev_intf = create_xen_proc_entry("xenbus", 0400); @@ -242,4 +243,6 @@ xenbus_dev_init(void) return 0; } +#ifndef MODULE __initcall(xenbus_dev_init); +#endif diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Jul 17 23:38:59 2006 +0100 @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -51,8 +52,12 @@ #include #include #include +#include #include "xenbus_comms.h" + +int xen_store_evtchn; +static unsigned long xen_store_mfn; extern struct mutex xenwatch_mutex; @@ -915,8 +920,7 @@ static int xsd_kva_mmap(struct file *fil if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0)) return -EINVAL; - if (remap_pfn_range(vma, vma->vm_start, - mfn_to_pfn(xen_start_info->store_mfn), + if (remap_pfn_range(vma, vma->vm_start, mfn_to_pfn(xen_store_mfn), size, vma->vm_page_prot)) return -EAGAIN; @@ -928,7 +932,7 @@ static int xsd_kva_read(char *page, char { int len; - len = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn)); + len = sprintf(page, "0x%p", mfn_to_virt(xen_store_mfn)); *eof = 1; return len; } @@ -938,12 +942,11 @@ static int xsd_port_read(char *page, cha { int len; - len = sprintf(page, "%d", xen_start_info->store_evtchn); + len = sprintf(page, "%d", xen_store_evtchn); *eof = 1; return len; } #endif - static int __init xenbus_probe_init(void) { @@ -962,7 +965,11 @@ static int __init xenbus_probe_init(void /* * Domain0 doesn't have a store_evtchn or store_mfn yet. */ +#ifdef CONFIG_XEN dom0 = (xen_start_info->store_evtchn == 0); +#else + dom0 = 0; +#endif if (dom0) { struct evtchn_alloc_unbound alloc_unbound; @@ -972,7 +979,7 @@ static int __init xenbus_probe_init(void if (!page) return -ENOMEM; - xen_start_info->store_mfn = + xen_store_mfn = pfn_to_mfn(virt_to_phys((void *)page) >> PAGE_SHIFT); @@ -985,7 +992,7 @@ static int __init xenbus_probe_init(void if (err == -ENOSYS) goto err; BUG_ON(err); - xen_start_info->store_evtchn = alloc_unbound.port; + xen_store_evtchn = alloc_unbound.port; #ifdef CONFIG_PROC_FS /* And finally publish the above info in /proc/xen */ @@ -1001,8 +1008,21 @@ static int __init xenbus_probe_init(void if (xsd_port_intf) xsd_port_intf->read_proc = xsd_port_read; #endif - } else + shared_xenstore_buf = mfn_to_virt(xen_store_mfn); + } else { xenstored_ready = 1; +#ifdef CONFIG_XEN + xen_store_evtchn = xen_start_info->store_evtchn; + xen_store_mfn = xen_start_info->store_mfn; + shared_xenstore_buf = mfn_to_virt(xen_store_mfn); +#else + xen_store_evtchn = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN); + xen_store_mfn = hvm_get_parameter(HVM_PARAM_STORE_PFN); + shared_xenstore_buf = ioremap(xen_store_mfn << PAGE_SHIFT, + PAGE_SIZE); + xenbus_dev_init(); +#endif + } /* Initialize the interface to xenstore. */ err = xs_init(); @@ -1035,8 +1055,10 @@ static int __init xenbus_probe_init(void } postcore_initcall(xenbus_probe_init); - - +MODULE_LICENSE("Dual BSD/GPL"); + + +#ifndef MODULE static int is_disconnected_device(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); @@ -1105,3 +1127,4 @@ static int __init wait_for_devices(void) } late_initcall(wait_for_devices); +#endif diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon Jul 17 23:38:59 2006 +0100 @@ -42,6 +42,7 @@ #define __STR(x) #x #define STR(x) __STR(x) +#ifdef CONFIG_XEN #define _hypercall0(type, name) \ ({ \ long __res; \ @@ -114,6 +115,92 @@ : "memory" ); \ (type)__res; \ }) +#else +#define _hypercall0(type, name) \ +({ \ + long __res; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res) \ + : \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall1(type, name, a1) \ +({ \ + long __res, __ign1; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res), "=b" (__ign1) \ + : "1" ((long)(a1)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall2(type, name, a1, a2) \ +({ \ + long __res, __ign1, __ign2; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ + : "1" ((long)(a1)), "2" ((long)(a2)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall3(type, name, a1, a2, a3) \ +({ \ + long __res, __ign1, __ign2, __ign3; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall4(type, name, a1, a2, a3, a4) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)), "4" ((long)(a4)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ + asm volatile ( \ + "movl hypercall_page, %%eax\n" \ + "addl $"STR(__HYPERVISOR_##name)" * 32, %%eax\n"\ + "call *%%eax" \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ + : "1" ((long)(a1)), "2" ((long)(a2)), \ + "3" ((long)(a3)), "4" ((long)(a4)), \ + "5" ((long)(a5)) \ + : "memory" ); \ + (type)__res; \ +}) +#endif static inline int HYPERVISOR_set_trap_table( @@ -354,6 +441,13 @@ HYPERVISOR_nmi_op( return _hypercall2(int, nmi_op, op, arg); } +static inline unsigned long +HYPERVISOR_hvm_op( + int op, void *arg) +{ + return _hypercall2(unsigned long, hvm_op, op, arg); +} + static inline int HYPERVISOR_callback_op( int cmd, void *arg) diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Mon Jul 17 23:38:59 2006 +0100 @@ -20,6 +20,7 @@ #include #include #include +#include #define arch_free_page(_page,_order) \ ({ int foreign = PageForeign(_page); \ @@ -59,123 +60,6 @@ #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) - -/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/ -#define INVALID_P2M_ENTRY (~0UL) -#define FOREIGN_FRAME_BIT (1UL<<31) -#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT) - -extern unsigned long *phys_to_machine_mapping; - -#undef machine_to_phys_mapping -extern unsigned long *machine_to_phys_mapping; -extern unsigned int machine_to_phys_order; - -static inline unsigned long pfn_to_mfn(unsigned long pfn) -{ - if (xen_feature(XENFEAT_auto_translated_physmap)) - return pfn; - return phys_to_machine_mapping[(unsigned int)(pfn)] & - ~FOREIGN_FRAME_BIT; -} - -static inline int phys_to_machine_mapping_valid(unsigned long pfn) -{ - if (xen_feature(XENFEAT_auto_translated_physmap)) - return 1; - return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY); -} - -static inline unsigned long mfn_to_pfn(unsigned long mfn) -{ - extern unsigned long max_mapnr; - unsigned long pfn; - - if (xen_feature(XENFEAT_auto_translated_physmap)) - return mfn; - - if (unlikely((mfn >> machine_to_phys_order) != 0)) - return max_mapnr; - - /* The array access can fail (e.g., device space beyond end of RAM). */ - asm ( - "1: movl %1,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3: movl %2,%0\n" - " jmp 2b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,3b\n" - ".previous" - : "=r" (pfn) - : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) ); - - return pfn; -} - -/* - * We detect special mappings in one of two ways: - * 1. If the MFN is an I/O page then Xen will set the m2p entry - * to be outside our maximum possible pseudophys range. - * 2. If the MFN belongs to a different domain then we will certainly - * not have MFN in our p2m table. Conversely, if the page is ours, - * then we'll have p2m(m2p(MFN))==MFN. - * If we detect a special mapping then it doesn't have a 'struct page'. - * We force !pfn_valid() by returning an out-of-range pointer. - * - * NB. These checks require that, for any MFN that is not in our reservation, - * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if - * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN. - * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety. - * - * NB2. When deliberately mapping foreign pages into the p2m table, you *must* - * use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we - * require. In all the cases we care about, the FOREIGN_FRAME bit is - * masked (e.g., pfn_to_mfn()) so behaviour there is correct. - */ -static inline unsigned long mfn_to_local_pfn(unsigned long mfn) -{ - extern unsigned long max_mapnr; - unsigned long pfn = mfn_to_pfn(mfn); - if ((pfn < max_mapnr) - && !xen_feature(XENFEAT_auto_translated_physmap) - && (phys_to_machine_mapping[pfn] != mfn)) - return max_mapnr; /* force !pfn_valid() */ - return pfn; -} - -static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn) -{ - if (xen_feature(XENFEAT_auto_translated_physmap)) { - BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); - return; - } - phys_to_machine_mapping[pfn] = mfn; -} - -/* Definitions for machine and pseudophysical addresses. */ -#ifdef CONFIG_X86_PAE -typedef unsigned long long paddr_t; -typedef unsigned long long maddr_t; -#else -typedef unsigned long paddr_t; -typedef unsigned long maddr_t; -#endif - -static inline maddr_t phys_to_machine(paddr_t phys) -{ - maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT); - machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); - return machine; -} -static inline paddr_t machine_to_phys(maddr_t machine) -{ - paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT); - phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); - return phys; -} /* * These are used to make use of C type-checking.. @@ -254,7 +138,6 @@ static inline unsigned long pgd_val(pgd_ #define pgprot_val(x) ((x).pgprot) -#define __pte_ma(x) ((pte_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) #endif /* !__ASSEMBLY__ */ @@ -323,11 +206,6 @@ extern int page_is_ram(unsigned long pag ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -/* VIRT <-> MACHINE conversion */ -#define virt_to_machine(v) (phys_to_machine(__pa(v))) -#define virt_to_mfn(v) (pfn_to_mfn(__pa(v) >> PAGE_SHIFT)) -#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) - #define __HAVE_ARCH_GATE_AREA 1 #endif /* __KERNEL__ */ diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h Mon Jul 17 23:38:59 2006 +0100 @@ -45,7 +45,6 @@ #define pte_none(x) (!(x).pte_low) #define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) /* diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h Mon Jul 17 23:38:59 2006 +0100 @@ -151,18 +151,6 @@ static inline int pte_none(pte_t pte) extern unsigned long long __supported_pte_mask; -static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot) -{ - pte_t pte; - - pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \ - (pgprot_val(pgprot) >> 32); - pte.pte_high &= (__supported_pte_mask >> 32); - pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \ - __supported_pte_mask; - return pte; -} - static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { return pfn_pte_ma(pfn_to_mfn(page_nr), pgprot); diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/xen/xenbus.h --- a/linux-2.6-xen-sparse/include/xen/xenbus.h Mon Jul 17 23:34:46 2006 +0100 +++ b/linux-2.6-xen-sparse/include/xen/xenbus.h Mon Jul 17 23:38:59 2006 +0100 @@ -295,5 +295,6 @@ void xenbus_dev_fatal(struct xenbus_devi void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...); +int __init xenbus_dev_init(void); #endif /* _XEN_XENBUS_H */ diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/maddr.h Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,153 @@ +#ifndef _I386_MADDR_H +#define _I386_MADDR_H + +#include +#include +#include + +/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/ +#define INVALID_P2M_ENTRY (~0UL) +#define FOREIGN_FRAME_BIT (1UL<<31) +#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT) + +extern unsigned long *phys_to_machine_mapping; + +#undef machine_to_phys_mapping +extern unsigned long *machine_to_phys_mapping; +extern unsigned int machine_to_phys_order; + +static inline unsigned long pfn_to_mfn(unsigned long pfn) +{ + if (xen_feature(XENFEAT_auto_translated_physmap)) + return pfn; + return phys_to_machine_mapping[(unsigned int)(pfn)] & + ~FOREIGN_FRAME_BIT; +} + +static inline int phys_to_machine_mapping_valid(unsigned long pfn) +{ + if (xen_feature(XENFEAT_auto_translated_physmap)) + return 1; + return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY); +} + +static inline unsigned long mfn_to_pfn(unsigned long mfn) +{ +#ifdef CONFIG_XEN + extern unsigned long max_mapnr; + unsigned long pfn; +#endif + if (xen_feature(XENFEAT_auto_translated_physmap)) + return mfn; + +#ifndef CONFIG_XEN + BUG(); +#else + if (unlikely((mfn >> machine_to_phys_order) != 0)) + return max_mapnr; + + /* The array access can fail (e.g., device space beyond end of RAM). */ + asm ( + "1: movl %1,%0\n" + "2:\n" + ".section .fixup,\"ax\"\n" + "3: movl %2,%0\n" + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,3b\n" + ".previous" + : "=r" (pfn) + : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) ); + + return pfn; +#endif +} + +/* + * We detect special mappings in one of two ways: + * 1. If the MFN is an I/O page then Xen will set the m2p entry + * to be outside our maximum possible pseudophys range. + * 2. If the MFN belongs to a different domain then we will certainly + * not have MFN in our p2m table. Conversely, if the page is ours, + * then we'll have p2m(m2p(MFN))==MFN. + * If we detect a special mapping then it doesn't have a 'struct page'. + * We force !pfn_valid() by returning an out-of-range pointer. + * + * NB. These checks require that, for any MFN that is not in our reservation, + * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if + * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN. + * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety. + * + * NB2. When deliberately mapping foreign pages into the p2m table, you *must* + * use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we + * require. In all the cases we care about, the FOREIGN_FRAME bit is + * masked (e.g., pfn_to_mfn()) so behaviour there is correct. + */ +static inline unsigned long mfn_to_local_pfn(unsigned long mfn) +{ + extern unsigned long max_mapnr; + unsigned long pfn = mfn_to_pfn(mfn); + if ((pfn < max_mapnr) + && !xen_feature(XENFEAT_auto_translated_physmap) + && (phys_to_machine_mapping[pfn] != mfn)) + return max_mapnr; /* force !pfn_valid() */ + return pfn; +} + +static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn) +{ + if (xen_feature(XENFEAT_auto_translated_physmap)) { + BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); + return; + } + phys_to_machine_mapping[pfn] = mfn; +} + +/* Definitions for machine and pseudophysical addresses. */ +#ifdef CONFIG_X86_PAE +typedef unsigned long long paddr_t; +typedef unsigned long long maddr_t; +#else +typedef unsigned long paddr_t; +typedef unsigned long maddr_t; +#endif + +static inline maddr_t phys_to_machine(paddr_t phys) +{ + maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT); + machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); + return machine; +} +static inline paddr_t machine_to_phys(maddr_t machine) +{ + paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT); + phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); + return phys; +} + +/* VIRT <-> MACHINE conversion */ +#define virt_to_machine(v) (phys_to_machine(__pa(v))) +#define virt_to_mfn(v) (pfn_to_mfn(__pa(v) >> PAGE_SHIFT)) +#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) + +#ifdef CONFIG_X86_PAE +static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot) +{ + pte_t pte; + + pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \ + (pgprot_val(pgprot) >> 32); + pte.pte_high &= (__supported_pte_mask >> 32); + pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \ + __supported_pte_mask; + return pte; +} +#else +#define pfn_pte_ma(pfn, prot) __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#endif + +#define __pte_ma(x) ((pte_t) { (x) } ) + +#endif /* _I386_MADDR_H */ diff -r 7053592c928b -r aa3087ee5769 linux-2.6-xen-sparse/include/xen/hvm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/include/xen/hvm.h Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,17 @@ +/* Simple wrappers around HVM functions */ +#ifndef XEN_HVM_H__ +#define XEN_HVM_H__ + +#include +#include + +static inline unsigned long hvm_get_parameter(int idx) +{ + struct xen_hvm_param xhv; + + xhv.domid = DOMID_SELF; + xhv.index = idx; + return HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); +} + +#endif /* XEN_HVM_H__ */ diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/Makefile Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,22 @@ +include $(M)/overrides.mk + +obj-$(CONFIG_XEN_EVTCHN_PCI) += evtchn-pci/ +obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += blkfront/ +obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/ +obj-m += xenbus/ + + +debug: + chmod +x compile.sh + chmod +x mkbuildtree + echo $(XEN_DRIVERS_ROOT) + echo $(EXTRA_CFLAGS) + ./compile.sh + +clean: + find . -name "*.o" |xargs rm -f + find . -name "*.ko" |xargs rm -f + find . -name "*.mod.c" |xargs rm -f + find . -name ".*.cmd" |xargs rm -f + rm .tmp_versions -rf + diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/README Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,7 @@ +To build, run ./mkbuildtree and then + +make -C /path/to/kernel/source M=$PWD modules + +You get four modules, xen-evtchn-pci.ko, xenbus.ko, xen-vbd.ko, and +xen-vnif.ko. Load xen-evtchn-pci first, then xenbus, and then +whichever of xen-vbd and xen-vnif you happen to need. diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/blkfront/Kbuild --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/blkfront/Kbuild Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,6 @@ +include $(M)/overrides.mk + +obj-m += xen-vbd.o + +xen-vbd-objs := blkfront.o vbd.o + diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/Kbuild --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/Kbuild Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,8 @@ +include $(M)/overrides.mk + +obj-m := xen-evtchn-pci.o + +EXTRA_CFLAGS += -I$(M)/evtchn-pci + +xen-evtchn-pci-objs := evtchn.o evtchn-pci.o gnttab.o xen_proc.o xen_support.o\ + features.o diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/debuginfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/debuginfo.h Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,56 @@ +#ifndef __DEBUG_INFO__ +#define __DEBUG_INFO__ +//#define INSERT_TEST +//#define VMX_DEBUG_INFO +//#define KERNEL_DEBUG_INFO +//#define FREQ_PRINT + +#define infotime(seconds, x, a...) \ +{ \ +static unsigned long prevjiffy = 0; \ + if(time_after(jiffies, prevjiffy + seconds*HZ)) { \ + prevjiffy = jiffies; \ + vmx_printk(x, ##a); \ + } \ +} + +#ifdef KERNEL_DEBUG_INFO +#define dprintk(x, a...) \ + printk(" " x, ##a) +#define dprintknl(x, a...) \ + printk(x, ##a) +#define dprintkentry(x, a...) \ + printk(" " x "\n", ##a) +#define dprintkexit(x, a...) \ + printk(" " x "\n", ##a) +#ifdef FREQ_PRINT +#define dprintkfreq(x, a...) \ + printk(" " x, ##a) +#else +#define dprintkfreq(x, a...) +#endif +#elif defined(VMX_DEBUG_INFO) +#define dprintk(x, a...) \ + vmx_printk(" " x, ##a) +#define dprintknl(x, a...) \ + vmx_printk(x, ##a) +#define dprintkentry(x, a...) \ + vmx_printk(" " x "\n", ##a) +#define dprintkexit(x, a...) \ + vmx_printk(" " x "\n", ##a) +#ifdef FREQ_PRINT +#define dprintkfreq(x, a...) \ + vmx_printk(" " x, ##a) +#else +#define dprintkfreq(x, a...) +#endif + +#else +#define dprintk(x, a...) +#define dprintkentry(x, a...) +#define dprintkexit(x, a...) +#define dprintkfreq(x, a...) +#define dprintknl(x, a...) +#endif +int vmx_printk(const char *fmt, ...); +#endif diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/evtchn-pci.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/evtchn-pci.c Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,299 @@ +/****************************************************************************** + * evtchn-pci.c + * xen event channel fake PCI device driver + * Copyright (C) 2005, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "evtchn-pci.h" + +#define DRV_NAME "xen-evtchn-pci" +#define DRV_VERSION "0.10" +#define DRV_RELDATE "03/03/2005" + +extern void *hypercall_page; + +static int callbackirq = 3; /* legacy mode irq */ +static int nopci = 0; +static char version[] __devinitdata = + KERN_INFO DRV_NAME ":version " DRV_VERSION " " DRV_RELDATE + " Xiaofeng. Ling\n"; + +MODULE_AUTHOR("xiaofeng.ling@xxxxxxxxx"); +MODULE_DESCRIPTION("Xen evtchn PCI device"); +MODULE_LICENSE("GPL"); + +MODULE_PARM(nopci, "i"); +MODULE_PARM(callbackirq, "i"); +MODULE_PARM_DESC(callbackirq, "callback irq number for xen event channel"); + +#define XEN_EVTCHN_VENDOR_ID 0xfffd +#define XEN_EVTCHN_DEVICE_ID 0x0101 + +static struct pci_device_id evtchn_pci_tbl[] __devinitdata = { + {XEN_EVTCHN_VENDOR_ID, XEN_EVTCHN_DEVICE_ID, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} +}; + +MODULE_DEVICE_TABLE(pci, evtchn_pci_tbl); + +unsigned long *phys_to_machine_mapping; +EXPORT_SYMBOL(phys_to_machine_mapping); + +static int __init init_xen_info(void) +{ + unsigned long shared_info_frame; + struct xen_add_to_physmap xatp; + + setup_xen_features(); + + shared_info_frame = alloc_xen_mmio(PAGE_SIZE) >> PAGE_SHIFT; + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = XENMAPSPACE_shared_info; + xatp.gpfn = shared_info_frame; + BUG_ON(HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)); + HYPERVISOR_shared_info = + ioremap(shared_info_frame << PAGE_SHIFT, PAGE_SIZE); + + if (!HYPERVISOR_shared_info) + panic("can't map shared info\n"); + + dprintk("ioremap shared_info successful\n"); + + phys_to_machine_mapping = NULL; + + gnttab_init(); + evtchn_init(); + + return 0; +} + +static void __devexit evtchn_pci_remove(struct pci_dev *pdev) +{ + long ioaddr, iolen; + + /*if there are io region, don't forget to release */ + ioaddr = pci_resource_start(pdev, 0); + iolen = pci_resource_len(pdev, 0); + if (ioaddr != 0) + { + release_region(ioaddr, iolen); + } + + pci_set_drvdata(pdev, NULL); + free_irq(pdev->irq, NULL); +} + +extern irqreturn_t evtchn_interrupt(int irq, void *devid, struct pt_regs *regs); + +unsigned long evtchn_mmio = 0xc000000; +unsigned long evtchn_mmio_alloc; +unsigned long evtchn_mmiolen = 0x1000000; + +unsigned long alloc_xen_mmio(unsigned long len) +{ + unsigned long addr; + + addr = 0; + if (evtchn_mmio_alloc + len <= evtchn_mmiolen) + { + addr = evtchn_mmio + evtchn_mmio_alloc; + evtchn_mmio_alloc += len; + } else { + panic("ran out of xen mmio space"); + } + return addr; +} + +static int __devinit evtchn_pci_init(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int i, ret, irq; + long ioaddr, iolen; + long mmio_addr, mmio_len; + + printk(KERN_INFO DRV_NAME ":found evtchn pci device model, do init\n"); + +#ifndef MODULE + static int printed_version; + if (!printed_version++) + printk(version); +#endif + + i = pci_enable_device(pdev); + if (i) + return i; + + ioaddr = pci_resource_start(pdev, 0); + iolen = pci_resource_len(pdev, 0); + + mmio_addr = pci_resource_start(pdev, 1); + mmio_len = pci_resource_len(pdev, 1); + + if (mmio_addr != 0) + { + if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) + { + printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n", + mmio_addr, mmio_len); + return -EBUSY; + } + evtchn_mmio = mmio_addr; + evtchn_mmiolen = mmio_len; + } + else + { + printk(KERN_WARNING DRV_NAME ":no MMIO found!\n"); + } + + irq = pdev->irq; + callbackirq = irq; + + /* + * maybe some day we may use I/O port for checking status + * when sharing interrupts + */ + if (ioaddr != 0) + { + if (request_region(ioaddr, iolen, DRV_NAME) == NULL) + { + printk(KERN_ERR DRV_NAME ":I/O resource 0x%lx @ 0x%lx busy\n", + iolen, ioaddr); + return -EBUSY; + } + + hypercall_page = (void *)__get_free_page(GFP_KERNEL); + if (!hypercall_page) + panic("Cannot get hypercall page.\n"); + memset(hypercall_page, 0xcc, PAGE_SIZE); + asm volatile("outl %%eax, %%dx\n" + : + : "a" (virt_to_phys(hypercall_page) >> PAGE_SHIFT), + "d" (ioaddr) + : "memory"); + } + printk(KERN_INFO DRV_NAME ":use irq %d for event channel\n", irq); + + if ((ret = request_irq(irq, evtchn_interrupt, SA_SHIRQ, + "xen-evtchn-pci", evtchn_interrupt))) { + goto out; + } + + if ((ret = init_xen_info())) + goto out; + + if ((ret = set_callback_irq(irq))) + goto out; + + out: + if (ret && hypercall_page) + free_page((unsigned long)hypercall_page); + return 0; +} + +static struct pci_driver evtchn_driver = { + name:DRV_NAME, + probe:evtchn_pci_init, + remove:__devexit_p(evtchn_pci_remove), + id_table:evtchn_pci_tbl, +}; + +int __init setup_xen_callback(void) +{ + int rc = 0; + /* two ways for call back from hypervisor */ + + printk(KERN_INFO DRV_NAME ":legacy driver request irq :%d\n", callbackirq); + rc = request_irq(callbackirq, evtchn_interrupt, SA_SHIRQ, + "xen-evtchn", evtchn_interrupt); + if (rc != 0) + printk(":request irq error:%d!", rc); + rc = set_callback_irq(callbackirq); + if (rc != 0) + printk(KERN_ERR DRV_NAME ":set call back irq error:%d!", rc); + return rc; +} + +static int __init evtchn_pci_module_init(void) +{ + int rc; + + printk(KERN_INFO DRV_NAME ":do xen module support init\n"); + +/* when a module, this is printed whether or not devices are found in probe */ +#ifdef MODULE + printk(version); +#endif + + if (!nopci) + { + rc = pci_module_init(&evtchn_driver); + if (rc) + printk(KERN_INFO DRV_NAME ":No evtchn pci device model found," + "use legacy mode\n"); + } + else + { + printk(KERN_INFO DRV_NAME ":disable evtchn pci device model" + "by module arguments,use legacy mode\n"); + rc = 1; + } + + if (rc) + { + /*No Pci device, try legacy mode */ + rc = init_xen_info(); + if (rc) + return rc; + setup_xen_callback(); + if (rc) + printk(KERN_ERR DRV_NAME ":setup xen legacy callback fail\n"); + } + + return rc; +} + +static void __exit evtchn_pci_module_cleanup(void) +{ + printk(KERN_INFO DRV_NAME ":Do evtchn module cleanup\n"); + /* disable hypervisor for callback irq */ + set_callback_irq(0); + + free_irq(callbackirq, NULL); + + /*TODO: unmap hypercall param share page */ + + pci_unregister_driver(&evtchn_driver); +} + +module_init(evtchn_pci_module_init); +module_exit(evtchn_pci_module_cleanup); diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/evtchn-pci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/evtchn-pci.h Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,58 @@ +/****************************************************************************** + * evtchn-pci.h + * module driver support in unmodified Linux + * Copyright (C) 2004, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#ifndef __XEN_SUPPORT_H +#define __XEN_SUPPORT_H +#include +#include +#include + +#include "debuginfo.h" + +extern unsigned long *phys_to_machine_mapping; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#else +#define __user +#endif + +static inline int set_callback_irq(int irq) +{ + struct xen_hvm_param a; + + a.domid = DOMID_SELF; + a.index = HVM_PARAM_CALLBACK_IRQ; + a.value = irq; + return HYPERVISOR_hvm_op(HVMOP_set_param, &a); +} + +#define L2_PAGETABLE_SHIFT 22 +unsigned long alloc_xen_mmio(unsigned long len); + +int gnttab_init(void); +void evtchn_init(void); +void ctrl_if_init(void); + +void xen_machphys_update(unsigned long mfn, unsigned long pfn); +int xen_do_init(void); + +void setup_xen_features(void); + +#endif diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/evtchn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/evtchn.c Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,200 @@ +/****************************************************************************** + * evtchn.c + * + * A simplified event channel for para-drivers in unmodified linux + * + * Copyright (c) 2002-2005, K A Fraser + * Copyright (c) 2005, + * + * This file may be distributed separately from the Linux kernel, or + * incorporated into other software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "evtchn-pci.h" + +void *hypercall_page; + +#define cpu_from_evtchn(port) (0) +#define MAX_EVTCHN 256 +static struct +{ + irqreturn_t(*handler) (int, void *, struct pt_regs *); + void *dev_id; +} evtchns[MAX_EVTCHN]; + +void mask_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + synch_set_bit(port, &s->evtchn_mask[0]); +} +EXPORT_SYMBOL(mask_evtchn); + +void unmask_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + unsigned int cpu = smp_processor_id(); + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + + /* Slow path (hypercall) if this is a non-local port. */ + if (unlikely(cpu != cpu_from_evtchn(port))) { + evtchn_unmask_t op = { .port = port }; + (void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, + &op); + return; + } + + synch_clear_bit(port, &s->evtchn_mask[0]); + + /* + * The following is basically the equivalent of 'hw_resend_irq'. Just + * like a real IO-APIC we 'lose the interrupt edge' if the channel is + * masked. + */ + if (synch_test_bit(port, &s->evtchn_pending[0]) && + !synch_test_and_set_bit(port / BITS_PER_LONG, + &vcpu_info->evtchn_pending_sel)) { + vcpu_info->evtchn_upcall_pending = 1; + if (!vcpu_info->evtchn_upcall_mask) + force_evtchn_callback(); + } +} +EXPORT_SYMBOL(unmask_evtchn); + +unsigned int bind_virq_to_evtchn(int virq) +{ + evtchn_bind_virq_t op; + + op.virq = virq; + op.vcpu = 0; + if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op) != 0) + BUG(); + + return op.port; +} + +int +bind_evtchn_to_irqhandler(unsigned int evtchn, + irqreturn_t(*handler) (int, void *, + struct pt_regs *), + unsigned long irqflags, const char *devname, + void *dev_id) +{ + if (evtchn >= MAX_EVTCHN) + return -EINVAL; + evtchns[evtchn].handler = handler; + evtchns[evtchn].dev_id = dev_id; + unmask_evtchn(evtchn); + return evtchn; +} + +EXPORT_SYMBOL(bind_evtchn_to_irqhandler); + +void unbind_from_irqhandler(unsigned int evtchn, void *dev_id) +{ + if (evtchn >= MAX_EVTCHN) + return; + + mask_evtchn(evtchn); + evtchns[evtchn].handler = NULL; +} + +EXPORT_SYMBOL(unbind_from_irqhandler); + +void notify_remote_via_irq(int irq) +{ + int evtchn = irq; + notify_remote_via_evtchn(evtchn); +} + +EXPORT_SYMBOL(notify_remote_via_irq); + +void unbind_evtchn_from_irq(unsigned int evtchn) +{ + return; +} + +EXPORT_SYMBOL(unbind_evtchn_from_irq); + +#define active_evtchns(cpu,sh,idx) \ + ((sh)->evtchn_pending[idx] & \ + ~(sh)->evtchn_mask[idx]) + +irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long l1, l2; + unsigned int l1i, l2i, port; + int cpu = smp_processor_id(); + irqreturn_t(*handler) (int, void *, struct pt_regs *); + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; + + vcpu_info->evtchn_upcall_pending = 0; + + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); + while (l1 != 0) + { + l1i = __ffs(l1); + l1 &= ~(1 << l1i); + + while ((l2 = active_evtchns(cpu, s, l1i)) != 0) + { + l2i = __ffs(l2); + + port = (l1i * BITS_PER_LONG) + l2i; + + if ((handler = evtchns[port].handler) != NULL) + { + clear_evtchn(port); + handler(port, evtchns[port].dev_id, regs); + } + else + { + evtchn_device_upcall(port); + } + } + } + + return IRQ_HANDLED; +} + +void force_evtchn_callback(void) +{ + evtchn_interrupt(0, NULL, NULL); +} + +EXPORT_SYMBOL(force_evtchn_callback); + +void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) +{ +} + +void __init evtchn_init(void) +{ + +} + +EXPORT_SYMBOL(hypercall_page); diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/evtchn-pci/xen_support.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/evtchn-pci/xen_support.c Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,53 @@ +/****************************************************************************** + * support.c + * Xen module support functions. + * Copyright (C) 2004, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include "evtchn-pci.h" + +shared_info_t *HYPERVISOR_shared_info = NULL; +EXPORT_SYMBOL(HYPERVISOR_shared_info); + +EXPORT_SYMBOL(xen_machphys_update); +void xen_machphys_update(unsigned long mfn, unsigned long pfn) +{ + mmu_update_t u; + u.ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; + u.val = pfn; + BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0); +} + +void balloon_update_driver_allowance(long delta) +{ +} + +EXPORT_SYMBOL(balloon_update_driver_allowance); + +void evtchn_device_upcall(int port) +{ + printk("Error,no device upcall in guest domain (%d)!\n", port); + clear_evtchn(port); +} + +EXPORT_SYMBOL (evtchn_device_upcall); diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/mkbuildtree --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/mkbuildtree Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,35 @@ +#! /bin/sh + +C=$PWD + +XEN=$C/../../xen +XL=$C/../../linux-2.6-xen-sparse + +for d in $(find ${XL}/drivers/xen/ -type d -maxdepth 1 | sed -e 1d); do + if ! echo $d | egrep -q back; then + lndir $d $(basename $d) > /dev/null 2>&1 + fi +done + +ln -sf ${XL}/drivers/xen/net_driver_util.c netfront + +ln -sf ${XL}/drivers/xen/core/gnttab.c evtchn-pci +ln -sf ${XL}/drivers/xen/core/features.c evtchn-pci +ln -sf ${XL}/drivers/xen/core/xen_proc.c evtchn-pci + +mkdir -p include +mkdir -p include/xen +mkdir -p include/public +mkdir -p include/asm + +lndir -silent ${XL}/include/xen include/xen +ln -sf ${XEN}/include/public include/xen/interface + +# Need to be quite careful here: we don't want the files we link in to +# risk overriding the native Linux ones (in particular, system.h must +# be native and not xenolinux). +ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm +ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm +ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm +ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm + diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/netfront/Kbuild --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/netfront/Kbuild Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,4 @@ +include $(M)/overrides.mk + +obj-m = xen-vnif.o +xen-vnif-objs := netfront.o diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/overrides.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/overrides.mk Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,16 @@ +# Hack: we need to use the config which was used to build the kernel, +# except that that won't have the right headers etc., so duplicate +# some of the mach-xen infrastructure in here. +# +# (i.e. we need the native config for things like -mregparm, but +# a Xen kernel to find the right headers) +CONFIG_X86_XEN=y +CONFIG_XEN_EVTCHN_PCI = m +CONFIG_XEN_BLKDEV_FRONTEND = m +CONFIG_XEN_NETDEV_FRONTEND = m +EXTRA_CFLAGS += -DCONFIG_VMX -DCONFIG_VMX_GUEST -DCONFIG_X86_XEN +EXTRA_CFLAGS += -DCONFIG_XEN_SHADOW_MODE -DCONFIG_XEN_SHADOW_TRANSLATE +EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS +EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX +EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202 +EXTRA_CFLAGS += -I$(M)/include diff -r 7053592c928b -r aa3087ee5769 unmodified_drivers/linux-2.6/xenbus/Kbuild --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/unmodified_drivers/linux-2.6/xenbus/Kbuild Mon Jul 17 23:38:59 2006 +0100 @@ -0,0 +1,9 @@ +include $(M)/overrides.mk + +obj-m += xenbus.o +xenbus-objs = +xenbus-objs += xenbus_comms.o +xenbus-objs += xenbus_xs.o +xenbus-objs += xenbus_probe.o +xenbus-objs += xenbus_dev.o +xenbus-objs += xenbus_client.o