From 531889de05511b2646f652d5f72e16601df75528 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 18 Jan 2005 11:03:57 +0000 Subject: [PATCH 001/199] bitkeeper revision 1.1159.223.1 (41eced1denT_MsS4LtXTQroXHucvZA) Fix small-packet delivery in netback driver. --- .../drivers/xen/netback/netback.c | 30 ++++++++----------- .../drivers/xen/netfront/netfront.c | 1 - 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c index d45b0c3f59..05b043c175 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c @@ -13,8 +13,8 @@ #include "common.h" #include +static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); -static void netif_skb_release(struct sk_buff *skb); static void make_tx_response(netif_t *netif, u16 id, s8 st); @@ -411,7 +411,7 @@ static void net_tx_action(unsigned long unused) mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; mcl[0].args[1] = 0; mcl[0].args[2] = 0; - mcl++; + mcl++; } mcl[-1].args[2] = UVMF_FLUSH_TLB; @@ -531,7 +531,7 @@ static void net_tx_action(unsigned long unused) pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)]; - data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size; + data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) ) { @@ -592,14 +592,15 @@ static void net_tx_action(unsigned long unused) phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] = FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT); - data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size; + data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size; __skb_put(skb, data_len); memcpy(skb->data, (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)), data_len); - if (data_len < txreq.size) { + if ( data_len < txreq.size ) + { /* Append the packet payload as a fragment. */ skb_shinfo(skb)->frags[0].page = virt_to_page(MMAP_VADDR(pending_idx)); @@ -607,10 +608,11 @@ static void net_tx_action(unsigned long unused) skb_shinfo(skb)->frags[0].page_offset = (txreq.addr + data_len) & ~PAGE_MASK; skb_shinfo(skb)->nr_frags = 1; - } else { - skb_shinfo(skb)->frags[0].page = - virt_to_page(MMAP_VADDR(pending_idx)); - skb->destructor = netif_skb_release; + } + else + { + /* Schedule a response immediately. */ + netif_idx_release(pending_idx); } skb->data_len = txreq.size - data_len; @@ -651,14 +653,6 @@ static void netif_page_release(struct page *page) netif_idx_release(pending_idx); } -static void netif_skb_release(struct sk_buff *skb) -{ - struct page *page = skb_shinfo(skb)->frags[0].page; - u16 pending_idx = page - virt_to_page(mmap_vstart); - - netif_idx_release(pending_idx); -} - irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs) { netif_t *netif = dev_id; @@ -747,7 +741,7 @@ static int __init netback_init(void) struct page *page; if ( !(xen_start_info.flags & SIF_NET_BE_DOMAIN) && - !(xen_start_info.flags & SIF_INITDOMAIN) ) + !(xen_start_info.flags & SIF_INITDOMAIN) ) return 0; printk("Initialising Xen netif backend\n"); diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c index fd2cd0b900..61626a7b91 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c @@ -273,7 +273,6 @@ static int send_fake_arp(struct net_device *dev) dst_ip, dev, src_ip, /*dst_hw*/ NULL, /*src_hw*/ NULL, /*target_hw*/ dev->dev_addr); - printk(KERN_ALERT "ARP sent on %08x %08x %p\n", dst_ip, src_ip, skb); if ( skb == NULL ) return -ENOMEM; From 3df033fe2be704d331943b0c5560011b61326982 Mon Sep 17 00:00:00 2001 From: "sos22@douglas.cl.cam.ac.uk" Date: Tue, 18 Jan 2005 16:37:06 +0000 Subject: [PATCH 002/199] bitkeeper revision 1.1159.223.2 (41ed3b32oUZznRTHk1xuGyZVTcWuvg) Get the domain to access from the right element of the union when setting up VM assists. --- xen/common/dom0_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 5622ae174e..4af61010df 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -640,7 +640,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { struct domain *d; ret = -ESRCH; - d = find_domain_by_id( op->u.setdomainmaxmem.domain ); + d = find_domain_by_id( op->u.setdomainvmassist.domain ); if ( d != NULL ) { vm_assist(d, op->u.setdomainvmassist.cmd, From 03461fc402cc963d2e6031eb64caf26ab5a00d85 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 19 Jan 2005 08:35:45 +0000 Subject: [PATCH 003/199] bitkeeper revision 1.1159.223.3 (41ee1be1xhzN-ZQVYs7w2xZ2OtDl1w) Fix 2.4 highmem build. --- linux-2.4.28-xen-sparse/arch/xen/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c b/linux-2.4.28-xen-sparse/arch/xen/mm/init.c index 980983fd03..c68e655a06 100644 --- a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c +++ b/linux-2.4.28-xen-sparse/arch/xen/mm/init.c @@ -377,7 +377,7 @@ static int __init free_pages_init(void) } #ifdef CONFIG_HIGHMEM for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--) - one_highpage_init((struct page *) (mem_map + pfn), pfn, + one_highpage_init((struct page *) (mem_map + pfn), (pfn < xen_start_info.nr_pages)); totalram_pages += totalhigh_pages; #endif From bec85fb4f6bf9ed5443f08db4d068aa9f24e8b0a Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 19 Jan 2005 08:53:07 +0000 Subject: [PATCH 004/199] bitkeeper revision 1.1159.223.4 (41ee1ff3MuvZmbN8TXMWZl0WCI4yMg) Clean up buddy allocator, as suggested by Rusty Russell. --- xen/common/page_alloc.c | 47 +++++++++++++++++++++++------------------ xen/include/xen/mm.h | 16 ++++++++------ 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 0127f52c4d..878948a121 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -203,10 +203,8 @@ unsigned long alloc_boot_pages(unsigned long size, unsigned long align) #define NR_ZONES 2 /* Up to 2^10 pages can be allocated at once. */ -#define MIN_ORDER 0 #define MAX_ORDER 10 -#define NR_ORDERS (MAX_ORDER - MIN_ORDER + 1) -static struct list_head heap[NR_ZONES][NR_ORDERS]; +static struct list_head heap[NR_ZONES][MAX_ORDER+1]; static unsigned long avail[NR_ZONES]; @@ -220,7 +218,7 @@ void end_boot_allocator(void) memset(avail, 0, sizeof(avail)); for ( i = 0; i < NR_ZONES; i++ ) - for ( j = 0; j < NR_ORDERS; j++ ) + for ( j = 0; j <= MAX_ORDER; j++ ) INIT_LIST_HEAD(&heap[i][j]); /* Pages that are free now go to the domain sub-allocator. */ @@ -236,34 +234,41 @@ void end_boot_allocator(void) } /* Hand the specified arbitrary page range to the specified heap zone. */ -void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages) +void init_heap_pages( + unsigned int zone, struct pfn_info *pg, unsigned long nr_pages) { unsigned long i; + ASSERT(zone < NR_ZONES); + for ( i = 0; i < nr_pages; i++ ) free_heap_pages(zone, pg+i, 0); } /* Allocate 2^@order contiguous pages. */ -struct pfn_info *alloc_heap_pages(int zone, int order) +struct pfn_info *alloc_heap_pages(unsigned int zone, unsigned int order) { int i; struct pfn_info *pg; - if ( unlikely(order < MIN_ORDER) || unlikely(order > MAX_ORDER) ) + ASSERT(zone < NR_ZONES); + + if ( unlikely(order > MAX_ORDER) ) return NULL; spin_lock(&heap_lock); /* Find smallest order which can satisfy the request. */ - for ( i = order; i < NR_ORDERS; i++ ) + for ( i = order; i <= MAX_ORDER; i++ ) if ( !list_empty(&heap[zone][i]) ) - break; + goto found; - if ( i == NR_ORDERS ) - goto no_memory; - + /* No suitable memory blocks. Fail the request. */ + spin_unlock(&heap_lock); + return NULL; + + found: pg = list_entry(heap[zone][i].next, struct pfn_info, list); list_del(&pg->list); @@ -281,18 +286,18 @@ struct pfn_info *alloc_heap_pages(int zone, int order) spin_unlock(&heap_lock); return pg; - - no_memory: - spin_unlock(&heap_lock); - return NULL; } /* Free 2^@order set of pages. */ -void free_heap_pages(int zone, struct pfn_info *pg, int order) +void free_heap_pages( + unsigned int zone, struct pfn_info *pg, unsigned int order) { unsigned long mask; + ASSERT(zone < NR_ZONES); + ASSERT(order <= MAX_ORDER); + spin_lock(&heap_lock); map_free(page_to_pfn(pg), 1 << order); @@ -393,7 +398,7 @@ void init_xenheap_pages(unsigned long ps, unsigned long pe) } -unsigned long alloc_xenheap_pages(int order) +unsigned long alloc_xenheap_pages(unsigned int order) { unsigned long flags; struct pfn_info *pg; @@ -431,7 +436,7 @@ unsigned long alloc_xenheap_pages(int order) } -void free_xenheap_pages(unsigned long p, int order) +void free_xenheap_pages(unsigned long p, unsigned int order) { unsigned long flags; @@ -459,7 +464,7 @@ void init_domheap_pages(unsigned long ps, unsigned long pe) } -struct pfn_info *alloc_domheap_pages(struct domain *d, int order) +struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order) { struct pfn_info *pg; unsigned long mask, flushed_mask, pfn_stamp, cpu_stamp; @@ -535,7 +540,7 @@ struct pfn_info *alloc_domheap_pages(struct domain *d, int order) } -void free_domheap_pages(struct pfn_info *pg, int order) +void free_domheap_pages(struct pfn_info *pg, unsigned int order) { int i, drop_dom_ref; struct domain *d = pg->u.inuse.domain; diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 21184b3a43..12242ca491 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -12,22 +12,24 @@ unsigned long alloc_boot_pages(unsigned long size, unsigned long align); void end_boot_allocator(void); /* Generic allocator. These functions are *not* interrupt-safe. */ -void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages); -struct pfn_info *alloc_heap_pages(int zone, int order); -void free_heap_pages(int zone, struct pfn_info *pg, int order); +void init_heap_pages( + unsigned int zone, struct pfn_info *pg, unsigned long nr_pages); +struct pfn_info *alloc_heap_pages(unsigned int zone, unsigned int order); +void free_heap_pages( + unsigned int zone, struct pfn_info *pg, unsigned int order); void scrub_heap_pages(void); /* Xen suballocator. These functions are interrupt-safe. */ void init_xenheap_pages(unsigned long ps, unsigned long pe); -unsigned long alloc_xenheap_pages(int order); -void free_xenheap_pages(unsigned long p, int order); +unsigned long alloc_xenheap_pages(unsigned int order); +void free_xenheap_pages(unsigned long p, unsigned int order); #define alloc_xenheap_page() (alloc_xenheap_pages(0)) #define free_xenheap_page(_p) (free_xenheap_pages(_p,0)) /* Domain suballocator. These functions are *not* interrupt-safe.*/ void init_domheap_pages(unsigned long ps, unsigned long pe); -struct pfn_info *alloc_domheap_pages(struct domain *d, int order); -void free_domheap_pages(struct pfn_info *pg, int order); +struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order); +void free_domheap_pages(struct pfn_info *pg, unsigned int order); unsigned long avail_domheap_pages(void); #define alloc_domheap_page(_d) (alloc_domheap_pages(_d,0)) #define free_domheap_page(_p) (free_domheap_pages(_p,0)) From 55e1e76bac62630c3de3117cf350815b4c26318c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 19 Jan 2005 14:03:33 +0000 Subject: [PATCH 005/199] bitkeeper revision 1.1159.223.5 (41ee68b5s7SXOX6FRHT9GQ92WWOtRA) Truncate the e820 RAM map to 4GB maximum on 32-bit x86. We don't support PAE36 mode. --- xen/arch/x86/e820.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index 63bc128c7e..50f1b5fc8b 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -309,8 +309,33 @@ static void __init machine_specific_memory_setup( struct e820entry *raw, int raw_nr) { char nr = (char)raw_nr; + int i; + sanitize_e820_map(raw, &nr); + (void)copy_e820_map(raw, nr); + +#ifdef __i386__ + /* 32-bit systems restricted to a 4GB physical memory map. */ + for ( i = 0; i < e820.nr_map; i++ ) + { + if ( (e820.map[i].addr + e820.map[i].size) <= 0x100000000ULL ) + continue; + printk("WARNING: Only the first 4GB of the physical memory map " + "can be accessed\n" + " by Xen in 32-bit mode. " + "Truncating the memory map...\n"); + if ( e820.map[i].addr >= 0x100000000ULL ) + { + e820.nr_map = i; + } + else + { + e820.map[i].size = 0x100000000ULL - e820.map[i].addr; + e820.nr_map = i + 1; + } + } +#endif } unsigned long init_e820(struct e820entry *raw, int raw_nr) From 7e4b2750899e080a4cbadea39dcb98df77566b24 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 19 Jan 2005 15:07:55 +0000 Subject: [PATCH 006/199] bitkeeper revision 1.1159.223.6 (41ee77cbILw-JaVF0uno2Fd5_A-GiQ) Fix error path in console-driver initilaisation. Remove module destructor as the console driver cannot be built as a module. --- .../drivers/xen/console/console.c | 32 ++++--------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/console/console.c b/linux-2.6.10-xen-sparse/drivers/xen/console/console.c index 514969cb4d..b9c09c3d73 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/console/console.c @@ -738,8 +738,13 @@ static int __init xencons_init(void) if ( (rc = tty_register_driver(DRV(xencons_driver))) != 0 ) { - printk("Couldn't register Xen virtual console driver as %s\n", - DRV(xencons_driver)->name); + printk("WARNING: Failed to register Xen virtual " + "console driver as '%s%d'\n", + DRV(xencons_driver)->name, DRV(xencons_driver)->name_base); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + put_tty_driver(xencons_driver); + xencons_driver = NULL; +#endif return rc; } @@ -764,27 +769,4 @@ static int __init xencons_init(void) return 0; } -static void __exit xencons_fini(void) -{ - int ret; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - tty_unregister_device(xencons_driver, 0); -#endif - - if ( (ret = tty_unregister_driver(DRV(xencons_driver))) != 0 ) - printk(KERN_ERR "Unable to unregister Xen console driver: %d\n", ret); - - if ( xen_start_info.flags & SIF_INITDOMAIN ) - { - free_irq(xencons_priv_irq, NULL); - unbind_virq_from_irq(VIRQ_CONSOLE); - } - else - { - ctrl_if_unregister_receiver(CMSG_CONSOLE, xencons_rx); - } -} - module_init(xencons_init); -module_exit(xencons_fini); From 2be8cb6730baf9ce903337e72bafd75ee2d5904c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 20 Jan 2005 22:18:00 +0000 Subject: [PATCH 007/199] bitkeeper revision 1.1159.223.7 (41f02e18RcwEdT0BXMaReeOUBf3KVw) timer_tsc.c, time.c: Fix time restore bug. --- linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c | 2 +- .../arch/xen/i386/kernel/timers/timer_tsc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c index 712e0948f1..47eabac205 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c @@ -84,7 +84,7 @@ spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED; EXPORT_SYMBOL(i8253_lock); -extern struct init_timer_opts __initdata timer_tsc_init; +extern struct init_timer_opts timer_tsc_init; extern struct timer_opts timer_tsc; struct timer_opts *cur_timer = &timer_tsc; diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c index f885505a8b..1947e910ef 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c @@ -326,7 +326,7 @@ static inline void cpufreq_delayed_get(void) { return; } #endif -static int __init init_tsc(char* override) +static int init_tsc(char* override) { u64 __cpu_khz; @@ -373,7 +373,7 @@ struct timer_opts timer_tsc = { .delay = delay_tsc, }; -struct init_timer_opts __initdata timer_tsc_init = { +struct init_timer_opts timer_tsc_init = { .init = init_tsc, .opts = &timer_tsc, }; From afa63d44d2d96950657639b698facf373f52dfe2 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 00:37:54 +0000 Subject: [PATCH 008/199] bitkeeper revision 1.1159.223.8 (41f04ee28OyElXpjo4VeyXy925falg) Upgrade to linux 2.4.29 --- .rootkeys | 168 ++--- .../Makefile | 4 +- .../arch/xen/Makefile | 0 .../arch/xen/boot/Makefile | 0 .../arch/xen/config.in | 0 .../arch/xen/defconfig-xen0 | 27 +- .../arch/xen/defconfig-xenU | 7 +- .../arch/xen/drivers/balloon/Makefile | 0 .../arch/xen/drivers/blkif/Makefile | 0 .../arch/xen/drivers/blkif/backend/Makefile | 0 .../arch/xen/drivers/blkif/frontend/Makefile | 0 .../arch/xen/drivers/blkif/frontend/common.h | 0 .../arch/xen/drivers/blkif/frontend/vbd.c | 0 .../arch/xen/drivers/console/Makefile | 0 .../arch/xen/drivers/dom0/Makefile | 0 .../arch/xen/drivers/evtchn/Makefile | 0 .../arch/xen/drivers/netif/Makefile | 0 .../arch/xen/drivers/netif/backend/Makefile | 0 .../arch/xen/drivers/netif/frontend/Makefile | 0 .../arch/xen/kernel/Makefile | 0 .../arch/xen/kernel/entry.S | 0 .../arch/xen/kernel/head.S | 0 .../arch/xen/kernel/i386_ksyms.c | 0 .../arch/xen/kernel/irq.c | 0 .../arch/xen/kernel/ldt.c | 0 .../arch/xen/kernel/pci-pc.c | 0 .../arch/xen/kernel/process.c | 0 .../arch/xen/kernel/setup.c | 0 .../arch/xen/kernel/signal.c | 0 .../arch/xen/kernel/time.c | 0 .../arch/xen/kernel/traps.c | 0 .../arch/xen/lib/Makefile | 0 .../arch/xen/lib/delay.c | 0 .../arch/xen/mm/Makefile | 0 .../arch/xen/mm/fault.c | 0 .../arch/xen/mm/init.c | 0 .../arch/xen/mm/ioremap.c | 0 .../arch/xen/vmlinux.lds | 0 .../drivers/block/ll_rw_blk.c | 0 .../drivers/char/Makefile | 0 .../drivers/char/mem.c | 0 .../drivers/char/tty_io.c | 597 +++++++++++++++--- .../drivers/scsi/aic7xxx/Makefile | 0 .../fs/exec.c | 32 +- .../include/asm-xen/bugs.h | 0 .../include/asm-xen/desc.h | 0 .../include/asm-xen/fixmap.h | 0 .../include/asm-xen/highmem.h | 0 .../include/asm-xen/hw_irq.h | 0 .../include/asm-xen/io.h | 0 .../include/asm-xen/irq.h | 0 .../include/asm-xen/keyboard.h | 0 .../include/asm-xen/mmu_context.h | 0 .../include/asm-xen/module.h | 0 .../include/asm-xen/msr.h | 0 .../include/asm-xen/page.h | 0 .../include/asm-xen/pci.h | 0 .../include/asm-xen/pgalloc.h | 0 .../include/asm-xen/pgtable-2level.h | 0 .../include/asm-xen/pgtable.h | 0 .../include/asm-xen/processor.h | 0 .../include/asm-xen/queues.h | 0 .../include/asm-xen/segment.h | 0 .../include/asm-xen/smp.h | 0 .../include/asm-xen/synch_bitops.h | 0 .../include/asm-xen/system.h | 0 .../include/asm-xen/vga.h | 0 .../include/asm-xen/xor.h | 0 .../include/linux/blk.h | 0 .../include/linux/irq.h | 0 .../include/linux/mm.h | 28 +- .../include/linux/sched.h | 3 + .../include/linux/skbuff.h | 0 .../include/linux/timer.h | 0 .../kernel/time.c | 0 .../kernel/timer.c | 0 .../mkbuildtree | 0 .../mm/highmem.c | 0 .../mm/memory.c | 9 +- .../mm/mprotect.c | 0 .../mm/mremap.c | 11 + .../mm/page_alloc.c | 0 .../mm/swapfile.c | 0 .../mm/vmalloc.c | 0 .../net/core/skbuff.c | 0 85 files changed, 667 insertions(+), 219 deletions(-) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/Makefile (99%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/boot/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/config.in (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/defconfig-xen0 (97%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/defconfig-xenU (99%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/balloon/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/blkif/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/blkif/backend/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/blkif/frontend/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/blkif/frontend/common.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/blkif/frontend/vbd.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/console/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/dom0/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/evtchn/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/netif/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/netif/backend/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/drivers/netif/frontend/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/entry.S (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/head.S (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/i386_ksyms.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/irq.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/ldt.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/pci-pc.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/process.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/setup.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/signal.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/time.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/kernel/traps.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/lib/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/lib/delay.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/mm/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/mm/fault.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/mm/init.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/mm/ioremap.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/arch/xen/vmlinux.lds (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/drivers/block/ll_rw_blk.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/drivers/char/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/drivers/char/mem.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/drivers/char/tty_io.c (82%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/drivers/scsi/aic7xxx/Makefile (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/fs/exec.c (97%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/bugs.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/desc.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/fixmap.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/highmem.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/hw_irq.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/io.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/irq.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/keyboard.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/mmu_context.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/module.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/msr.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/page.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/pci.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/pgalloc.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/pgtable-2level.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/pgtable.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/processor.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/queues.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/segment.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/smp.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/synch_bitops.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/system.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/vga.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/asm-xen/xor.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/blk.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/irq.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/mm.h (97%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/sched.h (99%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/skbuff.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/include/linux/timer.h (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/kernel/time.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/kernel/timer.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mkbuildtree (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/highmem.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/memory.c (99%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/mprotect.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/mremap.c (97%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/page_alloc.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/swapfile.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/mm/vmalloc.c (100%) rename {linux-2.4.28-xen-sparse => linux-2.4.29-xen-sparse}/net/core/skbuff.c (100%) diff --git a/.rootkeys b/.rootkeys index 9f7ea4cd17..0e6a0705b5 100644 --- a/.rootkeys +++ b/.rootkeys @@ -44,90 +44,90 @@ 3f815145vGYx1WY79voKkZB9yKwJKQ extras/mini-os/time.c 3f815145xlKBAQmal9oces3G_Mvxqw extras/mini-os/traps.c 4187ca95_eQN62ugV1zliQcfzXrHnw install.sh -3e5a4e6589G-U42lFKs43plskXoFxQ linux-2.4.28-xen-sparse/Makefile -3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg linux-2.4.28-xen-sparse/arch/xen/Makefile -3e5a4e65n-KhsEAs-A4ULiStBp-r6w linux-2.4.28-xen-sparse/arch/xen/boot/Makefile -3e5a4e65OV_j_DBtjzt5vej771AJsA linux-2.4.28-xen-sparse/arch/xen/config.in -40648526SxcA4lGIHB_k7ID8VlRSzw linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0 -40c73c77QesbL7eIvG-fJGAtVwhGRg linux-2.4.28-xen-sparse/arch/xen/defconfig-xenU -3e6377f5xwPfYZkPHPrDbEq1PRN7uQ linux-2.4.28-xen-sparse/arch/xen/drivers/balloon/Makefile -4083dc16z0jvZEH4PiVDbDRreaNp6w linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/Makefile -4083dc16KQus88a4U3uCV6qVCA6_8Q linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/backend/Makefile -4075806dI5kfeMD5RV-DA0PYoThx_w linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile -4075806d4-j7vN0Mn0bklI1cRUX1vQ linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/common.h -4075806dibjCcfuXv6CINMhxWTw3jQ linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c -3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ linux-2.4.28-xen-sparse/arch/xen/drivers/console/Makefile -3e5a4e656nfFISThfbyXQOA6HN6YHw linux-2.4.28-xen-sparse/arch/xen/drivers/dom0/Makefile -40420a6ebRqDjufoN1WSJvolEW2Wjw linux-2.4.28-xen-sparse/arch/xen/drivers/evtchn/Makefile -4083dc16-Kd5y9psK_yk161sme5j5Q linux-2.4.28-xen-sparse/arch/xen/drivers/netif/Makefile -4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4.28-xen-sparse/arch/xen/drivers/netif/backend/Makefile -405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.28-xen-sparse/arch/xen/drivers/netif/frontend/Makefile -3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.28-xen-sparse/arch/xen/kernel/Makefile -3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.28-xen-sparse/arch/xen/kernel/entry.S -3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.28-xen-sparse/arch/xen/kernel/head.S -3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.28-xen-sparse/arch/xen/kernel/i386_ksyms.c -3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.28-xen-sparse/arch/xen/kernel/irq.c -3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.28-xen-sparse/arch/xen/kernel/ldt.c -4051db95N9N99FjsRwi49YKUNHWI8A linux-2.4.28-xen-sparse/arch/xen/kernel/pci-pc.c -3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ linux-2.4.28-xen-sparse/arch/xen/kernel/process.c -3e5a4e66tR-qJMLj3MppcKqmvuI2XQ linux-2.4.28-xen-sparse/arch/xen/kernel/setup.c -3e5a4e66fWSTagLGU2P8BGFGRjhDiw linux-2.4.28-xen-sparse/arch/xen/kernel/signal.c -3e5a4e66N__lUXNwzQ-eADRzK9LXuQ linux-2.4.28-xen-sparse/arch/xen/kernel/time.c -3e5a4e66aHCbQ_F5QZ8VeyikLmuRZQ linux-2.4.28-xen-sparse/arch/xen/kernel/traps.c -3e5a4e66-9_NczrVMbuQkoSLyXckIw linux-2.4.28-xen-sparse/arch/xen/lib/Makefile -3e5a4e6637ZDk0BvFEC-aFQs599-ng linux-2.4.28-xen-sparse/arch/xen/lib/delay.c -3e5a4e66croVgpcJyJuF2ycQw0HuJw linux-2.4.28-xen-sparse/arch/xen/mm/Makefile -3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg linux-2.4.28-xen-sparse/arch/xen/mm/fault.c -3e5a4e661gLzzff25pJooKIIWe7IWg linux-2.4.28-xen-sparse/arch/xen/mm/init.c -3f0bed43UUdQichXAiVNrjV-y2Kzcg linux-2.4.28-xen-sparse/arch/xen/mm/ioremap.c -3e5a4e66qRlSTcjafidMB6ulECADvg linux-2.4.28-xen-sparse/arch/xen/vmlinux.lds -3e5a4e66mrtlmV75L1tjKDg8RaM5gA linux-2.4.28-xen-sparse/drivers/block/ll_rw_blk.c -40d70c24-Dy2HUMrwSZagfXvAPnI4w linux-2.4.28-xen-sparse/drivers/char/Makefile -3f108aeaLcGDgQdFAANLTUEid0a05w linux-2.4.28-xen-sparse/drivers/char/mem.c -3e5a4e66rw65CxyolW9PKz4GG42RcA linux-2.4.28-xen-sparse/drivers/char/tty_io.c -40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.28-xen-sparse/drivers/scsi/aic7xxx/Makefile -3e5a4e669uzIE54VwucPYtGwXLAbzA linux-2.4.28-xen-sparse/fs/exec.c -3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.28-xen-sparse/include/asm-xen/bugs.h -3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.28-xen-sparse/include/asm-xen/desc.h -3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw linux-2.4.28-xen-sparse/include/asm-xen/fixmap.h -406aeeaaQvl4RNtmd9hDEugBURbFpQ linux-2.4.28-xen-sparse/include/asm-xen/highmem.h -3e5a4e67YtcyDLQsShhCfQwPSELfvA linux-2.4.28-xen-sparse/include/asm-xen/hw_irq.h -4060044fVx7-tokvNLKBf_6qBB4lqQ linux-2.4.28-xen-sparse/include/asm-xen/io.h -3e5a4e673p7PEOyHFm3nHkYX6HQYBg linux-2.4.28-xen-sparse/include/asm-xen/irq.h -40d70c240tW7TWArl1VUgIFH2nVO1A linux-2.4.28-xen-sparse/include/asm-xen/keyboard.h -3e5a4e678ddsQOpbSiRdy1GRcDc9WA linux-2.4.28-xen-sparse/include/asm-xen/mmu_context.h -40d06e5b2YWInUX1Xv9amVANwd_2Xg linux-2.4.28-xen-sparse/include/asm-xen/module.h -3f8707e7ZmZ6TxyX0ZUEfvhA2Pb_xQ linux-2.4.28-xen-sparse/include/asm-xen/msr.h -3e5a4e67mnQfh-R8KcQCaVo2Oho6yg linux-2.4.28-xen-sparse/include/asm-xen/page.h -409ba2e7ZfV5hqTvIzxLtpClnxtIzg linux-2.4.28-xen-sparse/include/asm-xen/pci.h -3e5a4e67uTYU5oEnIDjxuaez8njjqg linux-2.4.28-xen-sparse/include/asm-xen/pgalloc.h -3e5a4e67X7JyupgdYkgDX19Huj2sAw linux-2.4.28-xen-sparse/include/asm-xen/pgtable-2level.h -3e5a4e67gr4NLGtQ5CvSLimMYZlkOA linux-2.4.28-xen-sparse/include/asm-xen/pgtable.h -3e5a4e676uK4xErTBDH6XJREn9LSyg linux-2.4.28-xen-sparse/include/asm-xen/processor.h -41224663YBCUMX1kVo_HRUtgaHTi7w linux-2.4.28-xen-sparse/include/asm-xen/queues.h -3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.28-xen-sparse/include/asm-xen/segment.h -3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.28-xen-sparse/include/asm-xen/smp.h -4062f7e2PzFOUGT0PaE7A0VprTU3JQ linux-2.4.28-xen-sparse/include/asm-xen/synch_bitops.h -3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.28-xen-sparse/include/asm-xen/system.h -3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.28-xen-sparse/include/asm-xen/vga.h -40659defgWA92arexpMGn8X3QMDj3w linux-2.4.28-xen-sparse/include/asm-xen/xor.h -3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.28-xen-sparse/include/linux/blk.h -419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.28-xen-sparse/include/linux/irq.h -4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.28-xen-sparse/include/linux/mm.h -401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.28-xen-sparse/include/linux/sched.h -40a248afgI0_JKthdYAe8beVfXSTpQ linux-2.4.28-xen-sparse/include/linux/skbuff.h -401c0592pLrp_aCbQRo9GXiYQQaVVA linux-2.4.28-xen-sparse/include/linux/timer.h -3f9d4b44247udoqWEgFkaHiWv6Uvyg linux-2.4.28-xen-sparse/kernel/time.c -401c059bjLBFYHRD4Py2uM3eA1D4zQ linux-2.4.28-xen-sparse/kernel/timer.c -3e6e7c1efbQe93xCvOpOVCnXTMmQ5w linux-2.4.28-xen-sparse/mkbuildtree -406aeeafkrnCuIVWLFv3kfn4uAD5Eg linux-2.4.28-xen-sparse/mm/highmem.c -3e5a4e68GxCIaFH4sy01v1wjapetaA linux-2.4.28-xen-sparse/mm/memory.c -3f108af5VxPkLv13tXpXgoRKALQtXQ linux-2.4.28-xen-sparse/mm/mprotect.c -3e5a4e681xMPdF9xCMwpyfuYMySU5g linux-2.4.28-xen-sparse/mm/mremap.c -409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.28-xen-sparse/mm/page_alloc.c -3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.28-xen-sparse/mm/swapfile.c -41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.28-xen-sparse/mm/vmalloc.c -41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.28-xen-sparse/net/core/skbuff.c +3e5a4e6589G-U42lFKs43plskXoFxQ linux-2.4.29-xen-sparse/Makefile +3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg linux-2.4.29-xen-sparse/arch/xen/Makefile +3e5a4e65n-KhsEAs-A4ULiStBp-r6w linux-2.4.29-xen-sparse/arch/xen/boot/Makefile +3e5a4e65OV_j_DBtjzt5vej771AJsA linux-2.4.29-xen-sparse/arch/xen/config.in +40648526SxcA4lGIHB_k7ID8VlRSzw linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 +40c73c77QesbL7eIvG-fJGAtVwhGRg linux-2.4.29-xen-sparse/arch/xen/defconfig-xenU +3e6377f5xwPfYZkPHPrDbEq1PRN7uQ linux-2.4.29-xen-sparse/arch/xen/drivers/balloon/Makefile +4083dc16z0jvZEH4PiVDbDRreaNp6w linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/Makefile +4083dc16KQus88a4U3uCV6qVCA6_8Q linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/backend/Makefile +4075806dI5kfeMD5RV-DA0PYoThx_w linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile +4075806d4-j7vN0Mn0bklI1cRUX1vQ linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/common.h +4075806dibjCcfuXv6CINMhxWTw3jQ linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c +3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ linux-2.4.29-xen-sparse/arch/xen/drivers/console/Makefile +3e5a4e656nfFISThfbyXQOA6HN6YHw linux-2.4.29-xen-sparse/arch/xen/drivers/dom0/Makefile +40420a6ebRqDjufoN1WSJvolEW2Wjw linux-2.4.29-xen-sparse/arch/xen/drivers/evtchn/Makefile +4083dc16-Kd5y9psK_yk161sme5j5Q linux-2.4.29-xen-sparse/arch/xen/drivers/netif/Makefile +4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4.29-xen-sparse/arch/xen/drivers/netif/backend/Makefile +405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.29-xen-sparse/arch/xen/drivers/netif/frontend/Makefile +3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.29-xen-sparse/arch/xen/kernel/Makefile +3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.29-xen-sparse/arch/xen/kernel/entry.S +3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.29-xen-sparse/arch/xen/kernel/head.S +3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.29-xen-sparse/arch/xen/kernel/i386_ksyms.c +3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.29-xen-sparse/arch/xen/kernel/irq.c +3e5a4e65muT6SU3ck47IP87Q7Ti5hA linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c +4051db95N9N99FjsRwi49YKUNHWI8A linux-2.4.29-xen-sparse/arch/xen/kernel/pci-pc.c +3e5a4e65IGt3WwQDNiL4h-gYWgNTWQ linux-2.4.29-xen-sparse/arch/xen/kernel/process.c +3e5a4e66tR-qJMLj3MppcKqmvuI2XQ linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c +3e5a4e66fWSTagLGU2P8BGFGRjhDiw linux-2.4.29-xen-sparse/arch/xen/kernel/signal.c +3e5a4e66N__lUXNwzQ-eADRzK9LXuQ linux-2.4.29-xen-sparse/arch/xen/kernel/time.c +3e5a4e66aHCbQ_F5QZ8VeyikLmuRZQ linux-2.4.29-xen-sparse/arch/xen/kernel/traps.c +3e5a4e66-9_NczrVMbuQkoSLyXckIw linux-2.4.29-xen-sparse/arch/xen/lib/Makefile +3e5a4e6637ZDk0BvFEC-aFQs599-ng linux-2.4.29-xen-sparse/arch/xen/lib/delay.c +3e5a4e66croVgpcJyJuF2ycQw0HuJw linux-2.4.29-xen-sparse/arch/xen/mm/Makefile +3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg linux-2.4.29-xen-sparse/arch/xen/mm/fault.c +3e5a4e661gLzzff25pJooKIIWe7IWg linux-2.4.29-xen-sparse/arch/xen/mm/init.c +3f0bed43UUdQichXAiVNrjV-y2Kzcg linux-2.4.29-xen-sparse/arch/xen/mm/ioremap.c +3e5a4e66qRlSTcjafidMB6ulECADvg linux-2.4.29-xen-sparse/arch/xen/vmlinux.lds +3e5a4e66mrtlmV75L1tjKDg8RaM5gA linux-2.4.29-xen-sparse/drivers/block/ll_rw_blk.c +40d70c24-Dy2HUMrwSZagfXvAPnI4w linux-2.4.29-xen-sparse/drivers/char/Makefile +3f108aeaLcGDgQdFAANLTUEid0a05w linux-2.4.29-xen-sparse/drivers/char/mem.c +3e5a4e66rw65CxyolW9PKz4GG42RcA linux-2.4.29-xen-sparse/drivers/char/tty_io.c +40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.29-xen-sparse/drivers/scsi/aic7xxx/Makefile +3e5a4e669uzIE54VwucPYtGwXLAbzA linux-2.4.29-xen-sparse/fs/exec.c +3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.29-xen-sparse/include/asm-xen/bugs.h +3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.29-xen-sparse/include/asm-xen/desc.h +3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw linux-2.4.29-xen-sparse/include/asm-xen/fixmap.h +406aeeaaQvl4RNtmd9hDEugBURbFpQ linux-2.4.29-xen-sparse/include/asm-xen/highmem.h +3e5a4e67YtcyDLQsShhCfQwPSELfvA linux-2.4.29-xen-sparse/include/asm-xen/hw_irq.h +4060044fVx7-tokvNLKBf_6qBB4lqQ linux-2.4.29-xen-sparse/include/asm-xen/io.h +3e5a4e673p7PEOyHFm3nHkYX6HQYBg linux-2.4.29-xen-sparse/include/asm-xen/irq.h +40d70c240tW7TWArl1VUgIFH2nVO1A linux-2.4.29-xen-sparse/include/asm-xen/keyboard.h +3e5a4e678ddsQOpbSiRdy1GRcDc9WA linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h +40d06e5b2YWInUX1Xv9amVANwd_2Xg linux-2.4.29-xen-sparse/include/asm-xen/module.h +3f8707e7ZmZ6TxyX0ZUEfvhA2Pb_xQ linux-2.4.29-xen-sparse/include/asm-xen/msr.h +3e5a4e67mnQfh-R8KcQCaVo2Oho6yg linux-2.4.29-xen-sparse/include/asm-xen/page.h +409ba2e7ZfV5hqTvIzxLtpClnxtIzg linux-2.4.29-xen-sparse/include/asm-xen/pci.h +3e5a4e67uTYU5oEnIDjxuaez8njjqg linux-2.4.29-xen-sparse/include/asm-xen/pgalloc.h +3e5a4e67X7JyupgdYkgDX19Huj2sAw linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h +3e5a4e67gr4NLGtQ5CvSLimMYZlkOA linux-2.4.29-xen-sparse/include/asm-xen/pgtable.h +3e5a4e676uK4xErTBDH6XJREn9LSyg linux-2.4.29-xen-sparse/include/asm-xen/processor.h +41224663YBCUMX1kVo_HRUtgaHTi7w linux-2.4.29-xen-sparse/include/asm-xen/queues.h +3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.29-xen-sparse/include/asm-xen/segment.h +3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.29-xen-sparse/include/asm-xen/smp.h +4062f7e2PzFOUGT0PaE7A0VprTU3JQ linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h +3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.29-xen-sparse/include/asm-xen/system.h +3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.29-xen-sparse/include/asm-xen/vga.h +40659defgWA92arexpMGn8X3QMDj3w linux-2.4.29-xen-sparse/include/asm-xen/xor.h +3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.29-xen-sparse/include/linux/blk.h +419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.29-xen-sparse/include/linux/irq.h +4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.29-xen-sparse/include/linux/mm.h +401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.29-xen-sparse/include/linux/sched.h +40a248afgI0_JKthdYAe8beVfXSTpQ linux-2.4.29-xen-sparse/include/linux/skbuff.h +401c0592pLrp_aCbQRo9GXiYQQaVVA linux-2.4.29-xen-sparse/include/linux/timer.h +3f9d4b44247udoqWEgFkaHiWv6Uvyg linux-2.4.29-xen-sparse/kernel/time.c +401c059bjLBFYHRD4Py2uM3eA1D4zQ linux-2.4.29-xen-sparse/kernel/timer.c +3e6e7c1efbQe93xCvOpOVCnXTMmQ5w linux-2.4.29-xen-sparse/mkbuildtree +406aeeafkrnCuIVWLFv3kfn4uAD5Eg linux-2.4.29-xen-sparse/mm/highmem.c +3e5a4e68GxCIaFH4sy01v1wjapetaA linux-2.4.29-xen-sparse/mm/memory.c +3f108af5VxPkLv13tXpXgoRKALQtXQ linux-2.4.29-xen-sparse/mm/mprotect.c +3e5a4e681xMPdF9xCMwpyfuYMySU5g linux-2.4.29-xen-sparse/mm/mremap.c +409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.29-xen-sparse/mm/page_alloc.c +3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.29-xen-sparse/mm/swapfile.c +41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.29-xen-sparse/mm/vmalloc.c +41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.29-xen-sparse/net/core/skbuff.c 40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.10-xen-sparse/arch/xen/Kconfig 40f56237utH41NPukqHksuNf29IC9A linux-2.6.10-xen-sparse/arch/xen/Kconfig.drivers 40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.10-xen-sparse/arch/xen/Makefile diff --git a/linux-2.4.28-xen-sparse/Makefile b/linux-2.4.29-xen-sparse/Makefile similarity index 99% rename from linux-2.4.28-xen-sparse/Makefile rename to linux-2.4.29-xen-sparse/Makefile index 70df708495..29bcb96ccc 100644 --- a/linux-2.4.28-xen-sparse/Makefile +++ b/linux-2.4.29-xen-sparse/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 28 -EXTRAVERSION = +SUBLEVEL = 29 +EXTRAVERSION =-xenU KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/linux-2.4.28-xen-sparse/arch/xen/Makefile b/linux-2.4.29-xen-sparse/arch/xen/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/boot/Makefile b/linux-2.4.29-xen-sparse/arch/xen/boot/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/boot/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/boot/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/config.in b/linux-2.4.29-xen-sparse/arch/xen/config.in similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/config.in rename to linux-2.4.29-xen-sparse/arch/xen/config.in diff --git a/linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0 b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 similarity index 97% rename from linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0 rename to linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 index ab9728239a..ace090e76d 100644 --- a/linux-2.4.28-xen-sparse/arch/xen/defconfig-xen0 +++ b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 @@ -188,7 +188,6 @@ CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_CONNTRACK=m # CONFIG_IP_NF_MATCH_UNCLEAN is not set # CONFIG_IP_NF_MATCH_OWNER is not set -CONFIG_IP_NF_MATCH_PHYSDEV=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y # CONFIG_IP_NF_TARGET_MIRROR is not set @@ -196,7 +195,6 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m @@ -226,32 +224,8 @@ CONFIG_VLAN_8021Q=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set CONFIG_BRIDGE=y -CONFIG_BRIDGE_NF_EBTABLES=m -CONFIG_BRIDGE_EBT_T_FILTER=m -CONFIG_BRIDGE_EBT_T_NAT=m -CONFIG_BRIDGE_EBT_BROUTE=m -CONFIG_BRIDGE_EBT_LOG=m -CONFIG_BRIDGE_EBT_IPF=m -CONFIG_BRIDGE_EBT_ARPF=m -CONFIG_BRIDGE_EBT_AMONG=m -CONFIG_BRIDGE_EBT_LIMIT=m -CONFIG_BRIDGE_EBT_VLANF=m -CONFIG_BRIDGE_EBT_802_3=m -CONFIG_BRIDGE_EBT_PKTTYPE=m -CONFIG_BRIDGE_EBT_STP=m -CONFIG_BRIDGE_EBT_MARKF=m -CONFIG_BRIDGE_EBT_ARPREPLY=m -CONFIG_BRIDGE_EBT_SNAT=m -CONFIG_BRIDGE_EBT_DNAT=m -CONFIG_BRIDGE_EBT_REDIRECT=m -CONFIG_BRIDGE_EBT_MARK_T=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set @@ -421,6 +395,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_SCSI_MEGARAID=y # CONFIG_SCSI_MEGARAID2 is not set CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_NV is not set diff --git a/linux-2.4.28-xen-sparse/arch/xen/defconfig-xenU b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xenU similarity index 99% rename from linux-2.4.28-xen-sparse/arch/xen/defconfig-xenU rename to linux-2.4.29-xen-sparse/arch/xen/defconfig-xenU index 555f7e82f9..6527523b71 100644 --- a/linux-2.4.28-xen-sparse/arch/xen/defconfig-xenU +++ b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xenU @@ -130,7 +130,6 @@ CONFIG_IP_NF_NAT=y CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_REDIRECT=y -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=y CONFIG_IP_NF_NAT_FTP=y @@ -160,11 +159,6 @@ CONFIG_VLAN_8021Q=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -228,6 +222,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_MEGARAID2 is not set # CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set # CONFIG_SCSI_ATA_PIIX is not set # CONFIG_SCSI_SATA_NV is not set diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/balloon/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/balloon/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/balloon/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/balloon/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/backend/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/backend/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/backend/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/backend/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/common.h b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/common.h similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/common.h rename to linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/common.h diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c rename to linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/console/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/console/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/console/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/console/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/dom0/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/dom0/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/dom0/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/dom0/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/evtchn/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/evtchn/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/evtchn/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/evtchn/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/netif/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/netif/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/netif/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/netif/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/netif/backend/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/netif/backend/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/netif/backend/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/netif/backend/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/drivers/netif/frontend/Makefile b/linux-2.4.29-xen-sparse/arch/xen/drivers/netif/frontend/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/drivers/netif/frontend/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/drivers/netif/frontend/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/Makefile b/linux-2.4.29-xen-sparse/arch/xen/kernel/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/kernel/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/entry.S b/linux-2.4.29-xen-sparse/arch/xen/kernel/entry.S similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/entry.S rename to linux-2.4.29-xen-sparse/arch/xen/kernel/entry.S diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/head.S b/linux-2.4.29-xen-sparse/arch/xen/kernel/head.S similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/head.S rename to linux-2.4.29-xen-sparse/arch/xen/kernel/head.S diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/i386_ksyms.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/i386_ksyms.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/i386_ksyms.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/i386_ksyms.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/irq.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/irq.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/irq.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/irq.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/ldt.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/ldt.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/ldt.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/pci-pc.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/pci-pc.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/pci-pc.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/pci-pc.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/process.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/process.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/process.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/process.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/setup.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/signal.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/signal.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/signal.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/signal.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/time.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/time.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/time.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/time.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/kernel/traps.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/traps.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/kernel/traps.c rename to linux-2.4.29-xen-sparse/arch/xen/kernel/traps.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/lib/Makefile b/linux-2.4.29-xen-sparse/arch/xen/lib/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/lib/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/lib/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/lib/delay.c b/linux-2.4.29-xen-sparse/arch/xen/lib/delay.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/lib/delay.c rename to linux-2.4.29-xen-sparse/arch/xen/lib/delay.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/Makefile b/linux-2.4.29-xen-sparse/arch/xen/mm/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/mm/Makefile rename to linux-2.4.29-xen-sparse/arch/xen/mm/Makefile diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/fault.c b/linux-2.4.29-xen-sparse/arch/xen/mm/fault.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/mm/fault.c rename to linux-2.4.29-xen-sparse/arch/xen/mm/fault.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c b/linux-2.4.29-xen-sparse/arch/xen/mm/init.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/mm/init.c rename to linux-2.4.29-xen-sparse/arch/xen/mm/init.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/mm/ioremap.c b/linux-2.4.29-xen-sparse/arch/xen/mm/ioremap.c similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/mm/ioremap.c rename to linux-2.4.29-xen-sparse/arch/xen/mm/ioremap.c diff --git a/linux-2.4.28-xen-sparse/arch/xen/vmlinux.lds b/linux-2.4.29-xen-sparse/arch/xen/vmlinux.lds similarity index 100% rename from linux-2.4.28-xen-sparse/arch/xen/vmlinux.lds rename to linux-2.4.29-xen-sparse/arch/xen/vmlinux.lds diff --git a/linux-2.4.28-xen-sparse/drivers/block/ll_rw_blk.c b/linux-2.4.29-xen-sparse/drivers/block/ll_rw_blk.c similarity index 100% rename from linux-2.4.28-xen-sparse/drivers/block/ll_rw_blk.c rename to linux-2.4.29-xen-sparse/drivers/block/ll_rw_blk.c diff --git a/linux-2.4.28-xen-sparse/drivers/char/Makefile b/linux-2.4.29-xen-sparse/drivers/char/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/drivers/char/Makefile rename to linux-2.4.29-xen-sparse/drivers/char/Makefile diff --git a/linux-2.4.28-xen-sparse/drivers/char/mem.c b/linux-2.4.29-xen-sparse/drivers/char/mem.c similarity index 100% rename from linux-2.4.28-xen-sparse/drivers/char/mem.c rename to linux-2.4.29-xen-sparse/drivers/char/mem.c diff --git a/linux-2.4.28-xen-sparse/drivers/char/tty_io.c b/linux-2.4.29-xen-sparse/drivers/char/tty_io.c similarity index 82% rename from linux-2.4.28-xen-sparse/drivers/char/tty_io.c rename to linux-2.4.29-xen-sparse/drivers/char/tty_io.c index 3a568eb5bc..c08218e8cc 100644 --- a/linux-2.4.28-xen-sparse/drivers/char/tty_io.c +++ b/linux-2.4.29-xen-sparse/drivers/char/tty_io.c @@ -124,7 +124,6 @@ extern void disable_early_printk(void); struct termios tty_std_termios; /* for the benefit of tty drivers */ struct tty_driver *tty_drivers; /* linked list of tty drivers */ -struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ #ifdef CONFIG_UNIX98_PTYS extern struct tty_driver ptm_driver[]; /* Unix98 pty masters; for /dev/ptmx */ @@ -264,63 +263,314 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) return 0; } +/* + * This is probably overkill for real world processors but + * they are not on hot paths so a little discipline won't do + * any harm. + */ + +static void tty_set_termios_ldisc(struct tty_struct *tty, int num) +{ + down(&tty->termios_sem); + tty->termios->c_line = num; + up(&tty->termios_sem); +} + +/* + * This guards the refcounted line discipline lists. The lock + * must be taken with irqs off because there are hangup path + * callers who will do ldisc lookups and cannot sleep. + */ + +spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED; +DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); +struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ + int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) { + + unsigned long flags; + int ret = 0; + if (disc < N_TTY || disc >= NR_LDISCS) return -EINVAL; - + + spin_lock_irqsave(&tty_ldisc_lock, flags); if (new_ldisc) { - ldiscs[disc] = *new_ldisc; - ldiscs[disc].flags |= LDISC_FLAG_DEFINED; - ldiscs[disc].num = disc; - } else - memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc)); + tty_ldiscs[disc] = *new_ldisc; + tty_ldiscs[disc].num = disc; + tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; + tty_ldiscs[disc].refcount = 0; + } else { + if(tty_ldiscs[disc].refcount) + ret = -EBUSY; + else + tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; + } + spin_unlock_irqrestore(&tty_ldisc_lock, flags); - return 0; + return ret; + } + EXPORT_SYMBOL(tty_register_ldisc); -/* Set the discipline of a tty line. */ +struct tty_ldisc *tty_ldisc_get(int disc) +{ + unsigned long flags; + struct tty_ldisc *ld; + + if (disc < N_TTY || disc >= NR_LDISCS) + return NULL; + + spin_lock_irqsave(&tty_ldisc_lock, flags); + + ld = &tty_ldiscs[disc]; + /* Check the entry is defined */ + if(ld->flags & LDISC_FLAG_DEFINED) + ld->refcount++; + else + ld = NULL; + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + return ld; +} + +EXPORT_SYMBOL_GPL(tty_ldisc_get); + +void tty_ldisc_put(int disc) +{ + struct tty_ldisc *ld; + unsigned long flags; + + if (disc < N_TTY || disc >= NR_LDISCS) + BUG(); + + spin_lock_irqsave(&tty_ldisc_lock, flags); + ld = &tty_ldiscs[disc]; + if(ld->refcount <= 0) + BUG(); + ld->refcount--; + spin_unlock_irqrestore(&tty_ldisc_lock, flags); +} + +EXPORT_SYMBOL_GPL(tty_ldisc_put); + +void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) +{ + tty->ldisc = *ld; + tty->ldisc.refcount = 0; +} + +/** + * tty_ldisc_try - internal helper + * @tty: the tty + * + * Make a single attempt to grab and bump the refcount on + * the tty ldisc. Return 0 on failure or 1 on success. This is + * used to implement both the waiting and non waiting versions + * of tty_ldisc_ref + */ + +static int tty_ldisc_try(struct tty_struct *tty) +{ + unsigned long flags; + struct tty_ldisc *ld; + int ret = 0; + + spin_lock_irqsave(&tty_ldisc_lock, flags); + ld = &tty->ldisc; + if(test_bit(TTY_LDISC, &tty->flags)) + { + ld->refcount++; + ret = 1; + } + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + return ret; +} + +/** + * tty_ldisc_ref_wait - wait for the tty ldisc + * @tty: tty device + * + * Dereference the line discipline for the terminal and take a + * reference to it. If the line discipline is in flux then + * wait patiently until it changes. + * + * Note: Must not be called from an IRQ/timer context. The caller + * must also be careful not to hold other locks that will deadlock + * against a discipline change, such as an existing ldisc reference + * (which we check for) + */ + +struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty) +{ + /* wait_event is a macro */ + wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); + return &tty->ldisc; +} + +EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); + +/** + * tty_ldisc_ref - get the tty ldisc + * @tty: tty device + * + * Dereference the line discipline for the terminal and take a + * reference to it. If the line discipline is in flux then + * return NULL. Can be called from IRQ and timer functions. + */ + +struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) +{ + if(tty_ldisc_try(tty)) + return &tty->ldisc; + return NULL; +} + +EXPORT_SYMBOL_GPL(tty_ldisc_ref); + + +void tty_ldisc_deref(struct tty_ldisc *ld) +{ + + unsigned long flags; + + if(ld == NULL) + BUG(); + + spin_lock_irqsave(&tty_ldisc_lock, flags); + if(ld->refcount == 0) + printk(KERN_EMERG "tty_ldisc_deref: no references.\n"); + else + ld->refcount--; + if(ld->refcount == 0) + wake_up(&tty_ldisc_wait); + spin_unlock_irqrestore(&tty_ldisc_lock, flags); +} + +EXPORT_SYMBOL_GPL(tty_ldisc_deref); + +/** + * tty_ldisc_enable - allow ldisc use + * @tty: terminal to activate ldisc on + * + * Set the TTY_LDISC flag when the line discipline can be called + * again. Do neccessary wakeups for existing sleepers. + * + * Note: nobody should set this bit except via this function. Clearing + * directly is allowed. + */ + +static void tty_ldisc_enable(struct tty_struct *tty) +{ + set_bit(TTY_LDISC, &tty->flags); + wake_up(&tty_ldisc_wait); +} + +/** + * tty_set_ldisc - set line discipline + * @tty: the terminal to set + * @ldisc: the line discipline + * + * Set the discipline of a tty line. Must be called from a process + * context. + */ + static int tty_set_ldisc(struct tty_struct *tty, int ldisc) { int retval = 0; struct tty_ldisc o_ldisc; char buf[64]; + unsigned long flags; + struct tty_ldisc *ld; if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) return -EINVAL; - /* Eduardo Blanco */ - /* Cyrus Durgin */ - if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) { - char modname [20]; - sprintf(modname, "tty-ldisc-%d", ldisc); - request_module (modname); - } - if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) - return -EINVAL; + +restart: if (tty->ldisc.num == ldisc) - return 0; /* We are already in the desired discipline */ - o_ldisc = tty->ldisc; + return 0; /* We are already in the desired discipline */ + ld = tty_ldisc_get(ldisc); + /* Eduardo Blanco */ + /* Cyrus Durgin */ + if (ld == NULL) + { + char modname [20]; + sprintf(modname, "tty-ldisc-%d", ldisc); + request_module (modname); + ld = tty_ldisc_get(ldisc); + } + + if (ld == NULL) + return -EINVAL; + + + o_ldisc = tty->ldisc; tty_wait_until_sent(tty, 0); + + /* + * Make sure we don't change while someone holds a + * reference to the line discipline. The TTY_LDISC bit + * prevents anyone taking a reference once it is clear. + * We need the lock to avoid racing reference takers. + */ + + spin_lock_irqsave(&tty_ldisc_lock, flags); + if(tty->ldisc.refcount) + { + /* Free the new ldisc we grabbed. Must drop the lock + first. */ + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + tty_ldisc_put(ldisc); + /* + * There are several reasons we may be busy, including + * random momentary I/O traffic. We must therefore + * retry. We could distinguish between blocking ops + * and retries if we made tty_ldisc_wait() smarter. That + * is up for discussion. + */ + if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0) + return -ERESTARTSYS; + goto restart; + } + clear_bit(TTY_LDISC, &tty->flags); + clear_bit(TTY_DONT_FLIP, &tty->flags); + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + + /* + * From this point on we know nobody has an ldisc + * usage reference, nor can they obtain one until + * we say so later on. + */ + + /* + * Wait for ->hangup_work and ->flip.work handlers to terminate + */ + run_task_queue(&tq_timer); + flush_scheduled_tasks(); /* Shutdown the current discipline. */ if (tty->ldisc.close) (tty->ldisc.close)(tty); /* Now set up the new line discipline. */ - tty->ldisc = ldiscs[ldisc]; - tty->termios->c_line = ldisc; + tty_ldisc_assign(tty, ld); + tty_set_termios_ldisc(tty, ldisc); if (tty->ldisc.open) retval = (tty->ldisc.open)(tty); if (retval < 0) { - tty->ldisc = o_ldisc; - tty->termios->c_line = tty->ldisc.num; + tty_ldisc_put(ldisc); + /* There is an outstanding reference here so this is safe */ + tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num)); + tty_set_termios_ldisc(tty, tty->ldisc.num); if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { - tty->ldisc = ldiscs[N_TTY]; - tty->termios->c_line = N_TTY; + tty_ldisc_put(o_ldisc.num); + /* This driver is always present */ + tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); + tty_set_termios_ldisc(tty, N_TTY); if (tty->ldisc.open) { int r = tty->ldisc.open(tty); @@ -331,8 +581,21 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) } } } + /* At this point we hold a reference to the new ldisc and a + reference to the old ldisc. If we ended up flipping back + to the existing ldisc we have two references to it */ + if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc) tty->driver.set_ldisc(tty); + + tty_ldisc_put(o_ldisc.num); + + /* + * Allow ldisc referencing to occur as soon as the driver + * ldisc callback completes. + */ + tty_ldisc_enable(tty); + return retval; } @@ -434,11 +697,55 @@ static struct file_operations hung_up_tty_fops = { static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED; static struct file *redirect; + +/** + * tty_wakeup - request more data + * @tty: terminal + * + * Internal and external helper for wakeups of tty. This function + * informs the line discipline if present that the driver is ready\ + * to receive more output data. + */ + +void tty_wakeup(struct tty_struct *tty) +{ + struct tty_ldisc *ld; + + if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { + ld = tty_ldisc_ref(tty); + if(ld) { + if(ld->write_wakeup) + ld->write_wakeup(tty); + tty_ldisc_deref(ld); + } + } + wake_up_interruptible(&tty->write_wait); +} + /* - * This can be called by the "eventd" kernel thread. That is process synchronous, - * but doesn't hold any locks, so we need to make sure we have the appropriate - * locks for what we're doing.. + * tty_wakeup/tty_ldisc_flush are actually _GPL exports but we can't do + * that in 2.4 for modutils compat reasons. */ +EXPORT_SYMBOL(tty_wakeup); + + +void tty_ldisc_flush(struct tty_struct *tty) +{ + struct tty_ldisc *ld = tty_ldisc_ref(tty); + if(ld) { + if(ld->flush_buffer) + ld->flush_buffer(tty); + tty_ldisc_deref(ld); + } +} + + +/* + * tty_wakeup/tty_ldisc_flush are actually _GPL exports but we can't do + * that in 2.4 for modutils compat reasons. + */ +EXPORT_SYMBOL(tty_ldisc_flush); + void do_tty_hangup(void *data) { struct tty_struct *tty = (struct tty_struct *) data; @@ -446,6 +753,7 @@ void do_tty_hangup(void *data) struct file *f = NULL; struct task_struct *p; struct list_head *l; + struct tty_ldisc *ld; int closecount = 0, n; if (!tty) @@ -479,20 +787,22 @@ void do_tty_hangup(void *data) file_list_unlock(); /* FIXME! What are the locking issues here? This may me overdoing things.. */ + ld = tty_ldisc_ref(tty); + if(ld != NULL) { - unsigned long flags; - - save_flags(flags); cli(); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); + if (ld->flush_buffer) + ld->flush_buffer(tty); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); - if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - restore_flags(flags); + if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && ld->write_wakeup) + ld->write_wakeup(tty); + if (ld->hangup) + ld->hangup(tty); } + /* FIXME: Once we trust the LDISC code better we can wait here for + ldisc completion and fix the driver call race */ + wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->read_wait); @@ -500,21 +810,19 @@ void do_tty_hangup(void *data) * Shutdown the current line discipline, and reset it to * N_TTY. */ + if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) - *tty->termios = tty->driver.init_termios; - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); - tty->ldisc = ldiscs[N_TTY]; - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) { - int i = (tty->ldisc.open)(tty); - if (i < 0) - printk(KERN_ERR "do_tty_hangup: N_TTY open: " - "error %d\n", -i); - } + { + down(&tty->termios_sem); + *tty->termios = tty->driver.init_termios; + up(&tty->termios_sem); } - + + /* Defer ldisc switch */ + /* tty_deferred_ldisc_switch(N_TTY) + This should get done automatically when the port closes and + tty_release is called */ + read_lock(&tasklist_lock); for_each_task(p) { if ((tty->session > 0) && (p->session == tty->session) && @@ -545,6 +853,17 @@ void do_tty_hangup(void *data) tty->driver.close(tty, cons_filp); } else if (tty->driver.hangup) (tty->driver.hangup)(tty); + + /* We don't want to have driver/ldisc interactions beyond + the ones we did here. The driver layer expects no + calls after ->hangup() from the ldisc side. However we + can't yet guarantee all that */ + + set_bit(TTY_HUPPED, &tty->flags); + if(ld) { + tty_ldisc_enable(tty); + tty_ldisc_deref(ld); + } unlock_kernel(); if (f) fput(f); @@ -648,10 +967,8 @@ void start_tty(struct tty_struct *tty) } if (tty->driver.start) (tty->driver.start)(tty); - if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); + /* If we have a running line discipline it may need kicking */ + tty_wakeup(tty); } static ssize_t tty_read(struct file * file, char * buf, size_t count, @@ -660,6 +977,7 @@ static ssize_t tty_read(struct file * file, char * buf, size_t count, int i; struct tty_struct * tty; struct inode *inode; + struct tty_ldisc *ld; /* Can't seek (pread) on ttys. */ if (ppos != &file->f_pos) @@ -688,11 +1006,15 @@ static ssize_t tty_read(struct file * file, char * buf, size_t count, return -ERESTARTSYS; } #endif + /* We want to wait for the line discipline to sort out in this + situation */ + ld = tty_ldisc_ref_wait(tty); lock_kernel(); - if (tty->ldisc.read) - i = (tty->ldisc.read)(tty,file,buf,count); + if (ld->read) + i = (ld->read)(tty,file,buf,count); else i = -EIO; + tty_ldisc_deref(ld); unlock_kernel(); if (i > 0) inode->i_atime = CURRENT_TIME; @@ -761,6 +1083,8 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count, int is_console; struct tty_struct * tty; struct inode *inode = file->f_dentry->d_inode; + ssize_t ret; + struct tty_ldisc *ld; /* Can't seek (pwrite) on ttys. */ if (ppos != &file->f_pos) @@ -807,13 +1131,19 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count, } } #endif - if (!tty->ldisc.write) - return -EIO; - return do_tty_write(tty->ldisc.write, tty, file, - (const unsigned char *)buf, count); + + ld = tty_ldisc_ref_wait(tty); + if (!ld->write) + ret = -EIO; + else + ret = do_tty_write(ld->write, tty, file, + (const unsigned char __user *)buf, count); + tty_ldisc_deref(ld); + return ret; } -/* Semaphore to protect creating and releasing a tty */ +/* Semaphore to protect creating and releasing a tty. This is shared with + vt.c for deeply disgusting hack reasons */ static DECLARE_MUTEX(tty_sem); static void down_tty_sem(int index) @@ -975,7 +1305,10 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty) (tty->ldisc.close)(tty); goto release_mem_out; } + set_bit(TTY_LDISC, &o_tty->flags); + tty_ldisc_enable(o_tty); } + tty_ldisc_enable(tty); goto success; /* @@ -1003,7 +1336,9 @@ fast_track: } tty->count++; tty->driver = *driver; /* N.B. why do this every time?? */ - + /* FIXME */ + if(!test_bit(TTY_LDISC, &tty->flags)) + printk(KERN_ERR "init_dev but no ldisc\n"); success: *ret_tty = tty; @@ -1084,6 +1419,7 @@ static void release_dev(struct file * filp) int pty_master, tty_closing, o_tty_closing, do_sleep; int idx; char buf[64]; + unsigned long flags; tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev")) @@ -1275,25 +1611,60 @@ static void release_dev(struct file * filp) printk(KERN_DEBUG "freeing tty structure..."); #endif + /* + * Prevent flush_to_ldisc() from rescheduling the work for later. Then + * kill any delayed work. As this is the final close it does not + * race with the set_ldisc code path. + */ + clear_bit(TTY_LDISC, &tty->flags); + clear_bit(TTY_DONT_FLIP, &tty->flags); + + /* + * Wait for ->hangup_work and ->flip.work handlers to terminate + */ + + run_task_queue(&tq_timer); + flush_scheduled_tasks(); + + /* + * Wait for any short term users (we know they are just driver + * side waiters as the file is closing so user count on the file + * side is zero. + */ + + spin_lock_irqsave(&tty_ldisc_lock, flags); + while(tty->ldisc.refcount) + { + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); + spin_lock_irqsave(&tty_ldisc_lock, flags); + } + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + /* * Shutdown the current line discipline, and reset it to N_TTY. * N.B. why reset ldisc when we're releasing the memory?? + * FIXME: this MUST get fixed for the new reflocking */ if (tty->ldisc.close) (tty->ldisc.close)(tty); - tty->ldisc = ldiscs[N_TTY]; - tty->termios->c_line = N_TTY; + tty_ldisc_put(tty->ldisc.num); + + /* + * Switch the line discipline back + */ + tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); + tty_set_termios_ldisc(tty,N_TTY); + if (o_tty) { + /* FIXME: could o_tty be in setldisc here ? */ + clear_bit(TTY_LDISC, &o_tty->flags); if (o_tty->ldisc.close) (o_tty->ldisc.close)(o_tty); - o_tty->ldisc = ldiscs[N_TTY]; + tty_ldisc_put(o_tty->ldisc.num); + tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); + tty_set_termios_ldisc(o_tty,N_TTY); } - - /* - * Make sure that the tty's task queue isn't activated. - */ - run_task_queue(&tq_timer); - flush_scheduled_tasks(); /* * The release_mem function takes care of the details of clearing @@ -1468,14 +1839,18 @@ static int tty_release(struct inode * inode, struct file * filp) static unsigned int tty_poll(struct file * filp, poll_table * wait) { struct tty_struct * tty; + struct tty_ldisc *ld; + int ret = 0; tty = (struct tty_struct *)filp->private_data; if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll")) return 0; - if (tty->ldisc.poll) - return (tty->ldisc.poll)(tty, filp, wait); - return 0; + ld = tty_ldisc_ref_wait(tty); + if (ld->poll) + ret = (ld->poll)(tty, filp, wait); + tty_ldisc_deref(ld); + return ret; } static int tty_fasync(int fd, struct file * filp, int on) @@ -1509,12 +1884,15 @@ static int tty_fasync(int fd, struct file * filp, int on) static int tiocsti(struct tty_struct *tty, char * arg) { char ch, mbz = 0; + struct tty_ldisc *ld; if ((current->tty != tty) && !suser()) return -EPERM; if (get_user(ch, arg)) return -EFAULT; - tty->ldisc.receive_buf(tty, &ch, &mbz, 1); + ld = tty_ldisc_ref_wait(tty); + ld->receive_buf(tty, &ch, &mbz, 1); + tty_ldisc_deref(ld); return 0; } @@ -1722,6 +2100,7 @@ int tty_ioctl(struct inode * inode, struct file * file, { struct tty_struct *tty, *real_tty; int retval; + struct tty_ldisc *ld; tty = (struct tty_struct *)file->private_data; if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl")) @@ -1812,6 +2191,7 @@ int tty_ioctl(struct inode * inode, struct file * file, case TIOCGSID: return tiocgsid(tty, real_tty, (pid_t *) arg); case TIOCGETD: + /* FIXME: check this is ok */ return put_user(tty->ldisc.num, (int *) arg); case TIOCSETD: return tiocsetd(tty, (int *) arg); @@ -1845,16 +2225,19 @@ int tty_ioctl(struct inode * inode, struct file * file, return send_break(tty, arg ? arg*(HZ/10) : HZ/4); } if (tty->driver.ioctl) { - int retval = (tty->driver.ioctl)(tty, file, cmd, arg); + retval = (tty->driver.ioctl)(tty, file, cmd, arg); if (retval != -ENOIOCTLCMD) return retval; } - if (tty->ldisc.ioctl) { - int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg); - if (retval != -ENOIOCTLCMD) - return retval; + ld = tty_ldisc_ref_wait(tty); + retval = -EINVAL; + if (ld->ioctl) { + retval = ld->ioctl(tty, file, cmd, arg); + if (retval == -ENOIOCTLCMD) + retval = -EINVAL; } - return -EINVAL; + tty_ldisc_deref(ld); + return retval; } @@ -1887,14 +2270,20 @@ static void __do_SAK(void *arg) int session; int i; struct file *filp; + struct tty_ldisc *disc; if (!tty) return; session = tty->session; - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); + /* We don't want an ldisc switch during this */ + disc = tty_ldisc_ref(tty); + if (disc && disc->flush_buffer) + disc->flush_buffer(tty); + tty_ldisc_deref(disc); + if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); + read_lock(&tasklist_lock); for_each_task(p) { if ((p->tty == tty) || @@ -1946,11 +2335,16 @@ static void flush_to_ldisc(void *private_) unsigned char *cp; char *fp; int count; - unsigned long flags; + unsigned long flags; + struct tty_ldisc *disc; + + disc = tty_ldisc_ref(tty); + if (disc == NULL) /* !TTY_LDISC */ + return; if (test_bit(TTY_DONT_FLIP, &tty->flags)) { queue_task(&tty->flip.tqueue, &tq_timer); - return; + goto out; } if (tty->flip.buf_num) { cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE; @@ -1973,7 +2367,31 @@ static void flush_to_ldisc(void *private_) tty->flip.count = 0; restore_flags(flags); - tty->ldisc.receive_buf(tty, cp, fp, count); + disc->receive_buf(tty, cp, fp, count); +out: + tty_ldisc_deref(disc); +} + +/* + * Call the ldisc flush directly from a driver. This function may + * return an error and need retrying by the user. + */ + +int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count) +{ + int ret = 0; + struct tty_ldisc *disc; + + disc = tty_ldisc_ref(tty); + if(test_bit(TTY_DONT_FLIP, &tty->flags)) + ret = -EAGAIN; + else if(disc == NULL) + ret = -EIO; + else + disc->receive_buf(tty, cp, fp, count); + tty_ldisc_deref(disc); + return ret; + } /* @@ -2036,13 +2454,14 @@ static void initialize_tty_struct(struct tty_struct *tty) { memset(tty, 0, sizeof(struct tty_struct)); tty->magic = TTY_MAGIC; - tty->ldisc = ldiscs[N_TTY]; + tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); tty->pgrp = -1; tty->flip.char_buf_ptr = tty->flip.char_buf; tty->flip.flag_buf_ptr = tty->flip.flag_buf; tty->flip.tqueue.routine = flush_to_ldisc; tty->flip.tqueue.data = tty; init_MUTEX(&tty->flip.pty_sem); + init_MUTEX(&tty->termios_sem); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); tty->tq_hangup.routine = do_tty_hangup; @@ -2221,7 +2640,7 @@ int tty_unregister_driver(struct tty_driver *driver) void __init console_init(void) { /* Setup the default TTY line discipline. */ - memset(ldiscs, 0, sizeof(ldiscs)); + memset(tty_ldiscs, 0, NR_LDISCS*sizeof(struct tty_ldisc)); (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY); /* diff --git a/linux-2.4.28-xen-sparse/drivers/scsi/aic7xxx/Makefile b/linux-2.4.29-xen-sparse/drivers/scsi/aic7xxx/Makefile similarity index 100% rename from linux-2.4.28-xen-sparse/drivers/scsi/aic7xxx/Makefile rename to linux-2.4.29-xen-sparse/drivers/scsi/aic7xxx/Makefile diff --git a/linux-2.4.28-xen-sparse/fs/exec.c b/linux-2.4.29-xen-sparse/fs/exec.c similarity index 97% rename from linux-2.4.28-xen-sparse/fs/exec.c rename to linux-2.4.29-xen-sparse/fs/exec.c index 16dc3193bf..8a114151a9 100644 --- a/linux-2.4.28-xen-sparse/fs/exec.c +++ b/linux-2.4.29-xen-sparse/fs/exec.c @@ -328,7 +328,7 @@ int setup_arg_pages(struct linux_binprm *bprm) { unsigned long stack_base; struct vm_area_struct *mpnt; - int i; + int i, ret; stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE; @@ -352,7 +352,11 @@ int setup_arg_pages(struct linux_binprm *bprm) mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; mpnt->vm_private_data = (void *) 0; - insert_vm_struct(current->mm, mpnt); + if ((ret = insert_vm_struct(current->mm, mpnt))) { + up_write(¤t->mm->mmap_sem); + kmem_cache_free(vm_area_cachep, mpnt); + return ret; + } current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } @@ -564,12 +568,29 @@ static inline void de_thread(struct task_struct *tsk) tsk->tgid = tsk->pid; } +void get_task_comm(char *buf, struct task_struct *tsk) +{ + /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); + memcpy(buf, tsk->comm, sizeof(tsk->comm)); + task_unlock(tsk); +} + +void set_task_comm(struct task_struct *tsk, char *buf) +{ + task_lock(tsk); + strncpy(tsk->comm, buf, sizeof(tsk->comm)); + tsk->comm[sizeof(tsk->comm)-1]='\0'; + task_unlock(tsk); +} + int flush_old_exec(struct linux_binprm * bprm) { char * name; int i, ch, retval; struct signal_struct * oldsig; struct files_struct * files; + char tcomm[sizeof(current->comm)]; /* * Make sure we have a private signal table @@ -611,10 +632,11 @@ int flush_old_exec(struct linux_binprm * bprm) if (ch == '/') i = 0; else - if (i < 15) - current->comm[i++] = ch; + if (i < (sizeof(tcomm) - 1)) + tcomm[i++] = ch; } - current->comm[i] = '\0'; + tcomm[i] = '\0'; + set_task_comm(current, tcomm); flush_thread(); diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/bugs.h b/linux-2.4.29-xen-sparse/include/asm-xen/bugs.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/bugs.h rename to linux-2.4.29-xen-sparse/include/asm-xen/bugs.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/desc.h b/linux-2.4.29-xen-sparse/include/asm-xen/desc.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/desc.h rename to linux-2.4.29-xen-sparse/include/asm-xen/desc.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/fixmap.h b/linux-2.4.29-xen-sparse/include/asm-xen/fixmap.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/fixmap.h rename to linux-2.4.29-xen-sparse/include/asm-xen/fixmap.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/highmem.h b/linux-2.4.29-xen-sparse/include/asm-xen/highmem.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/highmem.h rename to linux-2.4.29-xen-sparse/include/asm-xen/highmem.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/hw_irq.h b/linux-2.4.29-xen-sparse/include/asm-xen/hw_irq.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/hw_irq.h rename to linux-2.4.29-xen-sparse/include/asm-xen/hw_irq.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/io.h b/linux-2.4.29-xen-sparse/include/asm-xen/io.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/io.h rename to linux-2.4.29-xen-sparse/include/asm-xen/io.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/irq.h b/linux-2.4.29-xen-sparse/include/asm-xen/irq.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/irq.h rename to linux-2.4.29-xen-sparse/include/asm-xen/irq.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/keyboard.h b/linux-2.4.29-xen-sparse/include/asm-xen/keyboard.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/keyboard.h rename to linux-2.4.29-xen-sparse/include/asm-xen/keyboard.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/mmu_context.h b/linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/mmu_context.h rename to linux-2.4.29-xen-sparse/include/asm-xen/mmu_context.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/module.h b/linux-2.4.29-xen-sparse/include/asm-xen/module.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/module.h rename to linux-2.4.29-xen-sparse/include/asm-xen/module.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/msr.h b/linux-2.4.29-xen-sparse/include/asm-xen/msr.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/msr.h rename to linux-2.4.29-xen-sparse/include/asm-xen/msr.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/page.h b/linux-2.4.29-xen-sparse/include/asm-xen/page.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/page.h rename to linux-2.4.29-xen-sparse/include/asm-xen/page.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/pci.h b/linux-2.4.29-xen-sparse/include/asm-xen/pci.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/pci.h rename to linux-2.4.29-xen-sparse/include/asm-xen/pci.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/pgalloc.h b/linux-2.4.29-xen-sparse/include/asm-xen/pgalloc.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/pgalloc.h rename to linux-2.4.29-xen-sparse/include/asm-xen/pgalloc.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/pgtable-2level.h b/linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/pgtable-2level.h rename to linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/pgtable.h b/linux-2.4.29-xen-sparse/include/asm-xen/pgtable.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/pgtable.h rename to linux-2.4.29-xen-sparse/include/asm-xen/pgtable.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/processor.h b/linux-2.4.29-xen-sparse/include/asm-xen/processor.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/processor.h rename to linux-2.4.29-xen-sparse/include/asm-xen/processor.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/queues.h b/linux-2.4.29-xen-sparse/include/asm-xen/queues.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/queues.h rename to linux-2.4.29-xen-sparse/include/asm-xen/queues.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/segment.h b/linux-2.4.29-xen-sparse/include/asm-xen/segment.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/segment.h rename to linux-2.4.29-xen-sparse/include/asm-xen/segment.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/smp.h b/linux-2.4.29-xen-sparse/include/asm-xen/smp.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/smp.h rename to linux-2.4.29-xen-sparse/include/asm-xen/smp.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/synch_bitops.h b/linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/synch_bitops.h rename to linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/system.h b/linux-2.4.29-xen-sparse/include/asm-xen/system.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/system.h rename to linux-2.4.29-xen-sparse/include/asm-xen/system.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/vga.h b/linux-2.4.29-xen-sparse/include/asm-xen/vga.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/vga.h rename to linux-2.4.29-xen-sparse/include/asm-xen/vga.h diff --git a/linux-2.4.28-xen-sparse/include/asm-xen/xor.h b/linux-2.4.29-xen-sparse/include/asm-xen/xor.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/asm-xen/xor.h rename to linux-2.4.29-xen-sparse/include/asm-xen/xor.h diff --git a/linux-2.4.28-xen-sparse/include/linux/blk.h b/linux-2.4.29-xen-sparse/include/linux/blk.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/linux/blk.h rename to linux-2.4.29-xen-sparse/include/linux/blk.h diff --git a/linux-2.4.28-xen-sparse/include/linux/irq.h b/linux-2.4.29-xen-sparse/include/linux/irq.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/linux/irq.h rename to linux-2.4.29-xen-sparse/include/linux/irq.h diff --git a/linux-2.4.28-xen-sparse/include/linux/mm.h b/linux-2.4.29-xen-sparse/include/linux/mm.h similarity index 97% rename from linux-2.4.28-xen-sparse/include/linux/mm.h rename to linux-2.4.29-xen-sparse/include/linux/mm.h index 7efbd0adf0..10b81190c2 100644 --- a/linux-2.4.28-xen-sparse/include/linux/mm.h +++ b/linux-2.4.29-xen-sparse/include/linux/mm.h @@ -199,6 +199,11 @@ typedef struct page { #define page_count(p) atomic_read(&(p)->count) #define set_page_count(p,v) atomic_set(&(p)->count, v) +static inline struct page *nth_page(struct page *page, int n) +{ + return page + n; +} + /* * Various page->flags bits: * @@ -562,7 +567,7 @@ extern void __free_pte(pte_t); /* mmap.c */ extern void lock_vma_mappings(struct vm_area_struct *); extern void unlock_vma_mappings(struct vm_area_struct *); -extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); +extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void __insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void build_mmap_rb(struct mm_struct *); extern void exit_mmap(struct mm_struct *); @@ -661,18 +666,33 @@ static inline int expand_stack(struct vm_area_struct * vma, unsigned long addres unsigned long grow; /* - * vma->vm_start/vm_end cannot change under us because the caller is required - * to hold the mmap_sem in write mode. We need to get the spinlock only - * before relocating the vma range ourself. + * vma->vm_start/vm_end cannot change under us because the caller + * is required to hold the mmap_sem in read mode. We need the + * page_table_lock lock to serialize against concurrent expand_stacks. */ address &= PAGE_MASK; spin_lock(&vma->vm_mm->page_table_lock); + + /* already expanded while we were spinning? */ + if (vma->vm_start <= address) { + spin_unlock(&vma->vm_mm->page_table_lock); + return 0; + } + grow = (vma->vm_start - address) >> PAGE_SHIFT; if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) { spin_unlock(&vma->vm_mm->page_table_lock); return -ENOMEM; } + + if ((vma->vm_flags & VM_LOCKED) && + ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_MEMLOCK].rlim_cur) { + spin_unlock(&vma->vm_mm->page_table_lock); + return -ENOMEM; + } + + vma->vm_start = address; vma->vm_pgoff -= grow; vma->vm_mm->total_vm += grow; diff --git a/linux-2.4.28-xen-sparse/include/linux/sched.h b/linux-2.4.29-xen-sparse/include/linux/sched.h similarity index 99% rename from linux-2.4.28-xen-sparse/include/linux/sched.h rename to linux-2.4.29-xen-sparse/include/linux/sched.h index da2f49dfcf..9e318d7ed6 100644 --- a/linux-2.4.28-xen-sparse/include/linux/sched.h +++ b/linux-2.4.29-xen-sparse/include/linux/sched.h @@ -806,6 +806,9 @@ extern void daemonize(void); extern int do_execve(char *, char **, char **, struct pt_regs *); extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long); +extern void set_task_comm(struct task_struct *tsk, char *from); +extern void get_task_comm(char *to, struct task_struct *tsk); + extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); diff --git a/linux-2.4.28-xen-sparse/include/linux/skbuff.h b/linux-2.4.29-xen-sparse/include/linux/skbuff.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/linux/skbuff.h rename to linux-2.4.29-xen-sparse/include/linux/skbuff.h diff --git a/linux-2.4.28-xen-sparse/include/linux/timer.h b/linux-2.4.29-xen-sparse/include/linux/timer.h similarity index 100% rename from linux-2.4.28-xen-sparse/include/linux/timer.h rename to linux-2.4.29-xen-sparse/include/linux/timer.h diff --git a/linux-2.4.28-xen-sparse/kernel/time.c b/linux-2.4.29-xen-sparse/kernel/time.c similarity index 100% rename from linux-2.4.28-xen-sparse/kernel/time.c rename to linux-2.4.29-xen-sparse/kernel/time.c diff --git a/linux-2.4.28-xen-sparse/kernel/timer.c b/linux-2.4.29-xen-sparse/kernel/timer.c similarity index 100% rename from linux-2.4.28-xen-sparse/kernel/timer.c rename to linux-2.4.29-xen-sparse/kernel/timer.c diff --git a/linux-2.4.28-xen-sparse/mkbuildtree b/linux-2.4.29-xen-sparse/mkbuildtree similarity index 100% rename from linux-2.4.28-xen-sparse/mkbuildtree rename to linux-2.4.29-xen-sparse/mkbuildtree diff --git a/linux-2.4.28-xen-sparse/mm/highmem.c b/linux-2.4.29-xen-sparse/mm/highmem.c similarity index 100% rename from linux-2.4.28-xen-sparse/mm/highmem.c rename to linux-2.4.29-xen-sparse/mm/highmem.c diff --git a/linux-2.4.28-xen-sparse/mm/memory.c b/linux-2.4.29-xen-sparse/mm/memory.c similarity index 99% rename from linux-2.4.28-xen-sparse/mm/memory.c rename to linux-2.4.29-xen-sparse/mm/memory.c index 0dc91c305b..1ae2a42988 100644 --- a/linux-2.4.28-xen-sparse/mm/memory.c +++ b/linux-2.4.29-xen-sparse/mm/memory.c @@ -997,7 +997,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, if (PageReserved(old_page)) ++mm->rss; break_cow(vma, new_page, address, page_table); - lru_cache_add(new_page); + if (vm_anon_lru) + lru_cache_add(new_page); /* Free the old page.. */ new_page = old_page; @@ -1238,7 +1239,8 @@ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, mm->rss++; flush_page_to_ram(page); entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); - lru_cache_add(page); + if (vm_anon_lru) + lru_cache_add(page); mark_page_accessed(page); } @@ -1303,7 +1305,8 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma, } copy_user_highpage(page, new_page, address); page_cache_release(new_page); - lru_cache_add(page); + if (vm_anon_lru) + lru_cache_add(page); new_page = page; } diff --git a/linux-2.4.28-xen-sparse/mm/mprotect.c b/linux-2.4.29-xen-sparse/mm/mprotect.c similarity index 100% rename from linux-2.4.28-xen-sparse/mm/mprotect.c rename to linux-2.4.29-xen-sparse/mm/mprotect.c diff --git a/linux-2.4.28-xen-sparse/mm/mremap.c b/linux-2.4.29-xen-sparse/mm/mremap.c similarity index 97% rename from linux-2.4.28-xen-sparse/mm/mremap.c rename to linux-2.4.29-xen-sparse/mm/mremap.c index 965afa3805..330e194bae 100644 --- a/linux-2.4.28-xen-sparse/mm/mremap.c +++ b/linux-2.4.29-xen-sparse/mm/mremap.c @@ -198,6 +198,7 @@ static inline unsigned long move_vma(struct vm_area_struct * vma, insert_vm_struct(current->mm, new_vma); } + /* XXX: possible errors masked, mapping might remain */ do_munmap(current->mm, addr, old_len); current->mm->total_vm += new_len >> PAGE_SHIFT; @@ -238,6 +239,12 @@ unsigned long do_mremap(unsigned long addr, old_len = PAGE_ALIGN(old_len); new_len = PAGE_ALIGN(new_len); + if (old_len > TASK_SIZE || addr > TASK_SIZE - old_len) + goto out; + + if (addr >= TASK_SIZE) + goto out; + /* new_addr is only valid if MREMAP_FIXED is specified */ if (flags & MREMAP_FIXED) { if (new_addr & ~PAGE_MASK) @@ -247,6 +254,10 @@ unsigned long do_mremap(unsigned long addr, if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) goto out; + + if (new_addr >= TASK_SIZE) + goto out; + /* * Allow new_len == 0 only if new_addr == addr * to preserve truncation in place (that was working diff --git a/linux-2.4.28-xen-sparse/mm/page_alloc.c b/linux-2.4.29-xen-sparse/mm/page_alloc.c similarity index 100% rename from linux-2.4.28-xen-sparse/mm/page_alloc.c rename to linux-2.4.29-xen-sparse/mm/page_alloc.c diff --git a/linux-2.4.28-xen-sparse/mm/swapfile.c b/linux-2.4.29-xen-sparse/mm/swapfile.c similarity index 100% rename from linux-2.4.28-xen-sparse/mm/swapfile.c rename to linux-2.4.29-xen-sparse/mm/swapfile.c diff --git a/linux-2.4.28-xen-sparse/mm/vmalloc.c b/linux-2.4.29-xen-sparse/mm/vmalloc.c similarity index 100% rename from linux-2.4.28-xen-sparse/mm/vmalloc.c rename to linux-2.4.29-xen-sparse/mm/vmalloc.c diff --git a/linux-2.4.28-xen-sparse/net/core/skbuff.c b/linux-2.4.29-xen-sparse/net/core/skbuff.c similarity index 100% rename from linux-2.4.28-xen-sparse/net/core/skbuff.c rename to linux-2.4.29-xen-sparse/net/core/skbuff.c From 90c7adc7f0444609ee962fa15cdd0206f1135ba0 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 00:43:12 +0000 Subject: [PATCH 009/199] bitkeeper revision 1.1159.223.9 (41f05020SfVtxET_96qMp22pZ-tmOA) Update defconfig-xen0 for linux 2.4.29 --- .../arch/xen/defconfig-xen0 | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 index ace090e76d..ca10b9ef72 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 +++ b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 @@ -130,6 +130,7 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set +# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set @@ -160,6 +161,11 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set + # # IP: Netfilter Configuration # @@ -188,6 +194,7 @@ CONFIG_IP_NF_MATCH_STATE=m CONFIG_IP_NF_MATCH_CONNTRACK=m # CONFIG_IP_NF_MATCH_UNCLEAN is not set # CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_MATCH_PHYSDEV=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y # CONFIG_IP_NF_TARGET_MIRROR is not set @@ -195,6 +202,7 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m @@ -224,8 +232,32 @@ CONFIG_VLAN_8021Q=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set CONFIG_BRIDGE=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_IPF=m +CONFIG_BRIDGE_EBT_ARPF=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_VLANF=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_MARKF=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_MARK_T=m # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set @@ -395,7 +427,6 @@ CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_SCSI_MEGARAID=y # CONFIG_SCSI_MEGARAID2 is not set CONFIG_SCSI_SATA=y -# CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_NV is not set From a76a4247dd8d35f5506b7fa5a2b7628c956c1b3c Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 01:05:58 +0000 Subject: [PATCH 010/199] bitkeeper revision 1.1159.223.10 (41f05576mLJU5r_ZB3CGtm3RmSasYg) Fix linux 2.4.29 bug --- linux-2.4.29-xen-sparse/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.4.29-xen-sparse/Makefile b/linux-2.4.29-xen-sparse/Makefile index 29bcb96ccc..954de0b6d5 100644 --- a/linux-2.4.29-xen-sparse/Makefile +++ b/linux-2.4.29-xen-sparse/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 29 -EXTRAVERSION =-xenU +EXTRAVERSION = KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) From d6af4258a31148f23ca65b5d215f9849d8ea3f54 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 02:08:45 +0000 Subject: [PATCH 011/199] bitkeeper revision 1.1159.223.11 (41f0642dZhTGBhGAWv7_RECYAOxMhA) Update defconfig for linux 2.4.29 --- linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 index ca10b9ef72..4769ac7822 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 +++ b/linux-2.4.29-xen-sparse/arch/xen/defconfig-xen0 @@ -130,7 +130,6 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_MD is not set # CONFIG_BLK_DEV_MD is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set @@ -161,11 +160,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set - # # IP: Netfilter Configuration # @@ -202,7 +196,6 @@ CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=m CONFIG_IP_NF_NAT_FTP=m @@ -232,11 +225,6 @@ CONFIG_VLAN_8021Q=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set CONFIG_BRIDGE=y CONFIG_BRIDGE_NF_EBTABLES=m @@ -427,6 +415,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_SCSI_MEGARAID=y # CONFIG_SCSI_MEGARAID2 is not set CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_NV is not set From 2f32a8085286aaed3d81c5ca17bb6cad9a2a32a7 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 18:43:08 +0000 Subject: [PATCH 012/199] bitkeeper revision 1.1159.223.12 (41f14d3cE4GADmEAEr6XE9nXX4dyGw) Common-code cleanups. Moved arch-specific code out into arch/x86 and asm-x86. --- xen/arch/x86/dom0_ops.c | 158 +++++++++++++++++++++++++++++++ xen/arch/x86/domain.c | 42 ++++++++ xen/arch/x86/memory.c | 4 +- xen/common/Makefile | 2 + xen/common/dom0_ops.c | 158 ------------------------------- xen/common/domain.c | 14 +-- xen/common/elf.c | 34 +++++-- xen/common/keyhandler.c | 18 +--- xen/common/schedule.c | 11 +-- xen/common/softirq.c | 2 + xen/drivers/char/console.c | 5 +- xen/drivers/char/serial.c | 13 ++- xen/include/asm-x86/mm.h | 7 +- xen/include/public/arch-x86_32.h | 5 + xen/include/public/arch-x86_64.h | 5 + xen/include/public/xen.h | 5 - xen/include/xen/domain.h | 10 +- xen/include/xen/grant_table.h | 1 - xen/include/xen/slab.h | 10 ++ 19 files changed, 285 insertions(+), 219 deletions(-) diff --git a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c index 86479f1d17..d212324260 100644 --- a/xen/arch/x86/dom0_ops.c +++ b/xen/arch/x86/dom0_ops.c @@ -137,6 +137,164 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) } break; + case DOM0_IOPL: + { + extern long do_iopl(domid_t, unsigned int); + ret = do_iopl(op->u.iopl.domain, op->u.iopl.iopl); + } + break; + + case DOM0_PHYSINFO: + { + dom0_physinfo_t *pi = &op->u.physinfo; + + pi->ht_per_core = opt_noht ? 1 : ht_per_core; + pi->cores = smp_num_cpus / pi->ht_per_core; + pi->total_pages = max_page; + pi->free_pages = avail_domheap_pages(); + pi->cpu_khz = cpu_khz; + + copy_to_user(u_dom0_op, op, sizeof(*op)); + ret = 0; + } + break; + + case DOM0_GETPAGEFRAMEINFO: + { + struct pfn_info *page; + unsigned long pfn = op->u.getpageframeinfo.pfn; + domid_t dom = op->u.getpageframeinfo.domain; + struct domain *d; + + ret = -EINVAL; + + if ( unlikely(pfn >= max_page) || + unlikely((d = find_domain_by_id(dom)) == NULL) ) + break; + + page = &frame_table[pfn]; + + if ( likely(get_page(page, d)) ) + { + ret = 0; + + op->u.getpageframeinfo.type = NOTAB; + + if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) + { + switch ( page->u.inuse.type_info & PGT_type_mask ) + { + case PGT_l1_page_table: + op->u.getpageframeinfo.type = L1TAB; + break; + case PGT_l2_page_table: + op->u.getpageframeinfo.type = L2TAB; + break; + case PGT_l3_page_table: + op->u.getpageframeinfo.type = L3TAB; + break; + case PGT_l4_page_table: + op->u.getpageframeinfo.type = L4TAB; + break; + } + } + + put_page(page); + } + + put_domain(d); + + copy_to_user(u_dom0_op, op, sizeof(*op)); + } + break; + + case DOM0_GETPAGEFRAMEINFO2: + { +#define GPF2_BATCH 128 + int n,j; + int num = op->u.getpageframeinfo2.num; + domid_t dom = op->u.getpageframeinfo2.domain; + unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array; + struct domain *d; + unsigned long l_arr[GPF2_BATCH]; + ret = -ESRCH; + + if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) + break; + + if ( unlikely(num > 1024) ) + { + ret = -E2BIG; + break; + } + + ret = 0; + for( n = 0; n < num; ) + { + int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); + + if ( copy_from_user(l_arr, &s_ptr[n], k*sizeof(unsigned long)) ) + { + ret = -EINVAL; + break; + } + + for( j = 0; j < k; j++ ) + { + struct pfn_info *page; + unsigned long mfn = l_arr[j]; + + if ( unlikely(mfn >= max_page) ) + goto e2_err; + + page = &frame_table[mfn]; + + if ( likely(get_page(page, d)) ) + { + unsigned long type = 0; + + switch( page->u.inuse.type_info & PGT_type_mask ) + { + case PGT_l1_page_table: + type = L1TAB; + break; + case PGT_l2_page_table: + type = L2TAB; + break; + case PGT_l3_page_table: + type = L3TAB; + break; + case PGT_l4_page_table: + type = L4TAB; + break; + } + + if ( page->u.inuse.type_info & PGT_pinned ) + type |= LPINTAB; + l_arr[j] |= type; + put_page(page); + } + else + { + e2_err: + l_arr[j] |= XTAB; + } + + } + + if ( copy_to_user(&s_ptr[n], l_arr, k*sizeof(unsigned long)) ) + { + ret = -EINVAL; + break; + } + + n += j; + } + + put_domain(d); + } + break; + default: ret = -ENOSYS; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index fa73e458ef..2ba535a3ac 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -196,6 +196,48 @@ void machine_halt(void) __machine_halt(NULL); } +void dump_pageframe_info(struct domain *d) +{ + struct pfn_info *page; + struct list_head *ent; + + if ( d->tot_pages < 10 ) + { + list_for_each ( ent, &d->page_list ) + { + page = list_entry(ent, struct pfn_info, list); + printk("Page %08x: caf=%08x, taf=%08x\n", + page_to_phys(page), page->count_info, + page->u.inuse.type_info); + } + } + + page = virt_to_page(d->shared_info); + printk("Shared_info@%08x: caf=%08x, taf=%08x\n", + page_to_phys(page), page->count_info, + page->u.inuse.type_info); +} + +xmem_cache_t *domain_struct_cachep; +void __init domain_startofday(void) +{ + domain_struct_cachep = xmem_cache_create( + "domain_cache", sizeof(struct domain), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + if ( domain_struct_cachep == NULL ) + panic("No slab cache for domain structs."); +} + +struct domain *arch_alloc_domain_struct(void) +{ + return xmem_cache_alloc(domain_struct_cachep); +} + +void arch_free_domain_struct(struct domain *d) +{ + xmem_cache_free(domain_struct_cachep, d); +} + void free_perdomain_pt(struct domain *d) { free_xenheap_page((unsigned long)d->mm.perdomain_pt); diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index e51ae6235f..486d6ba407 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1325,7 +1325,7 @@ int do_mmu_update( u32 type_info; domid_t domid; - cleanup_writable_pagetable(d, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE); + cleanup_writable_pagetable(d); /* * If we are resuming after preemption, read how much work we have already @@ -1552,7 +1552,7 @@ int do_update_va_mapping(unsigned long page_nr, if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) ) return -EINVAL; - cleanup_writable_pagetable(d, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE); + cleanup_writable_pagetable(d); /* * XXX When we make this support 4MB superpages we should also deal with diff --git a/xen/common/Makefile b/xen/common/Makefile index 84e3a1292f..b764c1598a 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -2,6 +2,8 @@ include $(BASEDIR)/Rules.mk ifeq ($(TARGET_ARCH),ia64) +OBJS := $(subst dom_mem_ops.o,,$(OBJS)) +OBJS := $(subst grant_table.o,,$(OBJS)) OBJS := $(subst page_alloc.o,,$(OBJS)) OBJS := $(subst slab.o,,$(OBJS)) endif diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 4af61010df..e5b9f1d1e7 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -390,62 +390,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_GETPAGEFRAMEINFO: - { - struct pfn_info *page; - unsigned long pfn = op->u.getpageframeinfo.pfn; - domid_t dom = op->u.getpageframeinfo.domain; - struct domain *d; - - ret = -EINVAL; - - if ( unlikely(pfn >= max_page) || - unlikely((d = find_domain_by_id(dom)) == NULL) ) - break; - - page = &frame_table[pfn]; - - if ( likely(get_page(page, d)) ) - { - ret = 0; - - op->u.getpageframeinfo.type = NOTAB; - - if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) - { - switch ( page->u.inuse.type_info & PGT_type_mask ) - { - case PGT_l1_page_table: - op->u.getpageframeinfo.type = L1TAB; - break; - case PGT_l2_page_table: - op->u.getpageframeinfo.type = L2TAB; - break; - case PGT_l3_page_table: - op->u.getpageframeinfo.type = L3TAB; - break; - case PGT_l4_page_table: - op->u.getpageframeinfo.type = L4TAB; - break; - } - } - - put_page(page); - } - - put_domain(d); - - copy_to_user(u_dom0_op, op, sizeof(*op)); - } - break; - - case DOM0_IOPL: - { - extern long do_iopl(domid_t, unsigned int); - ret = do_iopl(op->u.iopl.domain, op->u.iopl.iopl); - } - break; - #ifdef XEN_DEBUGGER case DOM0_DEBUG: { @@ -482,21 +426,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_PHYSINFO: - { - dom0_physinfo_t *pi = &op->u.physinfo; - - pi->ht_per_core = opt_noht ? 1 : ht_per_core; - pi->cores = smp_num_cpus / pi->ht_per_core; - pi->total_pages = max_page; - pi->free_pages = avail_domheap_pages(); - pi->cpu_khz = cpu_khz; - - copy_to_user(u_dom0_op, op, sizeof(*op)); - ret = 0; - } - break; - case DOM0_PCIDEV_ACCESS: { extern int physdev_pci_access_modify(domid_t, int, int, int, int); @@ -549,93 +478,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_GETPAGEFRAMEINFO2: - { -#define GPF2_BATCH 128 - int n,j; - int num = op->u.getpageframeinfo2.num; - domid_t dom = op->u.getpageframeinfo2.domain; - unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array; - struct domain *d; - unsigned long l_arr[GPF2_BATCH]; - ret = -ESRCH; - - if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) - break; - - if ( unlikely(num > 1024) ) - { - ret = -E2BIG; - break; - } - - ret = 0; - for( n = 0; n < num; ) - { - int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); - - if ( copy_from_user(l_arr, &s_ptr[n], k*sizeof(unsigned long)) ) - { - ret = -EINVAL; - break; - } - - for( j = 0; j < k; j++ ) - { - struct pfn_info *page; - unsigned long mfn = l_arr[j]; - - if ( unlikely(mfn >= max_page) ) - goto e2_err; - - page = &frame_table[mfn]; - - if ( likely(get_page(page, d)) ) - { - unsigned long type = 0; - - switch( page->u.inuse.type_info & PGT_type_mask ) - { - case PGT_l1_page_table: - type = L1TAB; - break; - case PGT_l2_page_table: - type = L2TAB; - break; - case PGT_l3_page_table: - type = L3TAB; - break; - case PGT_l4_page_table: - type = L4TAB; - break; - } - - if ( page->u.inuse.type_info & PGT_pinned ) - type |= LPINTAB; - l_arr[j] |= type; - put_page(page); - } - else - { - e2_err: - l_arr[j] |= XTAB; - } - - } - - if ( copy_to_user(&s_ptr[n], l_arr, k*sizeof(unsigned long)) ) - { - ret = -EINVAL; - break; - } - - n += j; - } - - put_domain(d); - } - break; - case DOM0_SETDOMAINVMASSIST: { struct domain *d; diff --git a/xen/common/domain.c b/xen/common/domain.c index 42979c2fad..c2fe184267 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -22,18 +22,8 @@ rwlock_t domlist_lock = RW_LOCK_UNLOCKED; struct domain *domain_hash[DOMAIN_HASH_SIZE]; struct domain *domain_list; -xmem_cache_t *domain_struct_cachep; struct domain *dom0; -void __init domain_startofday(void) -{ - domain_struct_cachep = xmem_cache_create( - "domain_cache", sizeof(struct domain), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if ( domain_struct_cachep == NULL ) - panic("No slab cache for domain structs."); -} - struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) { struct domain *d, **pd; @@ -203,8 +193,8 @@ unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes) return -ENOMEM; } - /* initialise to machine_to_phys_mapping table to likely pfn */ - machine_to_phys_mapping[page-frame_table] = alloc_pfns; + /* Initialise the machine-to-phys mapping for this page. */ + set_machinetophys(page_to_pfn(page), alloc_pfns); } return 0; diff --git a/xen/common/elf.c b/xen/common/elf.c index 7f5a11e351..eae1c8fa10 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -10,6 +10,14 @@ #include #include +#ifdef CONFIG_X86 +#define FORCE_XENELF_IMAGE 1 +#define ELF_ADDR p_vaddr +#elif defined(__ia64__) +#define FORCE_XENELF_IMAGE 0 +#define ELF_ADDR p_paddr +#endif + static inline int is_loadable_phdr(Elf_Phdr *phdr) { return ((phdr->p_type == PT_LOAD) && @@ -84,7 +92,9 @@ int parseelfimage(char *elfbase, if ( guestinfo == NULL ) { printk("Not a Xen-ELF image: '__xen_guest' section not found.\n"); +#ifndef FORCE_XENELF_IMAGE return -EINVAL; +#endif } for ( h = 0; h < ehdr->e_phnum; h++ ) @@ -92,10 +102,10 @@ int parseelfimage(char *elfbase, phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); if ( !is_loadable_phdr(phdr) ) continue; - if ( phdr->p_vaddr < kernstart ) - kernstart = phdr->p_vaddr; - if ( (phdr->p_vaddr + phdr->p_memsz) > kernend ) - kernend = phdr->p_vaddr + phdr->p_memsz; + if ( phdr->ELF_ADDR < kernstart ) + kernstart = phdr->ELF_ADDR; + if ( (phdr->ELF_ADDR + phdr->p_memsz) > kernend ) + kernend = phdr->ELF_ADDR + phdr->p_memsz; } if ( (kernstart > kernend) || @@ -107,11 +117,15 @@ int parseelfimage(char *elfbase, } dsi->v_start = kernstart; - if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) - dsi->v_start = simple_strtoul(p+10, &p, 0); - if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) - dsi->use_writable_pagetables = 1; + if ( guestinfo != NULL ) + { + if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL ) + dsi->v_start = simple_strtoul(p+10, &p, 0); + + if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) + dsi->use_writable_pagetables = 1; + } dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; @@ -132,10 +146,10 @@ int loadelfimage(char *elfbase) if ( !is_loadable_phdr(phdr) ) continue; if ( phdr->p_filesz != 0 ) - memcpy((char *)phdr->p_vaddr, elfbase + phdr->p_offset, + memcpy((char *)phdr->ELF_ADDR, elfbase + phdr->p_offset, phdr->p_filesz); if ( phdr->p_memsz > phdr->p_filesz ) - memset((char *)phdr->p_vaddr + phdr->p_filesz, 0, + memset((char *)phdr->ELF_ADDR + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 8a9231e317..ef62fc4a5a 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -97,8 +97,6 @@ void do_task_queues(unsigned char key) { struct domain *d; s_time_t now = NOW(); - struct list_head *ent; - struct pfn_info *page; printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key, (u32)(now>>32), (u32)now); @@ -113,21 +111,7 @@ void do_task_queues(unsigned char key) test_bit(DF_RUNNING, &d->flags) ? 'T':'F', d->flags, atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages); - if ( d->tot_pages < 10 ) - { - list_for_each ( ent, &d->page_list ) - { - page = list_entry(ent, struct pfn_info, list); - printk("Page %08x: caf=%08x, taf=%08x\n", - page_to_phys(page), page->count_info, - page->u.inuse.type_info); - } - } - - page = virt_to_page(d->shared_info); - printk("Shared_info@%08x: caf=%08x, taf=%08x\n", - page_to_phys(page), page->count_info, - page->u.inuse.type_info); + dump_pageframe_info(d); printk("Guest: upcall_pend = %02x, upcall_mask = %02x\n", d->shared_info->vcpu_data[0].evtchn_upcall_pending, diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 8639e51465..5be947dc5a 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -89,26 +89,24 @@ static struct scheduler ops; /* Per-CPU periodic timer sends an event to the currently-executing domain. */ static struct ac_timer t_timer[NR_CPUS]; -extern xmem_cache_t *domain_struct_cachep; - void free_domain_struct(struct domain *d) { SCHED_OP(free_task, d); - xmem_cache_free(domain_struct_cachep, d); + arch_free_domain_struct(d); } struct domain *alloc_domain_struct(void) { struct domain *d; - if ( (d = xmem_cache_alloc(domain_struct_cachep)) == NULL ) + if ( (d = arch_alloc_domain_struct()) == NULL ) return NULL; memset(d, 0, sizeof(*d)); if ( SCHED_OP(alloc_task, d) < 0 ) { - xmem_cache_free(domain_struct_cachep, d); + arch_free_domain_struct(d); return NULL; } @@ -320,8 +318,7 @@ void __enter_scheduler(void) task_slice_t next_slice; s32 r_time; /* time for new dom to run */ - cleanup_writable_pagetable( - prev, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE); + cleanup_writable_pagetable(prev); perfc_incrc(sched_run); diff --git a/xen/common/softirq.c b/xen/common/softirq.c index 2a59925a07..17e850b3f6 100644 --- a/xen/common/softirq.c +++ b/xen/common/softirq.c @@ -15,7 +15,9 @@ #include #include +#ifndef __ARCH_IRQ_STAT irq_cpustat_t irq_stat[NR_CPUS]; +#endif static softirq_handler softirq_handlers[NR_SOFTIRQS]; diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index baa7adb496..75713575f4 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -18,6 +18,7 @@ #include #include #include +#include /* opt_console: comma-separated list of console outputs. */ static unsigned char opt_console[30] = "com1,vga"; @@ -31,7 +32,7 @@ static unsigned char opt_conswitch[5] = "a"; string_param("conswitch", opt_conswitch); static int xpos, ypos; -static unsigned char *video = __va(0xB8000); +static unsigned char *video; #define CONSOLE_RING_SIZE 16392 typedef struct console_ring_st @@ -137,6 +138,8 @@ static void init_vga(void) return; } + video = __va(0xB8000); + tmp = inb(0x3da); outb(0x00, 0x3c0); diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 43bae0b1a3..2c6fc895b4 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -100,6 +100,16 @@ static uart_t com[2] = { #define UART_ENABLED(_u) ((_u)->baud != 0) #define DISABLE_UART(_u) ((_u)->baud = 0) +#ifdef CONFIG_X86 +static inline int arch_serial_putc(uart_t *uart, unsigned char c) +{ + int space; + if ( (space = (inb(uart->io_base + LSR) & LSR_THRE)) ) + outb(c, uart->io_base + THR); + return space; +} +#endif + /*********************** * PRIVATE FUNCTIONS @@ -151,8 +161,7 @@ static inline void __serial_putc(uart_t *uart, int handle, unsigned char c) do { spin_lock_irqsave(&uart->lock, flags); - if ( (space = (inb(uart->io_base + LSR) & LSR_THRE)) ) - outb(c, uart->io_base + THR); + space = arch_serial_putc(uart, c); spin_unlock_irqrestore(&uart->lock, flags); } while ( !space ); diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index a37f9f2544..2af462e37d 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -224,6 +224,8 @@ extern unsigned long *machine_to_phys_mapping; extern unsigned long m2p_start_mfn; #endif +#define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn) + #define DEFAULT_GDT_ENTRIES (LAST_RESERVED_GDT_ENTRY+1) #define DEFAULT_GDT_ADDRESS ((unsigned long)gdt_table) @@ -285,10 +287,11 @@ do { \ ptwr_flush(PTWR_PT_INACTIVE); \ } while ( 0 ) -#define cleanup_writable_pagetable(_d, _w) \ +#define cleanup_writable_pagetable(_d) \ do { \ if ( unlikely(VM_ASSIST((_d), VMASST_TYPE_writable_pagetables)) ) \ - __cleanup_writable_pagetable(_w); \ + __cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | \ + PTWR_CLEANUP_INACTIVE); \ } while ( 0 ) #ifndef NDEBUG diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index b7210fc1b5..f3d402d2b3 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -9,6 +9,11 @@ #ifndef __XEN_PUBLIC_ARCH_X86_32_H__ #define __XEN_PUBLIC_ARCH_X86_32_H__ +#ifndef PACKED +/* GCC-specific way to pack structure definitions (no implicit padding). */ +#define PACKED __attribute__ ((packed)) +#endif + /* * Pointers and other address fields inside interface structures are padded to * 64 bits. This means that field alignments aren't different between 32- and diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 2144b0d63b..abba7bdf12 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -9,6 +9,11 @@ #ifndef __XEN_PUBLIC_ARCH_X86_64_H__ #define __XEN_PUBLIC_ARCH_X86_64_H__ +#ifndef PACKED +/* GCC-specific way to pack structure definitions (no implicit padding). */ +#define PACKED __attribute__ ((packed)) +#endif + /* Pointers are naturally 64 bits in this architecture; no padding needed. */ #define _MEMORY_PADDING(_X) #define MEMORY_PADDING diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 9817b1a9e8..ff13c0fb20 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -9,11 +9,6 @@ #ifndef __XEN_PUBLIC_XEN_H__ #define __XEN_PUBLIC_XEN_H__ -#ifndef PACKED -/* GCC-specific way to pack structure definitions (no implicit padding). */ -#define PACKED __attribute__ ((packed)) -#endif - #if defined(__i386__) #include "arch-x86_32.h" #elif defined(__x86_64__) diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 956e38087c..94d1e01635 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -2,12 +2,16 @@ #ifndef __XEN_DOMAIN_H__ #define __XEN_DOMAIN_H__ -extern void domain_startofday(void); - /* * Arch-specifics. */ +extern void domain_startofday(void); + +extern struct domain *arch_alloc_domain_struct(void); + +extern void arch_free_domain_struct(struct domain *d); + extern void arch_do_createdomain(struct domain *d); extern int arch_final_setup_guestos( @@ -17,4 +21,6 @@ extern void free_perdomain_pt(struct domain *d); extern void domain_relinquish_memory(struct domain *d); +extern void dump_pageframe_info(struct domain *d); + #endif /* __XEN_DOMAIN_H__ */ diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index eb9d8c15af..c161667cdf 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -25,7 +25,6 @@ #define __XEN_GRANT_H__ #include -#include #include /* Active grant entry - used for shadowing GTF_permit_access grants. */ diff --git a/xen/include/xen/slab.h b/xen/include/xen/slab.h index 81f43e8b47..692b3b63f3 100644 --- a/xen/include/xen/slab.h +++ b/xen/include/xen/slab.h @@ -6,6 +6,14 @@ #ifndef __SLAB_H__ #define __SLAB_H__ +#include + +#ifdef __ARCH_HAS_SLAB_ALLOCATOR + +#include + +#else + typedef struct xmem_cache_s xmem_cache_t; #include @@ -44,4 +52,6 @@ extern int xmem_cache_reap(void); extern void dump_slabinfo(); +#endif /* __ARCH_HAS_SLAB_ALLOCATOR */ + #endif /* __SLAB_H__ */ From aaa4b9f2f36d8857d0ce1f997b020a55fbd76c0b Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Fri, 21 Jan 2005 23:28:01 +0000 Subject: [PATCH 013/199] bitkeeper revision 1.1159.225.1 (41f19001RQR4BW0TNzYlpfwik2LIFg) Documentation fix. --- docs/src/user.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/user.tex b/docs/src/user.tex index 3b9d3773ca..a50300327c 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -1770,7 +1770,7 @@ editing \path{grub.conf}. possibilities are `bvt' (default), `atropos' and `rrobin'. For more information see Section~\ref{s:sched}. -\item [pci\_dom0\_hide=(xx.xx.x)(yy.yy.y)\ldots ] +\item [physdev\_dom0\_hide=(xx:xx.x)(yy:yy.y)\ldots ] Hide selected PCI devices from domain 0 (for instance, to stop it taking ownership of them so that they can be driven by another domain). Device IDs should be given in hex format. Bridge devices do From dce78bee0fe25b4484eab99757c3ec6269815cf5 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 17:10:17 +0000 Subject: [PATCH 014/199] bitkeeper revision 1.1159.223.14 (41f288f9VW8XW1rKJWnmSpC3nWXTgA) Kconfig cleanup suggested by Tobias Hunger [tobias@aquazul.com] Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.10-xen-sparse/arch/xen/Kconfig | 58 +++++++++--------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/Kconfig b/linux-2.6.10-xen-sparse/arch/xen/Kconfig index 13b3d1fed6..cfc3ea04c4 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/Kconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/Kconfig @@ -32,8 +32,7 @@ config XEN_PRIVILEGED_GUEST config XEN_PHYSDEV_ACCESS bool "Physical device access" - default y if XEN_PRIVILEGED_GUEST - default n if !XEN_PRIVILEGED_GUEST + default XEN_PRIVILEGED_GUEST help Assume access is available to physical hardware devices (e.g., hard drives, network cards). This allows you to configure @@ -42,8 +41,8 @@ config XEN_PHYSDEV_ACCESS config XEN_BLKDEV_BACKEND bool "Block-device backend driver" - default y if XEN_PHYSDEV_ACCESS - default n if !XEN_PHYSDEV_ACCESS + depends on XEN_PHYSDEV_ACCESS + default y help The block-device backend driver allows the kernel to export its block devices to other guests via a high-performance shared-memory @@ -51,8 +50,8 @@ config XEN_BLKDEV_BACKEND config XEN_NETDEV_BACKEND bool "Network-device backend driver" - default y if XEN_PHYSDEV_ACCESS - default n if !XEN_PHYSDEV_ACCESS + depends on XEN_PHYSDEV_ACCESS + default y help The network-device backend driver allows the kernel to export its network devices to other guests via a high-performance shared-memory @@ -76,9 +75,9 @@ config XEN_NETDEV_FRONTEND dedicated device-driver domain, or your master control domain (domain 0), then you almost certainly want to say Y here. -if XEN_NETDEV_FRONTEND config XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER bool "Pipelined transmitter (DANGEROUS)" + depends on XEN_NETDEV_FRONTEND default n help The driver will assume that the backend is pipelining packets for @@ -92,7 +91,6 @@ config XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER like reassembling packets to perform firewall filtering; or if you are unsure; or if you experience network hangs when this option is enabled; then you must say N here. -endif config XEN_WRITABLE_PAGETABLES bool @@ -109,40 +107,28 @@ config XEN_SCRUB_PAGES If security is not a concern then you may increase performance by saying N. +choice + prompt "Processor Type" + default X86 + +config X86 + bool "X86" + help + Choose this option if your computer is a X86 architecture. + +config X86_64 + bool "X86_64" + help + Choose this option if your computer is a X86 architecture. + +endchoice + endmenu config HAVE_ARCH_DEV_ALLOC_SKB bool default y -#config VT -# bool -# default y - -#config VT_CONSOLE -# bool -# default y - -#config HW_CONSOLE -# bool -# default y - -choice - prompt "Processor Type" - default X86 - -config X86 - bool "X86" - help - Choose this option if your computer is a X86 architecture. - -config X86_64 - bool "X86_64" - help - Choose this option if your computer is a X86 architecture. - -endchoice - source "init/Kconfig" if X86 From 8895336d36bbd9b98a09628549485b22e826c71a Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:23:10 +0000 Subject: [PATCH 015/199] bitkeeper revision 1.1159.223.15 (41f2c43e5U8GurDCsAUaiGJ2VOmnUQ) Description: Use proper targets in makefiles A rule in make should produce only what it's target allows. When it produces side-effects, things like ctrl-c and parallellism break it oddly. From Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/Makefile | 9 +++++---- xen/arch/x86/Makefile | 14 ++++++++++---- xen/common/Makefile | 3 ++- xen/drivers/acpi/Makefile | 3 ++- xen/drivers/char/Makefile | 3 ++- xen/drivers/pci/Makefile | 3 ++- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index 0c5c85e0f3..7eb1d17847 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -9,14 +9,15 @@ export BASEDIR := $(shell pwd) include Rules.mk -default: $(TARGET) - gzip -f -9 < $(TARGET) > $(TARGET).gz +default: $(TARGET).gz +$(TARGET).gz: $(TARGET) + gzip -f -9 < $< > $@.new + mv $@.new $@ debug: objdump -D -S $(TARGET)-syms > $(TARGET).s -install: $(TARGET) - gzip -f -9 < $(TARGET) > $(TARGET).gz +install: $(TARGET).gz mkdir -p $(prefix)/boot install -m0644 $(TARGET).gz $(prefix)/boot install -m0644 $(TARGET)-syms $(prefix)/boot diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 0062ce7678..574b0c35a5 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -12,12 +12,18 @@ OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c)) OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS)) -default: boot/$(TARGET_SUBARCH).o $(OBJS) boot/mkelf32 - $(LD) $(LDFLAGS) -r -o arch.o $(OBJS) - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ - boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $(TARGET)-syms +default: $(TARGET) + +$(TARGET): $(TARGET)-syms boot/mkelf32 ./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000 +$(CURDIR)/arch.o: $(OBJS) + $(LD) $(LDFLAGS) -r -o $@ $(OBJS) + +$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds + $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ + boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@ + asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(CC) $(CFLAGS) -S -o $@ $< diff --git a/xen/common/Makefile b/xen/common/Makefile index b764c1598a..1ae6148be2 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -21,7 +21,8 @@ ifneq ($(trace),y) OBJS := $(subst trace.o,,$(OBJS)) endif -default: $(OBJS) +default: common.o +common.o: $(OBJS) $(LD) $(LDFLAGS) -r -o common.o $(OBJS) clean: diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile index 2b80430148..fec92eb405 100644 --- a/xen/drivers/acpi/Makefile +++ b/xen/drivers/acpi/Makefile @@ -6,7 +6,8 @@ include $(BASEDIR)/Rules.mk OBJS := acpi_ksyms.o tables.o -default: $(OBJS) +default: driver.o +driver.o: $(OBJS) $(LD) $(LDFLAGS) -r -o driver.o $(OBJS) clean: diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile index f938f87017..957a4bc5a2 100644 --- a/xen/drivers/char/Makefile +++ b/xen/drivers/char/Makefile @@ -1,7 +1,8 @@ include $(BASEDIR)/Rules.mk -default: $(OBJS) +default: driver.o +driver.o: $(OBJS) $(LD) $(LDFLAGS) -r -o driver.o $(OBJS) clean: diff --git a/xen/drivers/pci/Makefile b/xen/drivers/pci/Makefile index 7fd6c1705f..040d5aaccd 100644 --- a/xen/drivers/pci/Makefile +++ b/xen/drivers/pci/Makefile @@ -28,7 +28,8 @@ OBJS := pci.o quirks.o compat.o names.o setup-res.o #obj-y += syscall.o #endif -default: $(OBJS) +default: driver.o +driver.o: $(OBJS) $(LD) $(LDFLAGS) -r -o driver.o $(OBJS) clean: From 7ebea330c936f8beca2e3fa3ec47d7228b421f63 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:30:03 +0000 Subject: [PATCH 016/199] bitkeeper revision 1.1159.223.16 (41f2c5dbDRm_plztIOBiTaL3Nj5qAQ) Description: support PIC code generation Libraries have 2 methods of being compiled; a .so must contain non-pic objects, while the .a can contain standard objects. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/libxc/Makefile | 34 +++++++++++++++++++++------------- tools/libxutil/Makefile | 11 ++++++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 6ee078644c..c8960c2a51 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -1,7 +1,8 @@ -MAJOR = 2.0 -MINOR = 0 -SONAME = libxc.so.$(MAJOR) +MAJOR := 2.0 +MINOR := 0 +LIB_NAME := libxc +SONAME := $(LIB_NAME).so.$(MAJOR) CC = gcc @@ -35,9 +36,10 @@ CFLAGS += $(INCLUDES) -I. CFLAGS += -Wp,-MD,.$(@F).d DEPS = .*.d -OBJS = $(patsubst %.c,%.o,$(SRCS)) +OBJS := $(patsubst %.c,%.o,$(SRCS)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) -LIB = libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) +LIB := $(LIB_NAME).a $(LIB_NAME).so $(LIB_NAME).so.$(MAJOR) $(LIB_NAME).so.$(MAJOR).$(MINOR) all: check-for-zlib mk-symlinks $(MAKE) $(LIB) @@ -65,12 +67,12 @@ install: all mkdir -p $(prefix)/usr/lib mkdir -p $(prefix)/usr/include install -m0755 $(LIB) $(prefix)/usr/lib - ln -sf libxc.so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/libxc.so.$(MAJOR) - ln -sf libxc.so.$(MAJOR) $(prefix)/usr/lib/libxc.so + ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/$(LIB_NAME).so.$(MAJOR) + ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so install -m0644 xc.h $(prefix)/usr/include clean: - rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) xen + rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen rpm: all rm -rf staging @@ -81,11 +83,17 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging -libxc.so: - ln -sf libxc.so.$(MAJOR) $@ -libxc.so.$(MAJOR): - ln -sf libxc.so.$(MAJOR).$(MINOR) $@ -libxc.so.$(MAJOR).$(MINOR): $(OBJS) +$(PIC_OBJS): %.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + +$(LIB_NAME).a: $(OBJS) + $(AR) rc $@ $^ + +$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) + ln -sf $< $@ +$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) + ln -sf $< $@ +$(LIB_NAME).so.$(MAJOR).$(MINOR): $(PIC_OBJS) $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -L../libxutil -lxutil -lz -include $(DEPS) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index b9034b5b8f..ae1b26ef6b 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -19,6 +19,7 @@ LIB_SRCS += sys_string.c LIB_SRCS += util.c LIB_OBJS := $(LIB_SRCS:.c=.o) +LIB_PIC_OBJS := $(LIB_SRCS:.c=.opic) CFLAGS += -Wall CFLAGS += -Werror @@ -33,6 +34,7 @@ DEPS = .*.d MAJOR := 2.0 MINOR := 0 LIB_NAME := libxutil +SO_NAME := $(LIB_NAME).so.$(MAJOR) LIB := $(LIB_NAME).so LIB += $(LIB_NAME).so.$(MAJOR) LIB += $(LIB_NAME).so.$(MAJOR).$(MINOR) @@ -41,14 +43,17 @@ LIB += $(LIB_NAME).a all: check-for-zlib $(MAKE) $(LIB) +$(LIB_PIC_OBJS): %.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + $(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) ln -sf $^ $@ $(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) ln -sf $^ $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_OBJS) - $(CC) -Wl,-soname -Wl,$(LIB_NAME).so.$(MAJOR) -shared -o $@ $^ +$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_PIC_OBJS) + $(CC) -Wl,-soname -Wl,$(SO_NAME) -shared -o $@ $^ $(LIB_NAME).a: $(LIB_OBJS) $(AR) rc $@ $^ @@ -68,7 +73,7 @@ install: all ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so clean: - $(RM) *.a *.so *.so.* *.o *.rpm + $(RM) *.a *.so *.so.* *.o *.opic *.rpm $(RM) *~ $(RM) $(DEPS) From dbaf99ecd4456954accb1e84013d857bb0ac2808 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:32:44 +0000 Subject: [PATCH 017/199] bitkeeper revision 1.1159.223.17 (41f2c67c7vKsSLIzqLuYY24HOjsC5w) Description: Use vars for complex programs It's generally standard to call complex programs indirectly thru make variables. This allows them to be replaced easily with alternative versions, without editting each makefile. Additionally, this patch makes use of $(pkgdocdir) in docs/Makefile. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- docs/Makefile | 53 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 86b5d8f1b1..f489fd776b 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,8 +1,21 @@ +#!/usr/bin/make -f -DOC_TEX := $(wildcard src/*.tex) -DOC_PS := $(patsubst src/%.tex,ps/%.ps,$(DOC_TEX)) -DOC_PDF := $(patsubst src/%.tex,pdf/%.pdf,$(DOC_TEX)) -DOC_HTML := $(patsubst src/%.tex,html/%/index.html,$(DOC_TEX)) + +PS2PDF := ps2pdf +DVIPS := dvips +LATEX := latex +FIG2DEV := fig2dev +TGIF := tgif +LATEX2HTML := latex2html + +package = xen +docdir = /usr/share/doc +pkgdocdir = $(docdir)/$(package) + +DOC_TEX := $(wildcard src/*.tex) +DOC_PS := $(patsubst src/%.tex,ps/%.ps,$(DOC_TEX)) +DOC_PDF := $(patsubst src/%.tex,pdf/%.pdf,$(DOC_TEX)) +DOC_HTML := $(patsubst src/%.tex,html/%/index.html,$(DOC_TEX)) GFX = $(patsubst %.obj, %.eps, $(wildcard figs/*.obj)) GFX += $(patsubst %.fig, %.eps, $(wildcard figs/*.fig)) @@ -22,30 +35,34 @@ clean: rm -rf $(GFX) ps pdf html install: all - rm -rf $(prefix)/usr/share/doc/xen - mkdir -p $(prefix)/usr/share/doc/xen - cp -dR ps $(prefix)/usr/share/doc/xen - cp -dR pdf $(prefix)/usr/share/doc/xen - cp -dR html $(prefix)/usr/share/doc/xen + rm -rf $(prefix)$(pkgdocdir) + mkdir -p $(prefix)$(pkgdocdir) + cp -dR ps $(prefix)$(pkgdocdir) + cp -dR pdf $(prefix)$(pkgdocdir) + cp -dR html $(prefix)$(pkgdocdir) pdf/%.pdf: ps/%.ps - mkdir -p pdf ; ps2pdf $< $@ + mkdir -p $(@D) + $(PS2PDF) $< $@.new + mv $@.new $@ ps/%.ps: %.dvi - mkdir -p ps ; dvips -Ppdf -G0 -o $@ $< + mkdir -p $(@D) + $(DVIPS) -Ppdf -G0 -o $@.new $< + mv $@.new $@ %.dvi: src/%.tex $(GFX) - latex $< >/dev/null - if [ -e $*.toc ] ; then latex $< >/dev/null ; fi + $(LATEX) $< >/dev/null + if [ -e $*.toc ] ; then $(LATEX) $< >/dev/null ; fi %.eps: %.fig - fig2dev -L eps $< $@ + $(FIG2DEV) -L eps $< $@ %.eps: %.obj - tgif -print -color -eps $< + $(TGIF) -print -color -eps $< html/%/index.html: src/%.tex - mkdir -p html/$* - latex2html -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ - -numbered_footnotes -local_icons -noinfo -math -dir html/$* \ + mkdir -p $(@D) + $(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ + -numbered_footnotes -local_icons -noinfo -math -dir $(@D) \ $< 1>/dev/null 2>/dev/null From 6b422c28fad9b0c0a9caf5c98eb8db1d7914e976 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:34:34 +0000 Subject: [PATCH 018/199] bitkeeper revision 1.1159.223.18 (41f2c6eamwtTkjdrv4CuL1WnOy4iGw) Description: use INSTALL everywhere Use install(by way of INSTALL variables) to create directories, install programs, and install data files. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 22 +++++++++++++--------- tools/examples/Makefile | 20 ++++++++++++-------- tools/libxc/Makefile | 12 ++++++++---- tools/libxutil/Makefile | 9 +++++++-- tools/misc/Makefile | 11 +++++++---- tools/misc/miniterm/Makefile | 7 +++++-- tools/sv/Makefile | 18 ++++++++++-------- tools/xentrace/Makefile | 16 ++++++++++------ tools/xfrd/Makefile | 8 ++++++-- xen/Makefile | 17 ++++++++++------- 10 files changed, 88 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 7332978f99..ecbc022e10 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,10 @@ DIST_DIR ?= $(shell pwd)/dist INSTALL_DIR ?= $(DIST_DIR)/install +INSTALL := install +INSTALL_DIR := $(INSTALL) -d -m0755 +INSTALL_DATA := $(INSTALL) -m0644 +INSTALL_PROG := $(INSTALL) -m0755 KERNELS ?= linux-2.6-xen0 linux-2.6-xenU # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU @@ -35,21 +39,21 @@ install-tools: $(MAKE) -C tools install install-kernels: - $(shell cp -a $(INSTALL_DIR)/boot/* /boot/) - $(shell cp -a $(INSTALL_DIR)/lib/modules/* /lib/modules/) - $(shell cp -dR $(INSTALL_DIR)/boot/*$(LINUX_VER)* $(prefix)/boot/) - $(shell cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/) + cp -a $(INSTALL_DIR)/boot/* /boot/ + cp -a $(INSTALL_DIR)/lib/modules/* /lib/modules/ + cp -dR $(INSTALL_DIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ + cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/ install-docs: sh ./docs/check_pkgs && $(MAKE) -C docs install || true # build and install everything into local dist directory dist: xen tools kernels docs - install -m0644 ./COPYING $(DIST_DIR) - install -m0644 ./README $(DIST_DIR) - install -m0755 ./install.sh $(DIST_DIR) - mkdir -p $(DIST_DIR)/check - install -m0755 tools/check/chk tools/check/check_* $(DIST_DIR)/check + $(INSTALL_DIR) $(DIST_DIR)/check + $(INSTALL_DATA) ./COPYING $(DIST_DIR) + $(INSTALL_DATA) ./README $(DIST_DIR) + $(INSTALL_PROG) ./install.sh $(DIST_DIR) + $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DIST_DIR)/check xen: $(MAKE) prefix=$(INSTALL_DIR) dist=yes -C xen install diff --git a/tools/examples/Makefile b/tools/examples/Makefile index 14f18ae84f..b19b9710ba 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -1,3 +1,7 @@ +INSTALL = install +INSTALL_DIR = $(INSTALL) -d -m0755 +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DATA = $(INSTALL) -m0644 # Init scripts. XEND_INITD = init.d/xend @@ -21,23 +25,23 @@ all: install: all install-initd install-configs install-scripts install-initd: - install -d $(prefix)/etc/init.d - install -m0755 $(XEND_INITD) $(prefix)/etc/init.d - install -m0755 $(XENDOMAINS_INITD) $(prefix)/etc/init.d + $(INSTALL_DIR) $(prefix)/etc/init.d + $(INSTALL_PROG) $(XEND_INITD) $(prefix)/etc/init.d + $(INSTALL_PROG) $(XENDOMAINS_INITD) $(prefix)/etc/init.d install-configs: - install -d $(prefix)$(XEN_CONFIG_DIR) - install -d $(prefix)$(XEN_CONFIG_DIR)/auto + $(INSTALL_DIR) $(prefix)$(XEN_CONFIG_DIR) + $(INSTALL_DIR) $(prefix)$(XEN_CONFIG_DIR)/auto for i in $(XEN_CONFIGS); \ do [ -a $(prefix)/$(XEN_CONFIG_DIR)/$$i ] || \ - install -m0644 $$i $(prefix)$(XEN_CONFIG_DIR); \ + $(INSTALL_DATA) $$i $(prefix)$(XEN_CONFIG_DIR); \ done install-scripts: - install -d $(prefix)$(XEN_SCRIPT_DIR) + $(INSTALL_DIR) $(prefix)$(XEN_SCRIPT_DIR) for i in $(XEN_SCRIPTS); \ do [ -a $(prefix)/$()/$$i ] || \ - install -m0755 $$i $(prefix)$(XEN_SCRIPT_DIR); \ + $(INSTALL_PROG) $$i $(prefix)$(XEN_SCRIPT_DIR); \ done clean: diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index c8960c2a51..c77b5c2767 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -1,3 +1,7 @@ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DATA = $(INSTALL) -m0644 +INSTALL_DIR = $(INSTALL) -d -m0755 MAJOR := 2.0 MINOR := 0 @@ -64,12 +68,12 @@ mk-symlinks: ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) install: all - mkdir -p $(prefix)/usr/lib - mkdir -p $(prefix)/usr/include - install -m0755 $(LIB) $(prefix)/usr/lib + $(INSTALL_DIR) $(prefix)/usr/lib + $(INSTALL_DIR) $(prefix)/usr/include + $(INSTALL_PROG) $(LIB) $(prefix)/usr/lib ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/$(LIB_NAME).so.$(MAJOR) ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so - install -m0644 xc.h $(prefix)/usr/include + $(INSTALL_DATA) xc.h $(prefix)/usr/include clean: rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index ae1b26ef6b..f576251224 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -1,4 +1,9 @@ XEN_ROOT = ../.. +INSTALL = install +INSTALL_DATA = $(INSTALL) -m0644 +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 + include $(XEN_ROOT)/tools/Make.defs CC = gcc @@ -67,8 +72,8 @@ check-for-zlib: fi install: all - mkdir -p $(prefix)/usr/lib - install -m0755 $(LIB) $(prefix)/usr/lib + $(INSTALL_DIR) -p $(prefix)/usr/lib + $(INSTALL_PROG) $(LIB) $(prefix)/usr/lib ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/$(LIB_NAME).so.$(MAJOR) ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 7c20e8d1b0..ab67ba8198 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -1,3 +1,6 @@ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 XEN_ROOT=../.. include $(XEN_ROOT)/tools/Make.defs @@ -20,10 +23,10 @@ all: $(TARGETS) $(MAKE) -C miniterm install: all - mkdir -p $(prefix)/usr/bin - mkdir -p $(prefix)/usr/sbin - install -m0755 $(INSTALL_BIN) $(prefix)/usr/bin - install -m0755 $(INSTALL_SBIN) $(prefix)/usr/sbin + $(INSTALL_DIR) $(prefix)/usr/bin + $(INSTALL_DIR) $(prefix)/usr/sbin + $(INSTALL_PROG) $(INSTALL_BIN) $(prefix)/usr/bin + $(INSTALL_PROG) $(INSTALL_SBIN) $(prefix)/usr/sbin $(MAKE) -C miniterm install clean: diff --git a/tools/misc/miniterm/Makefile b/tools/misc/miniterm/Makefile index 86e1bf0ccf..fbe4a5bcee 100644 --- a/tools/misc/miniterm/Makefile +++ b/tools/misc/miniterm/Makefile @@ -1,3 +1,6 @@ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 CC = gcc CFLAGS = -Wall -O3 @@ -6,8 +9,8 @@ TARGET = miniterm all: $(TARGET) install: all - mkdir -p $(prefix)/usr/bin - install -m0755 $(TARGET) $(prefix)/usr/bin + $(INSTALL_DIR) $(prefix)/usr/bin + $(INSTALL_PROG) $(TARGET) $(prefix)/usr/bin clean: $(RM) *.o $(TARGET) *~ diff --git a/tools/sv/Makefile b/tools/sv/Makefile index 8ae9a93f87..a285dc15d5 100755 --- a/tools/sv/Makefile +++ b/tools/sv/Makefile @@ -1,4 +1,7 @@ -sv_insdir := $(prefix)/var/xen/sv +sv_insdir := $(prefix)/var/xen/sv +INSTALL = install +INSTALL_DIR = $(INSTALL) -d -m0755 +INSTALL_DATA = $(INSTALL) -m0644 all: @@ -14,17 +17,16 @@ IMAGES += next.png previous.png finish.png install: # copy XenSV Main.rpy file - @mkdir -p $(sv_insdir) - @install -m0644 Main.rpy $(sv_insdir) + @$(INSTALL_DIR) $(sv_insdir) + @$(INSTALL_DATA) Main.rpy $(sv_insdir) # copy XenSV images - @mkdir -p $(sv_insdir)/images - @(cd images && install -m0644 $(IMAGES) $(sv_insdir)/images) + @($(INSTALL_DIR) $(sv_insdir)/images + @(cd images && $(INSTALL_DATA) $(IMAGES) $(sv_insdir)/images) # copy XenSV stylesheet - @mkdir -p $(sv_insdir)/inc - @install -m0644 inc/style.css $(sv_insdir)/inc - @install -m0644 inc/script.js $(sv_insdir)/inc + @$(INSTALL_DIR) $(sv_insdir)/inc + @$(INSTALL_DATA) inc/style.css inc/script.js $(sv_insdir)/inc clean: diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 1b13bd9d8b..c2545762a3 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -1,3 +1,7 @@ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 +INSTALL_DATA = $(INSTALL) -m0644 XEN_ROOT=../.. include $(XEN_ROOT)/tools/Make.defs @@ -20,12 +24,12 @@ MAN8 = $(wildcard *.8) all: $(BIN) install: all - mkdir -p $(prefix)/usr/bin - mkdir -p $(prefix)/usr/man/man1 - mkdir -p $(prefix)/usr/man/man8 - install -m0755 $(BIN) $(SCRIPTS) $(prefix)/usr/bin - install -m0644 $(MAN1) $(prefix)/usr/man/man1 - install -m0644 $(MAN8) $(prefix)/usr/man/man8 + $(INSTALL_DIR) $(prefix)/usr/bin + $(INSTALL_DIR) $(prefix)/usr/man/man1 + $(INSTALL_DIR) $(prefix)/usr/man/man8 + $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(prefix)/usr/bin + $(INSTALL_DATA) $(MAN1) $(prefix)/usr/man/man1 + $(INSTALL_DATA) $(MAN8) $(prefix)/usr/man/man8 clean: $(RM) *.a *.so *.o *.rpm $(BIN) diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 2330d829c4..07c17a3f35 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -4,6 +4,10 @@ # Mike Wray #============================================================================ +INSTALL = install +INSTALL_PROG = $(INSTALL) -m0755 +INSTALL_DIR = $(INSTALL) -d -m0755 + XEN_ROOT = ../.. include $(XEN_ROOT)/tools/Make.defs @@ -68,8 +72,8 @@ xfrd: $(XFRD_PROG_OBJ) .PHONY: install install: xfrd - mkdir -p $(prefix)/$(XFRD_INSTALL_DIR) - install -m 0755 xfrd $(prefix)/$(XFRD_INSTALL_DIR) + $(INSTALL_DIR) $(prefix)/$(XFRD_INSTALL_DIR) + $(INSTALL_PROG) xfrd $(prefix)/$(XFRD_INSTALL_DIR) .PHONY: libutil libutil: $(UTIL_LIB) diff --git a/xen/Makefile b/xen/Makefile index 7eb1d17847..28d8368464 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -1,3 +1,6 @@ +INSTALL = install +INSTALL_DATA = $(INSTALL) -m0644 +INSTALL_DIR = $(INSTALL) -d -m0755 # This is the correct place to edit the build version. # All other places this is stored (eg. compile.h) should be autogenerated. @@ -18,13 +21,13 @@ debug: objdump -D -S $(TARGET)-syms > $(TARGET).s install: $(TARGET).gz - mkdir -p $(prefix)/boot - install -m0644 $(TARGET).gz $(prefix)/boot - install -m0644 $(TARGET)-syms $(prefix)/boot - mkdir -p $(prefix)/usr/include/xen/io - install -m0644 include/public/*.h $(prefix)/usr/include/xen - install -m0644 include/public/io/*.h $(prefix)/usr/include/xen/io - install -m0644 include/public/COPYING $(prefix)/usr/include/xen + $(INSTALL_DIR) $(prefix)/boot + $(INSTALL_DATA) $(TARGET).gz $(prefix)/boot + $(INSTALL_DATA) $(TARGET)-syms $(prefix)/boot + $(INSTALL_DIR) $(prefix)/usr/include/xen/io + $(INSTALL_DATA) include/public/*.h $(prefix)/usr/include/xen + $(INSTALL_DATA) include/public/io/*.h $(prefix)/usr/include/xen/io + $(INSTALL_DATA) include/public/COPYING $(prefix)/usr/include/xen dist: $(TARGET) $(MAKE) prefix=`pwd`/../dist/install dist=yes install From 174b817ebc5c8c8ab34a822528ea74dc93697168 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:37:24 +0000 Subject: [PATCH 019/199] bitkeeper revision 1.1159.223.19 (41f2c794WPLLpYdW32MPpAaBhBhL0A) Description: mkbuildtree requires bash From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.4.29-xen-sparse/mkbuildtree | 2 +- linux-2.6.10-xen-sparse/mkbuildtree | 2 +- netbsd-2.0-xen-sparse/mkbuildtree | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-2.4.29-xen-sparse/mkbuildtree b/linux-2.4.29-xen-sparse/mkbuildtree index a0e52c2c5c..d586153418 100755 --- a/linux-2.4.29-xen-sparse/mkbuildtree +++ b/linux-2.4.29-xen-sparse/mkbuildtree @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # mkbuildtree # diff --git a/linux-2.6.10-xen-sparse/mkbuildtree b/linux-2.6.10-xen-sparse/mkbuildtree index d353015ff2..8ab2d42a7c 100755 --- a/linux-2.6.10-xen-sparse/mkbuildtree +++ b/linux-2.6.10-xen-sparse/mkbuildtree @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # mkbuildtree # diff --git a/netbsd-2.0-xen-sparse/mkbuildtree b/netbsd-2.0-xen-sparse/mkbuildtree index 1877db8a5e..0d5330d115 100755 --- a/netbsd-2.0-xen-sparse/mkbuildtree +++ b/netbsd-2.0-xen-sparse/mkbuildtree @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # mkbuildtree # From 273e434815f5930823933b876dd987395bd18f01 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:39:35 +0000 Subject: [PATCH 020/199] bitkeeper revision 1.1159.223.20 (41f2c8174klQJ8mMgM3YDtJ6GQBXjw) Missing prat of earlier patch. Description: use INSTALL everywhere Use install(by way of INSTALL variables) to create directories, install programs, and install data files. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- docs/Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index f489fd776b..e0b15b35a6 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,5 +1,7 @@ #!/usr/bin/make -f +INSTALL = install +INSTALL_DIR = $(INSTALL) -d -m0755 PS2PDF := ps2pdf DVIPS := dvips @@ -36,18 +38,18 @@ clean: install: all rm -rf $(prefix)$(pkgdocdir) - mkdir -p $(prefix)$(pkgdocdir) + $(INSTALL_DIR) $(prefix)$(pkgdocdir) cp -dR ps $(prefix)$(pkgdocdir) cp -dR pdf $(prefix)$(pkgdocdir) cp -dR html $(prefix)$(pkgdocdir) pdf/%.pdf: ps/%.ps - mkdir -p $(@D) + $(INSTALL_DIR) $(@D) $(PS2PDF) $< $@.new mv $@.new $@ ps/%.ps: %.dvi - mkdir -p $(@D) + $(INSTALL_DIR) $(@D) $(DVIPS) -Ppdf -G0 -o $@.new $< mv $@.new $@ @@ -62,7 +64,7 @@ ps/%.ps: %.dvi $(TGIF) -print -color -eps $< html/%/index.html: src/%.tex - mkdir -p $(@D) + $(INSTALL_DIR) $(@D) $(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ -numbered_footnotes -local_icons -noinfo -math -dir $(@D) \ $< 1>/dev/null 2>/dev/null From 2f2710b791a3061fab60d13491b1df26d79e2b5c Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:43:33 +0000 Subject: [PATCH 021/199] bitkeeper revision 1.1159.223.21 (41f2c905sBZq8YH0a-M9_-ucSA_KAQ) Description: support parallellism better Using shell for loops doesn't allow make to run it the most parallel modes. Use patsubst/addsuffix tricks to make this work. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 58 +++++++++++++++++++++------------------------------- xen/Makefile | 9 ++++---- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index ecbc022e10..230af6db05 100644 --- a/Makefile +++ b/Makefile @@ -30,25 +30,25 @@ all: dist # install everything into the standard system directories # NB: install explicitly does not check that everything is up to date! -install: install-tools install-xen install-kernels install-docs +install: xen.install tools.install kernels docs.install -install-xen: - $(MAKE) -C xen install - -install-tools: - $(MAKE) -C tools install - -install-kernels: +kernels.install: cp -a $(INSTALL_DIR)/boot/* /boot/ cp -a $(INSTALL_DIR)/lib/modules/* /lib/modules/ cp -dR $(INSTALL_DIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/ -install-docs: - sh ./docs/check_pkgs && $(MAKE) -C docs install || true +docs.install: + sh ./docs/check_pkgs && $(MAKE) -C docs install || true + +xen.install tools.install: %.install: + $(MAKE) -C $* install + +xen.dist tools.dist: %.dist: + $(MAKE) -C $* dist # build and install everything into local dist directory -dist: xen tools kernels docs +dist: xen.dist tools.dist kernels docs.install $(INSTALL_DIR) $(DIST_DIR)/check $(INSTALL_DATA) ./COPYING $(DIST_DIR) $(INSTALL_DATA) ./README $(DIST_DIR) @@ -61,8 +61,7 @@ xen: tools: $(MAKE) prefix=$(INSTALL_DIR) dist=yes -C tools install -kernels: - for i in $(XKERNELS) ; do $(MAKE) $$i-build ; done +kernels: $(addsuffix -build,$(XKERNELS)) docs: sh ./docs/check_pkgs && \ @@ -72,17 +71,13 @@ docs: kbuild: kernels # Delete the kernel build trees entirely -kdelete: - for i in $(XKERNELS) ; do $(MAKE) $$i-delete ; done +kdelete: $(addsuffix -clean,$(XKERNELS)) # Clean the kernel build trees -kclean: - for i in $(XKERNELS) ; do $(MAKE) $$i-clean ; done +kclean: $(addsuffix -clean,$(XKERNELS)) # Make patches from kernel sparse trees -mkpatches: - for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch ; done - +mkpatches: $(addsuffix -xen.patch,$(ALLSPARSETREES)) # build xen, the tools, and a domain 0 plus unprivileged linux-xen images, # and place them in the install directory. 'make install' should then @@ -93,16 +88,14 @@ world: $(MAKE) dist # clean doesn't do a kclean -clean: - $(MAKE) -C xen clean - $(MAKE) -C tools clean - $(MAKE) -C docs clean +clean: xen.clean tools.clean docs.clean + +xen.clean tools.clean docs.clean: %.clean: + $(MAKE) -C $* clean # clean, but blow away kernel build tree plus tar balls -mrproper: clean +mrproper: clean $(addsuffix -delete,$(ALLKERNELS)) $(addsuffix -mrproper,$(ALLSPARSETREES)) rm -rf dist patches/tmp - for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done - for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done install-twisted: wget http://www.twistedmatrix.com/products/get-current.epy @@ -165,13 +158,8 @@ uninstall: rm -rf "/usr/lib/python2.?/site-packages/xen* /usr/lib/libxc* /usr/lib/python2.?/site-packages/Xc*" # Legacy targets for compatibility -linux24: - $(MAKE) linux-2.4-xen0-build - $(MAKE) linux-2.4-xenU-build +linux24: linux-2.4-xen0-build linux-2.4-xenU-build -linux26: - $(MAKE) linux-2.6-xen0-build - $(MAKE) linux-2.6-xenU-build +linux26: linux-2.6-xen0-build linux-2.6-xenU-build -netbsd20: - $(MAKE) netbsd-2.0-xenU-build +netbsd20: netbsd-2.0-xenU-build diff --git a/xen/Makefile b/xen/Makefile index 28d8368464..4aa6330310 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -32,14 +32,13 @@ install: $(TARGET).gz dist: $(TARGET) $(MAKE) prefix=`pwd`/../dist/install dist=yes install -clean: - $(MAKE) -C tools clean - $(MAKE) -C common clean - $(MAKE) -C drivers clean - $(MAKE) -C arch/$(TARGET_ARCH) clean +clean: tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h rm -f include/asm-*/asm-offsets.h +tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean : %.clean: + $(MAKE) -C $* clean + $(TARGET): delete-unfresh-files [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm $(MAKE) -C tools From bce79d6f9804897cef40c7e42f9b9cbe87b8a3f1 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:45:39 +0000 Subject: [PATCH 022/199] bitkeeper revision 1.1159.223.22 (41f2c983tNSS8-VlWIzF9A78zTQx-w) Description: add force-reload option Debian policy requires init scripts to implement force-reload. So, alias that to restart. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/examples/init.d/xend | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/init.d/xend b/tools/examples/init.d/xend index 39324c7930..fc94c17dd2 100755 --- a/tools/examples/init.d/xend +++ b/tools/examples/init.d/xend @@ -32,14 +32,14 @@ case "$1" in status) xend status ;; - restart|reload) + restart|reload|force-reload) xend restart await_daemons_up ;; *) # do not advertise unreasonable commands that there is no reason # to use with this device - echo $"Usage: $0 {start|stop|status|restart|reload}" + echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}" exit 1 esac From 41df713e0177952d6b3b27effa780acc4aad9e69 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:47:15 +0000 Subject: [PATCH 023/199] bitkeeper revision 1.1159.223.23 (41f2c9e33H5dJn6K7RN-o2UASMwI3Q) Description: Use FHS-compatible paths From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/python/xen/sv/params.py | 4 ++-- tools/python/xen/xend/XendRoot.py | 2 +- tools/sv/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/sv/params.py b/tools/python/xen/sv/params.py index 16b764f088..beed647a4f 100644 --- a/tools/python/xen/sv/params.py +++ b/tools/python/xen/sv/params.py @@ -1,3 +1,3 @@ SV_PORT = 8080 -SV_ROOT = "/var/xen/sv/" -PID_FILE = "/var/xen/sv.pid" \ No newline at end of file +SV_ROOT = "/var/lib/xen/sv/" +PID_FILE = "/var/run/xen-sv.pid" diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index c9cc9a2279..dea3eeeb2f 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -20,7 +20,7 @@ class XendRoot: """Root of the management classes.""" """Default path to the root of the database.""" - dbroot_default = "/var/xen/xend-db" + dbroot_default = "/var/lib/xen/xend-db" """Default path to the config file.""" config_default = "/etc/xen/xend-config.sxp" diff --git a/tools/sv/Makefile b/tools/sv/Makefile index a285dc15d5..dc47b71e09 100755 --- a/tools/sv/Makefile +++ b/tools/sv/Makefile @@ -1,4 +1,4 @@ -sv_insdir := $(prefix)/var/xen/sv +sv_insdir := $(prefix)/var/lib/xen/sv INSTALL = install INSTALL_DIR = $(INSTALL) -d -m0755 INSTALL_DATA = $(INSTALL) -m0644 From 7f493a93051f8c2bf8700f084dfb812fcec56305 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:52:47 +0000 Subject: [PATCH 024/199] bitkeeper revision 1.1159.223.24 (41f2cb2floBkEBE6cfn2iLK2ZpPfhA) Description: conditionally call modules targets for 2.4 There was a complaint on the mailing list about linux 2.6 not building if module support was disabled; a patch was done to fix this. However, the same change was not done to the 2.4 files. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- buildconfigs/mk.linux-2.4-xen0 | 6 ++++-- buildconfigs/mk.linux-2.4-xenU | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/buildconfigs/mk.linux-2.4-xen0 b/buildconfigs/mk.linux-2.4-xen0 index b9f852eff8..e4a4537bc5 100644 --- a/buildconfigs/mk.linux-2.4-xen0 +++ b/buildconfigs/mk.linux-2.4-xen0 @@ -13,8 +13,10 @@ include buildconfigs/Rules.mk # The real action starts here! build: $(LINUX_DIR)/include/linux/autoconf.h - $(MAKE) -C $(LINUX_DIR) ARCH=xen modules - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install + if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + fi $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install patches/tmp/ebtables.diff: diff --git a/buildconfigs/mk.linux-2.4-xenU b/buildconfigs/mk.linux-2.4-xenU index a0937de4f6..86d38bb9d5 100644 --- a/buildconfigs/mk.linux-2.4-xenU +++ b/buildconfigs/mk.linux-2.4-xenU @@ -13,8 +13,10 @@ include buildconfigs/Rules.mk # The real action starts here! build: $(LINUX_DIR)/include/linux/autoconf.h - $(MAKE) -C $(LINUX_DIR) ARCH=xen modules - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install + if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + fi $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) From 84a280c8928e988f7e8fac3fe69f1b1e67d95da5 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 21:54:34 +0000 Subject: [PATCH 025/199] bitkeeper revision 1.1159.223.25 (41f2cb9aEKMZkZbvqBE0eXhpljlV4Q) Description: fix path to python There is no python2 in debian. Instead, use python. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/python/xen/xend/server/SrvServer.py | 2 +- tools/python/xen/xend/sxp.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 28ddaa7e48..353d6eed24 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/python # Copyright (C) 2004 Mike Wray """Example xend HTTP and console server. diff --git a/tools/python/xen/xend/sxp.py b/tools/python/xen/xend/sxp.py index 35b24aa8aa..e2c0de5c5b 100644 --- a/tools/python/xen/xend/sxp.py +++ b/tools/python/xen/xend/sxp.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/python # Copyright (C) 2004 Mike Wray """ Input-driven parsing for s-expression (sxp) format. From d2f5d53621f141ce1be63eeeae4a8a9e289498d8 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 22:03:34 +0000 Subject: [PATCH 026/199] bitkeeper revision 1.1159.223.26 (41f2cdb6LNpheOtPoAKEUn-czlZFig) Description: use DESTDIR correctly Standard makefiles always attempt to install to the root(/). Setting DESTDIR is the normal way to install to an alternative location. Setting prefix has the possibility of breaking programs, as the prefix may have been embedded inside a compiled binary. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 11 ++++++----- buildconfigs/mk.linux-2.4-xen0 | 4 ++-- buildconfigs/mk.linux-2.4-xenU | 4 ++-- buildconfigs/mk.linux-2.6-xen0 | 4 ++-- buildconfigs/mk.linux-2.6-xenU | 4 ++-- docs/Makefile | 13 +++++++------ tools/examples/Makefile | 20 ++++++++++---------- tools/libxc/Makefile | 12 ++++++------ tools/libxutil/Makefile | 8 ++++---- tools/misc/Makefile | 8 ++++---- tools/misc/miniterm/Makefile | 4 ++-- tools/python/Makefile | 6 +++++- tools/sv/Makefile | 14 +++++++------- tools/xentrace/Makefile | 12 ++++++------ tools/xfrd/Makefile | 4 ++-- xen/Makefile | 20 ++++++++++---------- 16 files changed, 77 insertions(+), 71 deletions(-) diff --git a/Makefile b/Makefile index 230af6db05..2e7d05cd19 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,9 @@ # Grand Unified Makefile for Xen. # -DIST_DIR ?= $(shell pwd)/dist -INSTALL_DIR ?= $(DIST_DIR)/install +DIST_DIR := $(CURDIR)/dist +DESTDIR := $(DIST_DIR)/install + INSTALL := install INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 @@ -18,7 +19,7 @@ ALLSPARSETREES = $(patsubst %-xen-sparse,%,$(wildcard *-xen-sparse)) XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) ) -export INSTALL_DIR +export DESTDIR include buildconfigs/Rules.mk @@ -56,10 +57,10 @@ dist: xen.dist tools.dist kernels docs.install $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DIST_DIR)/check xen: - $(MAKE) prefix=$(INSTALL_DIR) dist=yes -C xen install + $(MAKE) dist=yes -C xen install tools: - $(MAKE) prefix=$(INSTALL_DIR) dist=yes -C tools install + $(MAKE) dist=yes -C tools install kernels: $(addsuffix -build,$(XKERNELS)) diff --git a/buildconfigs/mk.linux-2.4-xen0 b/buildconfigs/mk.linux-2.4-xen0 index e4a4537bc5..c4f7fc359a 100644 --- a/buildconfigs/mk.linux-2.4-xen0 +++ b/buildconfigs/mk.linux-2.4-xen0 @@ -15,9 +15,9 @@ include buildconfigs/Rules.mk build: $(LINUX_DIR)/include/linux/autoconf.h if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \ fi - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install patches/tmp/ebtables.diff: mkdir -p patches/tmp diff --git a/buildconfigs/mk.linux-2.4-xenU b/buildconfigs/mk.linux-2.4-xenU index 86d38bb9d5..1c589faba2 100644 --- a/buildconfigs/mk.linux-2.4-xenU +++ b/buildconfigs/mk.linux-2.4-xenU @@ -15,9 +15,9 @@ include buildconfigs/Rules.mk build: $(LINUX_DIR)/include/linux/autoconf.h if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \ fi - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) rm -rf $(LINUX_DIR) diff --git a/buildconfigs/mk.linux-2.6-xen0 b/buildconfigs/mk.linux-2.6-xen0 index 82179c6c74..eda5bb46d8 100644 --- a/buildconfigs/mk.linux-2.6-xen0 +++ b/buildconfigs/mk.linux-2.6-xen0 @@ -15,9 +15,9 @@ include buildconfigs/Rules.mk build: $(LINUX_DIR)/include/linux/autoconf.h if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \ fi - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) rm -rf $(LINUX_DIR) diff --git a/buildconfigs/mk.linux-2.6-xenU b/buildconfigs/mk.linux-2.6-xenU index fa6e1109b3..ff6b47ff29 100644 --- a/buildconfigs/mk.linux-2.6-xenU +++ b/buildconfigs/mk.linux-2.6-xenU @@ -15,9 +15,9 @@ include buildconfigs/Rules.mk build: $(LINUX_DIR)/include/linux/autoconf.h if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \ $(MAKE) -C $(LINUX_DIR) ARCH=xen modules ; \ - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(INSTALL_DIR) modules_install ; \ + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_MOD_PATH=$(DESTDIR) modules_install ; \ fi - $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(INSTALL_DIR) install + $(MAKE) -C $(LINUX_DIR) ARCH=xen INSTALL_PATH=$(DESTDIR) install $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) rm -rf $(LINUX_DIR) diff --git a/docs/Makefile b/docs/Makefile index e0b15b35a6..46c2d38c59 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -11,7 +11,8 @@ TGIF := tgif LATEX2HTML := latex2html package = xen -docdir = /usr/share/doc +prefix = /usr +docdir = $(prefix)/share/doc pkgdocdir = $(docdir)/$(package) DOC_TEX := $(wildcard src/*.tex) @@ -37,11 +38,11 @@ clean: rm -rf $(GFX) ps pdf html install: all - rm -rf $(prefix)$(pkgdocdir) - $(INSTALL_DIR) $(prefix)$(pkgdocdir) - cp -dR ps $(prefix)$(pkgdocdir) - cp -dR pdf $(prefix)$(pkgdocdir) - cp -dR html $(prefix)$(pkgdocdir) + rm -rf $(DESTDIR)$(pkgdocdir) + $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir) + cp -dR ps $(DESTDIR)$(pkgdocdir) + cp -dR pdf $(DESTDIR)$(pkgdocdir) + cp -dR html $(DESTDIR)$(pkgdocdir) pdf/%.pdf: ps/%.ps $(INSTALL_DIR) $(@D) diff --git a/tools/examples/Makefile b/tools/examples/Makefile index b19b9710ba..0fb4950476 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -25,23 +25,23 @@ all: install: all install-initd install-configs install-scripts install-initd: - $(INSTALL_DIR) $(prefix)/etc/init.d - $(INSTALL_PROG) $(XEND_INITD) $(prefix)/etc/init.d - $(INSTALL_PROG) $(XENDOMAINS_INITD) $(prefix)/etc/init.d + $(INSTALL_DIR) $(DESTDIR)/etc/init.d + $(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d + $(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d install-configs: - $(INSTALL_DIR) $(prefix)$(XEN_CONFIG_DIR) - $(INSTALL_DIR) $(prefix)$(XEN_CONFIG_DIR)/auto + $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR) + $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto for i in $(XEN_CONFIGS); \ - do [ -a $(prefix)/$(XEN_CONFIG_DIR)/$$i ] || \ - $(INSTALL_DATA) $$i $(prefix)$(XEN_CONFIG_DIR); \ + do [ -a $(DESTDIR)/$(XEN_CONFIG_DIR)/$$i ] || \ + $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \ done install-scripts: - $(INSTALL_DIR) $(prefix)$(XEN_SCRIPT_DIR) + $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) for i in $(XEN_SCRIPTS); \ - do [ -a $(prefix)/$()/$$i ] || \ - $(INSTALL_PROG) $$i $(prefix)$(XEN_SCRIPT_DIR); \ + do [ -a $(DESTDIR)/$()/$$i ] || \ + $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \ done clean: diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index c77b5c2767..20714e0452 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -68,12 +68,12 @@ mk-symlinks: ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) install: all - $(INSTALL_DIR) $(prefix)/usr/lib - $(INSTALL_DIR) $(prefix)/usr/include - $(INSTALL_PROG) $(LIB) $(prefix)/usr/lib - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/$(LIB_NAME).so.$(MAJOR) - ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so - $(INSTALL_DATA) xc.h $(prefix)/usr/include + $(INSTALL_DIR) $(DESTDIR)/usr/lib + $(INSTALL_DIR) $(DESTDIR)/usr/include + $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib + ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) + ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so + $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include clean: rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index f576251224..9efb826b0b 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -72,10 +72,10 @@ check-for-zlib: fi install: all - $(INSTALL_DIR) -p $(prefix)/usr/lib - $(INSTALL_PROG) $(LIB) $(prefix)/usr/lib - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(prefix)/usr/lib/$(LIB_NAME).so.$(MAJOR) - ln -sf $(LIB_NAME).so.$(MAJOR) $(prefix)/usr/lib/$(LIB_NAME).so + $(INSTALL_DIR) -p $(DESTDIR)/usr/lib + $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib + ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) + ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so clean: $(RM) *.a *.so *.so.* *.o *.opic *.rpm diff --git a/tools/misc/Makefile b/tools/misc/Makefile index ab67ba8198..84166c72fc 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -23,10 +23,10 @@ all: $(TARGETS) $(MAKE) -C miniterm install: all - $(INSTALL_DIR) $(prefix)/usr/bin - $(INSTALL_DIR) $(prefix)/usr/sbin - $(INSTALL_PROG) $(INSTALL_BIN) $(prefix)/usr/bin - $(INSTALL_PROG) $(INSTALL_SBIN) $(prefix)/usr/sbin + $(INSTALL_DIR) $(DESTDIR)/usr/bin + $(INSTALL_DIR) $(DESTDIR)/usr/sbin + $(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin + $(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin $(MAKE) -C miniterm install clean: diff --git a/tools/misc/miniterm/Makefile b/tools/misc/miniterm/Makefile index fbe4a5bcee..e85ee3738e 100644 --- a/tools/misc/miniterm/Makefile +++ b/tools/misc/miniterm/Makefile @@ -9,8 +9,8 @@ TARGET = miniterm all: $(TARGET) install: all - $(INSTALL_DIR) $(prefix)/usr/bin - $(INSTALL_PROG) $(TARGET) $(prefix)/usr/bin + $(INSTALL_DIR) $(DESTDIR)/usr/bin + $(INSTALL_PROG) $(TARGET) $(DESTDIR)/usr/bin clean: $(RM) *.o $(TARGET) *~ diff --git a/tools/python/Makefile b/tools/python/Makefile index a3f4face53..9d39bd85b4 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -3,7 +3,11 @@ all: python setup.py build install: all - python setup.py install --home="$(prefix)/usr" + if [ "$(DESTDIR)" = "" ]; then \ + python setup.py install; \ + else \ + python setup.py install --root="$(DESTDIR)"; \ + fi clean: rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/sv/Makefile b/tools/sv/Makefile index dc47b71e09..c2b4e92dfc 100755 --- a/tools/sv/Makefile +++ b/tools/sv/Makefile @@ -1,4 +1,4 @@ -sv_insdir := $(prefix)/var/lib/xen/sv +sv_insdir := /var/lib/xen/sv INSTALL = install INSTALL_DIR = $(INSTALL) -d -m0755 INSTALL_DATA = $(INSTALL) -m0644 @@ -17,16 +17,16 @@ IMAGES += next.png previous.png finish.png install: # copy XenSV Main.rpy file - @$(INSTALL_DIR) $(sv_insdir) - @$(INSTALL_DATA) Main.rpy $(sv_insdir) + @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir) + @$(INSTALL_DATA) Main.rpy $(DESTDIR)$(sv_insdir) # copy XenSV images - @($(INSTALL_DIR) $(sv_insdir)/images - @(cd images && $(INSTALL_DATA) $(IMAGES) $(sv_insdir)/images) + @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/images + @(cd images && $(INSTALL_DATA) $(IMAGES) $(DESTDIR)$(sv_insdir)/images) # copy XenSV stylesheet - @$(INSTALL_DIR) $(sv_insdir)/inc - @$(INSTALL_DATA) inc/style.css inc/script.js $(sv_insdir)/inc + @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/inc + @$(INSTALL_DATA) inc/style.css inc/script.js $(DESTDIR)$(sv_insdir)/inc clean: diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index c2545762a3..9133271b66 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -24,12 +24,12 @@ MAN8 = $(wildcard *.8) all: $(BIN) install: all - $(INSTALL_DIR) $(prefix)/usr/bin - $(INSTALL_DIR) $(prefix)/usr/man/man1 - $(INSTALL_DIR) $(prefix)/usr/man/man8 - $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(prefix)/usr/bin - $(INSTALL_DATA) $(MAN1) $(prefix)/usr/man/man1 - $(INSTALL_DATA) $(MAN8) $(prefix)/usr/man/man8 + $(INSTALL_DIR) $(DESTDIR)/usr/bin + $(INSTALL_DIR) $(DESTDIR)/usr/man/man1 + $(INSTALL_DIR) $(DESTDIR)/usr/man/man8 + $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin + $(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/man/man1 + $(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/man/man8 clean: $(RM) *.a *.so *.o *.rpm $(BIN) diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 07c17a3f35..6ca1a1d12f 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -72,8 +72,8 @@ xfrd: $(XFRD_PROG_OBJ) .PHONY: install install: xfrd - $(INSTALL_DIR) $(prefix)/$(XFRD_INSTALL_DIR) - $(INSTALL_PROG) xfrd $(prefix)/$(XFRD_INSTALL_DIR) + $(INSTALL_DIR) $(DESTDIR)/$(XFRD_INSTALL_DIR) + $(INSTALL_PROG) xfrd $(DESTDIR)/$(XFRD_INSTALL_DIR) .PHONY: libutil libutil: $(UTIL_LIB) diff --git a/xen/Makefile b/xen/Makefile index 4aa6330310..b560ac1822 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -8,7 +8,8 @@ export XEN_VERSION = 2 export XEN_SUBVERSION = 0 export XEN_EXTRAVERSION = "" -export BASEDIR := $(shell pwd) +export BASEDIR := $(CURDIR) +DESTDIR := $(CURDIR)/../dist/install include Rules.mk @@ -21,16 +22,15 @@ debug: objdump -D -S $(TARGET)-syms > $(TARGET).s install: $(TARGET).gz - $(INSTALL_DIR) $(prefix)/boot - $(INSTALL_DATA) $(TARGET).gz $(prefix)/boot - $(INSTALL_DATA) $(TARGET)-syms $(prefix)/boot - $(INSTALL_DIR) $(prefix)/usr/include/xen/io - $(INSTALL_DATA) include/public/*.h $(prefix)/usr/include/xen - $(INSTALL_DATA) include/public/io/*.h $(prefix)/usr/include/xen/io - $(INSTALL_DATA) include/public/COPYING $(prefix)/usr/include/xen + $(INSTALL_DIR) $(DESTDIR)/boot + $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot + $(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot + $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io + $(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen + $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io + $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen -dist: $(TARGET) - $(MAKE) prefix=`pwd`/../dist/install dist=yes install +dist: install clean: tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h From feebe377b8dae7c5aae0900f0d9007f9366f47f2 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 22:05:19 +0000 Subject: [PATCH 027/199] bitkeeper revision 1.1159.223.27 (41f2ce1fr2yuEH_MHLrdXsDbSjsMJA) Description: fix non-standard make/shell syntax Fix use of `pwd`, &&, and || true. Also, remove (). From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 16 ++++++++-------- tools/Makefile | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 2e7d05cd19..5fcdc9f74c 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,8 @@ kernels.install: cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/ docs.install: - sh ./docs/check_pkgs && $(MAKE) -C docs install || true + sh ./docs/check_pkgs + -$(MAKE) -C docs install xen.install tools.install: %.install: $(MAKE) -C $* install @@ -65,8 +66,8 @@ tools: kernels: $(addsuffix -build,$(XKERNELS)) docs: - sh ./docs/check_pkgs && \ - $(MAKE) prefix=$(INSTALL_DIR) dist=yes -C docs install || true + sh ./docs/check_pkgs + -$(MAKE) dist=yes -C docs install # Build all the various kernels and modules kbuild: kernels @@ -101,20 +102,19 @@ mrproper: clean $(addsuffix -delete,$(ALLKERNELS)) $(addsuffix -mrproper,$(ALLSP install-twisted: wget http://www.twistedmatrix.com/products/get-current.epy tar -zxf Twisted-*.tar.gz - ( cd Twisted-* ; python setup.py install ) + cd Twisted-* && python setup.py install install-logging: LOGGING=logging-0.4.9.2 install-logging: [ -f $(LOGGING).tar.gz ] || wget http://www.red-dove.com/$(LOGGING).tar.gz tar -zxf $(LOGGING).tar.gz - ( cd $(LOGGING) && python setup.py install ) + cd $(LOGGING) && python setup.py install # handy target to upgrade iptables (use rpm or apt-get in preference) install-iptables: wget http://www.netfilter.org/files/iptables-1.2.11.tar.bz2 - tar -jxf iptables-*.tar.bz2 - ( cd iptables-* ; \ - make PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install) + tar -jxf iptables-1.2.11.tar.bz2 + $(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install help: @echo 'Installation targets:' diff --git a/tools/Makefile b/tools/Makefile index 6c9855bed7..a05c196d37 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,7 +23,7 @@ endif $(MAKE) -C sv install dist: $(TARGET) - $(MAKE) prefix=`pwd`/../../install dist=yes install + $(MAKE) prefix=$(CURDIR)/../../install dist=yes install clean: From 323114c5b34149b3b648ebdee08b24c78b0128de Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 22 Jan 2005 22:07:37 +0000 Subject: [PATCH 028/199] bitkeeper revision 1.1159.223.28 (41f2cea9tkhheORopsoScolnVoBxgw) Description: split banner.h Split banner.h, to make it easier to edit, and more properly fit in with normal build systems. Also, inline the rules to actually build figlet. From: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- .rootkeys | 2 ++ xen/Makefile | 48 +++++++++++++++++++----------------- xen/include/xen/banner.h | 12 +++++++++ xen/include/xen/compile.h.in | 13 ++++++++++ 4 files changed, 53 insertions(+), 22 deletions(-) create mode 100644 xen/include/xen/banner.h create mode 100644 xen/include/xen/compile.h.in diff --git a/.rootkeys b/.rootkeys index 0e6a0705b5..0dca6858e0 100644 --- a/.rootkeys +++ b/.rootkeys @@ -852,7 +852,9 @@ 3ddb79c25UE59iu4JJcbRalx95mvcg xen/include/public/xen.h 3e397e66m2tO3s-J8Jnr7Ws_tGoPTg xen/include/xen/ac_timer.h 40715b2epYl2jBbxzz9CI2rgIca7Zg xen/include/xen/acpi.h +41f2cea7ZvnB9JC4qkiq1K8H7xJw5Q xen/include/xen/banner.h 3ddb79c0c0cX_DZE209-Bb-Rx1v-Aw xen/include/xen/cache.h +41f2cea7Yna7xc0X9fyavIjoSFFeVg xen/include/xen/compile.h.in 3f840f12CkbYSlwMrY2S11Mpyxg7Nw xen/include/xen/compiler.h 3ddb79c259jh8hE7vre_8NuE7nwNSA xen/include/xen/config.h 3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h diff --git a/xen/Makefile b/xen/Makefile index b560ac1822..df01937245 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -35,14 +35,13 @@ dist: install clean: tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h rm -f include/asm-*/asm-offsets.h + rm -f tools/figlet/*.o tools/figlet/figlet tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean : %.clean: $(MAKE) -C $* clean -$(TARGET): delete-unfresh-files +$(TARGET): delete-unfresh-files include/xen/compile.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm - $(MAKE) -C tools - $(MAKE) include/xen/compile.h $(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s $(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h $(MAKE) -C common @@ -54,25 +53,30 @@ delete-unfresh-files: rm -f include/xen/compile.h common/kernel.o # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. -include/xen/compile.h: - @LANG=C echo /\* Autogenerated by root Makefile. Do not edit. \*/ > $@ - @LANG=C echo >> $@ - @LANG=C echo \#define XEN_COMPILE_DATE \"`date`\" >> $@ - @LANG=C echo \#define XEN_COMPILE_TIME \"`date +%T`\" >> $@ - @LANG=C echo \#define XEN_COMPILE_BY \"`whoami`\" >> $@ - @LANG=C echo \#define XEN_COMPILE_DOMAIN \"`([ -x /bin/dnsdomainname ] && /bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo [unknown])`\" >> $@ - @LANG=C echo \#define XEN_COMPILE_HOST \"`hostname`\" >> $@ - @LANG=C echo \#define XEN_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -n 1`\" >> $@ - @LANG=C echo >> $@ - @LANG=C echo \#define XEN_VERSION\ \ \ \ \ \ $(XEN_VERSION) >> $@ - @LANG=C echo \#define XEN_SUBVERSION\ \ \ $(XEN_SUBVERSION) >> $@ - @LANG=C echo \#define XEN_EXTRAVERSION \"$(XEN_EXTRAVERSION)\" >> $@ - @LANG=C echo >> $@ - @LANG=C echo \#define XEN_CHANGESET \"`bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo "information unavailable"`\" >> $@ - @LANG=C echo >> $@ - @LANG=C echo \#define XEN_BANNER \\ >> $@ - ( cd ./tools/figlet && ./figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) 1>>../../$@ ) - @LANG=C echo >> $@ +include/xen/compile.h: LANG=C +include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h + sed -e 's/@@date@@/$(shell date)/g' \ + -e 's/@@time@@/$(shell date +%T)/g' \ + -e 's/@@whoami@@/$(shell whoami)/g' \ + -e 's/@@domain@@/$(shell ([ -x /bin/dnsdomainname ] && /bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo [unknown]))/g' \ + -e 's/@@hostname@@/$(shell hostname)/g' \ + -e 's/@@compiler@@/$(shell $(CC) $(CFLAGS) -v 2>&1 | tail -1)/g' \ + -e 's/@@version@@/$(XEN_VERSION)/g' \ + -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ + -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ + -e 's/@@changeset@@/$(shell bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo information unavailable)/g' \ + < include/xen/compile.h.in > $@.new + cat include/xen/banner.h >> $@.new + mv $@.new $@ + +tools/figlet/figlet: tools/figlet/figlet.o + $(CC) -o $@ $< +tools/figlet/figlet.o: tools/figlet/figlet.c + $(CC) -o $@ -c $< + +include/xen/banner.h: tools/figlet/figlet tools/figlet/xen.flf + tools/figlet/figlet -d tools/figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) > $@.new + mv $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s @(set -e; \ diff --git a/xen/include/xen/banner.h b/xen/include/xen/banner.h new file mode 100644 index 0000000000..f9d5f90f06 --- /dev/null +++ b/xen/include/xen/banner.h @@ -0,0 +1,12 @@ +"\040\137\137\040\040\137\137\040\040\040\040\040\040\040\040\040\040\040" \ +"\040\137\137\137\137\040\040\040\040\137\137\137\040\040\012\040\134\040" \ +"\134\057\040\057\137\137\137\040\137\040\137\137\040\040\040\174\137\137" \ +"\137\040\134\040\040\057\040\137\040\134\040\012\040\040\134\040\040\057" \ +"\057\040\137\040\134\040\047\137\040\134\040\040\040\040\137\137\051\040" \ +"\174\174\040\174\040\174\040\174\012\040\040\057\040\040\134\040\040\137" \ +"\137\057\040\174\040\174\040\174\040\040\057\040\137\137\057\040\174\040" \ +"\174\137\174\040\174\012\040\057\137\057\134\137\134\137\137\137\174\137" \ +"\174\040\174\137\174\040\174\137\137\137\137\137\050\137\051\137\137\137" \ +"\057\040\012\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040" \ +"\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\012" \ + diff --git a/xen/include/xen/compile.h.in b/xen/include/xen/compile.h.in new file mode 100644 index 0000000000..e5179509fb --- /dev/null +++ b/xen/include/xen/compile.h.in @@ -0,0 +1,13 @@ +#define XEN_COMPILE_DATE "@@date@@" +#define XEN_COMPILE_TIME "@@time@@" +#define XEN_COMPILE_BY "@@whoami@@" +#define XEN_COMPILE_DOMAIN "@@domain@@" +#define XEN_COMPILE_HOST "@@hostname@@" +#define XEN_COMPILER "@@compiler@@" + +#define XEN_VERSION @@version@@ +#define XEN_SUBVERSION @@subversion@@ +#define XEN_EXTRAVERSION @@extraversion@@ + +#define XEN_CHANGESET "@@changeset@@" +#define XEN_BANNER \ From 1aedec574bd5393d2c069fb898c56666699ac406 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sun, 23 Jan 2005 13:27:13 +0000 Subject: [PATCH 029/199] bitkeeper revision 1.1159.226.1 (41f3a631b2JdeX6_Iif82X1YYyLKMw) Remove debugging from default kernel configs. David Becker points out that it hurts performance rather a lot! --- linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig | 9 +-------- linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig index 91aa6499b7..d3e884bff4 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig @@ -158,15 +158,8 @@ CONFIG_PCMCIA_PROBE=y # # Kernel hacking # -CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KERNEL is not set CONFIG_EARLY_PRINTK=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_SLAB=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_PAGEALLOC=y -# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set # CONFIG_4KSTACKS is not set diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig index e90dd4bc5a..63450b421c 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig @@ -128,15 +128,8 @@ CONFIG_HAVE_DEC_LOCK=y # # Kernel hacking # -CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KERNEL is not set CONFIG_EARLY_PRINTK=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_PAGEALLOC=y -# CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_FRAME_POINTER is not set # CONFIG_4KSTACKS is not set From 8febb23b3dd3def288a1f71222c5d68fa585c4fc Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 24 Jan 2005 17:30:59 +0000 Subject: [PATCH 030/199] bitkeeper revision 1.1159.226.2 (41f530d3LtbkTKUSgcI8LiQlQRJG0w) Fix Xen's linker command line. --- xen/arch/x86/Rules.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index d569a435c5..c3e1c2aea1 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -24,13 +24,13 @@ CFLAGS += $(call test-gcc-flag,-fno-stack-protector-all) ifeq ($(TARGET_SUBARCH),x86_32) CFLAGS += -m32 -march=i686 -LDFLAGS := --oformat elf32-i386 +LDFLAGS := -m elf_i386 endif ifeq ($(TARGET_SUBARCH),x86_64) CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks CFLAGS += -fno-asynchronous-unwind-tables -LDFLAGS := --oformat elf64-x86-64 +LDFLAGS := -m elf_x86_64 endif # Test for at least GCC v3.2.x. From aac66e34a6f0fd9a3e084945cf5e6a4b9eb9fd56 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Mon, 24 Jan 2005 20:37:34 +0000 Subject: [PATCH 031/199] bitkeeper revision 1.1159.226.3 (41f55c8er11pRwXCJ66we1vDzrEZ9Q) With ipv6, every network interface always has a link local address. This fools the network script into thinking that xen-br0 already has a network address, and it refuses to transfer over eth0's IP address to xen-br0. By grepping for 'inet ' instead of just 'inet', the network script is no longer fooled and does the right thing. This patch makes Xen networking work again on my Fedora system. Signed-off-by: Rik van Riel Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/examples/network | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/network b/tools/examples/network index b679b93e43..229881d737 100755 --- a/tools/examples/network +++ b/tools/examples/network @@ -61,13 +61,13 @@ transfer_addrs () { local src=$1 local dst=$2 # Don't bother if $dst already has IP addresses. - if ip addr show dev ${dst} | egrep -q '^ *inet' ; then + if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then return fi # Address lines start with 'inet' and have the device in them. # Replace 'inet' with 'ip addr add' and change the device name $src # to 'dev $src'. Remove netmask as we'll add routes later. - ip addr show dev ${src} | egrep '^ *inet' | sed -e " + ip addr show dev ${src} | egrep '^ *inet ' | sed -e " s/inet/ip addr add/ s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@ s/${src}/dev ${dst}/ From eab8489a4970a3ad8b03d6b81499401e363c7ebb Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Mon, 24 Jan 2005 22:34:15 +0000 Subject: [PATCH 032/199] bitkeeper revision 1.1159.223.29 (41f577e7ZJYpBbgJi8udTXWyfHvSYg) Cset exclude: iap10@labyrinth.cl.cam.ac.uk|ChangeSet|20050122214333|39257 --- Makefile | 57 ++++++++++++++++++++++++++++++++-------------------- xen/Makefile | 9 +++++---- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 5fcdc9f74c..924fbfbaca 100644 --- a/Makefile +++ b/Makefile @@ -31,26 +31,27 @@ all: dist # install everything into the standard system directories # NB: install explicitly does not check that everything is up to date! -install: xen.install tools.install kernels docs.install +install: install-tools install-xen install-kernels install-docs -kernels.install: +install-xen: + $(MAKE) -C xen install + +install-tools: + $(MAKE) -C tools install + +install-kernels: cp -a $(INSTALL_DIR)/boot/* /boot/ cp -a $(INSTALL_DIR)/lib/modules/* /lib/modules/ cp -dR $(INSTALL_DIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/ -docs.install: +install-docs: + sh ./docs/check_pkgs && $(MAKE) -C docs install || true sh ./docs/check_pkgs -$(MAKE) -C docs install -xen.install tools.install: %.install: - $(MAKE) -C $* install - -xen.dist tools.dist: %.dist: - $(MAKE) -C $* dist - # build and install everything into local dist directory -dist: xen.dist tools.dist kernels docs.install +dist: xen tools kernels docs $(INSTALL_DIR) $(DIST_DIR)/check $(INSTALL_DATA) ./COPYING $(DIST_DIR) $(INSTALL_DATA) ./README $(DIST_DIR) @@ -63,7 +64,8 @@ xen: tools: $(MAKE) dist=yes -C tools install -kernels: $(addsuffix -build,$(XKERNELS)) +kernels: + for i in $(XKERNELS) ; do $(MAKE) $$i-build ; done docs: sh ./docs/check_pkgs @@ -73,13 +75,17 @@ docs: kbuild: kernels # Delete the kernel build trees entirely -kdelete: $(addsuffix -clean,$(XKERNELS)) +kdelete: + for i in $(XKERNELS) ; do $(MAKE) $$i-delete ; done # Clean the kernel build trees -kclean: $(addsuffix -clean,$(XKERNELS)) +kclean: + for i in $(XKERNELS) ; do $(MAKE) $$i-clean ; done # Make patches from kernel sparse trees -mkpatches: $(addsuffix -xen.patch,$(ALLSPARSETREES)) +mkpatches: + for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch ; done + # build xen, the tools, and a domain 0 plus unprivileged linux-xen images, # and place them in the install directory. 'make install' should then @@ -90,14 +96,16 @@ world: $(MAKE) dist # clean doesn't do a kclean -clean: xen.clean tools.clean docs.clean - -xen.clean tools.clean docs.clean: %.clean: - $(MAKE) -C $* clean +clean: + $(MAKE) -C xen clean + $(MAKE) -C tools clean + $(MAKE) -C docs clean # clean, but blow away kernel build tree plus tar balls -mrproper: clean $(addsuffix -delete,$(ALLKERNELS)) $(addsuffix -mrproper,$(ALLSPARSETREES)) +mrproper: clean rm -rf dist patches/tmp + for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done + for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done install-twisted: wget http://www.twistedmatrix.com/products/get-current.epy @@ -159,8 +167,13 @@ uninstall: rm -rf "/usr/lib/python2.?/site-packages/xen* /usr/lib/libxc* /usr/lib/python2.?/site-packages/Xc*" # Legacy targets for compatibility -linux24: linux-2.4-xen0-build linux-2.4-xenU-build +linux24: + $(MAKE) linux-2.4-xen0-build + $(MAKE) linux-2.4-xenU-build -linux26: linux-2.6-xen0-build linux-2.6-xenU-build +linux26: + $(MAKE) linux-2.6-xen0-build + $(MAKE) linux-2.6-xenU-build -netbsd20: netbsd-2.0-xenU-build +netbsd20: + $(MAKE) netbsd-2.0-xenU-build diff --git a/xen/Makefile b/xen/Makefile index df01937245..52810f207a 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -32,14 +32,15 @@ install: $(TARGET).gz dist: install -clean: tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean +clean: + $(MAKE) -C tools clean + $(MAKE) -C common clean + $(MAKE) -C drivers clean + $(MAKE) -C arch/$(TARGET_ARCH) clean rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h rm -f include/asm-*/asm-offsets.h rm -f tools/figlet/*.o tools/figlet/figlet -tools.clean common.clean drivers.clean arch/$(TARGET_ARCH).clean : %.clean: - $(MAKE) -C $* clean - $(TARGET): delete-unfresh-files include/xen/compile.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm $(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s From cb43f93e4858c324e60916667f0cc724e620480f Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 00:58:36 +0000 Subject: [PATCH 033/199] bitkeeper revision 1.1159.223.31 (41f599bcklevTYwPtWQUZ7QK-azDbg) Fix recent patch to change the way the version string is generated. Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/Makefile b/xen/Makefile index 52810f207a..78d903eca6 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -65,7 +65,7 @@ include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h -e 's/@@version@@/$(XEN_VERSION)/g' \ -e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \ -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ - -e 's/@@changeset@@/$(shell bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo information unavailable)/g' \ + -e 's!@@changeset@@!$(shell bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo information unavailable)!g' \ < include/xen/compile.h.in > $@.new cat include/xen/banner.h >> $@.new mv $@.new $@ From ffa6a8cdbc10cc1dfbb44c2344d82daa22b25c97 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 01:00:05 +0000 Subject: [PATCH 034/199] bitkeeper revision 1.1159.223.32 (41f59a1519YIchUo4ggA1xTruDvUZg) Bitkeeper ignore *.opic Signed-off-by: ian.pratt@cl.cam.ac.uk --- BitKeeper/etc/ignore | 1 + 1 file changed, 1 insertion(+) diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index de77ccebfc..e4c0509b45 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -1,6 +1,7 @@ *.a *.d *.o +*.opic *.pyc *.so *.so.* From ae69d44b66bcb017ab2d05f929f87a5a5c09826e Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 01:25:26 +0000 Subject: [PATCH 035/199] bitkeeper revision 1.1159.223.33 (41f5a006O57aqVcLmvmGSgDN2Chvbw) install.sh now creates vmlinuz-2.6.99-xen0 -> vmlinuz-2.6-xen0 links etc Signed-off-by: pl@us.ibm.com Signed-off-by: ian.pratt@cl.cam.ac.uk --- install.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/install.sh b/install.sh index f21294f5f7..611e6e6417 100755 --- a/install.sh +++ b/install.sh @@ -23,6 +23,15 @@ if ! [ -d $dst ]; then fi echo "Installing Xen from '$src' to '$dst'..." +cd $src/boot +(echo '2.6.*' -2.6; echo '2.4.*' -2.4; echo '2.*.*' '') | while read mv +do + l=$(eval ls -t vmlinuz-$m-xen0 2>/dev/null | head -n 1) + [ -e "$l" ] && ln -fs "$l" vmlinuz${v}-xen0 + l=$(eval ls -t vmlinuz-$m-xenU 2>/dev/null | head -n 1) + [ -e "$l" ] && ln -fs "$l" vmlinuz${v}-xenU +done +cd - cp -fdR $src/* $dst echo "All done." From 3a0c731407c18ed10aca142dcc7d0fdad8fb86c9 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 02:23:49 +0000 Subject: [PATCH 036/199] bitkeeper revision 1.1159.223.34 (41f5adb5w-LSQUPVS2ApmlrBDOFN4A) "mv -f" fix Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index 78d903eca6..d86e6a7187 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -68,7 +68,7 @@ include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h -e 's!@@changeset@@!$(shell bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo information unavailable)!g' \ < include/xen/compile.h.in > $@.new cat include/xen/banner.h >> $@.new - mv $@.new $@ + mv -f $@.new $@ tools/figlet/figlet: tools/figlet/figlet.o $(CC) -o $@ $< @@ -77,7 +77,7 @@ tools/figlet/figlet.o: tools/figlet/figlet.c include/xen/banner.h: tools/figlet/figlet tools/figlet/xen.flf tools/figlet/figlet -d tools/figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) > $@.new - mv $@.new $@ + mv -f $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s @(set -e; \ From 1ac07367bb077785c1ecb6f8d3ab27d79ff73f17 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 13:05:37 +0000 Subject: [PATCH 037/199] bitkeeper revision 1.1159.223.35 (41f64421LB8rsesmi-im4VxTqnNVhg) Don't check in banner.h. --- .rootkeys | 1 - BitKeeper/etc/ignore | 2 ++ xen/Makefile | 10 +++++----- xen/include/xen/banner.h | 12 ------------ 4 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 xen/include/xen/banner.h diff --git a/.rootkeys b/.rootkeys index 0dca6858e0..4dde2f8460 100644 --- a/.rootkeys +++ b/.rootkeys @@ -852,7 +852,6 @@ 3ddb79c25UE59iu4JJcbRalx95mvcg xen/include/public/xen.h 3e397e66m2tO3s-J8Jnr7Ws_tGoPTg xen/include/xen/ac_timer.h 40715b2epYl2jBbxzz9CI2rgIca7Zg xen/include/xen/acpi.h -41f2cea7ZvnB9JC4qkiq1K8H7xJw5Q xen/include/xen/banner.h 3ddb79c0c0cX_DZE209-Bb-Rx1v-Aw xen/include/xen/cache.h 41f2cea7Yna7xc0X9fyavIjoSFFeVg xen/include/xen/compile.h.in 3f840f12CkbYSlwMrY2S11Mpyxg7Nw xen/include/xen/compiler.h diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index e4c0509b45..0b96e34b39 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -79,6 +79,8 @@ xen/figlet/figlet xen/include/asm xen/include/asm-*/asm-offsets.h xen/include/hypervisor-ifs/arch +xen/include/xen/*.new +xen/include/xen/banner.h xen/include/xen/compile.h xen/tools/elf-reloc xen/tools/figlet/figlet diff --git a/xen/Makefile b/xen/Makefile index d86e6a7187..1e477388ba 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -51,12 +51,12 @@ $(TARGET): delete-unfresh-files include/xen/compile.h # Blow away kernel.o because build info is stored statically within it. delete-unfresh-files: - rm -f include/xen/compile.h common/kernel.o + rm -f include/xen/banner.h include/xen/compile.h common/kernel.o # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. include/xen/compile.h: LANG=C include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h - sed -e 's/@@date@@/$(shell date)/g' \ + @sed -e 's/@@date@@/$(shell date)/g' \ -e 's/@@time@@/$(shell date +%T)/g' \ -e 's/@@whoami@@/$(shell whoami)/g' \ -e 's/@@domain@@/$(shell ([ -x /bin/dnsdomainname ] && /bin/dnsdomainname) || ([ -x /bin/domainname ] && /bin/domainname || echo [unknown]))/g' \ @@ -67,8 +67,8 @@ include/xen/compile.h: include/xen/compile.h.in include/xen/banner.h -e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \ -e 's!@@changeset@@!$(shell bk changes -nd':D: :T: :REV: :MD5KEY:' -r+ 2>/dev/null || echo information unavailable)!g' \ < include/xen/compile.h.in > $@.new - cat include/xen/banner.h >> $@.new - mv -f $@.new $@ + @cat include/xen/banner.h >> $@.new + @mv -f $@.new $@ tools/figlet/figlet: tools/figlet/figlet.o $(CC) -o $@ $< @@ -77,7 +77,7 @@ tools/figlet/figlet.o: tools/figlet/figlet.c include/xen/banner.h: tools/figlet/figlet tools/figlet/xen.flf tools/figlet/figlet -d tools/figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) > $@.new - mv -f $@.new $@ + @mv -f $@.new $@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s @(set -e; \ diff --git a/xen/include/xen/banner.h b/xen/include/xen/banner.h deleted file mode 100644 index f9d5f90f06..0000000000 --- a/xen/include/xen/banner.h +++ /dev/null @@ -1,12 +0,0 @@ -"\040\137\137\040\040\137\137\040\040\040\040\040\040\040\040\040\040\040" \ -"\040\137\137\137\137\040\040\040\040\137\137\137\040\040\012\040\134\040" \ -"\134\057\040\057\137\137\137\040\137\040\137\137\040\040\040\174\137\137" \ -"\137\040\134\040\040\057\040\137\040\134\040\012\040\040\134\040\040\057" \ -"\057\040\137\040\134\040\047\137\040\134\040\040\040\040\137\137\051\040" \ -"\174\174\040\174\040\174\040\174\012\040\040\057\040\040\134\040\040\137" \ -"\137\057\040\174\040\174\040\174\040\040\057\040\137\137\057\040\174\040" \ -"\174\137\174\040\174\012\040\057\137\057\134\137\134\137\137\137\174\137" \ -"\174\040\174\137\174\040\174\137\137\137\137\137\050\137\051\137\137\137" \ -"\057\040\012\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040" \ -"\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\012" \ - From b62201e6afb9451a9b44560223894b390574b780 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 13:06:39 +0000 Subject: [PATCH 038/199] bitkeeper revision 1.1159.229.1 (41f6445fD7VhZd6QcRqU9K9iqEPPzQ) Don't silently ignore failures while building kernels. Signed-off-by: michael.fetterman@cl.cam.ac.uk Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 924fbfbaca..8e2988dc08 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 INSTALL_PROG := $(INSTALL) -m0755 -KERNELS ?= linux-2.6-xen0 linux-2.6-xenU +KERNELS ?= linux-2.6-xen0 linux-2.6-xenU linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU # You may use wildcards in the above e.g. KERNELS=*2.4* @@ -65,7 +65,7 @@ tools: $(MAKE) dist=yes -C tools install kernels: - for i in $(XKERNELS) ; do $(MAKE) $$i-build ; done + for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done docs: sh ./docs/check_pkgs @@ -84,7 +84,7 @@ kclean: # Make patches from kernel sparse trees mkpatches: - for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch ; done + for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch || exit 1; done # build xen, the tools, and a domain 0 plus unprivileged linux-xen images, From 05dec242c352a08f908d713396f11327eccf9549 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 13:08:13 +0000 Subject: [PATCH 039/199] bitkeeper revision 1.1159.229.2 (41f644bdEYN9P3oj15IyKySMNPk1yg) Fix "make dist" target in tools directory. Signed-off-by: michael.fetterman@cl.cam.ac.uk Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile b/tools/Makefile index a05c196d37..722f9d9f7d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,7 +23,7 @@ endif $(MAKE) -C sv install dist: $(TARGET) - $(MAKE) prefix=$(CURDIR)/../../install dist=yes install + $(MAKE) prefix=$(CURDIR)/../dist/install dist=yes install clean: From 36f2347fd3fe710aa6f10909597c7f47bfb3430f Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 14:05:02 +0000 Subject: [PATCH 040/199] bitkeeper revision 1.1159.230.1 (41f6520ec91dTdY6i_ggr80c6cRooQ) Fix Xen dependencies and always rebuild arch/x86/setup.o rather than common/kernel.o (boot banner was moved out to arch-specific). signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/Makefile | 4 ++-- xen/Rules.mk | 1 + xen/arch/x86/Makefile | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index 1e477388ba..fd2c06df3d 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -49,9 +49,9 @@ $(TARGET): delete-unfresh-files include/xen/compile.h $(MAKE) -C drivers $(MAKE) -C arch/$(TARGET_ARCH) -# Blow away kernel.o because build info is stored statically within it. delete-unfresh-files: - rm -f include/xen/banner.h include/xen/compile.h common/kernel.o + rm -f include/xen/banner.h include/xen/compile.h + $(MAKE) -C arch/$(TARGET_ARCH) delete-unfresh-files # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. include/xen/compile.h: LANG=C diff --git a/xen/Rules.mk b/xen/Rules.mk index 63c3a51784..c5d3405781 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -22,6 +22,7 @@ HDRS += $(wildcard $(BASEDIR)/include/public/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h) # compile.h is always regenerated, but other files shouldn't be rebuilt +HDRS := $(subst $(BASEDIR)/include/xen/banner.h,,$(HDRS)) HDRS := $(subst $(BASEDIR)/include/xen/compile.h,,$(HDRS)) C_SRCS := $(wildcard *.c) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 574b0c35a5..805591766e 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -35,4 +35,8 @@ clean: rm -f x86_32/*.o x86_32/*~ x86_32/core rm -f x86_64/*.o x86_64/*~ x86_64/core -.PHONY: default clean +# setup.o contains bits of compile.h so it must be blown away +delete-unfresh-files: + rm -f setup.o + +.PHONY: default clean delete-unfresh-files From f7d9f40807395f70bc9624f5478da4ce0a0caef4 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 14:05:40 +0000 Subject: [PATCH 041/199] bitkeeper revision 1.1159.230.2 (41f65234Pi4Crimteaw690fX-H8jyg) Use list_for_each_entry() in preference to list_for_each(). signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/domain.c | 4 +- xen/arch/x86/mpparse.c | 5 +- xen/arch/x86/pci-pc.c | 4 +- xen/arch/x86/pdb-stub.c | 8 +- xen/common/physdev.c | 21 ++-- xen/common/sched_atropos.c | 210 ++++++++++++++++--------------------- xen/common/sched_bvt.c | 15 +-- xen/common/sched_rrobin.c | 5 +- xen/common/slab.c | 22 ++-- xen/drivers/pci/pci.c | 42 ++++---- xen/include/xen/list.h | 5 +- xen/include/xen/pci.h | 2 +- 12 files changed, 141 insertions(+), 202 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2ba535a3ac..4ca96f5d3c 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -199,13 +199,11 @@ void machine_halt(void) void dump_pageframe_info(struct domain *d) { struct pfn_info *page; - struct list_head *ent; if ( d->tot_pages < 10 ) { - list_for_each ( ent, &d->page_list ) + list_for_each_entry ( page, &d->page_list, list ) { - page = list_entry(ent, struct pfn_info, list); printk("Page %08x: caf=%08x, taf=%08x\n", page_to_phys(page), page->count_info, page->u.inuse.type_info); diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c index 5cf760d62e..7db6f8a6da 100644 --- a/xen/arch/x86/mpparse.c +++ b/xen/arch/x86/mpparse.c @@ -1232,7 +1232,6 @@ void __init mp_config_acpi_legacy_irqs (void) void __init mp_parse_prt (void) { - struct list_head *node = NULL; struct acpi_prt_entry *entry = NULL; int ioapic = -1; int ioapic_pin = 0; @@ -1245,9 +1244,7 @@ void __init mp_parse_prt (void) * Parsing through the PCI Interrupt Routing Table (PRT) and program * routing for all entries. */ - list_for_each(node, &acpi_prt.entries) { - entry = list_entry(node, struct acpi_prt_entry, node); - + list_for_each_entry(entry, &acpi_prt.entries, node) { /* Need to get irq for dynamic entry */ if (entry->link.handle) { irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low); diff --git a/xen/arch/x86/pci-pc.c b/xen/arch/x86/pci-pc.c index 363b635141..cb5889628c 100644 --- a/xen/arch/x86/pci-pc.c +++ b/xen/arch/x86/pci-pc.c @@ -1372,11 +1372,9 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) struct pci_bus * __devinit pcibios_scan_root(int busnum) { - struct list_head *list; struct pci_bus *bus; - list_for_each(list, &pci_root_buses) { - bus = pci_bus_b(list); + pci_for_each_bus(bus) { if (bus->number == busnum) { /* Already scanned */ return bus; diff --git a/xen/arch/x86/pdb-stub.c b/xen/arch/x86/pdb-stub.c index 827035e07f..568bcea113 100644 --- a/xen/arch/x86/pdb-stub.c +++ b/xen/arch/x86/pdb-stub.c @@ -778,12 +778,10 @@ void pdb_bkpt_add (unsigned long cr3, unsigned long address) struct pdb_breakpoint* pdb_bkpt_search (unsigned long cr3, unsigned long address) { - struct list_head *list_entry; struct pdb_breakpoint *bkpt; - list_for_each(list_entry, &breakpoints.list) + list_for_each_entry ( bkpt, &breakpoints.list, list ) { - bkpt = list_entry(list_entry, struct pdb_breakpoint, list); if ( bkpt->cr3 == cr3 && bkpt->address == address ) return bkpt; } @@ -797,12 +795,10 @@ struct pdb_breakpoint* pdb_bkpt_search (unsigned long cr3, */ int pdb_bkpt_remove (unsigned long cr3, unsigned long address) { - struct list_head *list_entry; struct pdb_breakpoint *bkpt; - list_for_each(list_entry, &breakpoints.list) + list_for_each_entry ( bkpt, &breakpoints.list, list ) { - bkpt = list_entry(list_entry, struct pdb_breakpoint, list); if ( bkpt->cr3 == cr3 && bkpt->address == address ) { list_del(&bkpt->list); diff --git a/xen/common/physdev.c b/xen/common/physdev.c index 4b6f398e9a..cd4d2811e3 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -73,11 +73,9 @@ typedef struct _phys_dev_st { static phys_dev_t *find_pdev(struct domain *p, struct pci_dev *dev) { phys_dev_t *t, *res = NULL; - struct list_head *tmp; - list_for_each(tmp, &p->pcidev_list) + list_for_each_entry ( t, &p->pcidev_list, node ) { - t = list_entry(tmp, phys_dev_t, node); if ( dev == t->dev ) { res = t; @@ -149,9 +147,9 @@ int physdev_pci_access_modify( /* Make the domain privileged. */ set_bit(DF_PHYSDEV, &p->flags); - /* FIXME: MAW for now make the domain REALLY privileged so that it - * can run a backend driver (hw access should work OK otherwise) */ - set_bit(DF_PRIVILEGED, &p->flags); + /* FIXME: MAW for now make the domain REALLY privileged so that it + * can run a backend driver (hw access should work OK otherwise) */ + set_bit(DF_PRIVILEGED, &p->flags); /* Grant write access to the specified device. */ if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL ) @@ -214,17 +212,16 @@ int physdev_pci_access_modify( int domain_iomem_in_pfn(struct domain *p, unsigned long pfn) { int ret = 0; - struct list_head *l; + phys_dev_t *phys_dev; VERBOSE_INFO("Checking if physdev-capable domain %u needs access to " "pfn %08lx\n", p->id, pfn); spin_lock(&p->pcidev_lock); - list_for_each(l, &p->pcidev_list) + list_for_each_entry ( phys_dev, &p->pcidev_list, node ) { int i; - phys_dev_t *phys_dev = list_entry(l, phys_dev_t, node); struct pci_dev *pci_dev = phys_dev->dev; for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ ) @@ -619,15 +616,11 @@ static long pci_cfgreg_write(int bus, int dev, int func, int reg, static long pci_probe_root_buses(u32 *busmask) { phys_dev_t *pdev; - struct list_head *tmp; memset(busmask, 0, 256/8); - list_for_each ( tmp, ¤t->pcidev_list ) - { - pdev = list_entry(tmp, phys_dev_t, node); + list_for_each_entry ( pdev, ¤t->pcidev_list, node ) set_bit(pdev->dev->bus->number, busmask); - } return 0; } diff --git a/xen/common/sched_atropos.c b/xen/common/sched_atropos.c index 1565b86ac9..b5901f2397 100644 --- a/xen/common/sched_atropos.c +++ b/xen/common/sched_atropos.c @@ -1,6 +1,6 @@ /* - * atropos.c - * --------- + * atropos.c + * --------- * * Copyright (c) 1994 University of Cambridge Computer Laboratory. * This is part of Nemesis; consult your contract for terms and conditions. @@ -98,8 +98,9 @@ static inline int __task_on_runqueue(struct domain *d) static int q_len(struct list_head *q) { int i = 0; - struct list_head *tmp; - list_for_each(tmp, q) i++; + struct at_dom_info *tmp; + list_for_each_entry ( tmp, q, waitq ) + i++; return i; } @@ -129,60 +130,39 @@ static inline struct domain *waitq_el(struct list_head *l) */ static void requeue(struct domain *sdom) { - struct at_dom_info *inf = DOM_INFO(sdom); - struct list_head *prev; - struct list_head *next; + struct at_dom_info *i, *inf = DOM_INFO(sdom); - - if(!domain_runnable(sdom)) return; + if ( !domain_runnable(sdom) ) + return; - if(inf->state == ATROPOS_TASK_WAIT || - inf->state == ATROPOS_TASK_UNBLOCKED) + if ( (inf->state == ATROPOS_TASK_WAIT) || + (inf->state == ATROPOS_TASK_UNBLOCKED) ) { - prev = WAITQ(sdom->processor); - - list_for_each(next, WAITQ(sdom->processor)) + list_for_each_entry ( i, WAITQ(sdom->processor), waitq ) { - struct at_dom_info *i = - list_entry(next, struct at_dom_info, waitq); if ( i->deadline > inf->deadline ) { - __list_add(&inf->waitq, prev, next); + __list_add(&inf->waitq, i->waitq.prev, &i->waitq); break; } - - prev = next; } - /* put the domain on the end of the list if it hasn't been put - * elsewhere */ - if ( next == WAITQ(sdom->processor) ) + if ( &i->waitq == WAITQ(sdom->processor) ) list_add_tail(&inf->waitq, WAITQ(sdom->processor)); } else if ( domain_runnable(sdom) ) { - /* insert into ordered run queue */ - - prev = RUNQ(sdom->processor); - - list_for_each(next, RUNQ(sdom->processor)) + list_for_each_entry ( i, RUNQ(sdom->processor), run_list ) { - struct at_dom_info *p = list_entry(next, struct at_dom_info, - run_list); - - if( p->deadline > inf->deadline || is_idle_task(p->owner) ) + if ( (i->deadline > inf->deadline) || is_idle_task(i->owner) ) { - __list_add(&inf->run_list, prev, next); + __list_add(&inf->run_list, i->run_list.prev, &i->run_list); break; } - - prev = next; } - if ( next == RUNQ(sdom->processor) ) + if ( &i->waitq == RUNQ(sdom->processor) ) list_add_tail(&inf->run_list, RUNQ(sdom->processor)); - - } /* silently ignore tasks in other states like BLOCKED, DYING, STOPPED, etc * - they shouldn't be on any queue */ @@ -194,7 +174,7 @@ static int at_alloc_task(struct domain *p) ASSERT(p != NULL); p->sched_priv = xmem_cache_alloc(dom_info_cache); - if( p->sched_priv == NULL ) + if ( p->sched_priv == NULL ) return -1; return 0; @@ -294,26 +274,26 @@ static void unblock(struct domain *sdom) { /* Long blocking case */ - /* The sdom has passed its deadline since it was blocked. - Give it its new deadline based on the latency value. */ - inf->prevddln = time; + /* The sdom has passed its deadline since it was blocked. + Give it its new deadline based on the latency value. */ + inf->prevddln = time; /* Scale the scheduling parameters as requested by the latency hint. */ - inf->deadline = time + inf->latency; + inf->deadline = time + inf->latency; inf->slice = inf->nat_slice / ( inf->nat_period / inf->latency ); inf->period = inf->latency; - inf->remain = inf->slice; + inf->remain = inf->slice; } else { /* Short blocking case */ - /* We leave REMAIN intact, but put this domain on the WAIT - queue marked as recently unblocked. It will be given - priority over other domains on the wait queue until while - REMAIN>0 in a generous attempt to help it make up for its - own foolishness. */ - if(inf->remain > 0) + /* We leave REMAIN intact, but put this domain on the WAIT + queue marked as recently unblocked. It will be given + priority over other domains on the wait queue until while + REMAIN>0 in a generous attempt to help it make up for its + own foolishness. */ + if(inf->remain > 0) inf->state = ATROPOS_TASK_UNBLOCKED; else inf->state = ATROPOS_TASK_WAIT; @@ -349,10 +329,10 @@ static void block(struct domain* sdom) */ task_slice_t ksched_scheduler(s_time_t time) { - struct domain *cur_sdom = current; /* Current sdom */ - s_time_t newtime; - s_time_t ranfor; /* How long the domain ran */ - struct domain *sdom; /* tmp. scheduling domain */ + struct domain *cur_sdom = current; /* Current sdom */ + s_time_t newtime; + s_time_t ranfor; /* How long the domain ran */ + struct domain *sdom; /* tmp. scheduling domain */ int cpu = cur_sdom->processor; /* current CPU */ struct at_dom_info *cur_info; static unsigned long waitq_rrobin = 0; @@ -367,7 +347,7 @@ task_slice_t ksched_scheduler(s_time_t time) /* If we were spinning in the idle loop, there is no current * domain to deschedule. */ if (is_idle_task(cur_sdom)) - goto deschedule_done; + goto deschedule_done; /***************************** * @@ -375,7 +355,7 @@ task_slice_t ksched_scheduler(s_time_t time) * ****************************/ - /* Record the time the domain was preempted and for how long it + /* Record the time the domain was preempted and for how long it ran. Work out if the domain is going to be blocked to save some pointless queue shuffling */ cur_sdom->lastdeschd = time; @@ -388,26 +368,26 @@ task_slice_t ksched_scheduler(s_time_t time) (cur_info->state == ATROPOS_TASK_UNBLOCKED) ) { - /* In this block, we are doing accounting for an sdom which has - been running in contracted time. Note that this could now happen - even if the domain is on the wait queue (i.e. if it blocked) */ + /* In this block, we are doing accounting for an sdom which has + been running in contracted time. Note that this could now happen + even if the domain is on the wait queue (i.e. if it blocked) */ - /* Deduct guaranteed time from the domain */ - cur_info->remain -= ranfor; + /* Deduct guaranteed time from the domain */ + cur_info->remain -= ranfor; - /* If guaranteed time has run out... */ - if ( cur_info->remain <= 0 ) + /* If guaranteed time has run out... */ + if ( cur_info->remain <= 0 ) { - /* Move domain to correct position in WAIT queue */ + /* Move domain to correct position in WAIT queue */ /* XXX sdom_unblocked doesn't need this since it is already in the correct place. */ - cur_info->state = ATROPOS_TASK_WAIT; - } + cur_info->state = ATROPOS_TASK_WAIT; + } } requeue(cur_sdom); -deschedule_done: + deschedule_done: /***************************** * * We have now successfully descheduled the current sdom. @@ -424,10 +404,10 @@ deschedule_done: ****************************/ while(!list_empty(WAITQ(cpu)) && - DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) + DOM_INFO(sdom = waitq_el(WAITQ(cpu)->next))->deadline <= time ) { - struct at_dom_info *inf = DOM_INFO(sdom); + struct at_dom_info *inf = DOM_INFO(sdom); dequeue(sdom); if ( inf->period != inf->nat_period ) @@ -444,22 +424,22 @@ deschedule_done: } } - /* Domain begins a new period and receives a slice of CPU - * If this domain has been blocking then throw away the - * rest of it's remain - it can't be trusted */ - if (inf->remain > 0) - inf->remain = inf->slice; + /* Domain begins a new period and receives a slice of CPU + * If this domain has been blocking then throw away the + * rest of it's remain - it can't be trusted */ + if (inf->remain > 0) + inf->remain = inf->slice; else - inf->remain += inf->slice; + inf->remain += inf->slice; - inf->prevddln = inf->deadline; - inf->deadline += inf->period; + inf->prevddln = inf->deadline; + inf->deadline += inf->period; if ( inf->remain <= 0 ) inf->state = ATROPOS_TASK_WAIT; - /* Place on the appropriate queue */ - requeue(sdom); + /* Place on the appropriate queue */ + requeue(sdom); } /***************************** @@ -484,30 +464,27 @@ deschedule_done: * queue */ if (cur_sdom->id == IDLE_DOMAIN_ID && !list_empty(WAITQ(cpu))) { - struct list_head *item; + struct at_dom_info *inf; - /* Try running a domain on the WAIT queue - this part of the - scheduler isn't particularly efficient but then again, we - don't have any guaranteed domains to worry about. */ - - /* See if there are any unblocked domains on the WAIT - queue who we can give preferential treatment to. */ + /* Try running a domain on the WAIT queue - this part of the + scheduler isn't particularly efficient but then again, we + don't have any guaranteed domains to worry about. */ + + /* See if there are any unblocked domains on the WAIT + queue who we can give preferential treatment to. */ - list_for_each(item, WAITQ(cpu)) + list_for_each_entry ( inf, WAITQ(cpu), waitq ) { - struct at_dom_info *inf = - list_entry(item, struct at_dom_info, waitq); - sdom = inf->owner; - if (inf->state == ATROPOS_TASK_UNBLOCKED) + if (inf->state == ATROPOS_TASK_UNBLOCKED) { - cur_sdom = sdom; - cur_info = inf; - newtime = time + inf->remain; - goto found; - } - } + cur_sdom = sdom; + cur_info = inf; + newtime = time + inf->remain; + goto found; + } + } /* init values needed to approximate round-robin for slack time */ i = 0; @@ -515,14 +492,11 @@ deschedule_done: waitq_rrobin = 0; - /* Last chance: pick a domain on the wait queue with the XTRA - flag set. The NEXT_OPTM field is used to cheaply achieve - an approximation of round-robin order */ - list_for_each(item, WAITQ(cpu)) + /* Last chance: pick a domain on the wait queue with the XTRA + flag set. The NEXT_OPTM field is used to cheaply achieve + an approximation of round-robin order */ + list_for_each_entry ( inf, WAITQ(cpu), waitq ) { - struct at_dom_info *inf = - list_entry(item, struct at_dom_info, waitq); - sdom = inf->owner; if (inf->xtratime && i >= waitq_rrobin) @@ -538,7 +512,7 @@ deschedule_done: } } - found: + found: /********************** * * We now have to work out the time when we next need to @@ -554,7 +528,7 @@ deschedule_done: /* exhausted its time, cut short the time allocation */ if (!list_empty(WAITQ(cpu))) { - newtime = MIN(newtime, + newtime = MIN(newtime, DOM_INFO(waitq_el(WAITQ(cpu)->next))->deadline); } @@ -603,44 +577,44 @@ static void at_dump_runq_el(struct domain *p) /* dump relevant per-cpu state for a run queue dump */ static void at_dump_cpu_state(int cpu) { - struct list_head *list, *queue; + struct list_head *queue; int loop = 0; struct at_dom_info *d_inf; struct domain *d; queue = RUNQ(cpu); printk("\nRUNQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, - (unsigned long) queue->next, (unsigned long) queue->prev); + (unsigned long) queue->next, (unsigned long) queue->prev); - list_for_each ( list, queue ) + list_for_each_entry ( d_inf, queue, run_list ) { - d_inf = list_entry(list, struct at_dom_info, run_list); d = d_inf->owner; printk("%3d: %d has=%c ", loop++, d->id, - test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); + test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); at_dump_runq_el(d); printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); printk(" l: %lx n: %lx p: %lx\n", - (unsigned long)list, (unsigned long)list->next, - (unsigned long)list->prev); + (unsigned long)&d_inf->run_list, + (unsigned long)d_inf->run_list.next, + (unsigned long)d_inf->run_list.prev); } queue = WAITQ(cpu); printk("\nWAITQUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, - (unsigned long) queue->next, (unsigned long) queue->prev); + (unsigned long) queue->next, (unsigned long) queue->prev); - list_for_each ( list, queue ) + list_for_each_entry ( d_inf, queue, waitq ) { - d_inf = list_entry(list, struct at_dom_info, waitq); d = d_inf->owner; printk("%3d: %d has=%c ", loop++, d->id, - test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); + test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); at_dump_runq_el(d); printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); printk(" l: %lx n: %lx p: %lx\n", - (unsigned long)list, (unsigned long)list->next, - (unsigned long)list->prev); + (unsigned long)&d_inf->waitq, + (unsigned long)d_inf->waitq.next, + (unsigned long)d_inf->waitq.prev); } } diff --git a/xen/common/sched_bvt.c b/xen/common/sched_bvt.c index 1d447b718b..6f0a79fad1 100644 --- a/xen/common/sched_bvt.c +++ b/xen/common/sched_bvt.c @@ -348,7 +348,6 @@ int bvt_adjdom( static task_slice_t bvt_do_schedule(s_time_t now) { struct domain *prev = current, *next = NULL, *next_prime, *p; - struct list_head *tmp; int cpu = prev->processor; s32 r_time; /* time for new dom to run */ u32 next_evt, next_prime_evt, min_avt; @@ -392,10 +391,8 @@ static task_slice_t bvt_do_schedule(s_time_t now) next_prime_evt = ~0U; min_avt = ~0U; - list_for_each ( tmp, RUNQUEUE(cpu) ) + list_for_each_entry ( p_inf, RUNQUEUE(cpu), run_list ) { - p_inf = list_entry(tmp, struct bvt_dom_info, run_list); - if ( p_inf->evt < next_evt ) { next_prime_inf = next_inf; @@ -505,7 +502,7 @@ static void bvt_dump_settings(void) static void bvt_dump_cpu_state(int i) { - struct list_head *list, *queue; + struct list_head *queue; int loop = 0; struct bvt_dom_info *d_inf; struct domain *d; @@ -516,17 +513,15 @@ static void bvt_dump_cpu_state(int i) printk("QUEUE rq %lx n: %lx, p: %lx\n", (unsigned long)queue, (unsigned long) queue->next, (unsigned long) queue->prev); - list_for_each ( list, queue ) + list_for_each_entry ( d_inf, queue, run_list ) { - d_inf = list_entry(list, struct bvt_dom_info, run_list); d = d_inf->domain; printk("%3d: %u has=%c ", loop++, d->id, test_bit(DF_RUNNING, &d->flags) ? 'T':'F'); bvt_dump_runq_el(d); printk("c=0x%X%08X\n", (u32)(d->cpu_time>>32), (u32)d->cpu_time); - printk(" l: %lx n: %lx p: %lx\n", - (unsigned long)list, (unsigned long)list->next, - (unsigned long)list->prev); + printk(" l: %p n: %p p: %p\n", + &d_inf->run_list, d_inf->run_list.next, d_inf->run_list.prev); } } diff --git a/xen/common/sched_rrobin.c b/xen/common/sched_rrobin.c index fbf17ab84c..2164ce22b4 100644 --- a/xen/common/sched_rrobin.c +++ b/xen/common/sched_rrobin.c @@ -187,7 +187,7 @@ static void rr_dump_domain(struct domain *d) static void rr_dump_cpu_state(int i) { - struct list_head *list, *queue; + struct list_head *queue; int loop = 0; struct rrobin_dom_info *d_inf; @@ -199,10 +199,9 @@ static void rr_dump_cpu_state(int i) d_inf = list_entry(queue, struct rrobin_dom_info, run_list); rr_dump_domain(d_inf->domain); - list_for_each ( list, queue ) + list_for_each_entry ( d_inf, queue, run_list ) { printk("%3d: ",loop++); - d_inf = list_entry(list, struct rrobin_dom_info, run_list); rr_dump_domain(d_inf->domain); } } diff --git a/xen/common/slab.c b/xen/common/slab.c index 3e91a6a058..cfbf402261 100644 --- a/xen/common/slab.c +++ b/xen/common/slab.c @@ -774,11 +774,9 @@ xmem_cache_create (const char *name, size_t size, size_t offset, /* Need the semaphore to access the chain. */ down(&cache_chain_sem); { - struct list_head *p; - - list_for_each(p, &cache_chain) { - xmem_cache_t *pc = list_entry(p, xmem_cache_t, next); + xmem_cache_t *pc; + list_for_each_entry(pc, &cache_chain, next) { /* The name field is constant - no lock needed. */ if (!strcmp(pc->name, name)) BUG(); @@ -802,14 +800,14 @@ xmem_cache_create (const char *name, size_t size, size_t offset, */ static int is_chained_xmem_cache(xmem_cache_t * cachep) { - struct list_head *p; + xmem_cache_t *pc; int ret = 0; unsigned long spin_flags; /* Find the cache in the chain of caches. */ down(&cache_chain_sem); - list_for_each(p, &cache_chain) { - if (p == &cachep->next) { + list_for_each_entry(pc, &cache_chain, next) { + if (pc == &cachep) { ret = 1; break; } @@ -1765,7 +1763,6 @@ void dump_slabinfo() p = &cache_cache.next; do { xmem_cache_t *cachep; - struct list_head *q; slab_t *slabp; unsigned long active_objs; unsigned long num_objs; @@ -1776,22 +1773,19 @@ void dump_slabinfo() spin_lock_irq(&cachep->spinlock); active_objs = 0; num_slabs = 0; - list_for_each(q,&cachep->slabs_full) { - slabp = list_entry(q, slab_t, list); + list_for_each_entry(slabp, &cachep->slabs_full, list) { if (slabp->inuse != cachep->num) BUG(); active_objs += cachep->num; active_slabs++; } - list_for_each(q,&cachep->slabs_partial) { - slabp = list_entry(q, slab_t, list); + list_for_each_entry(slabp, &cachep->slabs_partial, list) { if (slabp->inuse == cachep->num || !slabp->inuse) BUG(); active_objs += slabp->inuse; active_slabs++; } - list_for_each(q,&cachep->slabs_free) { - slabp = list_entry(q, slab_t, list); + list_for_each_entry(slabp, &cachep->slabs_free, list) { if (slabp->inuse) BUG(); num_slabs++; diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c index 4ae22d07e0..50a4ebb5e0 100644 --- a/xen/drivers/pci/pci.c +++ b/xen/drivers/pci/pci.c @@ -1565,15 +1565,15 @@ static int pci_pm_resume_device(struct pci_dev *dev) static int pci_pm_save_state_bus(struct pci_bus *bus, u32 state) { - struct list_head *list; + struct pci_bus *i; int error = 0; - list_for_each(list, &bus->children) { - error = pci_pm_save_state_bus(pci_bus_b(list),state); + list_for_each_entry(i, &bus->children, node) { + error = pci_pm_save_state_bus(i, state); if (error) return error; } - list_for_each(list, &bus->devices) { - error = pci_pm_save_state_device(pci_dev_b(list),state); + list_for_each_entry(i, &bus->devices, node) { + error = pci_pm_save_state_device(i, state); if (error) return error; } return 0; @@ -1581,40 +1581,38 @@ static int pci_pm_save_state_bus(struct pci_bus *bus, u32 state) static int pci_pm_suspend_bus(struct pci_bus *bus, u32 state) { - struct list_head *list; + struct pci_bus *i; /* Walk the bus children list */ - list_for_each(list, &bus->children) - pci_pm_suspend_bus(pci_bus_b(list),state); + list_for_each_entry(i, &bus->children, node) + pci_pm_suspend_bus(i, state); /* Walk the device children list */ - list_for_each(list, &bus->devices) - pci_pm_suspend_device(pci_dev_b(list),state); + list_for_each_entry(i, &bus->devices, node) + pci_pm_suspend_device(i, state); return 0; } static int pci_pm_resume_bus(struct pci_bus *bus) { - struct list_head *list; + struct pci_bus *i; /* Walk the device children list */ - list_for_each(list, &bus->devices) - pci_pm_resume_device(pci_dev_b(list)); + list_for_each_entry(i, &bus->devices, node) + pci_pm_resume_device(i); /* And then walk the bus children */ - list_for_each(list, &bus->children) - pci_pm_resume_bus(pci_bus_b(list)); + list_for_each_entry(i, &bus->children, node) + pci_pm_resume_bus(i); return 0; } static int pci_pm_save_state(u32 state) { - struct list_head *list; struct pci_bus *bus; int error = 0; - list_for_each(list, &pci_root_buses) { - bus = pci_bus_b(list); + list_for_each_entry(bus, &pci_root_buses, node) { error = pci_pm_save_state_bus(bus,state); if (!error) error = pci_pm_save_state_device(bus->self,state); @@ -1624,11 +1622,9 @@ static int pci_pm_save_state(u32 state) static int pci_pm_suspend(u32 state) { - struct list_head *list; struct pci_bus *bus; - list_for_each(list, &pci_root_buses) { - bus = pci_bus_b(list); + list_for_each_entry(bus, &pci_root_buses, node) { pci_pm_suspend_bus(bus,state); pci_pm_suspend_device(bus->self,state); } @@ -1637,11 +1633,9 @@ static int pci_pm_suspend(u32 state) int pci_pm_resume(void) { - struct list_head *list; struct pci_bus *bus; - list_for_each(list, &pci_root_buses) { - bus = pci_bus_b(list); + list_for_each_entry(bus, &pci_root_buses, node) { pci_pm_resume_device(bus->self); pci_pm_resume_bus(bus); } diff --git a/xen/include/xen/list.h b/xen/include/xen/list.h index cc38a310cd..7b19bb4650 100644 --- a/xen/include/xen/list.h +++ b/xen/include/xen/list.h @@ -161,8 +161,6 @@ static __inline__ void list_splice(struct list_head *list, struct list_head *hea for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) -#endif - /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop counter. @@ -175,3 +173,6 @@ static __inline__ void list_splice(struct list_head *list, struct list_head *hea &pos->member != (head); \ pos = list_entry(pos->member.next, typeof(*pos), member), \ prefetch(pos->member.next)) + +#endif /* _LINUX_LIST_H */ + diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index c81cd0d57d..5f8740a31c 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -358,7 +358,7 @@ enum pci_mmap_state { for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev)) #define pci_for_each_bus(bus) \ -for(bus = pci_bus_b(pci_root_buses.next); bus != pci_bus_b(&pci_root_buses); bus = pci_bus_b(bus->node.next)) + list_for_each_entry(bus, &pci_root_buses, node) /* * The pci_dev structure is used to describe both PCI and ISAPnP devices. From 201fb48f0920e7d9cfd7d84ad03d85a23ef92fdd Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 15:37:49 +0000 Subject: [PATCH 042/199] bitkeeper revision 1.1159.223.38 (41f667cdBlErg8MU1cuAekL1VC008w) More fixes to the build system further to earlier patch. Signed-off-by: ian.pratt@cl.cam.ac.uk --- Makefile | 22 +++++++++++----------- buildconfigs/Rules.mk | 4 ++-- buildconfigs/mk.linux-2.4-xen0 | 4 ++-- buildconfigs/mk.linux-2.4-xenU | 4 ++-- buildconfigs/mk.linux-2.6-xen0 | 4 ++-- buildconfigs/mk.linux-2.6-xenU | 4 ++-- buildconfigs/mk.netbsd-2.0-xenU | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 8e2988dc08..c7b4640ecc 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ # Grand Unified Makefile for Xen. # -DIST_DIR := $(CURDIR)/dist -DESTDIR := $(DIST_DIR)/install +DISTDIR ?= $(CURDIR)/dist +DESTDIR ?= $(DISTDIR)/install INSTALL := install INSTALL_DIR := $(INSTALL) -d -m0755 @@ -40,10 +40,10 @@ install-tools: $(MAKE) -C tools install install-kernels: - cp -a $(INSTALL_DIR)/boot/* /boot/ - cp -a $(INSTALL_DIR)/lib/modules/* /lib/modules/ - cp -dR $(INSTALL_DIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ - cp -dR $(INSTALL_DIR)/lib/modules/* $(prefix)/lib/modules/ + cp -a $(DESTDIR)/boot/* /boot/ + cp -a $(DESTDIR)/lib/modules/* /lib/modules/ + cp -dR $(DESTDIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ + cp -dR $(DESTDIR)/lib/modules/* $(prefix)/lib/modules/ install-docs: sh ./docs/check_pkgs && $(MAKE) -C docs install || true @@ -52,11 +52,11 @@ install-docs: # build and install everything into local dist directory dist: xen tools kernels docs - $(INSTALL_DIR) $(DIST_DIR)/check - $(INSTALL_DATA) ./COPYING $(DIST_DIR) - $(INSTALL_DATA) ./README $(DIST_DIR) - $(INSTALL_PROG) ./install.sh $(DIST_DIR) - $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DIST_DIR)/check + $(INSTALL_DIR) $(DISTDIR)/check + $(INSTALL_DATA) ./COPYING $(DISTDIR) + $(INSTALL_DATA) ./README $(DISTDIR) + $(INSTALL_PROG) ./install.sh $(DISTDIR) + $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DISTDIR)/check xen: $(MAKE) dist=yes -C xen install diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index e2bd054473..cdb6b096e2 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -1,8 +1,8 @@ # We expect these two to already be set if people # are using the top-level Makefile -DIST_DIR ?= $(shell pwd)/dist -INSTALL_DIR ?= $(DIST_DIR)/install +DISTDIR ?= $(CURDIR)/dist +DESTDIR ?= $(DISTDIR)/install .PHONY: mkpatches mrproper diff --git a/buildconfigs/mk.linux-2.4-xen0 b/buildconfigs/mk.linux-2.4-xen0 index c4f7fc359a..be21fc5ec3 100644 --- a/buildconfigs/mk.linux-2.4-xen0 +++ b/buildconfigs/mk.linux-2.4-xen0 @@ -37,8 +37,8 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) # add ebtables patch ( cd $(LINUX_DIR) ; patch -p1 -F3 < ../patches/tmp/ebtables.diff ) # Re-use config from install dir if one exits else use default config - [ -r $(INSTALL_DIR)/boot/config-$(FULLVERSION) ] && \ - cp $(INSTALL_DIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ + [ -r $(DESTDIR)/boot/config-$(FULLVERSION) ] && \ + cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/defconfig-$(EXTRAVERSION) \ $(LINUX_DIR)/.config make -C $(LINUX_DIR) ARCH=xen oldconfig diff --git a/buildconfigs/mk.linux-2.4-xenU b/buildconfigs/mk.linux-2.4-xenU index 1c589faba2..26563c11e6 100644 --- a/buildconfigs/mk.linux-2.4-xenU +++ b/buildconfigs/mk.linux-2.4-xenU @@ -30,8 +30,8 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) sed -e 's/^EXTRAVERSION.*/&-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \ rm -f Makefile ; mv Mk.tmp Makefile ) # Re-use config from install dir if one exits else use default config - [ -r $(INSTALL_DIR)/boot/config-$(FULLVERSION) ] && \ - cp $(INSTALL_DIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ + [ -r $(DESTDIR)/boot/config-$(FULLVERSION) ] && \ + cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/defconfig-$(EXTRAVERSION) \ $(LINUX_DIR)/.config make -C $(LINUX_DIR) ARCH=xen oldconfig diff --git a/buildconfigs/mk.linux-2.6-xen0 b/buildconfigs/mk.linux-2.6-xen0 index eda5bb46d8..f4310f5925 100644 --- a/buildconfigs/mk.linux-2.6-xen0 +++ b/buildconfigs/mk.linux-2.6-xen0 @@ -30,8 +30,8 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) sed -e 's/^EXTRAVERSION.*/&-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \ rm -f Makefile ; mv Mk.tmp Makefile ) # Re-use config from install dir if one exits else use default config - [ -r $(INSTALL_DIR)/boot/config-$(FULLVERSION) ] && \ - cp $(INSTALL_DIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ + [ -r $(DESTDIR)/boot/config-$(FULLVERSION) ] && \ + cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig \ $(LINUX_DIR)/.config make -C $(LINUX_DIR) ARCH=xen oldconfig diff --git a/buildconfigs/mk.linux-2.6-xenU b/buildconfigs/mk.linux-2.6-xenU index ff6b47ff29..79a3d66777 100644 --- a/buildconfigs/mk.linux-2.6-xenU +++ b/buildconfigs/mk.linux-2.6-xenU @@ -30,8 +30,8 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) sed -e 's/^EXTRAVERSION.*/&-$(EXTRAVERSION)/' Makefile >Mk.tmp ; \ rm -f Makefile ; mv Mk.tmp Makefile ) # Re-use config from install dir if one exits else use default config - [ -r $(INSTALL_DIR)/boot/config-$(FULLVERSION) ] && \ - cp $(INSTALL_DIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ + [ -r $(DESTDIR)/boot/config-$(FULLVERSION) ] && \ + cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig \ $(LINUX_DIR)/.config make -C $(LINUX_DIR) ARCH=xen oldconfig diff --git a/buildconfigs/mk.netbsd-2.0-xenU b/buildconfigs/mk.netbsd-2.0-xenU index 55a802f143..acd7e5801a 100644 --- a/buildconfigs/mk.netbsd-2.0-xenU +++ b/buildconfigs/mk.netbsd-2.0-xenU @@ -34,7 +34,7 @@ $(NETBSD_DIR)/.valid: pristine-netbsd-$(NETBSD_VER) netbsd-xen%: $(NETBSD_DIR)/.valid netbsd-$(NETBSD_RELEASE)-tools $(MAKE) -C netbsd-$(FULLVERSION) config $(MAKE) -C netbsd-$(FULLVERSION) netbsd - $(MAKE) -C netbsd-$(FULLVERSION) INSTALL_PATH=$(INSTALL_DIR) INSTALL_NAME=boot/netbsd-$(NETBSD_VER)-xen$* install + $(MAKE) -C netbsd-$(FULLVERSION) INSTALL_PATH=$(DESTDIR) INSTALL_NAME=boot/netbsd-$(NETBSD_VER)-xen$* install clean: $(MAKE) -C netbsd-$(FULLVERSION) clean From d63e6e0318369f1d14ec09381f6c96deddcd0fce Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 15:59:28 +0000 Subject: [PATCH 043/199] bitkeeper revision 1.1159.223.39 (41f66ce0jpkVCVDUEA2oOsgUQP1D9A) Cset exclude: iap10@labyrinth.cl.cam.ac.uk|ChangeSet|20050122213003|38297 --- tools/libxc/Makefile | 30 +++++++++++------------------- tools/libxutil/Makefile | 11 +++-------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 20714e0452..3db364201d 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -3,10 +3,9 @@ INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DATA = $(INSTALL) -m0644 INSTALL_DIR = $(INSTALL) -d -m0755 -MAJOR := 2.0 -MINOR := 0 -LIB_NAME := libxc -SONAME := $(LIB_NAME).so.$(MAJOR) +MAJOR = 2.0 +MINOR = 0 +SONAME = libxc.so.$(MAJOR) CC = gcc @@ -40,10 +39,9 @@ CFLAGS += $(INCLUDES) -I. CFLAGS += -Wp,-MD,.$(@F).d DEPS = .*.d -OBJS := $(patsubst %.c,%.o,$(SRCS)) -PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) +OBJS = $(patsubst %.c,%.o,$(SRCS)) -LIB := $(LIB_NAME).a $(LIB_NAME).so $(LIB_NAME).so.$(MAJOR) $(LIB_NAME).so.$(MAJOR).$(MINOR) +LIB = libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) all: check-for-zlib mk-symlinks $(MAKE) $(LIB) @@ -76,7 +74,7 @@ install: all $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include clean: - rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen + rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) xen rpm: all rm -rf staging @@ -87,17 +85,11 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging -$(PIC_OBJS): %.opic: %.c - $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< - -$(LIB_NAME).a: $(OBJS) - $(AR) rc $@ $^ - -$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) - ln -sf $< $@ -$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) - ln -sf $< $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(PIC_OBJS) +libxc.so: + ln -sf libxc.so.$(MAJOR) $@ +libxc.so.$(MAJOR): + ln -sf libxc.so.$(MAJOR).$(MINOR) $@ +libxc.so.$(MAJOR).$(MINOR): $(OBJS) $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -L../libxutil -lxutil -lz -include $(DEPS) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index 9efb826b0b..d68699de28 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -24,7 +24,6 @@ LIB_SRCS += sys_string.c LIB_SRCS += util.c LIB_OBJS := $(LIB_SRCS:.c=.o) -LIB_PIC_OBJS := $(LIB_SRCS:.c=.opic) CFLAGS += -Wall CFLAGS += -Werror @@ -39,7 +38,6 @@ DEPS = .*.d MAJOR := 2.0 MINOR := 0 LIB_NAME := libxutil -SO_NAME := $(LIB_NAME).so.$(MAJOR) LIB := $(LIB_NAME).so LIB += $(LIB_NAME).so.$(MAJOR) LIB += $(LIB_NAME).so.$(MAJOR).$(MINOR) @@ -48,17 +46,14 @@ LIB += $(LIB_NAME).a all: check-for-zlib $(MAKE) $(LIB) -$(LIB_PIC_OBJS): %.opic: %.c - $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< - $(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) ln -sf $^ $@ $(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) ln -sf $^ $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_PIC_OBJS) - $(CC) -Wl,-soname -Wl,$(SO_NAME) -shared -o $@ $^ +$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_OBJS) + $(CC) -Wl,-soname -Wl,$(LIB_NAME).so.$(MAJOR) -shared -o $@ $^ $(LIB_NAME).a: $(LIB_OBJS) $(AR) rc $@ $^ @@ -78,7 +73,7 @@ install: all ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so clean: - $(RM) *.a *.so *.so.* *.o *.opic *.rpm + $(RM) *.a *.so *.so.* *.o *.rpm $(RM) *~ $(RM) $(DEPS) From 3279b48916b664d78b652c8358ff0ec06e2cdaca Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 16:41:47 +0000 Subject: [PATCH 044/199] bitkeeper revision 1.1159.223.40 (41f676cbajLGqFeWFqajtJ3X4OkgoA) Build system fixes. Signed-off-by: keir.fraser@cl.cam.ac.uk --- Makefile | 49 +++++++---------------- docs/Makefile | 5 +-- linux-2.4.29-xen-sparse/arch/xen/Makefile | 3 -- linux-2.6.10-xen-sparse/arch/xen/Makefile | 2 - tools/Makefile | 8 +--- tools/examples/Makefile | 4 +- tools/libxutil/Makefile | 6 +-- tools/python/Makefile | 6 +-- tools/vnet/Makefile | 3 -- tools/vnet/examples/Makefile | 4 +- tools/vnet/vnet-module/Makefile-2.4 | 4 +- tools/vnet/vnet-module/Makefile-2.6 | 4 +- tools/vnet/vnetd/Makefile | 4 +- tools/xfrd/Makefile | 4 +- xen/Makefile | 3 -- 15 files changed, 31 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index c7b4640ecc..0bd91f33ab 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,6 @@ # Grand Unified Makefile for Xen. # -DISTDIR ?= $(CURDIR)/dist -DESTDIR ?= $(DISTDIR)/install - INSTALL := install INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 @@ -18,7 +15,6 @@ ALLKERNELS = $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.*)) ALLSPARSETREES = $(patsubst %-xen-sparse,%,$(wildcard *-xen-sparse)) XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) ) - export DESTDIR include buildconfigs/Rules.mk @@ -31,26 +27,16 @@ all: dist # install everything into the standard system directories # NB: install explicitly does not check that everything is up to date! -install: install-tools install-xen install-kernels install-docs +install: xen checked-tools kernels docs -install-xen: - $(MAKE) -C xen install - -install-tools: +# Only check for install req'mts on 'make install', not on 'make dist'. +checked-tools: + $(MAKE) -C tools/check install $(MAKE) -C tools install -install-kernels: - cp -a $(DESTDIR)/boot/* /boot/ - cp -a $(DESTDIR)/lib/modules/* /lib/modules/ - cp -dR $(DESTDIR)/boot/*$(LINUX_VER)* $(prefix)/boot/ - cp -dR $(DESTDIR)/lib/modules/* $(prefix)/lib/modules/ - -install-docs: - sh ./docs/check_pkgs && $(MAKE) -C docs install || true - sh ./docs/check_pkgs - -$(MAKE) -C docs install - # build and install everything into local dist directory +dist: DISTDIR=$(CURDIR)/dist +dist: DESTDIR=$(DISTDIR)/install dist: xen tools kernels docs $(INSTALL_DIR) $(DISTDIR)/check $(INSTALL_DATA) ./COPYING $(DISTDIR) @@ -59,17 +45,16 @@ dist: xen tools kernels docs $(INSTALL_PROG) tools/check/chk tools/check/check_* $(DISTDIR)/check xen: - $(MAKE) dist=yes -C xen install + $(MAKE) -C xen install tools: - $(MAKE) dist=yes -C tools install + $(MAKE) -C tools install kernels: for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done docs: - sh ./docs/check_pkgs - -$(MAKE) dist=yes -C docs install + sh ./docs/check_pkgs && $(MAKE) -C docs install || true # Build all the various kernels and modules kbuild: kernels @@ -126,21 +111,17 @@ install-iptables: help: @echo 'Installation targets:' - @echo ' install - install everything' - @echo ' install-xen - install the Xen hypervisor' - @echo ' install-tools - install the control tools' - @echo ' install-kernels - install guest kernels' - @echo ' install-docs - install documentation' + @echo ' install - build and install everything' @echo '' @echo 'Building targets:' - @echo ' dist - build everything and place in dist/' + @echo ' dist - build and install everything into local dist directory' @echo ' world - clean everything, delete guest kernel build' @echo ' trees then make dist' - @echo ' xen - build Xen hypervisor and place in dist/' - @echo ' tools - build tools and place in dist/' - @echo ' kernels - build guest kernels and place in dist/' + @echo ' xen - build and install Xen hypervisor' + @echo ' tools - build and install tools' + @echo ' kernels - build and install guest kernels' @echo ' kbuild - synonym for make kernels' - @echo ' docs - build docs and place in dist/' + @echo ' docs - build and install docs' @echo '' @echo 'Cleaning targets:' @echo ' clean - clean the Xen, tools and docs (but not' diff --git a/docs/Makefile b/docs/Makefile index 46c2d38c59..d9ae6715ac 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -10,10 +10,7 @@ FIG2DEV := fig2dev TGIF := tgif LATEX2HTML := latex2html -package = xen -prefix = /usr -docdir = $(prefix)/share/doc -pkgdocdir = $(docdir)/$(package) +pkgdocdir := /usr/share/doc/xen DOC_TEX := $(wildcard src/*.tex) DOC_PS := $(patsubst src/%.tex,ps/%.ps,$(DOC_TEX)) diff --git a/linux-2.4.29-xen-sparse/arch/xen/Makefile b/linux-2.4.29-xen-sparse/arch/xen/Makefile index df13c06a6e..0f1d0580da 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/Makefile +++ b/linux-2.4.29-xen-sparse/arch/xen/Makefile @@ -118,9 +118,6 @@ install: bzImage install -m0664 .config $(INSTALL_PATH)/boot/config-$(INSTALL_NAME)$(INSTALL_SUFFIX) install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(INSTALL_NAME)$(INSTALL_SUFFIX) -dist: - $(MAKE) INSTALL_PATH=../dist/install install - %_config: arch/xen/defconfig-% rm -f .config arch/xen/defconfig cp -f arch/xen/defconfig-$(@:_config=) arch/xen/defconfig diff --git a/linux-2.6.10-xen-sparse/arch/xen/Makefile b/linux-2.6.10-xen-sparse/arch/xen/Makefile index eeaea0c89e..86132ecf16 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/Makefile +++ b/linux-2.6.10-xen-sparse/arch/xen/Makefile @@ -54,8 +54,6 @@ install: vmlinuz install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX) mkdir -p $(INSTALL_PATH)/usr/include/xen/linux install -m0644 include/asm-xen/linux-public/*.h $(INSTALL_PATH)/usr/include/xen/linux -dist: - $(MAKE) INSTALL_PATH=../dist/install install archclean: @if [ -e arch/xen/arch ]; then $(MAKE) $(clean)=arch/xen/arch; fi; diff --git a/tools/Makefile b/tools/Makefile index 722f9d9f7d..907260707b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,9 +10,7 @@ all: $(MAKE) -C xfrd install: -ifneq ($(dist),yes) - $(MAKE) -C check install -endif + $(MAKE) -C check $(MAKE) -C libxutil install $(MAKE) -C libxc install $(MAKE) -C misc install @@ -22,10 +20,6 @@ endif $(MAKE) -C xfrd install $(MAKE) -C sv install -dist: $(TARGET) - $(MAKE) prefix=$(CURDIR)/../dist/install dist=yes install - - clean: $(MAKE) -C libxutil clean $(MAKE) -C libxc clean diff --git a/tools/examples/Makefile b/tools/examples/Makefile index 0fb4950476..cc9ebbc50e 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -33,14 +33,14 @@ install-configs: $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR) $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto for i in $(XEN_CONFIGS); \ - do [ -a $(DESTDIR)/$(XEN_CONFIG_DIR)/$$i ] || \ + do [ -a $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \ done install-scripts: $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) for i in $(XEN_SCRIPTS); \ - do [ -a $(DESTDIR)/$()/$$i ] || \ + do [ -a $(DESTDIR)$(XEN_SCRIPT_DIR)/$$i ] || \ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \ done diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index d68699de28..bedbcc7c5c 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -25,11 +25,7 @@ LIB_SRCS += util.c LIB_OBJS := $(LIB_SRCS:.c=.o) -CFLAGS += -Wall -CFLAGS += -Werror -CFLAGS += -g -CFLAGS += -O3 -CFLAGS += -fno-strict-aliasing +CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing # Get gcc to generate the dependencies for us. CFLAGS += -Wp,-MD,.$(@F).d diff --git a/tools/python/Makefile b/tools/python/Makefile index 9d39bd85b4..18bfeb1f7d 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -3,11 +3,7 @@ all: python setup.py build install: all - if [ "$(DESTDIR)" = "" ]; then \ - python setup.py install; \ - else \ - python setup.py install --root="$(DESTDIR)"; \ - fi + python setup.py install --home="$(DESTDIR)/usr" clean: rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/vnet/Makefile b/tools/vnet/Makefile index 1eddeb44cc..63939dff9d 100644 --- a/tools/vnet/Makefile +++ b/tools/vnet/Makefile @@ -44,9 +44,6 @@ install: compile $(MAKE) -C vnet-module install $(MAKE) -C examples install -dist: $(TARGET) - $(MAKE) install - clean: -$(MAKE) -C vnetd clean -$(MAKE) -C vnet-module clean diff --git a/tools/vnet/examples/Makefile b/tools/vnet/examples/Makefile index fe9d9f56ad..d0cc4a6e57 100644 --- a/tools/vnet/examples/Makefile +++ b/tools/vnet/examples/Makefile @@ -6,7 +6,7 @@ XEN_SCRIPT_DIR:=/etc/xen/scripts all: install: - install -m 0755 -d $(prefix)$(XEN_SCRIPT_DIR) - install -m 0554 network-vnet $(prefix)$(XEN_SCRIPT_DIR) + install -m 0755 -d $(DESTDIR)$(XEN_SCRIPT_DIR) + install -m 0554 network-vnet $(DESTDIR)$(XEN_SCRIPT_DIR) clean: \ No newline at end of file diff --git a/tools/vnet/vnet-module/Makefile-2.4 b/tools/vnet/vnet-module/Makefile-2.4 index 4a512aaa3b..68c34c2b29 100644 --- a/tools/vnet/vnet-module/Makefile-2.4 +++ b/tools/vnet/vnet-module/Makefile-2.4 @@ -83,8 +83,8 @@ $(KERNEL_MODULE): $(VNET_OBJ) .PHONY: install install-module modules_install install install-module modules_install: module - install -m 0755 -d $(prefix)$(KERNEL_MODULE_DIR) - install -m 0554 $(KERNEL_MODULE) $(prefix)$(KERNEL_MODULE_DIR) + install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR) + install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR) TAGS: etags *.c *.h diff --git a/tools/vnet/vnet-module/Makefile-2.6 b/tools/vnet/vnet-module/Makefile-2.6 index 698644a1f4..64e57ea5ff 100644 --- a/tools/vnet/vnet-module/Makefile-2.6 +++ b/tools/vnet/vnet-module/Makefile-2.6 @@ -38,8 +38,8 @@ module modules: .PHONY: install install-module modules_install install install-module modules_install: module - install -m 0755 -d $(prefix)$(KERNEL_MODULE_DIR) - install -m 0554 $(KERNEL_MODULE) $(prefix)$(KERNEL_MODULE_DIR) + install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR) + install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR) .PHONY: clean clean: diff --git a/tools/vnet/vnetd/Makefile b/tools/vnet/vnetd/Makefile index 69d4c0269c..be13801a0c 100644 --- a/tools/vnet/vnetd/Makefile +++ b/tools/vnet/vnetd/Makefile @@ -92,8 +92,8 @@ vnetd: $(VNETD_OBJ) $(CC) $(CFLAGS) -o $@ $^ $(VNETD_LIBS) -ldl -lpthread install: vnetd - mkdir -p $(prefix)/$(VNETD_INSTALL_DIR) - install -m 0755 vnetd $(prefix)/$(VNETD_INSTALL_DIR) + mkdir -p $(DESTDIR)$(VNETD_INSTALL_DIR) + install -m 0755 vnetd $(DESTDIR)$(VNETD_INSTALL_DIR) clean: -rm -f *.a *.o *~ diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 6ca1a1d12f..0b16891eaf 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -72,8 +72,8 @@ xfrd: $(XFRD_PROG_OBJ) .PHONY: install install: xfrd - $(INSTALL_DIR) $(DESTDIR)/$(XFRD_INSTALL_DIR) - $(INSTALL_PROG) xfrd $(DESTDIR)/$(XFRD_INSTALL_DIR) + $(INSTALL_DIR) $(DESTDIR)$(XFRD_INSTALL_DIR) + $(INSTALL_PROG) xfrd $(DESTDIR)$(XFRD_INSTALL_DIR) .PHONY: libutil libutil: $(UTIL_LIB) diff --git a/xen/Makefile b/xen/Makefile index fd2c06df3d..2a84ca6835 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -9,7 +9,6 @@ export XEN_SUBVERSION = 0 export XEN_EXTRAVERSION = "" export BASEDIR := $(CURDIR) -DESTDIR := $(CURDIR)/../dist/install include Rules.mk @@ -30,8 +29,6 @@ install: $(TARGET).gz $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen -dist: install - clean: $(MAKE) -C tools clean $(MAKE) -C common clean From f92899900f763390971025945a90a02ca9fd5259 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 25 Jan 2005 17:57:23 +0000 Subject: [PATCH 045/199] bitkeeper revision 1.1159.223.41 (41f68883FaU7hVfFtWiOkCPnI6N1Hw) Fix root Makefile so that targets only install to / if you do a 'make install'. All other targets will install to local dist directory, as before. --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0bd91f33ab..d1d7ba5df4 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ # Grand Unified Makefile for Xen. # +# Default is to install to local 'dist' directory. +DISTDIR ?= $(CURDIR)/dist +DESTDIR ?= $(DISTDIR)/install + INSTALL := install INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 @@ -27,6 +31,7 @@ all: dist # install everything into the standard system directories # NB: install explicitly does not check that everything is up to date! +install: DESTDIR= install: xen checked-tools kernels docs # Only check for install req'mts on 'make install', not on 'make dist'. @@ -35,8 +40,6 @@ checked-tools: $(MAKE) -C tools install # build and install everything into local dist directory -dist: DISTDIR=$(CURDIR)/dist -dist: DESTDIR=$(DISTDIR)/install dist: xen tools kernels docs $(INSTALL_DIR) $(DISTDIR)/check $(INSTALL_DATA) ./COPYING $(DISTDIR) From 71e256b6ed65ef1f3ad27cb2edbba2ef0f1d29df Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 26 Jan 2005 10:56:17 +0000 Subject: [PATCH 046/199] bitkeeper revision 1.1159.223.42 (41f77751X73w7_t6jI0dgGV6N-Bweg) More build system fixes and tweaks. --- Makefile | 17 ++++++++++++++--- tools/libxc/Makefile | 4 ++-- tools/vnet/vnet-module/Makefile-2.4 | 1 - tools/vnet/vnetd/Makefile | 1 - tools/x2d2/Makefile | 2 +- tools/xfrd/Makefile | 4 +--- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index d1d7ba5df4..33bac70d43 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 INSTALL_PROG := $(INSTALL) -m0755 -KERNELS ?= linux-2.6-xen0 linux-2.6-xenU linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU +KERNELS ?= *2.6* # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU # You may use wildcards in the above e.g. KERNELS=*2.4* @@ -146,9 +146,20 @@ help: @echo ' with extreme care!)' # Use this target with extreme care! +uninstall: DESTDIR= +uninstall: D=$(DESTDIR) uninstall: - cp -a /etc/xen /etc/xen.old && rm -rf /etc/xen - rm -rf "/usr/lib/python2.?/site-packages/xen* /usr/lib/libxc* /usr/lib/python2.?/site-packages/Xc*" + [ ! -d $(D)/etc/xen ] || mv -f $(D)/etc/xen $(D)/etc/xen.old + rm -rf $(D)/etc/init.d/xend* + rm -rf $(D)/usr/lib/libxc* $(D)/usr/lib/libxutil* + rm -rf $(D)/usr/lib/python/xen $(D)/usr/include/xen + rm -rf $(D)/usr/include/xcs_proto.h $(D)/usr/include/xc.h + rm -rf $(D)/usr/sbin/xcs $(D)/usr/sbin/xcsdump $(D)/usr/sbin/xen* + rm -rf $(D)/usr/sbin/netfix + rm -rf $(D)/usr/sbin/xfrd $(D)/usr/sbin/xm $(D)/var/lib/xen + rm -rf $(D)/usr/share/doc/xen $(D)/usr/man/man*/xentrace* + rm -rf $(D)/usr/bin/xen* $(D)/usr/bin/miniterm + rm -rf $(D)/boot/*xen* # Legacy targets for compatibility linux24: diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 3db364201d..a0f62b9c6f 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -69,8 +69,8 @@ install: all $(INSTALL_DIR) $(DESTDIR)/usr/lib $(INSTALL_DIR) $(DESTDIR)/usr/include $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) - ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so + ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) + ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include clean: diff --git a/tools/vnet/vnet-module/Makefile-2.4 b/tools/vnet/vnet-module/Makefile-2.4 index 68c34c2b29..5781fca097 100644 --- a/tools/vnet/vnet-module/Makefile-2.4 +++ b/tools/vnet/vnet-module/Makefile-2.4 @@ -61,7 +61,6 @@ CFLAGS += -Wno-trigraphs CFLAGS += -Wno-unused-function CFLAGS += -Wno-unused-parameter -CFLAGS += -g CFLAGS += -O2 CFLAGS += -fno-strict-aliasing CFLAGS += -fno-common diff --git a/tools/vnet/vnetd/Makefile b/tools/vnet/vnetd/Makefile index be13801a0c..a507666b5d 100644 --- a/tools/vnet/vnetd/Makefile +++ b/tools/vnet/vnetd/Makefile @@ -42,7 +42,6 @@ INCLUDES += -I$(GC_INCLUDE) CPPFLAGS += -D USE_GC #---------------------------------------------------------------------------- -CFLAGS += -g CFLAGS += -Wall CFLAGS += $(INCLUDES) $(LIBS) diff --git a/tools/x2d2/Makefile b/tools/x2d2/Makefile index 36de2856ae..fbe408107f 100644 --- a/tools/x2d2/Makefile +++ b/tools/x2d2/Makefile @@ -2,7 +2,7 @@ XEN_ROOT=../.. include $(XEN_ROOT)/tools/Make.defs CC = gcc -CFLAGS = -Wall -Werror -g +CFLAGS = -Wall -Werror -O3 -fno-strict-aliasing CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 0b16891eaf..1b07ffa498 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -36,9 +36,7 @@ endif CC := gcc -CFLAGS += -g -CFLAGS += -Wall -CFLAGS += -Werror +CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing CFLAGS += $(INCLUDES) # Make gcc generate dependencies. CFLAGS += -Wp,-MD,.$(@F).d From 35fcf160380833d4d3bc858bfda75cc8f0dbae7b Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Wed, 26 Jan 2005 20:15:25 +0000 Subject: [PATCH 047/199] bitkeeper revision 1.1159.223.43 (41f7fa5dY-DhsXNFoEJlVfLdK5MEXQ) fix missing space --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 611e6e6417..09a59046f6 100755 --- a/install.sh +++ b/install.sh @@ -24,7 +24,7 @@ fi echo "Installing Xen from '$src' to '$dst'..." cd $src/boot -(echo '2.6.*' -2.6; echo '2.4.*' -2.4; echo '2.*.*' '') | while read mv +(echo '2.6.*' -2.6; echo '2.4.*' -2.4; echo '2.*.*' '') | while read m v do l=$(eval ls -t vmlinuz-$m-xen0 2>/dev/null | head -n 1) [ -e "$l" ] && ln -fs "$l" vmlinuz${v}-xen0 From 2f34aafbb609ff31be3fd880538c65ee78e379f0 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 10:53:38 +0000 Subject: [PATCH 048/199] bitkeeper revision 1.1159.223.44 (41f8c832pMZZ7WmykH_gAUBQHtPF1A) Allow target architecture to be specified by specifying ARCH variable to root Makefile (e.g, make ARCH=x86_32). --- .rootkeys | 2 +- Makefile | 14 ++++++++++---- tools/{Make.defs => Rules.mk} | 11 +++++++++++ tools/libxc/Makefile | 2 +- tools/libxutil/Makefile | 2 +- tools/misc/Makefile | 9 +++++---- tools/python/Makefile | 7 +++++-- tools/vnet/vnetd/Makefile | 2 +- tools/x2d2/Makefile | 4 ++-- tools/xentrace/Makefile | 4 ++-- tools/xfrd/Makefile | 2 +- 11 files changed, 40 insertions(+), 19 deletions(-) rename tools/{Make.defs => Rules.mk} (54%) diff --git a/.rootkeys b/.rootkeys index 4dde2f8460..b14c560ec8 100644 --- a/.rootkeys +++ b/.rootkeys @@ -294,8 +294,8 @@ 413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.9/agpgart.patch 413aa1d0ewvSv-ohnNnQQNGsbPTTNA patches/linux-2.6.9/drm.patch 418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.9/nettel.patch -40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Make.defs 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile +40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Rules.mk 4124b307nRyK3dhn1hAsvrY76NuV3g tools/check/Makefile 4124b307vHLUWbfpemVefmaWDcdfag tools/check/README 4124b307jt7T3CHysgl9LijNHSe1tA tools/check/check_brctl diff --git a/Makefile b/Makefile index 33bac70d43..094acb7fe4 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,12 @@ XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildc export DESTDIR +# Export target architecture overrides to Xen and Linux sub-trees. +ifneq ($(ARCH),) +export TARGET_SUBARCH := $(ARCH) +export SUBARCH := $(subst x86_32,i386,$(ARCH)) +endif + include buildconfigs/Rules.mk .PHONY: all dist install xen tools kernels docs world clean mkpatches mrproper @@ -36,8 +42,8 @@ install: xen checked-tools kernels docs # Only check for install req'mts on 'make install', not on 'make dist'. checked-tools: - $(MAKE) -C tools/check install - $(MAKE) -C tools install + $(MAKE) ARCH=$(ARCH) -C tools/check install + $(MAKE) ARCH=$(ARCH) -C tools install # build and install everything into local dist directory dist: xen tools kernels docs @@ -51,7 +57,7 @@ xen: $(MAKE) -C xen install tools: - $(MAKE) -C tools install + $(MAKE) ARCH=$(ARCH) -C tools install kernels: for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done @@ -86,7 +92,7 @@ world: # clean doesn't do a kclean clean: $(MAKE) -C xen clean - $(MAKE) -C tools clean + $(MAKE) ARCH=$(ARCH) -C tools clean $(MAKE) -C docs clean # clean, but blow away kernel build tree plus tar balls diff --git a/tools/Make.defs b/tools/Rules.mk similarity index 54% rename from tools/Make.defs rename to tools/Rules.mk index 132e4347cc..2876c7eb61 100644 --- a/tools/Make.defs +++ b/tools/Rules.mk @@ -1,4 +1,15 @@ # -*- mode: Makefile; -*- + XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_LIBXUTIL = $(XEN_ROOT)/tools/libxutil + +ifeq ($(ARCH),x86_32) +CFLAGS += -m32 -march=i686 +LDFLAGS += -m elf_i386 +endif + +ifeq ($(ARCH),x86_64) +CFLAGS += -m64 +LDFLAGS += -m elf_x86_64 +endif diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index a0f62b9c6f..d25e653467 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -10,7 +10,7 @@ SONAME = libxc.so.$(MAJOR) CC = gcc XEN_ROOT = ../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk vpath %c $(XEN_LIBXUTIL) INCLUDES += -I $(XEN_LIBXUTIL) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index bedbcc7c5c..67cfbe08fd 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -4,7 +4,7 @@ INSTALL_DATA = $(INSTALL) -m0644 INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DIR = $(INSTALL) -d -m0755 -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk CC = gcc diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 84166c72fc..b339e300db 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -3,10 +3,10 @@ INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DIR = $(INSTALL) -d -m0755 XEN_ROOT=../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk -CC = gcc -CFLAGS = -Wall -Werror -O3 +CC = gcc +CFLAGS += -Wall -Werror -O3 INCLUDES += -I $(XEN_XC) INCLUDES += -I $(XEN_LIBXC) @@ -27,7 +27,8 @@ install: all $(INSTALL_DIR) $(DESTDIR)/usr/sbin $(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin $(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin - $(MAKE) -C miniterm install +# No sense in installing miniterm on the Xen box. +# $(MAKE) -C miniterm install clean: $(RM) *.o $(TARGETS) *~ diff --git a/tools/python/Makefile b/tools/python/Makefile index 18bfeb1f7d..7d152e12ae 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -1,9 +1,12 @@ +XEN_ROOT = ../.. +include $(XEN_ROOT)/tools/Rules.mk + all: - python setup.py build + CFLAGS="$(CFLAGS)" python setup.py build install: all - python setup.py install --home="$(DESTDIR)/usr" + CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" clean: rm -rf build *.pyc *.pyo *.o *.a *~ diff --git a/tools/vnet/vnetd/Makefile b/tools/vnet/vnetd/Makefile index a507666b5d..3783fa3833 100644 --- a/tools/vnet/vnetd/Makefile +++ b/tools/vnet/vnetd/Makefile @@ -21,7 +21,7 @@ all: vnetd #---------------------------------------------------------------------------- XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk VNETD_INSTALL_DIR = /usr/sbin diff --git a/tools/x2d2/Makefile b/tools/x2d2/Makefile index fbe408107f..43f6964cae 100644 --- a/tools/x2d2/Makefile +++ b/tools/x2d2/Makefile @@ -1,8 +1,8 @@ XEN_ROOT=../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk CC = gcc -CFLAGS = -Wall -Werror -O3 -fno-strict-aliasing +CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 9133271b66..5fe6a9d61d 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -4,10 +4,10 @@ INSTALL_DIR = $(INSTALL) -d -m0755 INSTALL_DATA = $(INSTALL) -m0644 XEN_ROOT=../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk CC = gcc -CFLAGS = -Wall -Werror -O3 +CFLAGS += -Wall -Werror -O3 CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 1b07ffa498..e986755140 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -9,7 +9,7 @@ INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DIR = $(INSTALL) -d -m0755 XEN_ROOT = ../.. -include $(XEN_ROOT)/tools/Make.defs +include $(XEN_ROOT)/tools/Rules.mk XFRD_INSTALL_DIR = /usr/sbin From 04ce93fe81e83a89a74770bff096e12f4b1b411a Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 13:44:41 +0000 Subject: [PATCH 049/199] bitkeeper revision 1.1159.223.45 (41f8f049ZJjSGVQ7S0Y7kGBwMIZfZQ) No longer override target arch with ARCH but instead use TARGET_ARCH. Xen now requires specification of TARGET_ARCH alone, not TARGET_ARCH and TARGET_SUBARCH. Xen derives correct internal ARCH/SUBARCH components automatically. --- Makefile | 14 +++++++------- tools/Rules.mk | 4 ++-- xen/Rules.mk | 15 ++++++++------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 094acb7fe4..73098aa3dd 100644 --- a/Makefile +++ b/Makefile @@ -22,9 +22,9 @@ XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildc export DESTDIR # Export target architecture overrides to Xen and Linux sub-trees. -ifneq ($(ARCH),) -export TARGET_SUBARCH := $(ARCH) -export SUBARCH := $(subst x86_32,i386,$(ARCH)) +ifneq ($(TARGET_ARCH),) +SUBARCH := $(subst x86_32,i386,$(ARCH)) +export TARGET_ARCH SUBARCH endif include buildconfigs/Rules.mk @@ -42,8 +42,8 @@ install: xen checked-tools kernels docs # Only check for install req'mts on 'make install', not on 'make dist'. checked-tools: - $(MAKE) ARCH=$(ARCH) -C tools/check install - $(MAKE) ARCH=$(ARCH) -C tools install + $(MAKE) -C tools/check install + $(MAKE) -C tools install # build and install everything into local dist directory dist: xen tools kernels docs @@ -57,7 +57,7 @@ xen: $(MAKE) -C xen install tools: - $(MAKE) ARCH=$(ARCH) -C tools install + $(MAKE) -C tools install kernels: for i in $(XKERNELS) ; do $(MAKE) $$i-build || exit 1; done @@ -92,7 +92,7 @@ world: # clean doesn't do a kclean clean: $(MAKE) -C xen clean - $(MAKE) ARCH=$(ARCH) -C tools clean + $(MAKE) -C tools clean $(MAKE) -C docs clean # clean, but blow away kernel build tree plus tar balls diff --git a/tools/Rules.mk b/tools/Rules.mk index 2876c7eb61..2666f43842 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -4,12 +4,12 @@ XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_LIBXUTIL = $(XEN_ROOT)/tools/libxutil -ifeq ($(ARCH),x86_32) +ifeq ($(TARGET_ARCH),x86_32) CFLAGS += -m32 -march=i686 LDFLAGS += -m elf_i386 endif -ifeq ($(ARCH),x86_64) +ifeq ($(TARGET_ARCH),x86_64) CFLAGS += -m64 LDFLAGS += -m elf_x86_64 endif diff --git a/xen/Rules.mk b/xen/Rules.mk index c5d3405781..cf6972f097 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -6,14 +6,15 @@ perfc ?= n trace ?= n optimize ?= y -# Currently supported architectures: -# {COMPILE,TARGET}_ARCH := x86 -# {COMPILE,TARGET}_SUBARCH := x86_32 | x86_64 -COMPILE_ARCH := x86 -COMPILE_SUBARCH := $(shell uname -m | sed -e s/i.86/x86_32/) - +# Currently supported architectures: x86_32, x86_64 +COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) TARGET_ARCH ?= $(COMPILE_ARCH) -TARGET_SUBARCH ?= $(COMPILE_SUBARCH) + +# Set ARCH/SUBARCH appropriately. +COMPILE_SUBARCH := $(COMPILE_ARCH) +TARGET_SUBARCH := $(COMPILE_ARCH) +COMPILE_ARCH := $(patsubst x86%,x86,$(COMPILE_ARCH)) +TARGET_ARCH := $(patsubst x86%,x86,$(TARGET_ARCH)) TARGET := $(BASEDIR)/xen HDRS := $(wildcard $(BASEDIR)/include/xen/*.h) From 475057590a57c971b641a9888124a39c397fb2c8 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 13:47:05 +0000 Subject: [PATCH 050/199] bitkeeper revision 1.1159.223.46 (41f8f0d9VFDhRZsmMXXU3I_OEu8ADQ) silly mistake... --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 73098aa3dd..1c8ee8dc8a 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ export DESTDIR # Export target architecture overrides to Xen and Linux sub-trees. ifneq ($(TARGET_ARCH),) -SUBARCH := $(subst x86_32,i386,$(ARCH)) +SUBARCH := $(subst x86_32,i386,$(TARGET_ARCH)) export TARGET_ARCH SUBARCH endif From 157e1a5562556b6799d3660ee94801e020bf1d8b Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 16:02:39 +0000 Subject: [PATCH 051/199] bitkeeper revision 1.1159.223.47 (41f9109fKznqwLcV_lTngHAhBvwOZw) Minor domU net-backend fixes. --- linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c | 3 +-- tools/python/xen/xend/XendDomainInfo.py | 2 +- tools/python/xen/xend/server/netif.py | 6 ++++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c index 61626a7b91..ee53c8b1a6 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c @@ -1295,8 +1295,7 @@ static int __init netif_init(void) { int err = 0; - if ( (xen_start_info.flags & SIF_INITDOMAIN) || - (xen_start_info.flags & SIF_NET_BE_DOMAIN) ) + if ( xen_start_info.flags & SIF_INITDOMAIN ) return 0; IPRINTK("Initialising virtual ethernet driver.\n"); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 1a229a5599..05647c83ab 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -449,9 +449,9 @@ class XendDomainInfo: self.init_domain() self.configure_console() + self.configure_backends() self.construct_image() self.configure_restart() - self.configure_backends() deferred = self.configure() def cberr(err): self.destroy() diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 9152c2abf4..d63c342435 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -140,7 +140,8 @@ class NetDev(controller.SplitDev): self.ipaddr = self._get_config_ipaddr(config) or [] try: - self.backendDomain = int(sxp.child_value(config, 'backend', '0')) + xd = get_component('xen.xend.XendDomain') + self.backendDomain = int(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id) except: raise XendError('invalid backend domain') @@ -161,7 +162,8 @@ class NetDev(controller.SplitDev): bridge = sxp.child_value(config, 'bridge') script = sxp.child_value(config, 'script') ipaddr = self._get_config_ipaddr(config) - backendDomain = sxp.child_value(config, 'backend', '0') + xd = get_component('xen.xend.XendDomain') + backendDomain = str(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id) if (mac is not None) and (mac != self.mac): raise XendError("cannot change mac") if (backendDomain is not None) and (backendDomain != str(self.backendDomain)): From 8f230701e201bbc77fae73dc2671343081ba8d05 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Thu, 27 Jan 2005 17:09:14 +0000 Subject: [PATCH 052/199] bitkeeper revision 1.1159.234.1 (41f9203a3hESfmWBG29VVoqa-chOrA) Build system cleanups. Signed-off-by: c@pin.lu --- Makefile | 25 ++--- linux-2.6.10-xen-sparse/arch/xen/Kconfig | 126 +++++++++++------------ tools/examples/Makefile | 11 +- tools/libxc/Makefile | 4 +- tools/libxutil/Makefile | 2 +- tools/misc/Makefile | 4 +- tools/misc/miniterm/Makefile | 2 +- tools/sv/Makefile | 8 +- tools/xentrace/Makefile | 8 +- tools/xfrd/Makefile | 3 +- xen/Makefile | 5 +- 11 files changed, 104 insertions(+), 94 deletions(-) diff --git a/Makefile b/Makefile index 1c8ee8dc8a..b7229fc9a7 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ INSTALL_DIR := $(INSTALL) -d -m0755 INSTALL_DATA := $(INSTALL) -m0644 INSTALL_PROG := $(INSTALL) -m0755 -KERNELS ?= *2.6* +KERNELS ?= linux-2.6-xen0 linux-2.6-xenU # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU # You may use wildcards in the above e.g. KERNELS=*2.4* @@ -30,20 +30,12 @@ endif include buildconfigs/Rules.mk .PHONY: all dist install xen tools kernels docs world clean mkpatches mrproper -.PHONY: kbuild kdelete kclean install-tools install-xen install-docs -.PHONY: install-kernels +.PHONY: kbuild kdelete kclean all: dist -# install everything into the standard system directories -# NB: install explicitly does not check that everything is up to date! -install: DESTDIR= -install: xen checked-tools kernels docs - -# Only check for install req'mts on 'make install', not on 'make dist'. -checked-tools: - $(MAKE) -C tools/check install - $(MAKE) -C tools install +# build and install everything into the standard system directories +install: install-xen install-tools install-kernels install-docs # build and install everything into local dist directory dist: xen tools kernels docs @@ -118,9 +110,17 @@ install-iptables: tar -jxf iptables-1.2.11.tar.bz2 $(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install +install-%: DESTDIR= +install-%: % + @: # do nothing + help: @echo 'Installation targets:' @echo ' install - build and install everything' + @echo ' install-xen - build and install the Xen hypervisor' + @echo ' install-tools - build and install the control tools' + @echo ' install-kernels - build and install guest kernels' + @echo ' install-docs - build and install documentation' @echo '' @echo 'Building targets:' @echo ' dist - build and install everything into local dist directory' @@ -178,3 +178,4 @@ linux26: netbsd20: $(MAKE) netbsd-2.0-xenU-build + diff --git a/linux-2.6.10-xen-sparse/arch/xen/Kconfig b/linux-2.6.10-xen-sparse/arch/xen/Kconfig index cfc3ea04c4..27eac46739 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/Kconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/Kconfig @@ -26,7 +26,7 @@ menu "XEN" config XEN_PRIVILEGED_GUEST bool "Privileged Guest (domain 0)" default n - select XEN_PHYSDEV_ACCESS + select XEN_PHYSDEV_ACCESS help Support for privileged operation (domain 0) @@ -35,91 +35,91 @@ config XEN_PHYSDEV_ACCESS default XEN_PRIVILEGED_GUEST help Assume access is available to physical hardware devices - (e.g., hard drives, network cards). This allows you to configure - such devices and also includes some low-level support that is - otherwise not compiled into the kernel. + (e.g., hard drives, network cards). This allows you to configure + such devices and also includes some low-level support that is + otherwise not compiled into the kernel. config XEN_BLKDEV_BACKEND - bool "Block-device backend driver" - depends on XEN_PHYSDEV_ACCESS - default y - help - The block-device backend driver allows the kernel to export its - block devices to other guests via a high-performance shared-memory - interface. + bool "Block-device backend driver" + depends on XEN_PHYSDEV_ACCESS + default y + help + The block-device backend driver allows the kernel to export its + block devices to other guests via a high-performance shared-memory + interface. config XEN_NETDEV_BACKEND - bool "Network-device backend driver" - depends on XEN_PHYSDEV_ACCESS - default y - help - The network-device backend driver allows the kernel to export its - network devices to other guests via a high-performance shared-memory - interface. + bool "Network-device backend driver" + depends on XEN_PHYSDEV_ACCESS + default y + help + The network-device backend driver allows the kernel to export its + network devices to other guests via a high-performance shared-memory + interface. config XEN_BLKDEV_FRONTEND - bool "Block-device frontend driver" - default y - help - The block-device frontend driver allows the kernel to access block - devices mounted within another guest OS. Unless you are building a - dedicated device-driver domain, or your master control domain - (domain 0), then you almost certainly want to say Y here. + bool "Block-device frontend driver" + default y + help + The block-device frontend driver allows the kernel to access block + devices mounted within another guest OS. Unless you are building a + dedicated device-driver domain, or your master control domain + (domain 0), then you almost certainly want to say Y here. config XEN_NETDEV_FRONTEND - bool "Network-device frontend driver" - default y - help - The network-device frontend driver allows the kernel to access - network interfaces within another guest OS. Unless you are building a - dedicated device-driver domain, or your master control domain - (domain 0), then you almost certainly want to say Y here. + bool "Network-device frontend driver" + default y + help + The network-device frontend driver allows the kernel to access + network interfaces within another guest OS. Unless you are building a + dedicated device-driver domain, or your master control domain + (domain 0), then you almost certainly want to say Y here. config XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER - bool "Pipelined transmitter (DANGEROUS)" + bool "Pipelined transmitter (DANGEROUS)" depends on XEN_NETDEV_FRONTEND - default n - help - The driver will assume that the backend is pipelining packets for - transmission: whenever packets are pending in the remote backend, - the driver will not send asynchronous notifications when it queues - additional packets for transmission. - If the backend is a dumb domain, such as a transparent Ethernet - bridge with no local IP interface, it is safe to say Y here to get - slightly lower network overhead. - If the backend has a local IP interface; or may be doing smart things - like reassembling packets to perform firewall filtering; or if you - are unsure; or if you experience network hangs when this option is - enabled; then you must say N here. + default n + help + The driver will assume that the backend is pipelining packets for + transmission: whenever packets are pending in the remote backend, + the driver will not send asynchronous notifications when it queues + additional packets for transmission. + If the backend is a dumb domain, such as a transparent Ethernet + bridge with no local IP interface, it is safe to say Y here to get + slightly lower network overhead. + If the backend has a local IP interface; or may be doing smart things + like reassembling packets to perform firewall filtering; or if you + are unsure; or if you experience network hangs when this option is + enabled; then you must say N here. config XEN_WRITABLE_PAGETABLES bool default y config XEN_SCRUB_PAGES - bool "Scrub memory before freeing it to Xen" - default y - help - Erase memory contents before freeing it back to Xen's global - pool. This ensures that any secrets contained within that - memory (e.g., private keys) cannot be found by other guests that - may be running on the machine. Most people will want to say Y here. - If security is not a concern then you may increase performance by - saying N. + bool "Scrub memory before freeing it to Xen" + default y + help + Erase memory contents before freeing it back to Xen's global + pool. This ensures that any secrets contained within that + memory (e.g., private keys) cannot be found by other guests that + may be running on the machine. Most people will want to say Y here. + If security is not a concern then you may increase performance by + saying N. choice - prompt "Processor Type" - default X86 + prompt "Processor Type" + default X86 config X86 - bool "X86" - help - Choose this option if your computer is a X86 architecture. + bool "X86" + help + Choose this option if your computer is a X86 architecture. config X86_64 - bool "X86_64" - help - Choose this option if your computer is a X86 architecture. + bool "X86_64" + help + Choose this option if your computer is a X86 architecture. endchoice diff --git a/tools/examples/Makefile b/tools/examples/Makefile index cc9ebbc50e..72c1f610eb 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -25,20 +25,23 @@ all: install: all install-initd install-configs install-scripts install-initd: - $(INSTALL_DIR) $(DESTDIR)/etc/init.d + [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d $(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d $(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d install-configs: - $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR) - $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto + [ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \ + $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR) + [ -d $(DESTDIR)$(XEN_CONFIG_DIR)/auto ] || \ + $(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto for i in $(XEN_CONFIGS); \ do [ -a $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \ $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \ done install-scripts: - $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) + [ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \ + $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) for i in $(XEN_SCRIPTS); \ do [ -a $(DESTDIR)$(XEN_SCRIPT_DIR)/$$i ] || \ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \ diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index d25e653467..e27556349e 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -66,8 +66,8 @@ mk-symlinks: ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) install: all - $(INSTALL_DIR) $(DESTDIR)/usr/lib - $(INSTALL_DIR) $(DESTDIR)/usr/include + [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib + [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index 67cfbe08fd..70d2a02c19 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -63,7 +63,7 @@ check-for-zlib: fi install: all - $(INSTALL_DIR) -p $(DESTDIR)/usr/lib + [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so diff --git a/tools/misc/Makefile b/tools/misc/Makefile index b339e300db..4cfc16f58e 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -23,8 +23,8 @@ all: $(TARGETS) $(MAKE) -C miniterm install: all - $(INSTALL_DIR) $(DESTDIR)/usr/bin - $(INSTALL_DIR) $(DESTDIR)/usr/sbin + [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin + [ -d $(DESTDIR)/usr/sbin ] || $(INSTALL_DIR) $(DESTDIR)/usr/sbin $(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin $(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin # No sense in installing miniterm on the Xen box. diff --git a/tools/misc/miniterm/Makefile b/tools/misc/miniterm/Makefile index e85ee3738e..4051eb61de 100644 --- a/tools/misc/miniterm/Makefile +++ b/tools/misc/miniterm/Makefile @@ -9,7 +9,7 @@ TARGET = miniterm all: $(TARGET) install: all - $(INSTALL_DIR) $(DESTDIR)/usr/bin + [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin $(INSTALL_PROG) $(TARGET) $(DESTDIR)/usr/bin clean: diff --git a/tools/sv/Makefile b/tools/sv/Makefile index c2b4e92dfc..4da91e0674 100755 --- a/tools/sv/Makefile +++ b/tools/sv/Makefile @@ -17,15 +17,17 @@ IMAGES += next.png previous.png finish.png install: # copy XenSV Main.rpy file - @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir) + @[ -d $(DESTDIR)$(sv_insdir) ] || $(INSTALL_DIR) $(DESTDIR)$(sv_insdir) @$(INSTALL_DATA) Main.rpy $(DESTDIR)$(sv_insdir) # copy XenSV images - @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/images + @[ -d $(DESTDIR)$(sv_insdir)/images ] || \ + $(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/images @(cd images && $(INSTALL_DATA) $(IMAGES) $(DESTDIR)$(sv_insdir)/images) # copy XenSV stylesheet - @$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/inc + @[ -d $(DESTDIR)$(sv_insdir)/inc ] || \ + $(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/inc @$(INSTALL_DATA) inc/style.css inc/script.js $(DESTDIR)$(sv_insdir)/inc clean: diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 5fe6a9d61d..5ed26cf795 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -24,9 +24,11 @@ MAN8 = $(wildcard *.8) all: $(BIN) install: all - $(INSTALL_DIR) $(DESTDIR)/usr/bin - $(INSTALL_DIR) $(DESTDIR)/usr/man/man1 - $(INSTALL_DIR) $(DESTDIR)/usr/man/man8 + [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin + [ -d $(DESTDIR)/usr/man/man1 ] || \ + $(INSTALL_DIR) $(DESTDIR)/usr/man/man1 + [ -d $(DESTDIR)/usr/man/man8 ] || \ + $(INSTALL_DIR) $(DESTDIR)/usr/man/man8 $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin $(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/man/man1 $(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/man/man8 diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index e986755140..4cdc810e95 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -70,7 +70,8 @@ xfrd: $(XFRD_PROG_OBJ) .PHONY: install install: xfrd - $(INSTALL_DIR) $(DESTDIR)$(XFRD_INSTALL_DIR) + [ -d $(DESTDIR)$(XFRD_INSTALL_DIR) ] || \ + $(INSTALL_DIR) $(DESTDIR)$(XFRD_INSTALL_DIR) $(INSTALL_PROG) xfrd $(DESTDIR)$(XFRD_INSTALL_DIR) .PHONY: libutil diff --git a/xen/Makefile b/xen/Makefile index 2a84ca6835..42f0ffafb0 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -21,10 +21,11 @@ debug: objdump -D -S $(TARGET)-syms > $(TARGET).s install: $(TARGET).gz - $(INSTALL_DIR) $(DESTDIR)/boot + [ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot $(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot - $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io + [ -d $(DESTDIR)/usr/include/xen/io ] || \ + $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io $(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen From 3c3e0b071ef9556dc2568eb2db4fcdebde37897e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 28 Jan 2005 15:07:36 +0000 Subject: [PATCH 053/199] bitkeeper revision 1.1159.223.49 (41fa5538VkhzExY3oLvE43gn3nUTRQ) trivial elf-parsing fix. --- xen/common/elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/elf.c b/xen/common/elf.c index eae1c8fa10..8241d96520 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -92,7 +92,7 @@ int parseelfimage(char *elfbase, if ( guestinfo == NULL ) { printk("Not a Xen-ELF image: '__xen_guest' section not found.\n"); -#ifndef FORCE_XENELF_IMAGE +#if FORCE_XENELF_IMAGE return -EINVAL; #endif } From dbb2d95b1d17436180618de305c8d9ac9bf9433e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 28 Jan 2005 15:39:31 +0000 Subject: [PATCH 054/199] bitkeeper revision 1.1159.223.50 (41fa5cb3P9qKPSczsZkXrCrJzdeZAg) Linker fixes. --- xen/arch/x86/boot/mkelf32.c | 2 +- xen/arch/x86/x86_32/xen.lds | 4 ---- xen/arch/x86/x86_64/xen.lds | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/xen/arch/x86/boot/mkelf32.c b/xen/arch/x86/boot/mkelf32.c index 286a61315a..e16756237b 100644 --- a/xen/arch/x86/boot/mkelf32.c +++ b/xen/arch/x86/boot/mkelf32.c @@ -201,7 +201,7 @@ int main(int argc, char **argv) if ( in32_ehdr.e_phnum != 1 ) { - fprintf(stderr, "Expect precisly 1 program header; found %d.\n", + fprintf(stderr, "Expect precisely 1 program header; found %d.\n", (int)in32_ehdr.e_phnum); return 1; } diff --git a/xen/arch/x86/x86_32/xen.lds b/xen/arch/x86/x86_32/xen.lds index 537ebf15ba..298c9fee4d 100644 --- a/xen/arch/x86/x86_32/xen.lds +++ b/xen/arch/x86/x86_32/xen.lds @@ -64,12 +64,8 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall.init) } :text __initcall_end = .; - . = ALIGN(4096); __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } :text - __bss_start = .; /* BSS */ .bss : { *(.bss) diff --git a/xen/arch/x86/x86_64/xen.lds b/xen/arch/x86/x86_64/xen.lds index 8a6b3a27ac..2bb2d9ed49 100644 --- a/xen/arch/x86/x86_64/xen.lds +++ b/xen/arch/x86/x86_64/xen.lds @@ -62,12 +62,8 @@ SECTIONS __initcall_start = .; .initcall.init : { *(.initcall.init) } :text __initcall_end = .; - . = ALIGN(4096); __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } :text - __bss_start = .; /* BSS */ .bss : { *(.bss) From 085a587c38e8aee53fbc420e2f2531777b79d9c2 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 28 Jan 2005 23:19:23 +0000 Subject: [PATCH 055/199] bitkeeper revision 1.1159.223.51 (41fac87bR5uD5TAFu58tuaTMLSmbrw) Fix makefiles creating copies instead of symlinks of shared libs. Signed-off-by: Arun Sharma Signed-off-by: Keir Fraser --- tools/libxc/Makefile | 2 +- tools/libxutil/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index e27556349e..6369785d68 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -68,7 +68,7 @@ mk-symlinks: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include - $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib + $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index 70d2a02c19..cb12a93251 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -64,7 +64,7 @@ check-for-zlib: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib - $(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib + $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so From 161acb14ddf247b147056814aa6acc22cfeb6e86 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sat, 29 Jan 2005 12:03:44 +0000 Subject: [PATCH 056/199] bitkeeper revision 1.1159.223.52 (41fb7ba0KYbuQ5SmW1MZjMO0P-RCew) Small build fixes. Xen and XenLinux now build for x86_32 from within an x86_64 build environment if you set TARGET_ARCH=x86_32. --- BitKeeper/etc/logging_ok | 1 + buildconfigs/mk.linux-2.6-xen0 | 2 +- buildconfigs/mk.linux-2.6-xenU | 2 +- linux-2.6.10-xen-sparse/arch/xen/i386/Makefile | 3 +++ linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile | 2 +- xen/Rules.mk | 8 ++++---- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index a5aabc0fcf..f2a27dc63d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -32,6 +32,7 @@ kaf24@penguin.local kaf24@plym.cl.cam.ac.uk kaf24@scramble.cl.cam.ac.uk kaf24@striker.cl.cam.ac.uk +kaf24@viper.(none) laudney@eclipse.(none) lynx@idefix.cl.cam.ac.uk mafetter@fleming.research diff --git a/buildconfigs/mk.linux-2.6-xen0 b/buildconfigs/mk.linux-2.6-xen0 index f4310f5925..5685eb3e12 100644 --- a/buildconfigs/mk.linux-2.6-xen0 +++ b/buildconfigs/mk.linux-2.6-xen0 @@ -34,7 +34,7 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig \ $(LINUX_DIR)/.config - make -C $(LINUX_DIR) ARCH=xen oldconfig + $(MAKE) -C $(LINUX_DIR) ARCH=xen oldconfig clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean diff --git a/buildconfigs/mk.linux-2.6-xenU b/buildconfigs/mk.linux-2.6-xenU index 79a3d66777..1e5bbd4f37 100644 --- a/buildconfigs/mk.linux-2.6-xenU +++ b/buildconfigs/mk.linux-2.6-xenU @@ -34,7 +34,7 @@ $(LINUX_DIR)/include/linux/autoconf.h: pristine-linux-$(LINUX_VER) cp $(DESTDIR)/boot/config-$(FULLVERSION) $(LINUX_DIR)/.config \ || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig \ $(LINUX_DIR)/.config - make -C $(LINUX_DIR) ARCH=xen oldconfig + $(MAKE) -C $(LINUX_DIR) ARCH=xen oldconfig clean: $(MAKE) -C $(LINUX_DIR) ARCH=xen clean diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/Makefile b/linux-2.6.10-xen-sparse/arch/xen/i386/Makefile index bbfbab8a54..8af1059853 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/Makefile +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/Makefile @@ -21,6 +21,9 @@ LDFLAGS := -m elf_i386 LDFLAGS_vmlinux := CHECK := $(CHECK) -D__i386__=1 +CFLAGS += -m32 +AFLAGS += -m32 + CFLAGS += -pipe -msoft-float # prevent gcc from keeping the stack 16 byte aligned diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile index c304fbb0cd..522bab987a 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile @@ -54,7 +54,7 @@ targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) # The DSO images are built using a special linker script. quiet_cmd_syscall = SYSCALL $@ - cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \ + cmd_syscall = $(CC) -nostdlib -m32 $(SYSCFLAGS_$(@F)) \ -Wl,-T,$(filter-out FORCE,$^) -o $@ vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 diff --git a/xen/Rules.mk b/xen/Rules.mk index cf6972f097..82599afec0 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -11,10 +11,10 @@ COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) TARGET_ARCH ?= $(COMPILE_ARCH) # Set ARCH/SUBARCH appropriately. -COMPILE_SUBARCH := $(COMPILE_ARCH) -TARGET_SUBARCH := $(COMPILE_ARCH) -COMPILE_ARCH := $(patsubst x86%,x86,$(COMPILE_ARCH)) -TARGET_ARCH := $(patsubst x86%,x86,$(TARGET_ARCH)) +override COMPILE_SUBARCH := $(COMPILE_ARCH) +override TARGET_SUBARCH := $(TARGET_ARCH) +override COMPILE_ARCH := $(patsubst x86%,x86,$(COMPILE_ARCH)) +override TARGET_ARCH := $(patsubst x86%,x86,$(TARGET_ARCH)) TARGET := $(BASEDIR)/xen HDRS := $(wildcard $(BASEDIR)/include/xen/*.h) From 744d0bbffba678a9335cdbe18ab7e1d10a00a2cd Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 29 Jan 2005 22:20:09 +0000 Subject: [PATCH 057/199] bitkeeper revision 1.1159.223.53 (41fc0c19tGe1rM62SUQk8WYZjH-D1Q) Add iptables modules to the default xen0 kernel, and add example configuration files for a NAT setup. --- .rootkeys | 3 + .../arch/xen/configs/xen0_defconfig | 15 ++- tools/examples/network-nat | 77 +++++++++++ tools/examples/vif-nat | 66 ++++++++++ tools/examples/xmexample3 | 120 ++++++++++++++++++ 5 files changed, 278 insertions(+), 3 deletions(-) create mode 100644 tools/examples/network-nat create mode 100644 tools/examples/vif-nat create mode 100644 tools/examples/xmexample3 diff --git a/.rootkeys b/.rootkeys index b14c560ec8..a6f49dc24c 100644 --- a/.rootkeys +++ b/.rootkeys @@ -314,12 +314,15 @@ 405ff55dawQyCHFEnJ067ChPRoXBBA tools/examples/init.d/xend 40278d94cIUWl2eRgnwZtr4hTyWT1Q tools/examples/init.d/xendomains 40ee75a9xFz6S05sDKu-JCLqyVTkDA tools/examples/network +41fc0c18hVgK5rKJyZUsqybux9D9Dg tools/examples/network-nat 41e661e1giIEKbJ25qfiP-ke8u8hFA tools/examples/network-route 40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge +41fc0c18AFAVXA1uGm1JFWHMeeznVw tools/examples/vif-nat 41e661e1ooiRKlOfwumG6wwzc0PdhQ tools/examples/vif-route 40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp 41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1 40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2 +41fc0c18_k4iL81hu4pMIWQu9dKpKA tools/examples/xmexample3 3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile 41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h 3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig index d3e884bff4..d41daac521 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig @@ -499,7 +499,7 @@ CONFIG_IP_NF_FTP=m # CONFIG_IP_NF_QUEUE is not set CONFIG_IP_NF_IPTABLES=m # CONFIG_IP_NF_MATCH_LIMIT is not set -# CONFIG_IP_NF_MATCH_IPRANGE is not set +CONFIG_IP_NF_MATCH_IPRANGE=m # CONFIG_IP_NF_MATCH_MAC is not set # CONFIG_IP_NF_MATCH_PKTTYPE is not set # CONFIG_IP_NF_MATCH_MARK is not set @@ -522,11 +522,20 @@ CONFIG_IP_NF_IPTABLES=m # CONFIG_IP_NF_MATCH_SCTP is not set # CONFIG_IP_NF_MATCH_COMMENT is not set # CONFIG_IP_NF_MATCH_HASHLIMIT is not set -# CONFIG_IP_NF_FILTER is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m # CONFIG_IP_NF_TARGET_LOG is not set # CONFIG_IP_NF_TARGET_ULOG is not set # CONFIG_IP_NF_TARGET_TCPMSS is not set -# CONFIG_IP_NF_NAT is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_REDIRECT is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set # CONFIG_IP_NF_RAW is not set # CONFIG_IP_NF_ARPTABLES is not set diff --git a/tools/examples/network-nat b/tools/examples/network-nat new file mode 100644 index 0000000000..ed32b70c58 --- /dev/null +++ b/tools/examples/network-nat @@ -0,0 +1,77 @@ +#!/bin/sh +#============================================================================ +# Default Xen network start/stop script. +# Xend calls a network script when it starts. +# The script name to use is defined in /etc/xen/xend-config.sxp +# in the network-script field. +# +# Usage: +# +# network-route (start|stop|status) {VAR=VAL}* +# +# Vars: +# +# netdev The gateway interface (default eth0). +# antispoof Whether to use iptables to prevent spoofing (default yes). +# +#============================================================================ + + + +# Exit if anything goes wrong. +set -e + +# First arg is the operation. +OP=$1 +shift + +# Pull variables in args in to environment. +for arg ; do export "${arg}" ; done + +netdev=${netdev:-eth0} +# antispoofing not yet implemented +antispoof=${antispoof:-yes} + +echo "network-nat $OP netdev=$netdev antispoof=$antispoof" + + +op_start() { + echo 1 >/proc/sys/net/ipv4/ip_forward + iptables -t nat -A POSTROUTING -o ${netdev} -j MASQUERADE +} + + +op_stop() { + iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE +} + + +show_status() { + echo '============================================================' + ifconfig + echo ' ' + ip route list + echo ' ' + route -n + echo '============================================================' + +} + +case ${OP} in + start) + op_start + ;; + + stop) + op_stop + ;; + + status) + show_status + ;; + + *) + echo 'Unknown command: ' ${OP} + echo 'Valid commands are: start, stop, status' + exit 1 +esac diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat new file mode 100644 index 0000000000..2cf3557806 --- /dev/null +++ b/tools/examples/vif-nat @@ -0,0 +1,66 @@ +#!/bin/sh +#============================================================================ +# /etc/xen/vif-nat +# +# Script for configuring a vif in routed-nat mode. +# Xend calls a vif script when bringing a vif up or down. +# This script is the default - but it can be configured for each vif. +# +# Example invocation: +# +# vif-nat up domain=VM1 vif=vif1.0 ip="192.168.0.10/31" +# +# Usage: +# vif-nat (up|down) {VAR=VAL}* +# +# Vars: +# +# domain name of the domain the interface is on (required). +# vif vif interface name (required). +# ip list of IP networks for the vif, space-separated (required). +#============================================================================ + +# Exit if anything goes wrong +set -e + +echo "vif-nat $*" + +# Operation name. +OP=$1 +shift + +# Pull variables in args into environment +for arg ; do export "${arg}" ; done + +# Required parameters. Fail if not set. +domain=${domain:?} +vif=${vif:?} +ip=${ip:?} + +# better way to strip /netmask from the ip? +vif_ip=`echo ${ip} | awk -F. '{print $1"."$2"."$3"."$4}'` + +main_ip=`ifconfig eth0 | grep "inet addr:" | sed -e 's/.*inet addr:\(\w\w*\.\w\w*\.\w\w*\.\w\w*\).*/\1/'` + +# Are we going up or down? +case $OP in + up) + ifconfig ${vif} ${vif_ip} netmask 255.255.255.0 up + echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp + iptcmd='-A' + ipcmd='a' + ;; + down) + ifconfig ${vif} down + iptcmd='-D' + ipcmd='d' + ;; + *) + echo 'Invalid command: ' $OP + echo 'Valid commands are: up, down' + exit 1 + ;; +esac + +ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip} +# iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT diff --git a/tools/examples/xmexample3 b/tools/examples/xmexample3 new file mode 100644 index 0000000000..fd96a7b201 --- /dev/null +++ b/tools/examples/xmexample3 @@ -0,0 +1,120 @@ +# -*- mode: python; -*- +#============================================================================ +# Example Python setup script for 'xm create'. +# This script sets the parameters used when a domain is created using 'xm create'. +# +# This is a relatively advanced script that uses a parameter, vmid, to control +# the settings. So this script can be used to start a set of domains by +# setting the vmid parameter on the 'xm create' command line. For example: +# +# xm create vmid=1 +# xm create vmid=2 +# xm create vmid=3 +# +# The vmid is purely a script variable, and has no effect on the the domain +# id assigned to the new domain. +#============================================================================ + +# Define script variables here. +# xm_vars is defined automatically, use xm_vars.var() to define a variable. + +# This function checks that 'vmid' has been given a valid value. +# It is called automatically by 'xm create'. +def vmid_check(var, val): + val = int(val) + if val <= 0: + raise ValueError + return val + +# Define the 'vmid' variable so that 'xm create' knows about it. +xm_vars.var('vmid', + use="Virtual machine id. Integer greater than 0.", + check=vmid_check) + +# Check the defined variables have valid values.. +xm_vars.check() + +#---------------------------------------------------------------------------- +# Kernel image file. +kernel = "/path/to/domU/kernel" + +# Optional ramdisk. +#ramdisk = "/boot/initrd.gz" + +# The domain build function. Default is 'linux'. +#builder='linux' + +# Initial memory allocation (in megabytes) for the new domain. +memory = 64 + +# A name for the new domain. All domains have to have different names, +# so we use the vmid to create a name. +name = "VM%d" % vmid + +# Which CPU to start domain on? +#cpu = -1 # leave to Xen to pick +cpu = vmid # set based on vmid (mod number of CPUs) + +#---------------------------------------------------------------------------- +# Define network interfaces. + +# Number of network interfaces. Default is 1. +#nics=1 + +# Optionally define mac and/or bridge for the network interfaces. +# Random MACs are assigned if not given. + +vif = [ 'ip=192.168.%d.1/24' % (vmid)] + +#---------------------------------------------------------------------------- +# Define the disk devices you want the domain to have access to, and +# what you want them accessible as. +# Each disk entry is of the form phy:UNAME,DEV,MODE +# where UNAME is the device, DEV is the device name the domain will see, +# and MODE is r for read-only, w for read-write. + +# This makes the disk device depend on the vmid - assuming +# tHat devices sda7, sda8 etc. exist. The device is exported +# to all domains as sda1. +# All domains get sda6 read-only (to use for /usr, see below). +disk = [ 'phy:hda%d,hda1,w' % (vmid)] + +#---------------------------------------------------------------------------- +# Set the kernel command line for the new domain. +# You only need to define the IP parameters and hostname if the domain's +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP. +# You can use 'extra' to set the runlevel and custom environment +# variables used by custom rc scripts (e.g. VMID=, usr= ). + +# Set if you want dhcp to allocate the IP address. +dhcp="off" +ip="192.168.%d.2" % (vmid) +# Set netmask. +netmask="255.255.255.0" +# Set default gateway. +gateway="192.168.%d.1" % (vmid) +# Set the hostname. +hostname= "domain-%d.xeno" % vmid + +# Set root device. +root = "/dev/hda1 ro" + +# Root device for nfs. +#root = "/dev/nfs" +# The nfs server. +#nfs_server = "10.212.4.103" +# Root directory on the nfs server. +#nfs_root = "/path/to/root/filesystem" + +# Sets runlevel 4 and the device for /usr. +extra = "4 VMID=%d" % vmid + +#---------------------------------------------------------------------------- +# Set according to whether you want the domain restarted when it exits. +# The default is 'onreboot', which restarts the domain when it shuts down +# with exit code reboot. +# Other values are 'always', and 'never'. + +#restart = 'onreboot' + +#============================================================================ From 4baf6e1ed5aa662f25307b63f0444e2c4a1bbda7 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 1 Feb 2005 09:21:09 +0000 Subject: [PATCH 058/199] bitkeeper revision 1.1159.223.54 (41ff4a05JwUWXLAjyzybyxNxCOE3yw) Defer NMI that cannot be handled, instead of dropping it completely. --- xen/arch/x86/traps.c | 1 + xen/arch/x86/x86_32/asm-offsets.c | 3 + xen/arch/x86/x86_32/entry.S | 16 +- xen/include/asm-x86/apicdef.h | 251 ------------------------------ xen/include/asm-x86/processor.h | 1 + 5 files changed, 19 insertions(+), 253 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 2bdb160373..d053705c13 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -803,6 +803,7 @@ void __init trap_init(void) set_intr_gate(TRAP_alignment_check,&alignment_check); set_intr_gate(TRAP_machine_check,&machine_check); set_intr_gate(TRAP_simd_error,&simd_coprocessor_error); + set_intr_gate(TRAP_deferred_nmi,&nmi); /* Only ring 1 can access Xen services. */ _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall); diff --git a/xen/arch/x86/x86_32/asm-offsets.c b/xen/arch/x86/x86_32/asm-offsets.c index f187acbc4c..a85aa15db4 100644 --- a/xen/arch/x86/x86_32/asm-offsets.c +++ b/xen/arch/x86/x86_32/asm-offsets.c @@ -67,4 +67,7 @@ void __dummy__(void) OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]); OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]); OFFSET(MULTICALL_result, multicall_entry_t, args[5]); + BLANK(); + + DEFINE(FIXMAP_apic_base, fix_to_virt(FIX_APIC_BASE)); } diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 7eb7c9075c..aeef45059c 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -57,6 +57,7 @@ #include #include #include +#include #include #define GET_CURRENT(reg) \ @@ -497,10 +498,10 @@ ENTRY(nmi) jnz do_watchdog_tick movl %ds,%eax cmpw $(__HYPERVISOR_DS),%ax - jne restore_all_xen + jne defer_nmi movl %es,%eax cmpw $(__HYPERVISOR_DS),%ax - jne restore_all_xen + jne defer_nmi do_watchdog_tick: movl $(__HYPERVISOR_DS),%edx @@ -518,6 +519,17 @@ do_watchdog_tick: GET_CURRENT(%ebx) jmp restore_all_guest +defer_nmi: + movl $FIXMAP_apic_base,%eax + # apic_wait_icr_idle() +1: movl APIC_ICR(%eax),%ebx + testl $APIC_ICR_BUSY,%ebx + jnz 1b + # __send_IPI_shortcut(APIC_DEST_SELF, TRAP_deferred_nmi) + movl $(APIC_DM_FIXED | APIC_DEST_SELF | APIC_DEST_LOGICAL | \ + TRAP_deferred_nmi),APIC_ICR(%eax) + jmp restore_all_xen + nmi_parity_err: # Clear and disable the parity-error line andb $0xf,%al diff --git a/xen/include/asm-x86/apicdef.h b/xen/include/asm-x86/apicdef.h index 9f07409b3f..8d7f3aa3d7 100644 --- a/xen/include/asm-x86/apicdef.h +++ b/xen/include/asm-x86/apicdef.h @@ -125,255 +125,4 @@ #define APIC_BROADCAST_ID_XAPIC (0xFF) #define APIC_BROADCAST_ID_APIC (0x0F) -/* - * the local APIC register structure, memory mapped. Not terribly well - * tested, but we might eventually use this one in the future - the - * problem why we cannot use it right now is the P5 APIC, it has an - * errata which cannot take 8-bit reads and writes, only 32-bit ones ... - */ -#define u32 unsigned int - -#define lapic ((volatile struct local_apic *)APIC_BASE) - -struct local_apic { - -/*000*/ struct { u32 __reserved[4]; } __reserved_01; - -/*010*/ struct { u32 __reserved[4]; } __reserved_02; - -/*020*/ struct { /* APIC ID Register */ - u32 __reserved_1 : 24, - phys_apic_id : 4, - __reserved_2 : 4; - u32 __reserved[3]; - } id; - -/*030*/ const - struct { /* APIC Version Register */ - u32 version : 8, - __reserved_1 : 8, - max_lvt : 8, - __reserved_2 : 8; - u32 __reserved[3]; - } version; - -/*040*/ struct { u32 __reserved[4]; } __reserved_03; - -/*050*/ struct { u32 __reserved[4]; } __reserved_04; - -/*060*/ struct { u32 __reserved[4]; } __reserved_05; - -/*070*/ struct { u32 __reserved[4]; } __reserved_06; - -/*080*/ struct { /* Task Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } tpr; - -/*090*/ const - struct { /* Arbitration Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } apr; - -/*0A0*/ const - struct { /* Processor Priority Register */ - u32 priority : 8, - __reserved_1 : 24; - u32 __reserved_2[3]; - } ppr; - -/*0B0*/ struct { /* End Of Interrupt Register */ - u32 eoi; - u32 __reserved[3]; - } eoi; - -/*0C0*/ struct { u32 __reserved[4]; } __reserved_07; - -/*0D0*/ struct { /* Logical Destination Register */ - u32 __reserved_1 : 24, - logical_dest : 8; - u32 __reserved_2[3]; - } ldr; - -/*0E0*/ struct { /* Destination Format Register */ - u32 __reserved_1 : 28, - model : 4; - u32 __reserved_2[3]; - } dfr; - -/*0F0*/ struct { /* Spurious Interrupt Vector Register */ - u32 spurious_vector : 8, - apic_enabled : 1, - focus_cpu : 1, - __reserved_2 : 22; - u32 __reserved_3[3]; - } svr; - -/*100*/ struct { /* In Service Register */ -/*170*/ u32 bitfield; - u32 __reserved[3]; - } isr [8]; - -/*180*/ struct { /* Trigger Mode Register */ -/*1F0*/ u32 bitfield; - u32 __reserved[3]; - } tmr [8]; - -/*200*/ struct { /* Interrupt Request Register */ -/*270*/ u32 bitfield; - u32 __reserved[3]; - } irr [8]; - -/*280*/ union { /* Error Status Register */ - struct { - u32 send_cs_error : 1, - receive_cs_error : 1, - send_accept_error : 1, - receive_accept_error : 1, - __reserved_1 : 1, - send_illegal_vector : 1, - receive_illegal_vector : 1, - illegal_register_address : 1, - __reserved_2 : 24; - u32 __reserved_3[3]; - } error_bits; - struct { - u32 errors; - u32 __reserved_3[3]; - } all_errors; - } esr; - -/*290*/ struct { u32 __reserved[4]; } __reserved_08; - -/*2A0*/ struct { u32 __reserved[4]; } __reserved_09; - -/*2B0*/ struct { u32 __reserved[4]; } __reserved_10; - -/*2C0*/ struct { u32 __reserved[4]; } __reserved_11; - -/*2D0*/ struct { u32 __reserved[4]; } __reserved_12; - -/*2E0*/ struct { u32 __reserved[4]; } __reserved_13; - -/*2F0*/ struct { u32 __reserved[4]; } __reserved_14; - -/*300*/ struct { /* Interrupt Command Register 1 */ - u32 vector : 8, - delivery_mode : 3, - destination_mode : 1, - delivery_status : 1, - __reserved_1 : 1, - level : 1, - trigger : 1, - __reserved_2 : 2, - shorthand : 2, - __reserved_3 : 12; - u32 __reserved_4[3]; - } icr1; - -/*310*/ struct { /* Interrupt Command Register 2 */ - union { - u32 __reserved_1 : 24, - phys_dest : 4, - __reserved_2 : 4; - u32 __reserved_3 : 24, - logical_dest : 8; - } dest; - u32 __reserved_4[3]; - } icr2; - -/*320*/ struct { /* LVT - Timer */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - timer_mode : 1, - __reserved_3 : 14; - u32 __reserved_4[3]; - } lvt_timer; - -/*330*/ struct { u32 __reserved[4]; } __reserved_15; - -/*340*/ struct { /* LVT - Performance Counter */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_pc; - -/*350*/ struct { /* LVT - LINT0 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint0; - -/*360*/ struct { /* LVT - LINT1 */ - u32 vector : 8, - delivery_mode : 3, - __reserved_1 : 1, - delivery_status : 1, - polarity : 1, - remote_irr : 1, - trigger : 1, - mask : 1, - __reserved_2 : 15; - u32 __reserved_3[3]; - } lvt_lint1; - -/*370*/ struct { /* LVT - Error */ - u32 vector : 8, - __reserved_1 : 4, - delivery_status : 1, - __reserved_2 : 3, - mask : 1, - __reserved_3 : 15; - u32 __reserved_4[3]; - } lvt_error; - -/*380*/ struct { /* Timer Initial Count Register */ - u32 initial_count; - u32 __reserved_2[3]; - } timer_icr; - -/*390*/ const - struct { /* Timer Current Count Register */ - u32 curr_count; - u32 __reserved_2[3]; - } timer_ccr; - -/*3A0*/ struct { u32 __reserved[4]; } __reserved_16; - -/*3B0*/ struct { u32 __reserved[4]; } __reserved_17; - -/*3C0*/ struct { u32 __reserved[4]; } __reserved_18; - -/*3D0*/ struct { u32 __reserved[4]; } __reserved_19; - -/*3E0*/ struct { /* Timer Divide Configuration Register */ - u32 divisor : 4, - __reserved_1 : 28; - u32 __reserved_2[3]; - } timer_dcr; - -/*3F0*/ struct { u32 __reserved[4]; } __reserved_20; - -} __attribute__ ((packed)); - -#undef u32 - #endif diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 55deb004a9..e3446aaeae 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -108,6 +108,7 @@ #define TRAP_alignment_check 17 #define TRAP_machine_check 18 #define TRAP_simd_error 19 +#define TRAP_deferred_nmi 31 /* * Non-fatal fault/trap handlers return an error code to the caller. If the From bae735390fe42f0c59dbfbea4cfe9349e074cee2 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 1 Feb 2005 21:55:39 +0000 Subject: [PATCH 059/199] bitkeeper revision 1.1159.223.55 (41fffadb9KX8y2tjTwUVGZRrZQdJ2g) Fix incorrect result-check in xlvbd_init_device Signed-off-by: Jody Belka Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c index 00be870d91..25bfa59e79 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c @@ -317,7 +317,7 @@ static int xlvbd_init_device(vdisk_t *xd) down(&bd->bd_sem); gd = xlvbd_get_gendisk(mi, minor, xd); - if (mi == NULL) { + if (gd == NULL) { err = -EPERM; goto out; } From 2eb8f64d4ab00206859f777c6779254e7b711cc3 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 1 Feb 2005 21:59:12 +0000 Subject: [PATCH 060/199] bitkeeper revision 1.1159.223.56 (41fffbb0baSUSOWVCJ_0NFmEtCmUkw) Fix the device number calculation for /dev/hd* device names; ide device numbering works differently to scsi Signed-off-by: Jody Belka Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/python/xen/xend/server/blkif.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index b980ebcb72..8a1de09bfc 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -66,8 +66,11 @@ def blkdev_name_to_number(name): if re.match( '/dev/sd[a-p]([0-9]|1[0-5])', n): return 8 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:]) - if re.match( '/dev/hd[a-p]([0-9]|[1-5][0-9]|6[0-3])', n): - return 3 * 256 + 16 * (ord(n[7:8]) - ord('a')) + int(n[8:]) + if re.match( '/dev/hd[a-t]([1-9]|[1-5][0-9]|6[0-3])?', n): + ide_majors = [ 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 ] + major = ide_majors[(ord(n[7:8]) - ord('a')) / 2] + minor = ((ord(n[7:8]) - ord('a')) % 2) * 64 + int(n[8:] or 0) + return major * 256 + minor # see if this is a hex device number if re.match( '^(0x)?[0-9a-fA-F]+$', name ): From a3eea3d4418aa499f2a1f7f00de011b9f4902cdd Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Wed, 2 Feb 2005 09:17:21 +0000 Subject: [PATCH 061/199] bitkeeper revision 1.1159.223.57 (42009aa1vckOCJ3XiCz8SXnP4BQsFw) Small hack to make CROMMULTISESSION ioctl return success rather than enosys, like we did on Xen 1.2. From: Anthony Liguori aliguori@us.ibm.com Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c index 9216e148e7..e28db67411 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -223,6 +223,7 @@ int blkif_release(struct inode *inode, struct file *filep) int blkif_ioctl(struct inode *inode, struct file *filep, unsigned command, unsigned long argument) { + int i; /* struct gendisk *gd = inode->i_bdev->bd_disk; */ DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n", @@ -234,6 +235,12 @@ int blkif_ioctl(struct inode *inode, struct file *filep, /* return ENOSYS to use defaults */ return -ENOSYS; + case CDROMMULTISESSION: + DPRINTK("FIXME: support multisession CDs later\n"); + for ( i = 0; i < sizeof(struct cdrom_multisession); i++ ) + if ( put_user(0, (byte *)(argument + i)) ) return -EFAULT; + return 0; + default: printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", command); From 4e751b5fa010c3f19939d3ee4dd036932aedb180 Mon Sep 17 00:00:00 2001 From: "mafetter@fleming.research" Date: Wed, 2 Feb 2005 15:09:37 +0000 Subject: [PATCH 062/199] bitkeeper revision 1.1159.223.58 (4200ed31YDg6myRSqtQaWLMgRgJ7dA) Fix "make dist" so that it works from inside the xen subdirectory. --- xen/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xen/Makefile b/xen/Makefile index 42f0ffafb0..33b03f4854 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -1,3 +1,7 @@ +# Default is to install to local 'dist' directory. +DISTDIR ?= ../dist +DESTDIR ?= $(DISTDIR)/install + INSTALL = install INSTALL_DATA = $(INSTALL) -m0644 INSTALL_DIR = $(INSTALL) -d -m0755 @@ -20,6 +24,9 @@ $(TARGET).gz: $(TARGET) debug: objdump -D -S $(TARGET)-syms > $(TARGET).s +dist: + $(MAKE) install + install: $(TARGET).gz [ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot From 8e1f3d67e1d37f06af892f7f4b27a278130b0c03 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Wed, 2 Feb 2005 22:40:20 +0000 Subject: [PATCH 063/199] bitkeeper revision 1.1159.223.59 (420156d4cxaGMuI8rtUWoTShsPVlNQ) setup.c: Always disable irqdebug until we have a way to avoid interrupt conflicts. Signed-off-by: c@pin.lu --- linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c index a1f7bfee88..852c556778 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1491,6 +1491,10 @@ void __init setup_arch(char **cmdline_p) get_smp_config(); #endif + /* XXX Disable irqdebug until we have a way to avoid interrupt + * conflicts. */ + noirqdebug_setup(""); + register_memory(max_low_pfn); /* If we are a privileged guest OS then we should request IO privs. */ From 61573e23645558123297373daa2af8f9e589f132 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Wed, 2 Feb 2005 23:06:19 +0000 Subject: [PATCH 064/199] bitkeeper revision 1.1159.223.60 (42015cebANp9qR68FaUpAYoMHdrfpQ) console.c: Disable watchdog before doing the 5 second delay before machine restart. Signed-off-by: c@pin.lu --- xen/drivers/char/console.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 75713575f4..ba4c53f927 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -506,6 +506,7 @@ void panic(const char *fmt, ...) __putstr("Reboot in five seconds...\n"); spin_unlock_irqrestore(&console_lock, flags); + watchdog_on = 0; mdelay(5000); machine_restart(0); } From 557f25a0fa50db5f8d5ec81757634cf7005284b3 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 3 Feb 2005 08:38:03 +0000 Subject: [PATCH 065/199] bitkeeper revision 1.1159.223.61 (4201e2eb-AZrvBiRdKncIUx8FuLkeA) Fix ioremap() for local RAM pages. --- linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c | 14 ++++++++++---- .../include/asm-xen/asm-i386/pgtable.h | 12 +----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c index fabb7350f2..b9034505b5 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -79,6 +79,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void __iomem * addr; struct vm_struct * area; unsigned long offset, last_addr; + domid_t domid = DOMID_IO; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -106,6 +107,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) if(!PageReserved(page)) return NULL; + + domid = DOMID_LOCAL; } /* @@ -382,10 +385,13 @@ int direct_remap_area_pages(struct mm_struct *mm, #define MAX_DIRECTMAP_MMU_QUEUE 130 mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v; - u[0].ptr = MMU_EXTENDED_COMMAND; - u[0].val = MMUEXT_SET_FOREIGNDOM; - u[0].val |= (unsigned long)domid << 16; - v = w = &u[1]; + v = w = &u[0]; + if (domid != DOMID_LOCAL) { + u[0].ptr = MMU_EXTENDED_COMMAND; + u[0].val = MMUEXT_SET_FOREIGNDOM; + u[0].val |= (unsigned long)domid << 16; + v = w = &u[1]; + } start_address = address; diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h index 07afd66e29..3c0ae34e97 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -475,6 +475,7 @@ void make_pages_writable(void *va, unsigned int nr); #define kern_addr_valid(addr) (1) #endif /* !CONFIG_DISCONTIGMEM */ +#define DOMID_LOCAL (0xFFFFU) int direct_remap_area_pages(struct mm_struct *mm, unsigned long address, unsigned long machine_addr, @@ -489,17 +490,6 @@ int __direct_remap_area_pages(struct mm_struct *mm, #define io_remap_page_range(vma,from,phys,size,prot) \ direct_remap_area_pages(vma->vm_mm,from,phys,size,prot,DOMID_IO) -int direct_remap_area_pages(struct mm_struct *mm, - unsigned long address, - unsigned long machine_addr, - unsigned long size, - pgprot_t prot, - domid_t domid); -int __direct_remap_area_pages(struct mm_struct *mm, - unsigned long address, - unsigned long size, - mmu_update_t *v); - #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY #define __HAVE_ARCH_PTEP_GET_AND_CLEAR From 8fbc50190ab7df449d9c6d9b33b3b2a92ea71e74 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 3 Feb 2005 17:02:18 +0000 Subject: [PATCH 066/199] bitkeeper revision 1.1159.223.62 (4202591aKU7cGiiCesn0hIfz1J0vUQ) Fix bootmem allocator. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/common/page_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 878948a121..1790e3520d 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -176,7 +176,7 @@ unsigned long alloc_boot_pages(unsigned long size, unsigned long align) size = round_pgup(size) >> PAGE_SHIFT; align = round_pgup(align) >> PAGE_SHIFT; - for ( pg = 0; (pg + size) < (bitmap_size*PAGES_PER_MAPWORD); pg += align ) + for ( pg = 0; (pg + size) < (bitmap_size*8); pg += align ) { for ( i = 0; i < size; i++ ) if ( allocated_in_map(pg + i) ) From dc3c6686e653f53285b5e62eebb8dae32a79efa3 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 3 Feb 2005 20:10:15 +0000 Subject: [PATCH 067/199] bitkeeper revision 1.1159.223.63 (42028527-fv-d9BM0_LRp8UKGP19gQ) Fix NMI deferral. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/x86_32/entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index aeef45059c..1afeded9c9 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -522,12 +522,12 @@ do_watchdog_tick: defer_nmi: movl $FIXMAP_apic_base,%eax # apic_wait_icr_idle() -1: movl APIC_ICR(%eax),%ebx +1: movl %ss:APIC_ICR(%eax),%ebx testl $APIC_ICR_BUSY,%ebx jnz 1b # __send_IPI_shortcut(APIC_DEST_SELF, TRAP_deferred_nmi) movl $(APIC_DM_FIXED | APIC_DEST_SELF | APIC_DEST_LOGICAL | \ - TRAP_deferred_nmi),APIC_ICR(%eax) + TRAP_deferred_nmi),%ss:APIC_ICR(%eax) jmp restore_all_xen nmi_parity_err: From f7b633e6e8d6d5edf67463ff486aab8ca9e2cbc3 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 5 Feb 2005 09:05:43 +0000 Subject: [PATCH 068/199] bitkeeper revision 1.1159.223.64 (42048c67tDD9EILuuYdpEx-vM6LTnw) Name: tools-misc-TARGETS.patch Description: Split compile/link stages distcc behaves much better when you compile and link in 2 separate steps. Plus, this is a more standard way of doing things. Signed-off-by: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/misc/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 4cfc16f58e..39bfc424e6 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -34,5 +34,8 @@ clean: $(RM) *.o $(TARGETS) *~ $(MAKE) -C miniterm clean -%: %.c $(HDRS) Makefile +%.o: %.c $(HDRS) Makefile + $(CC) -c $(CFLAGS) -o $@ $< + +$(TARGETS): %: %.o Makefile $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil From bc7cc5527b150d2cdbc760f332e0b36c5ebd6946 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 5 Feb 2005 09:11:51 +0000 Subject: [PATCH 069/199] bitkeeper revision 1.1159.223.65 (42048dd7csr55HLi2cE2XeC4OklTGg) Name: clean-mtrr.patch Description: clean mtrr Clean xen/arch/x86/mtrr/* Signed-off-by: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/arch/x86/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 805591766e..aa6caae098 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -34,6 +34,7 @@ clean: rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32 rm -f x86_32/*.o x86_32/*~ x86_32/core rm -f x86_64/*.o x86_64/*~ x86_64/core + rm -f mtrr/*.o mtrr/*~ mtrr/core # setup.o contains bits of compile.h so it must be blown away delete-unfresh-files: From d8ab68ec413218ba2a8d25c3d019801d72bbdcea Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Sat, 5 Feb 2005 09:16:37 +0000 Subject: [PATCH 070/199] bitkeeper revision 1.1159.223.66 (42048ef5frMFQFFm-sKDC6PrU8yraQ) Name: pic-lib.patch Description: support PIC code generation Libraries have 2 methods of being compiled; a .so must contain non-pic objects, while the .a can contain standard objects. Signed-off-by: Adam Heath Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/libxc/Makefile | 33 +++++++++++++++++++++------------ tools/libxutil/Makefile | 12 +++++++++--- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 6369785d68..db605acdd2 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -5,7 +5,8 @@ INSTALL_DIR = $(INSTALL) -d -m0755 MAJOR = 2.0 MINOR = 0 -SONAME = libxc.so.$(MAJOR) +LIB_NAME = libxc +SONAME = $(LIB_NAME).so.$(MAJOR) CC = gcc @@ -39,9 +40,10 @@ CFLAGS += $(INCLUDES) -I. CFLAGS += -Wp,-MD,.$(@F).d DEPS = .*.d -OBJS = $(patsubst %.c,%.o,$(SRCS)) +OBJS := $(patsubst %.c,%.o,$(SRCS)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) -LIB = libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) +LIB := $(LIB_NAME).a $(LIB_NAME).so $(LIB_NAME).so.$(MAJOR) $(LIB_NAME).so.$(MAJOR).$(MINOR) all: check-for-zlib mk-symlinks $(MAKE) $(LIB) @@ -68,13 +70,14 @@ mk-symlinks: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include - $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib - ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) - ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so + $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib + $(INSTALL_DATA) $(LIB_NAME).a $(DESTDIR)/usr/lib + ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) + ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include clean: - rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) xen + rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen rpm: all rm -rf staging @@ -85,11 +88,17 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging -libxc.so: - ln -sf libxc.so.$(MAJOR) $@ -libxc.so.$(MAJOR): - ln -sf libxc.so.$(MAJOR).$(MINOR) $@ -libxc.so.$(MAJOR).$(MINOR): $(OBJS) +$(PIC_OBJS): %.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + +$(LIB_NAME).a: $(OBJS) + $(AR) rc $@ $^ + +$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) + ln -sf $< $@ +$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) + ln -sf $< $@ +$(LIB_NAME).so.$(MAJOR).$(MINOR): $(PIC_OBJS) $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -L../libxutil -lxutil -lz -include $(DEPS) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index cb12a93251..d9ac3b6e32 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -24,6 +24,7 @@ LIB_SRCS += sys_string.c LIB_SRCS += util.c LIB_OBJS := $(LIB_SRCS:.c=.o) +LIB_PIC_OBJS := $(LIB_SRCS:.c=.opic) CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing @@ -34,6 +35,7 @@ DEPS = .*.d MAJOR := 2.0 MINOR := 0 LIB_NAME := libxutil +SO_NAME := $(LIB_NAME).so.$(MAJOR) LIB := $(LIB_NAME).so LIB += $(LIB_NAME).so.$(MAJOR) LIB += $(LIB_NAME).so.$(MAJOR).$(MINOR) @@ -42,14 +44,17 @@ LIB += $(LIB_NAME).a all: check-for-zlib $(MAKE) $(LIB) +$(LIB_PIC_OBJS): %.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + $(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) ln -sf $^ $@ $(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) ln -sf $^ $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_OBJS) - $(CC) -Wl,-soname -Wl,$(LIB_NAME).so.$(MAJOR) -shared -o $@ $^ +$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_PIC_OBJS) + $(CC) -Wl,-soname -Wl,$(SO_NAME) -shared -o $@ $^ $(LIB_NAME).a: $(LIB_OBJS) $(AR) rc $@ $^ @@ -65,11 +70,12 @@ check-for-zlib: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib + $(INSTALL_DATA) $(LIB_NAME).a $(DESTDIR)/usr/lib ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so clean: - $(RM) *.a *.so *.so.* *.o *.rpm + $(RM) *.a *.so *.so.* *.o *.opic *.rpm $(RM) *~ $(RM) $(DEPS) From fc3efe0adac3a82e9adfdb201afa6e2afc54cc1c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 5 Feb 2005 10:31:37 +0000 Subject: [PATCH 071/199] bitkeeper revision 1.1159.223.67 (4204a089yB7FSdCp0Isa4dMFs_V3qQ) Building PIC .so libs is now optional. Defaults to enabled for Debian. Signed-off-by: keir.fraser@cl.cam.ac.uk --- tools/libxc/Makefile | 43 +++++++++++++++++++++++------------- tools/libxutil/Makefile | 48 +++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index db605acdd2..770b400326 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -1,3 +1,12 @@ + +ifndef BUILD_PIC_LIBS +ifeq ($(wildcard /etc/debian_version),) +BUILD_PIC_LIBS=n +else +BUILD_PIC_LIBS=y +endif +endif + INSTALL = install INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DATA = $(INSTALL) -m0644 @@ -5,8 +14,6 @@ INSTALL_DIR = $(INSTALL) -d -m0755 MAJOR = 2.0 MINOR = 0 -LIB_NAME = libxc -SONAME = $(LIB_NAME).so.$(MAJOR) CC = gcc @@ -40,10 +47,10 @@ CFLAGS += $(INCLUDES) -I. CFLAGS += -Wp,-MD,.$(@F).d DEPS = .*.d -OBJS := $(patsubst %.c,%.o,$(SRCS)) +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) -LIB := $(LIB_NAME).a $(LIB_NAME).so $(LIB_NAME).so.$(MAJOR) $(LIB_NAME).so.$(MAJOR).$(MINOR) +LIB := libxc.a libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) all: check-for-zlib mk-symlinks $(MAKE) $(LIB) @@ -70,14 +77,14 @@ mk-symlinks: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include - $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib - $(INSTALL_DATA) $(LIB_NAME).a $(DESTDIR)/usr/lib - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) - ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so + $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib + $(INSTALL_DATA) libxc.a $(DESTDIR)/usr/lib + ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR) + ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include clean: - rm -rf *.a *.so *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen + rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen rpm: all rm -rf staging @@ -90,15 +97,21 @@ rpm: all $(PIC_OBJS): %.opic: %.c $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< - -$(LIB_NAME).a: $(OBJS) + +libxc.a: $(OBJS) $(AR) rc $@ $^ -$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) +libxc.so: libxc.so.$(MAJOR) ln -sf $< $@ -$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) +libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR) ln -sf $< $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -L../libxutil -lxutil -lz + +ifeq ($(BUILD_PIC_LIBS),y) +libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS) + $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz +else +libxc.so.$(MAJOR).$(MINOR): $(LIB_OBJS) + $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz +endif -include $(DEPS) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index d9ac3b6e32..595cd97e83 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -1,3 +1,12 @@ + +ifndef BUILD_PIC_LIBS +ifeq ($(wildcard /etc/debian_version),) +BUILD_PIC_LIBS=n +else +BUILD_PIC_LIBS=y +endif +endif + XEN_ROOT = ../.. INSTALL = install INSTALL_DATA = $(INSTALL) -m0644 @@ -24,7 +33,7 @@ LIB_SRCS += sys_string.c LIB_SRCS += util.c LIB_OBJS := $(LIB_SRCS:.c=.o) -LIB_PIC_OBJS := $(LIB_SRCS:.c=.opic) +PIC_OBJS := $(LIB_SRCS:.c=.opic) CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing @@ -34,29 +43,32 @@ DEPS = .*.d MAJOR := 2.0 MINOR := 0 -LIB_NAME := libxutil -SO_NAME := $(LIB_NAME).so.$(MAJOR) -LIB := $(LIB_NAME).so -LIB += $(LIB_NAME).so.$(MAJOR) -LIB += $(LIB_NAME).so.$(MAJOR).$(MINOR) -LIB += $(LIB_NAME).a +LIB := libxutil.so +LIB += libxutil.so.$(MAJOR) +LIB += libxutil.so.$(MAJOR).$(MINOR) +LIB += libxutil.a all: check-for-zlib $(MAKE) $(LIB) -$(LIB_PIC_OBJS): %.opic: %.c +$(PIC_OBJS): %.opic: %.c $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< -$(LIB_NAME).so: $(LIB_NAME).so.$(MAJOR) +libxutil.so: libxutil.so.$(MAJOR) ln -sf $^ $@ -$(LIB_NAME).so.$(MAJOR): $(LIB_NAME).so.$(MAJOR).$(MINOR) +libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) ln -sf $^ $@ -$(LIB_NAME).so.$(MAJOR).$(MINOR): $(LIB_PIC_OBJS) - $(CC) -Wl,-soname -Wl,$(SO_NAME) -shared -o $@ $^ +ifeq ($(BUILD_PIC_LIBS),y) +libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) + $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ +else +libxutil.so.$(MAJOR).$(MINOR): $(LIB_OBJS) + $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ +endif -$(LIB_NAME).a: $(LIB_OBJS) +libxutil.a: $(LIB_OBJS) $(AR) rc $@ $^ check-for-zlib: @@ -69,13 +81,13 @@ check-for-zlib: install: all [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib - $(INSTALL_PROG) $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib - $(INSTALL_DATA) $(LIB_NAME).a $(DESTDIR)/usr/lib - ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR) - ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so + $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib + $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/lib + ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxutil.so.$(MAJOR) + ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/lib/libxutil.so clean: - $(RM) *.a *.so *.so.* *.o *.opic *.rpm + $(RM) *.a *.so* *.o *.opic *.rpm $(RM) *~ $(RM) $(DEPS) From f18239411ba4d145f4cc04239b3177fc4382a41a Mon Sep 17 00:00:00 2001 From: "mafetter@fleming.research" Date: Sat, 5 Feb 2005 10:50:49 +0000 Subject: [PATCH 072/199] bitkeeper revision 1.1159.223.68 (4204a5090n9Cd2ll6YcdL3tK2uDu1A) Bug fix to the scheduler for writable page tables. Don't flush the writable page tables inside __enter_scheduler() until after we've committed to switching to another domain. Here's the problem: if enough debugging messages are enabled (for example, shadow mode and/or writable page tables messages), then we can get into a situation where we *always* visit __enter_scheduler() after every page fault and/or hypercall. If we flush the writable page tables every time we take a page fault, we'll never end up actually getting into the domain with write permissions enabled to its page table. Signed-off-by: michael.fetterman@cl.cam.ac.uk --- xen/common/schedule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 5be947dc5a..ec215d5ed9 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -318,8 +318,6 @@ void __enter_scheduler(void) task_slice_t next_slice; s32 r_time; /* time for new dom to run */ - cleanup_writable_pagetable(prev); - perfc_incrc(sched_run); spin_lock_irq(&schedule_data[cpu].schedule_lock); @@ -369,6 +367,8 @@ void __enter_scheduler(void) perfc_incrc(sched_ctx); + cleanup_writable_pagetable(prev); + #if defined(WAKE_HISTO) if ( !is_idle_task(next) && next->wokenup ) { ulong diff = (ulong)(now - next->wokenup); From 48ff6b71e1f93a06d9184e52fbb92b8ae8401e6e Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 5 Feb 2005 12:39:34 +0000 Subject: [PATCH 073/199] bitkeeper revision 1.1159.245.1 (4204be86F8AKmyv5_m4N44YWgyyt_Q) Another NMI watchdog fix. Deferred NMIs need to ACK the local APIC. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/traps.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index d053705c13..8e965c5f60 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -591,14 +591,14 @@ asmlinkage void io_check_error(struct xen_regs *regs) fatal_trap(TRAP_nmi, regs); } -static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs) +static void unknown_nmi_error(unsigned char reason) { printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); printk("Dazed and confused, but trying to continue\n"); printk("Do you have a strange power saving mode enabled?\n"); } -asmlinkage void do_nmi(struct xen_regs * regs, unsigned long reason) +asmlinkage void do_nmi(struct xen_regs *regs, unsigned long reason) { ++nmi_count(smp_processor_id()); @@ -607,7 +607,7 @@ asmlinkage void do_nmi(struct xen_regs * regs, unsigned long reason) nmi_watchdog_tick(regs); else #endif - unknown_nmi_error((unsigned char)(reason&0xff), regs); + unknown_nmi_error((unsigned char)(reason&0xff)); } unsigned long nmi_softirq_reason; @@ -695,6 +695,13 @@ asmlinkage int do_spurious_interrupt_bug(struct xen_regs *regs) return EXCRET_not_a_fault; } +BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi) +asmlinkage void smp_deferred_nmi(struct xen_regs regs) +{ + ack_APIC_irq(); + do_nmi(®s, 0); +} + #define _set_gate(gate_addr,type,dpl,addr) \ do { \ int __d0, __d1; \ @@ -803,7 +810,7 @@ void __init trap_init(void) set_intr_gate(TRAP_alignment_check,&alignment_check); set_intr_gate(TRAP_machine_check,&machine_check); set_intr_gate(TRAP_simd_error,&simd_coprocessor_error); - set_intr_gate(TRAP_deferred_nmi,&nmi); + set_intr_gate(TRAP_deferred_nmi,&deferred_nmi); /* Only ring 1 can access Xen services. */ _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall); From a30533c4467bbb4c11005dc9dacab8a5eca71f47 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Sun, 6 Feb 2005 09:39:38 +0000 Subject: [PATCH 074/199] bitkeeper revision 1.1159.223.70 (4205e5daVr3OnfNS5GMFcoc8j80ODQ) trivial fix to the ioremap for local pages --- linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c index b9034505b5..efd4663bcc 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -129,7 +129,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr, size, __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED - | flags), DOMID_IO)) { + | flags), domid)) { vunmap((void __force *) addr); return NULL; } From 33788f79da6e83e14027826ed94723303900ee00 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sun, 6 Feb 2005 12:07:18 +0000 Subject: [PATCH 075/199] bitkeeper revision 1.1159.223.71 (42060876pgZEpnal0wuK3VOOWP9zCQ) Fix build system to rebuild file containing banner text every time. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/Makefile | 3 ++- xen/arch/x86/Makefile | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index 33b03f4854..57a89ad454 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -54,8 +54,9 @@ $(TARGET): delete-unfresh-files include/xen/compile.h $(MAKE) -C drivers $(MAKE) -C arch/$(TARGET_ARCH) +# drivers/char/console.o may contain static banner/compile info. Blow it away. delete-unfresh-files: - rm -f include/xen/banner.h include/xen/compile.h + rm -f include/xen/banner.h include/xen/compile.h drivers/char/console.o $(MAKE) -C arch/$(TARGET_ARCH) delete-unfresh-files # compile.h contains dynamic build info. Rebuilt on every 'make' invocation. diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index aa6caae098..9a6029dcaf 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -36,8 +36,7 @@ clean: rm -f x86_64/*.o x86_64/*~ x86_64/core rm -f mtrr/*.o mtrr/*~ mtrr/core -# setup.o contains bits of compile.h so it must be blown away delete-unfresh-files: - rm -f setup.o + # nothing .PHONY: default clean delete-unfresh-files From c0d41e43157bca272cc2f18e59ff02730898a1f9 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sun, 6 Feb 2005 12:09:52 +0000 Subject: [PATCH 076/199] bitkeeper revision 1.1159.223.72 (42060910CAWXk13FiquPxR_uRrD_1A) Prevent stack overflow in PCI setup code. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/pci-pc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/pci-pc.c b/xen/arch/x86/pci-pc.c index cb5889628c..c3c097efdc 100644 --- a/xen/arch/x86/pci-pc.c +++ b/xen/arch/x86/pci-pc.c @@ -1,3 +1,4 @@ +/* -*- Mode:C; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Low-Level PCI Support for PC * @@ -445,8 +446,9 @@ static struct pci_ops pci_direct_conf2 = { static int __devinit pci_sanity_check(struct pci_ops *o) { u16 x; - struct pci_bus bus; /* Fake bus and device */ - struct pci_dev dev; + /* XEN: static is important to prevent stack overflow! */ + static struct pci_bus bus; /* Fake bus and device */ + static struct pci_dev dev; if (pci_probe & PCI_NO_CHECKS) return 1; @@ -1131,8 +1133,9 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b) static void __devinit pcibios_fixup_peer_bridges(void) { int n; - struct pci_bus bus; - struct pci_dev dev; + /* XEN: static is important to prevent stack overflow! */ + static struct pci_bus bus; + static struct pci_dev dev; u16 l; if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) From cef3a40634164bf20408748091faa9584b044051 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sun, 6 Feb 2005 12:48:07 +0000 Subject: [PATCH 077/199] bitkeeper revision 1.1159.223.73 (42061207JyX53LmlrclgfiWwVqnF7w) Avoid large stack frame in arch_dom0_op by dynamically allocating space for getmeminfo batch. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/dom0_ops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c index d212324260..b6ade93ee7 100644 --- a/xen/arch/x86/dom0_ops.c +++ b/xen/arch/x86/dom0_ops.c @@ -216,7 +216,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) domid_t dom = op->u.getpageframeinfo2.domain; unsigned long *s_ptr = (unsigned long*) op->u.getpageframeinfo2.array; struct domain *d; - unsigned long l_arr[GPF2_BATCH]; + unsigned long *l_arr; ret = -ESRCH; if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) @@ -227,6 +227,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) ret = -E2BIG; break; } + + l_arr = (unsigned long *)alloc_xenheap_page(); ret = 0; for( n = 0; n < num; ) @@ -291,6 +293,8 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op) n += j; } + free_xenheap_page((unsigned long)l_arr); + put_domain(d); } break; From 88381e599a556df1b6d7ee03cfeaa1c822083488 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 7 Feb 2005 11:57:29 +0000 Subject: [PATCH 078/199] bitkeeper revision 1.1159.223.74 (420757a9FtyPHOdlg42s6EIT2DD1zw) Pad Xen image to end on a page boundary. Avoids kexec bug. Signed-off-by: keir.fraser@cl.cam.ac.uk --- xen/arch/x86/boot/mkelf32.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xen/arch/x86/boot/mkelf32.c b/xen/arch/x86/boot/mkelf32.c index e16756237b..4f32a7c055 100644 --- a/xen/arch/x86/boot/mkelf32.c +++ b/xen/arch/x86/boot/mkelf32.c @@ -245,6 +245,12 @@ int main(int argc, char **argv) return 1; } + /* + * End the image on a page boundary. This gets round alignment bugs + * in the boot- or chain-loader (e.g., kexec on the XenoBoot CD). + */ + mem_siz += -(loadbase + mem_siz) & 0xfff; + out_ehdr.e_entry = loadbase; out_ehdr.e_shoff = RAW_OFFSET + dat_siz; From d08dd0ac713846d51d52b8ee90a73a347c97dfb8 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Mon, 7 Feb 2005 15:48:40 +0000 Subject: [PATCH 079/199] bitkeeper revision 1.1159.223.75 (42078dd8VBcyJ0X9yF-bRHcBVUJ3Ww) As pointed out on the xen-devel list, the vm86 call was not very robust in Xen. It turned out to be due to a missing check in the pagefault handler, determining whether the pagefault came from userspace or from the kernel. Now the syscall-crash tool doesn't cause any "Oops" on the vm86 calls anymore. From: Stephan Diestelhorst Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c index b869fad317..9b5ba2b3d7 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c @@ -228,7 +228,9 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code, /* Set the "privileged fault" bit to something sane. */ error_code &= 3; error_code |= (regs->xcs & 2) << 1; - + if (regs->eflags & X86_EFLAGS_VM) + error_code |= 4; + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, SIGSEGV) == NOTIFY_STOP) return; From 6f6dcfb95e72d56334add1e90c27f660029fc114 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Mon, 7 Feb 2005 18:33:22 +0000 Subject: [PATCH 080/199] bitkeeper revision 1.1159.223.76 (4207b472nHz4nbC_OJgbSmfRVow8XQ) Don't let xend throw away stderr... --- tools/python/xen/xend/server/SrvDaemon.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 338d6e4d4a..d54dec26bb 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -484,10 +484,12 @@ class Daemon: # XXX KAF: Why doesn't this capture output from C extensions that # fprintf(stdout) or fprintf(stderr) ?? os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT) + os.dup(1) else: os.open('/dev/null', os.O_RDWR) os.dup(0) - os.dup(1) + os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT) + def start(self, trace=0): """Attempts to start the daemons. From 90dd5b6a182bbea3e5159c4022e709c72c8ed448 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Mon, 7 Feb 2005 19:11:33 +0000 Subject: [PATCH 081/199] bitkeeper revision 1.1159.223.77 (4207bd65yRdFmE9Py8fLUBk3826_Ig) Minor tidy of vif-nat script. Signed-off-by: keir.fraser@cl.cam.ac.uk --- tools/examples/vif-nat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index 2cf3557806..4b6d348dfa 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -37,8 +37,8 @@ domain=${domain:?} vif=${vif:?} ip=${ip:?} -# better way to strip /netmask from the ip? -vif_ip=`echo ${ip} | awk -F. '{print $1"."$2"."$3"."$4}'` +# strip /netmask +vif_ip=`echo ${ip} | awk -F/ '{print $1}'` main_ip=`ifconfig eth0 | grep "inet addr:" | sed -e 's/.*inet addr:\(\w\w*\.\w\w*\.\w\w*\.\w\w*\).*/\1/'` From f5fedc454db71ca7d266240157936932d8f4db6c Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 01:16:50 +0000 Subject: [PATCH 082/199] bitkeeper revision 1.1159.223.78 (42081302-eWxmHBN6T8FdRJD5VvsOg) This very simple patch is really just cosmetic. It "fixes" xend so that it doesn't report restart as: "WARNING (XendDomainInfo:1038) Unknown config field restart" in the xend.log. I'm not sure who should sign off on this, but the patch is attached. From: "B.G. Bruce" Signed-off-by: ian@xensource.com --- tools/python/xen/xend/XendDomainInfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 05647c83ab..c946031309 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1227,6 +1227,7 @@ add_config_handler('memory', vm_field_ignore) add_config_handler('cpu', vm_field_ignore) add_config_handler('cpu_weight', vm_field_ignore) add_config_handler('console', vm_field_ignore) +add_config_handler('restart', vm_field_ignore) add_config_handler('image', vm_field_ignore) add_config_handler('device', vm_field_ignore) add_config_handler('backend', vm_field_ignore) From 02f82c278807571fd2a6a88e7921f5f11f8975d3 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 03:14:41 +0000 Subject: [PATCH 083/199] bitkeeper revision 1.1159.223.79 (42082ea1obdbIutzD0IY-9Fdcf7Exw) Fix to memory debugging audit code. Signed-off-by: ian@xensource.com --- xen/arch/x86/memory.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 486d6ba407..e438ed68b8 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -2279,7 +2279,6 @@ void audit_domain(struct domain *d) } /* PHASE 3 */ - list_ent = d->page_list.next; for ( i = 0; (list_ent != &d->page_list); i++ ) { @@ -2300,7 +2299,12 @@ void audit_domain(struct domain *d) if ( pt[i] & _PAGE_PRESENT ) { unsigned long l1pfn = pt[i]>>PAGE_SHIFT; - struct pfn_info *l1page = &frame_table[l1pfn]; + struct pfn_info *l1page; + + if (l1pfn>max_page) + continue; + + l1page = &frame_table[l1pfn]; if ( l1page->u.inuse.domain == d) adjust(l1page, 1, 1); @@ -2321,7 +2325,12 @@ void audit_domain(struct domain *d) if ( pt[i] & _PAGE_PRESENT ) { unsigned long l1pfn = pt[i]>>PAGE_SHIFT; - struct pfn_info *l1page = &frame_table[l1pfn]; + struct pfn_info *l1page; + + if (l1pfn>max_page) + continue; + + l1page = &frame_table[l1pfn]; if ( (l1page->u.inuse.domain != d) || (l1pfn < 0x100) || (l1pfn > max_page) ) From 055935cf6d7925378728bea9a68aa4e58807db4d Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 15:43:01 +0000 Subject: [PATCH 084/199] bitkeeper revision 1.1159.223.80 (4208de05Xtv_u_3smJSRU6ex6bTAfA) Some functions aren't static and could be (damn C language!). I tried turning on -Wmissing-prototypes: unfortunately gives warnings for functions used in asm, which means introducing gratuitous prototypes for them. Not sure it's worth it. 1) keyhandler.c: keypress_softirq() and do_task_queues() can be static. 2) physdev.c: pcidev_dom0_hidden() can be static. 3) resource.c/resource.h: check_region is deprecated (racy): remove. 4) sched_bvt.c: lots of things can be static. 5) pci/compat.c: not required for Xen. Signed-off-by: Rusty Russell (authored) Signed-off-by: ian.pratt@cl.cam.ac.uk --- xen/common/keyhandler.c | 4 +-- xen/common/physdev.c | 2 +- xen/common/resource.c | 13 -------- xen/common/sched_bvt.c | 16 +++++----- xen/drivers/pci/Makefile | 2 +- xen/drivers/pci/compat.c | 65 ---------------------------------------- xen/include/xen/ioport.h | 8 ++--- 7 files changed, 14 insertions(+), 96 deletions(-) diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index ef62fc4a5a..dad82476d0 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -26,7 +26,7 @@ static struct { static unsigned char keypress_key; -void keypress_softirq(void) +static void keypress_softirq(void) { keyhandler_t *h; unsigned char key = keypress_key; @@ -93,7 +93,7 @@ static void halt_machine(unsigned char key, struct xen_regs *regs) machine_restart(NULL); } -void do_task_queues(unsigned char key) +static void do_task_queues(unsigned char key) { struct domain *d; s_time_t now = NOW(); diff --git a/xen/common/physdev.c b/xen/common/physdev.c index cd4d2811e3..516479c0b8 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -704,7 +704,7 @@ string_param("physdev_dom0_hide", opt_physdev_dom0_hide); /* Test if boot params specify this device should NOT be visible to DOM0 * (e.g. so that another domain can control it instead) */ -int pcidev_dom0_hidden(struct pci_dev *dev) +static int pcidev_dom0_hidden(struct pci_dev *dev) { char cmp[10] = "(.......)"; diff --git a/xen/common/resource.c b/xen/common/resource.c index 8df57772a6..3ce6d89c97 100644 --- a/xen/common/resource.c +++ b/xen/common/resource.c @@ -253,19 +253,6 @@ struct resource * __request_region(struct resource *parent, unsigned long start, return res; } -int __check_region(struct resource *parent, unsigned long start, unsigned long n) -{ - struct resource * res; - - res = __request_region(parent, start, n, "check-region"); - if (!res) - return -EBUSY; - - release_resource(res); - xfree(res); - return 0; -} - void __release_region(struct resource *parent, unsigned long start, unsigned long n) { struct resource **p; diff --git a/xen/common/sched_bvt.c b/xen/common/sched_bvt.c index 6f0a79fad1..edad59ca18 100644 --- a/xen/common/sched_bvt.c +++ b/xen/common/sched_bvt.c @@ -159,7 +159,7 @@ static inline u32 calc_evt(struct domain *d, u32 avt) * * Returns non-zero on failure. */ -int bvt_alloc_task(struct domain *d) +static int bvt_alloc_task(struct domain *d) { if ( (d->sched_priv = xmem_cache_alloc(dom_info_cache)) == NULL ) return -1; @@ -170,7 +170,7 @@ int bvt_alloc_task(struct domain *d) /* * Add and remove a domain */ -void bvt_add_task(struct domain *d) +static void bvt_add_task(struct domain *d) { struct bvt_dom_info *inf = BVT_INFO(d); ASSERT(inf != NULL); @@ -206,7 +206,7 @@ void bvt_add_task(struct domain *d) } } -int bvt_init_idle_task(struct domain *p) +static int bvt_init_idle_task(struct domain *p) { if ( bvt_alloc_task(p) < 0 ) return -1; @@ -220,7 +220,7 @@ int bvt_init_idle_task(struct domain *p) return 0; } -void bvt_wake(struct domain *d) +static void bvt_wake(struct domain *d) { struct bvt_dom_info *inf = BVT_INFO(d); struct domain *curr; @@ -271,14 +271,14 @@ static void bvt_sleep(struct domain *d) * bvt_free_task - free BVT private structures for a task * @d: task */ -void bvt_free_task(struct domain *d) +static void bvt_free_task(struct domain *d) { ASSERT(d->sched_priv != NULL); xmem_cache_free(dom_info_cache, d->sched_priv); } /* Control the scheduler. */ -int bvt_ctl(struct sched_ctl_cmd *cmd) +static int bvt_ctl(struct sched_ctl_cmd *cmd) { struct bvt_ctl *params = &cmd->u.bvt; @@ -291,7 +291,7 @@ int bvt_ctl(struct sched_ctl_cmd *cmd) } /* Adjust scheduling parameter for a given domain. */ -int bvt_adjdom( +static int bvt_adjdom( struct domain *d, struct sched_adjdom_cmd *cmd) { struct bvt_adjdom *params = &cmd->u.bvt; @@ -526,7 +526,7 @@ static void bvt_dump_cpu_state(int i) } /* Initialise the data structures. */ -int bvt_init_scheduler() +static int bvt_init_scheduler(void) { int i; diff --git a/xen/drivers/pci/Makefile b/xen/drivers/pci/Makefile index 040d5aaccd..f2580105df 100644 --- a/xen/drivers/pci/Makefile +++ b/xen/drivers/pci/Makefile @@ -4,7 +4,7 @@ include $(BASEDIR)/Rules.mk -OBJS := pci.o quirks.o compat.o names.o setup-res.o +OBJS := pci.o quirks.o names.o setup-res.o #obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o #obj-$(CONFIG_PROC_FS) += proc.o diff --git a/xen/drivers/pci/compat.c b/xen/drivers/pci/compat.c index 61e14b0a84..e69de29bb2 100644 --- a/xen/drivers/pci/compat.c +++ b/xen/drivers/pci/compat.c @@ -1,65 +0,0 @@ -/* - * $Id: compat.c,v 1.1 1998/02/16 10:35:50 mj Exp $ - * - * PCI Bus Services -- Function For Backward Compatibility - * - * Copyright 1998--2000 Martin Mares - */ - -#include -//#include -#include - -int -pcibios_present(void) -{ - return !list_empty(&pci_devices); -} - -int -pcibios_find_class(unsigned int class, unsigned short index, unsigned char *bus, unsigned char *devfn) -{ - const struct pci_dev *dev = NULL; - int cnt = 0; - - while ((dev = pci_find_class(class, dev))) - if (index == cnt++) { - *bus = dev->bus->number; - *devfn = dev->devfn; - return PCIBIOS_SUCCESSFUL; - } - return PCIBIOS_DEVICE_NOT_FOUND; -} - - -int -pcibios_find_device(unsigned short vendor, unsigned short device, unsigned short index, - unsigned char *bus, unsigned char *devfn) -{ - const struct pci_dev *dev = NULL; - int cnt = 0; - - while ((dev = pci_find_device(vendor, device, dev))) - if (index == cnt++) { - *bus = dev->bus->number; - *devfn = dev->devfn; - return PCIBIOS_SUCCESSFUL; - } - return PCIBIOS_DEVICE_NOT_FOUND; -} - -#define PCI_OP(rw,size,type) \ -int pcibios_##rw##_config_##size (unsigned char bus, unsigned char dev_fn, \ - unsigned char where, unsigned type val) \ -{ \ - struct pci_dev *dev = pci_find_slot(bus, dev_fn); \ - if (!dev) return PCIBIOS_DEVICE_NOT_FOUND; \ - return pci_##rw##_config_##size(dev, where, val); \ -} - -PCI_OP(read, byte, char *) -PCI_OP(read, word, short *) -PCI_OP(read, dword, int *) -PCI_OP(write, byte, char) -PCI_OP(write, word, short) -PCI_OP(write, dword, int) diff --git a/xen/include/xen/ioport.h b/xen/include/xen/ioport.h index 0416edc71e..b39d07ae32 100644 --- a/xen/include/xen/ioport.h +++ b/xen/include/xen/ioport.h @@ -100,17 +100,13 @@ extern int allocate_resource(struct resource *root, struct resource *new, #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) -extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name); - -/* Compatibility cruft */ -#define check_region(start,n) __check_region(&ioport_resource, (start), (n)) #define release_region(start,n) __release_region(&ioport_resource, (start), (n)) -#define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) #define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) -extern int __check_region(struct resource *, unsigned long, unsigned long); extern void __release_region(struct resource *, unsigned long, unsigned long); +extern struct resource * __request_region(struct resource *, unsigned long start, unsigned long n, const char *name); + #define get_ioport_list(buf) get_resource_list(&ioport_resource, buf, PAGE_SIZE) #define get_mem_list(buf) get_resource_list(&iomem_resource, buf, PAGE_SIZE) From faf69408ee386b7fdfd5551f1e183e5aeda9d477 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 19:52:18 +0000 Subject: [PATCH 085/199] bitkeeper revision 1.1159.223.81 (42091872lrObHIRNczDaqDeQw3NmyA) debug memory audit cleanups + comment fix from Jon Mason. Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c | 8 ++++---- xen/arch/x86/domain.c | 3 +++ xen/arch/x86/memory.c | 9 +++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c index 05b043c175..6d29cc262f 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c @@ -1,11 +1,11 @@ /****************************************************************************** - * arch/xen/drivers/netif/backend/main.c + * drivers/xen/netback/netback.c * - * Back-end of the driver for virtual block devices. This portion of the - * driver exports a 'unified' block-device interface that can be accessed + * Back-end of the driver for virtual network devices. This portion of the + * driver exports a 'unified' network-device interface that can be accessed * by any operating system that implements a compatible front end. A * reference front-end implementation can be found in: - * arch/xen/drivers/netif/frontend + * drivers/xen/netfront/netfront.c * * Copyright (c) 2002-2004, K A Fraser */ diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 4ca96f5d3c..e4c427d402 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -578,8 +578,11 @@ void domain_relinquish_memory(struct domain *d) /* Drop the in-use reference to the page-table base. */ if ( pagetable_val(d->mm.pagetable) != 0 ) + { put_page_and_type(&frame_table[pagetable_val(d->mm.pagetable) >> PAGE_SHIFT]); + d->mm.pagetable = mk_pagetable(0); + } /* * Relinquish GDT mappings. No need for explicit unmapping of the LDT as diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index e438ed68b8..8034b67406 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -2098,8 +2098,8 @@ void audit_domain(struct domain *d) /* PHASE 1 */ - - adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1); + if( pagetable_val(d->mm.pagetable) ) + adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1); list_ent = d->page_list.next; for ( i = 0; (list_ent != &d->page_list); i++ ) @@ -2352,9 +2352,10 @@ void audit_domain(struct domain *d) spin_unlock(&d->page_alloc_lock); - adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1); + if( pagetable_val(d->mm.pagetable) ) + adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1); - printk("Audit %d: Done. ctot=%d ttot=%d\n", d->id, ctot, ttot ); + printk("Audit %d: Done. pages=%d ctot=%d ttot=%d\n", i, d->id, ctot, ttot ); if ( d != current ) domain_unpause(d); From 09d5eb57206854f55438aff3442135e3664972c0 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 22:39:08 +0000 Subject: [PATCH 086/199] bitkeeper revision 1.1159.223.82 (42093f8cxZb9FQfWwmj7IIok9ndiPg) minor stats collection addition ian@xensource.com --- xen/arch/x86/memory.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 8034b67406..631e5c50c9 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -2039,7 +2039,7 @@ void audit_domain(struct domain *d) scan_for_pfn( e, xpfn ); } - int i; + int i, l1, l2; unsigned long pfn; struct list_head *list_ent; struct pfn_info *page; @@ -2280,6 +2280,7 @@ void audit_domain(struct domain *d) /* PHASE 3 */ list_ent = d->page_list.next; + l1 = l2 = 0; for ( i = 0; (list_ent != &d->page_list); i++ ) { unsigned long *pt; @@ -2289,6 +2290,7 @@ void audit_domain(struct domain *d) switch ( page->u.inuse.type_info & PGT_type_mask ) { case PGT_l2_page_table: + l2++; if ( (page->u.inuse.type_info & PGT_pinned) == PGT_pinned ) adjust( page, 1, 1 ); @@ -2315,6 +2317,7 @@ void audit_domain(struct domain *d) break; case PGT_l1_page_table: + l1++; if ( (page->u.inuse.type_info & PGT_pinned) == PGT_pinned ) adjust( page, 1, 1 ); @@ -2355,7 +2358,7 @@ void audit_domain(struct domain *d) if( pagetable_val(d->mm.pagetable) ) adjust(&frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1); - printk("Audit %d: Done. pages=%d ctot=%d ttot=%d\n", i, d->id, ctot, ttot ); + printk("Audit %d: Done. pages=%d l1=%d l2=%d ctot=%d ttot=%d\n", d->id, i, l1, l2, ctot, ttot ); if ( d != current ) domain_unpause(d); From 0eef50acd62083f9e80d45ae844940c9b2c5a4a0 Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Wed, 9 Feb 2005 02:58:09 +0000 Subject: [PATCH 087/199] bitkeeper revision 1.1159.223.83 (42097c41y12EFATQuIKPTDS1smnkWQ) Subject: [Xen-devel] [PATCH] Fix initrd support for Linux 2.4/2.6 The following patch sets the default root device to be the null device. This is the behavior Linux is launched with no root device specified in the command line and without a device provided by the boot loader. Previously, the default root device was set to be /dev/ram0. This broke initrd support. This change was made in 2.6 to because of a bug reported on September 14th with dynamic ipconfig. I've recreated his problem and looked through the code and the source of the problem was that his kernel command line was incorrect. He was missing the BOOTP field in the config line requiring that there be an actual root device. This worked with 2.4 but only because 2.4 was also broken. His patch just introduced that bug into 2.6. I've tested this against the 2.6 and 2.4 trees in a recent copy of xen-unstable. I've tested initrd support and ipconfig support (including dynamic ip support). They both now work as expected. If anyone needs an initrd for testing let me know. Regards, -- Anthony Liguori Linux Technology Center (LTC) - IBM Austin E-mail: aliguori@us.ibm.com Phone: (512) 838-1208 Signed-off-by: Anthony Liguori Signed-off-by: ian@xensource.com --- linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c | 4 +++- linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c index 3b27174ba6..46507fbd93 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c @@ -240,7 +240,9 @@ void __init setup_arch(char **cmdline_p) boot_cpu_data.pgd_quick = cpu0_pgd_quicklist; boot_cpu_data.pte_quick = cpu0_pte_quicklist; - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + /* This must be initialized to UNNAMED_MAJOR for ipconfig to work + properly. Setting ROOT_DEV to default to /dev/ram0 breaks initrd. */ + ROOT_DEV = MKDEV(UNNAMED_MAJOR,0); memset(&drive_info, 0, sizeof(drive_info)); memset(&screen_info, 0, sizeof(screen_info)); diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c index 852c556778..ab77b119b1 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1359,7 +1359,10 @@ void __init setup_arch(char **cmdline_p) efi_enabled = 1; #endif - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); /*old_decode_dev(ORIG_ROOT_DEV);*/ + /* This must be initialized to UNNAMED_MAJOR for ipconfig to work + properly. Setting ROOT_DEV to default to /dev/ram0 breaks initrd. + */ + ROOT_DEV = MKDEV(UNNAMED_MAJOR,0); drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; edid_info = EDID_INFO; From 6be18e86c3d59af8af7dd6edf995797b09ffe3ef Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Wed, 9 Feb 2005 19:44:49 +0000 Subject: [PATCH 088/199] bitkeeper revision 1.1159.223.84 (420a6831W2g6HHtXksV16NZox0sA5Q) Subject: [Xen-devel] [PATCH 1/2] netfront coding style clean-up (trivial) Signed-off-by: Jon Mason Signed-off-by: ian@xensource.com --- .../drivers/xen/netfront/netfront.c | 248 +++++++----------- 1 file changed, 98 insertions(+), 150 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c index ee53c8b1a6..16e55a9578 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -48,11 +50,6 @@ #include #include -#include -#include - -#define DEBUG 0 - #ifndef __GFP_NOWARN #define __GFP_NOWARN 0 #endif @@ -63,7 +60,7 @@ atomic_set(&(skb_shinfo(_skb)->dataref), 1); \ skb_shinfo(_skb)->nr_frags = 0; \ skb_shinfo(_skb)->frag_list = NULL; \ - } while ( 0 ) + } while (0) /* Allow headroom on each rx pkt for Ethernet header, alignment padding, ... */ #define RX_HEADROOM 200 @@ -171,10 +168,9 @@ static struct net_device *find_dev_by_handle(unsigned int handle) { struct list_head *ent; struct net_private *np; - list_for_each ( ent, &dev_list ) - { + list_for_each (ent, &dev_list) { np = list_entry(ent, struct net_private, list); - if ( np->handle == handle ) + if (np->handle == handle) return np->dev; } return NULL; @@ -203,7 +199,7 @@ static void netctrl_init(void) */ static int netctrl_err(int err) { - if ( (err < 0) && !netctrl.err ) + if ((err < 0) && !netctrl.err) netctrl.err = err; return netctrl.err; } @@ -216,9 +212,9 @@ static int netctrl_connected(void) { int ok; - if ( netctrl.err ) + if (netctrl.err) ok = netctrl.err; - else if ( netctrl.up == NETIF_DRIVER_STATUS_UP ) + else if (netctrl.up == NETIF_DRIVER_STATUS_UP) ok = (netctrl.connected_n == netctrl.interface_n); else ok = 0; @@ -266,14 +262,14 @@ static int send_fake_arp(struct net_device *dev) src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK); /* No IP? Then nothing to do. */ - if ( src_ip == 0 ) + if (src_ip == 0) return 0; skb = arp_create(ARPOP_REPLY, ETH_P_ARP, dst_ip, dev, src_ip, /*dst_hw*/ NULL, /*src_hw*/ NULL, /*target_hw*/ dev->dev_addr); - if ( skb == NULL ) + if (skb == NULL) return -ENOMEM; return dev_queue_xmit(skb); @@ -302,15 +298,14 @@ static void network_tx_buf_gc(struct net_device *dev) struct net_private *np = netdev_priv(dev); struct sk_buff *skb; - if ( np->backend_state != BEST_CONNECTED ) + if (np->backend_state != BEST_CONNECTED) return; do { prod = np->tx->resp_prod; rmb(); /* Ensure we see responses up to 'rp'. */ - for ( i = np->tx_resp_cons; i != prod; i++ ) - { + for (i = np->tx_resp_cons; i != prod; i++) { id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id; skb = np->tx_skbs[id]; ADD_ID_TO_FREELIST(np->tx_skbs, id); @@ -330,14 +325,11 @@ static void network_tx_buf_gc(struct net_device *dev) np->tx->event = prod + ((np->tx->req_prod - prod) >> 1) + 1; mb(); - } - while ( prod != np->tx->resp_prod ); + } while (prod != np->tx->resp_prod); - if ( np->tx_full && - ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) ) - { + if (np->tx_full && ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE)) { np->tx_full = 0; - if ( np->user_state == UST_OPEN ) + if (np->user_state == UST_OPEN) netif_wake_queue(dev); } } @@ -351,7 +343,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) int i, batch_target; NETIF_RING_IDX req_prod = np->rx->req_prod; - if ( unlikely(np->backend_state != BEST_CONNECTED) ) + if (unlikely(np->backend_state != BEST_CONNECTED)) return; /* @@ -361,20 +353,18 @@ static void network_alloc_rx_buffers(struct net_device *dev) * ourself and for other kernel subsystems. */ batch_target = np->rx_target - (req_prod - np->rx_resp_cons); - for ( i = skb_queue_len(&np->rx_batch); i < batch_target; i++ ) - { - if ( unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL) ) + for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { + if (unlikely((skb = alloc_xen_skb(dev->mtu + RX_HEADROOM)) == NULL)) break; __skb_queue_tail(&np->rx_batch, skb); } /* Is the batch large enough to be worthwhile? */ - if ( i < (np->rx_target/2) ) + if (i < (np->rx_target/2)) return; - for ( i = 0; ; i++ ) - { - if ( (skb = __skb_dequeue(&np->rx_batch)) == NULL ) + for (i = 0; ; i++) { + if ((skb = __skb_dequeue(&np->rx_batch)) == NULL) break; skb->dev = dev; @@ -421,15 +411,15 @@ static void network_alloc_rx_buffers(struct net_device *dev) (void)HYPERVISOR_multicall(rx_mcl, i+1); /* Check return status of HYPERVISOR_dom_mem_op(). */ - if ( unlikely(rx_mcl[i].args[5] != i) ) + if (unlikely(rx_mcl[i].args[5] != i)) panic("Unable to reduce memory reservation\n"); /* Above is a suitable barrier to ensure backend will see requests. */ np->rx->req_prod = req_prod + i; /* Adjust our floating fill target if we risked running out of buffers. */ - if ( ((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) && - ((np->rx_target *= 2) > RX_MAX_TARGET) ) + if (((req_prod - np->rx->resp_prod) < (np->rx_target / 4)) && + ((np->rx_target *= 2) > RX_MAX_TARGET)) np->rx_target = RX_MAX_TARGET; } @@ -441,18 +431,16 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_tx_request_t *tx; NETIF_RING_IDX i; - if ( unlikely(np->tx_full) ) - { + if (unlikely(np->tx_full)) { printk(KERN_ALERT "%s: full queue wasn't stopped!\n", dev->name); netif_stop_queue(dev); goto drop; } - if ( unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= - PAGE_SIZE) ) - { + if (unlikely((((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= + PAGE_SIZE)) { struct sk_buff *nskb; - if ( unlikely((nskb = alloc_xen_skb(skb->len)) == NULL) ) + if (unlikely((nskb = alloc_xen_skb(skb->len)) == NULL)) goto drop; skb_put(nskb, skb->len); memcpy(nskb->data, skb->data, skb->len); @@ -463,8 +451,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&np->tx_lock); - if ( np->backend_state != BEST_CONNECTED ) - { + if (np->backend_state != BEST_CONNECTED) { spin_unlock_irq(&np->tx_lock); goto drop; } @@ -485,8 +472,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) network_tx_buf_gc(dev); - if ( (i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1) ) - { + if ((i - np->tx_resp_cons) == (NETIF_TX_RING_SIZE - 1)) { np->tx_full = 1; netif_stop_queue(dev); } @@ -498,7 +484,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Only notify Xen if we really have to. */ mb(); - if ( np->tx->TX_TEST_IDX == i ) + if (np->tx->TX_TEST_IDX == i) notify_via_evtchn(np->evtchn); return 0; @@ -509,7 +495,6 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) { struct net_device *dev = dev_id; @@ -520,8 +505,7 @@ static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs) network_tx_buf_gc(dev); spin_unlock_irqrestore(&np->tx_lock, flags); - if ( (np->rx_resp_cons != np->rx->resp_prod) && - (np->user_state == UST_OPEN) ) + if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN)) netif_rx_schedule(dev); return IRQ_HANDLED; @@ -542,33 +526,30 @@ static int netif_poll(struct net_device *dev, int *pbudget) spin_lock(&np->rx_lock); - if ( np->backend_state != BEST_CONNECTED ) - { + if (np->backend_state != BEST_CONNECTED) { spin_unlock(&np->rx_lock); return 0; } skb_queue_head_init(&rxq); - if ( (budget = *pbudget) > dev->quota ) + if ((budget = *pbudget) > dev->quota) budget = dev->quota; rp = np->rx->resp_prod; rmb(); /* Ensure we see queued responses up to 'rp'. */ - for ( i = np->rx_resp_cons, work_done = 0; - (i != rp) && (work_done < budget); - i++, work_done++ ) - { + for (i = np->rx_resp_cons, work_done = 0; + (i != rp) && (work_done < budget); + i++, work_done++) { rx = &np->rx->ring[MASK_NETIF_RX_IDX(i)].resp; /* * An error here is very odd. Usually indicates a backend bug, * low-memory condition, or that we didn't have reservation headroom. */ - if ( unlikely(rx->status <= 0) ) - { - if ( net_ratelimit() ) + if (unlikely(rx->status <= 0)) { + if (net_ratelimit()) printk(KERN_WARNING "Bad rx buffer (memory squeeze?).\n"); np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; wmb(); @@ -608,8 +589,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) balloon_update_driver_allowance(-work_done); /* Do all the remapping work, and M->P updates, in one big hypercall. */ - if ( likely((mcl - rx_mcl) != 0) ) - { + if (likely((mcl - rx_mcl) != 0)) { mcl->op = __HYPERVISOR_mmu_update; mcl->args[0] = (unsigned long)rx_mmu; mcl->args[1] = mmu - rx_mmu; @@ -618,33 +598,29 @@ static int netif_poll(struct net_device *dev, int *pbudget) (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); } - while ( (skb = __skb_dequeue(&rxq)) != NULL ) - { + while ((skb = __skb_dequeue(&rxq)) != NULL) { /* * Enough room in skbuff for the data we were passed? Also, Linux * expects at least 16 bytes headroom in each receive buffer. */ - if ( unlikely(skb->tail > skb->end) || - unlikely((skb->data - skb->head) < 16) ) - { + if (unlikely(skb->tail > skb->end) || + unlikely((skb->data - skb->head) < 16)) { nskb = NULL; /* Only copy the packet if it fits in the current MTU. */ - if ( skb->len <= (dev->mtu + ETH_HLEN) ) - { - if ( (skb->tail > skb->end) && net_ratelimit() ) + if (skb->len <= (dev->mtu + ETH_HLEN)) { + if ((skb->tail > skb->end) && net_ratelimit()) printk(KERN_INFO "Received packet needs %d bytes more " "headroom.\n", skb->tail - skb->end); - if ( (nskb = alloc_xen_skb(skb->len + 2)) != NULL ) - { + if ((nskb = alloc_xen_skb(skb->len + 2)) != NULL) { skb_reserve(nskb, 2); skb_put(nskb, skb->len); memcpy(nskb->data, skb->data, skb->len); nskb->dev = skb->dev; } } - else if ( net_ratelimit() ) + else if (net_ratelimit()) printk(KERN_INFO "Received packet too big for MTU " "(%d > %d)\n", skb->len - ETH_HLEN, dev->mtu); @@ -655,7 +631,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) dev_kfree_skb(skb); /* Switch old for new, if we copied the buffer. */ - if ( (skb = nskb) == NULL ) + if ((skb = nskb) == NULL) continue; } @@ -674,8 +650,8 @@ static int netif_poll(struct net_device *dev, int *pbudget) /* If we get a callback with very few responses, reduce fill target. */ /* NB. Note exponential increase, linear decrease. */ - if ( ((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) && - (--np->rx_target < RX_MIN_TARGET) ) + if (((np->rx->req_prod - np->rx->resp_prod) > ((3*np->rx_target) / 4)) && + (--np->rx_target < RX_MIN_TARGET)) np->rx_target = RX_MIN_TARGET; network_alloc_rx_buffers(dev); @@ -683,16 +659,14 @@ static int netif_poll(struct net_device *dev, int *pbudget) *pbudget -= work_done; dev->quota -= work_done; - if ( work_done < budget ) - { + if (work_done < budget) { local_irq_save(flags); np->rx->event = i + 1; /* Deal with hypervisor racing our resetting of rx_event. */ mb(); - if ( np->rx->resp_prod == i ) - { + if (np->rx->resp_prod == i) { __netif_rx_complete(dev); more_to_do = 0; } @@ -755,10 +729,8 @@ static void network_connect(struct net_device *dev, * to avoid this but maybe it doesn't matter so much given the * interface has been down. */ - for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ) - { - if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET ) - { + for (requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++) { + if ((unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET) { struct sk_buff *skb = np->tx_skbs[i]; tx = &np->tx->ring[requeue_idx++].req; @@ -775,8 +747,8 @@ static void network_connect(struct net_device *dev, np->tx->req_prod = requeue_idx; /* Rebuild the RX buffer freelist and the RX ring itself. */ - for ( requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++ ) - if ( (unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET ) + for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) + if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) np->rx->ring[requeue_idx++].req.id = i; wmb(); np->rx->req_prod = requeue_idx; @@ -791,7 +763,7 @@ static void network_connect(struct net_device *dev, notify_via_evtchn(status->evtchn); network_tx_buf_gc(dev); - if ( np->user_state == UST_OPEN ) + if (np->user_state == UST_OPEN) netif_start_queue(dev); spin_unlock(&np->rx_lock); @@ -917,9 +889,7 @@ static void vif_disconnect(struct net_private *np) * is initiated by a special "RESET" message - disconnect could * just mean we're not allowed to use this interface any more. */ -static void -vif_reset( - struct net_private *np) +static void vif_reset(struct net_private *np) { IPRINTK("Attempting to reconnect network interface: handle=%u\n", np->handle); @@ -932,9 +902,8 @@ vif_reset( * Sets the mac and event channel from the message. * Binds the irq to the event channel. */ -static void -vif_connect( - struct net_private *np, netif_fe_interface_status_t *status) +static void +vif_connect(struct net_private *np, netif_fe_interface_status_t *status) { struct net_device *dev = np->dev; memcpy(dev->dev_addr, status->mac, ETH_ALEN); @@ -959,8 +928,7 @@ static int create_netdev(int handle, struct net_device **val) struct net_device *dev = NULL; struct net_private *np = NULL; - if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL ) - { + if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) { printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); err = -ENOMEM; goto exit; @@ -978,9 +946,9 @@ static int create_netdev(int handle, struct net_device **val) np->rx_target = RX_MIN_TARGET; /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ - for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ) + for (i = 0; i <= NETIF_TX_RING_SIZE; i++) np->tx_skbs[i] = (void *)(i+1); - for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ) + for (i = 0; i <= NETIF_RX_RING_SIZE; i++) np->rx_skbs[i] = (void *)(i+1); dev->open = network_open; @@ -990,8 +958,7 @@ static int create_netdev(int handle, struct net_device **val) dev->poll = netif_poll; dev->weight = 64; - if ( (err = register_netdev(dev)) != 0 ) - { + if ((err = register_netdev(dev)) != 0) { printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); goto exit; } @@ -999,9 +966,9 @@ static int create_netdev(int handle, struct net_device **val) list_add(&np->list, &dev_list); exit: - if ( (err != 0) && (dev != NULL ) ) + if ((err != 0) && (dev != NULL )) kfree(dev); - else if ( val != NULL ) + else if (val != NULL) *val = dev; return err; } @@ -1015,36 +982,34 @@ static int create_netdev(int handle, struct net_device **val) * @return 0 on success, error code otherwise */ static int -target_vif( - netif_fe_interface_status_t *status, struct net_private **np) +target_vif(netif_fe_interface_status_t *status, struct net_private **np) { int err = 0; struct net_device *dev; DPRINTK("> handle=%d\n", status->handle); - if ( status->handle < 0 ) - { + if (status->handle < 0) { err = -EINVAL; goto exit; } - if ( (dev = find_dev_by_handle(status->handle)) != NULL ) + if ((dev = find_dev_by_handle(status->handle)) != NULL) goto exit; - if ( status->status == NETIF_INTERFACE_STATUS_CLOSED ) + if (status->status == NETIF_INTERFACE_STATUS_CLOSED) goto exit; - if ( status->status == NETIF_INTERFACE_STATUS_CHANGED ) + if (status->status == NETIF_INTERFACE_STATUS_CHANGED) goto exit; /* It's a new interface in a good state - create it. */ DPRINTK("> create device...\n"); - if ( (err = create_netdev(status->handle, &dev)) != 0 ) + if ((err = create_netdev(status->handle, &dev)) != 0) goto exit; netctrl.interface_n++; exit: - if ( np != NULL ) + if (np != NULL) *np = ((dev && !err) ? netdev_priv(dev) : NULL); DPRINTK("< err=%d\n", err); return err; @@ -1059,23 +1024,19 @@ static void netif_interface_status(netif_fe_interface_status_t *status) DPRINTK("> status=%s handle=%d\n", status_name[status->status], status->handle); - if ( (err = target_vif(status, &np)) != 0 ) - { + if ((err = target_vif(status, &np)) != 0) { WPRINTK("Invalid netif: handle=%u\n", status->handle); return; } - if ( np == NULL ) - { + if (np == NULL) { DPRINTK("> no vif\n"); return; } - switch ( status->status ) - { + switch (status->status) { case NETIF_INTERFACE_STATUS_CLOSED: - switch ( np->backend_state ) - { + switch (np->backend_state) { case BEST_CLOSED: case BEST_DISCONNECTED: case BEST_CONNECTED: @@ -1085,8 +1046,7 @@ static void netif_interface_status(netif_fe_interface_status_t *status) break; case NETIF_INTERFACE_STATUS_DISCONNECTED: - switch ( np->backend_state ) - { + switch (np->backend_state) { case BEST_CLOSED: vif_disconnect(np); break; @@ -1098,8 +1058,7 @@ static void netif_interface_status(netif_fe_interface_status_t *status) break; case NETIF_INTERFACE_STATUS_CONNECTED: - switch ( np->backend_state ) - { + switch (np->backend_state) { case BEST_CLOSED: WPRINTK("Unexpected netif status %s in state %s\n", status_name[status->status], @@ -1141,20 +1100,17 @@ static void netif_driver_status(netif_fe_driver_status_t *status) static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) { - switch ( msg->subtype ) - { + switch (msg->subtype) { case CMSG_NETIF_FE_INTERFACE_STATUS: - if ( msg->length != sizeof(netif_fe_interface_status_t) ) + if (msg->length != sizeof(netif_fe_interface_status_t)) goto error; - netif_interface_status((netif_fe_interface_status_t *) - &msg->msg[0]); + netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]); break; case CMSG_NETIF_FE_DRIVER_STATUS: - if ( msg->length != sizeof(netif_fe_driver_status_t) ) + if (msg->length != sizeof(netif_fe_driver_status_t)) goto error; - netif_driver_status((netif_fe_driver_status_t *) - &msg->msg[0]); + netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]); break; error: @@ -1179,8 +1135,7 @@ static int probe_interfaces(void) DPRINTK(">\n"); - for ( wait_i = 0; wait_i < wait_n; wait_i++) - { + for (wait_i = 0; wait_i < wait_n; wait_i++) { DPRINTK("> wait_i=%d\n", wait_i); conn = netctrl_connected(); if(conn) break; @@ -1190,8 +1145,7 @@ static int probe_interfaces(void) } DPRINTK("> wait finished...\n"); - if ( conn <= 0 ) - { + if (conn <= 0) { err = netctrl_err(-ENETDOWN); WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); } @@ -1223,8 +1177,7 @@ static int probe_interfaces(void) DPRINTK(">\n"); netctrl.interface_n = 0; - for ( wait_i = 0; wait_i < wait_n; wait_i++ ) - { + for (wait_i = 0; wait_i < wait_n; wait_i++) { DPRINTK("> wait_i=%d query=%d\n", wait_i, query); msg.handle = query; memcpy(cmsg.msg, &msg, sizeof(msg)); @@ -1236,7 +1189,7 @@ static int probe_interfaces(void) DPRINTK("> err=%d\n", err); if(err) goto exit; DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); - if((int)reply->handle < 0){ + if((int)reply->handle < 0) { // No more interfaces. break; } @@ -1246,8 +1199,7 @@ static int probe_interfaces(void) } exit: - if ( err ) - { + if (err) { err = netctrl_err(-ENETDOWN); WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err); } @@ -1262,22 +1214,20 @@ static int probe_interfaces(void) * We use this notifier to send out a fake ARP reply to reset switches and * router ARP caches when an IP interface is brought up on a VIF. */ -static int inetdev_notify(struct notifier_block *this, - unsigned long event, - void *ptr) +static int +inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr) { struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; struct net_device *dev = ifa->ifa_dev->dev; struct list_head *ent; struct net_private *np; - if ( event != NETDEV_UP ) + if (event != NETDEV_UP) goto out; - list_for_each ( ent, &dev_list ) - { + list_for_each (ent, &dev_list) { np = list_entry(ent, struct net_private, list); - if ( np->dev == dev ) + if (np->dev == dev) (void)send_fake_arp(dev); } @@ -1295,7 +1245,7 @@ static int __init netif_init(void) { int err = 0; - if ( xen_start_info.flags & SIF_INITDOMAIN ) + if (xen_start_info.flags & SIF_INITDOMAIN) return 0; IPRINTK("Initialising virtual ethernet driver.\n"); @@ -1306,7 +1256,7 @@ static int __init netif_init(void) CALLBACK_IN_BLOCKING_CONTEXT); send_driver_status(1); err = probe_interfaces(); - if ( err ) + if (err) ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); DPRINTK("< err=%d\n", err); @@ -1338,8 +1288,7 @@ void netif_suspend(void) struct list_head *ent; struct net_private *np; - list_for_each ( ent, &dev_list ) - { + list_for_each (ent, &dev_list) { np = list_entry(ent, struct net_private, list); vif_suspend(np); } @@ -1350,8 +1299,7 @@ void netif_resume(void) struct list_head *ent; struct net_private *np; - list_for_each ( ent, &dev_list ) - { + list_for_each (ent, &dev_list) { np = list_entry(ent, struct net_private, list); vif_resume(np); } From 4db4e4f09f85c3905b01c37ad0dc4f1d59ffe2bb Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 10 Feb 2005 17:13:35 +0000 Subject: [PATCH 089/199] bitkeeper revision 1.1159.258.1 (420b963fGDqQqmlp_DO3u-T_klF82g) Fixes to make the vnet module compile under 2.6.10. Thanks to Brian Bruce for spotting the problem and suggesting fixes. Signed-off-by: Mike Wray --- .rootkeys | 1 + tools/vnet/00INSTALL | 31 +++++++++++++++++++++++++++++++ tools/vnet/Makefile | 6 +++--- tools/vnet/vnet-module/if_varp.h | 2 +- tools/vnet/vnet-module/varp.c | 14 +++++++------- 5 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 tools/vnet/00INSTALL diff --git a/.rootkeys b/.rootkeys index a6f49dc24c..f876ba5eec 100644 --- a/.rootkeys +++ b/.rootkeys @@ -555,6 +555,7 @@ 40fcefb3yMSrZvApO9ToIi-iQwnchA tools/sv/images/xen.png 41013a83z27rKvWIxAfUBMVZ1eDCDg tools/sv/inc/script.js 40fcefb3zGC9XNBkSwTEobCoq8YClA tools/sv/inc/style.css +420b963dK3yGNtqxRM8npGZtrCQd1g tools/vnet/00INSTALL 41a21888_WlknVWjSxb32Fo13_ujsw tools/vnet/00README 41a21888bOiOJc7blzRbe4MNJoaYTw tools/vnet/Makefile 41a21888mg2k5HeiVjlQYEtJBZT4Qg tools/vnet/doc/vnet-module.txt diff --git a/tools/vnet/00INSTALL b/tools/vnet/00INSTALL new file mode 100644 index 0000000000..1c76986d83 --- /dev/null +++ b/tools/vnet/00INSTALL @@ -0,0 +1,31 @@ + +To compile and install run "make install"; if it fails or you need to reinstall +run "make clean" first or the build will fail, at least that is what I have +found under 2.6.10. + +Other important items: +1) You will need to have your xen0 kernel compiled with HMAC_SUPPORT + 2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support) + BEFORE running "make install". + +2) You will want at least some of the other alogorithms listed under + "Cryptographic Options" for the kernel compiled as modules. + +3) You will want the networking IPsec/VLAN options compiled in as modules + 2.6.x = (MAIN MENU: Device Drivers -> Networking Support -> + Networking Options -> + IP: AH transformation + IP: ESP transformation + IP: IPComp transformation + IP: tunnel transformation + + IPsec user configuration interface + + 802.1Q VLAN Support + +4) The module (vnet_module) will not properly load from the command line + with a "modprobe vnet_module". Use network-vnet to properly configure + your system and load the module for you. + +Please refer to the additional documentation found in tools/vnet/doc for +proper syntax and config file parameters. diff --git a/tools/vnet/Makefile b/tools/vnet/Makefile index 63939dff9d..76d2abae05 100644 --- a/tools/vnet/Makefile +++ b/tools/vnet/Makefile @@ -20,10 +20,10 @@ gc: gc.tar.gz tar xfz gc.tar.gz ln -sf gc?.? gc -gc/Makefile: - (cd gc && ./configure --prefix=`pwd`/install) +gc/.configure-makefile: + (cd gc && ./configure --prefix=`pwd`/install && touch .configure-makefile) -gc-install: gc gc/Makefile +gc-install: gc gc/.configure-makefile make -C gc make -C gc install diff --git a/tools/vnet/vnet-module/if_varp.h b/tools/vnet/vnet-module/if_varp.h index 49058471db..a9a7438a7e 100644 --- a/tools/vnet/vnet-module/if_varp.h +++ b/tools/vnet/vnet-module/if_varp.h @@ -36,7 +36,7 @@ typedef struct VnetMsgHdr { } __attribute__((packed)) VnetMsgHdr; typedef struct VarpHdr { - VnetMsgHdr; + VnetMsgHdr hdr; uint32_t vnet; Vmac vmac; uint32_t addr; diff --git a/tools/vnet/vnet-module/varp.c b/tools/vnet/vnet-module/varp.c index 3b1507e045..1e44a915b7 100644 --- a/tools/vnet/vnet-module/varp.c +++ b/tools/vnet/vnet-module/varp.c @@ -368,8 +368,8 @@ int varp_send(u16 opcode, struct net_device *dev, struct sk_buff *skbin, // Varp header. varph = (void*)skb_put(skbout, varp_n); *varph = (VarpHdr){}; - varph->id = htons(VARP_ID); - varph->opcode = htons(opcode); + varph->hdr.id = htons(VARP_ID); + varph->hdr.opcode = htons(opcode); varph->vnet = htonl(vnet); varph->vmac = *vmac; varph->addr = saddr; @@ -1076,9 +1076,9 @@ int varp_handle_message(struct sk_buff *skb){ goto exit; } mine = 1; - if(varph->id != htons(VARP_ID)){ + if(varph->hdr.id != htons(VARP_ID)){ // It's not varp at all - ignore it. - wprintf("> Unknown id: %d \n", ntohs(varph->id)); + wprintf("> Unknown id: %d \n", ntohs(varph->hdr.id)); goto exit; } if(1){ @@ -1086,13 +1086,13 @@ int varp_handle_message(struct sk_buff *skb){ NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr)); dprintf("> sport=%u dport=%u\n", ntohs(skb->h.uh->source), ntohs(skb->h.uh->dest)); dprintf("> opcode=%d vnet=%u vmac=" MACFMT " addr=" IPFMT "\n", - ntohs(varph->opcode), + ntohs(varph->hdr.opcode), ntohl(varph->vnet), MAC6TUPLE(varph->vmac.mac), NIPQUAD(varph->addr)); varp_dprint(); } - switch(ntohs(varph->opcode)){ + switch(ntohs(varph->hdr.opcode)){ case VARP_OP_REQUEST: err = varp_handle_request(skb, varph); break; @@ -1100,7 +1100,7 @@ int varp_handle_message(struct sk_buff *skb){ err = varp_handle_announce(skb, varph); break; default: - wprintf("> Unknown opcode: %d \n", ntohs(varph->opcode)); + wprintf("> Unknown opcode: %d \n", ntohs(varph->hdr.opcode)); break; } exit: From a20f62e8f83830438cd81cef224652c86224ed50 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Fri, 11 Feb 2005 16:28:22 +0000 Subject: [PATCH 090/199] bitkeeper revision 1.1159.258.2 (420cdd26biP1GgUIcVSoyZGOZjAu2A) Pass pointer to register set to set_pre_exception_table instead of eip. Signed-off-by: cl349@cl.cam.ac.uk --- xen/arch/x86/extable.c | 3 ++- xen/arch/x86/x86_32/entry.S | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c index d3292027e0..bb70a3842b 100644 --- a/xen/arch/x86/extable.c +++ b/xen/arch/x86/extable.c @@ -63,8 +63,9 @@ search_exception_table(unsigned long addr) } unsigned long -search_pre_exception_table(unsigned long addr) +search_pre_exception_table(struct xen_regs *regs) { + unsigned long addr = (unsigned long)regs->eip; unsigned long fixup = search_one_table( __start___pre_ex_table, __stop___pre_ex_table-1, addr); DPRINTK("Pre-exception: %08lx -> %08lx\n", addr, fixup); diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 1afeded9c9..aaf6caccef 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -379,7 +379,7 @@ exception_with_ints_disabled: testl $(3|X86_EFLAGS_VM),%eax # interrupts disabled outside Xen? jnz 1b # it really does happen! # (e.g., DOM0 X server) - pushl XREGS_eip(%esp) + pushl %esp call search_pre_exception_table addl $4,%esp testl %eax,%eax # no fixup code for faulting EIP? From b9692e52eb582de971810d61fdb1c09787dacd82 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Sat, 12 Feb 2005 01:30:21 +0000 Subject: [PATCH 091/199] bitkeeper revision 1.1159.258.3 (420d5c2dj-e3ZU_Q3wOxYdZ-yax62A) Use "ide" as device name and "hdX" as disk name. Signed-off-by: chris@xensource.com --- .../drivers/xen/blkfront/block.h | 5 +++-- .../drivers/xen/blkfront/vbd.c | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h index 1edebd5e05..9d9bb03db6 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h @@ -5,7 +5,7 @@ * * Copyright (c) 2003-2004, Keir Fraser & Steve Hand * Modifications by Mark A. Williamson are (c) Intel Research Cambridge - * Copyright (c) 2004, Christian Limpach + * Copyright (c) 2004-2005, Christian Limpach * * This file may be distributed separately from the Linux kernel, or * incorporated into other software packages, subject to the following license: @@ -68,7 +68,8 @@ struct xlbd_type_info { int devs_per_major; int hardsect_size; int max_sectors; - char *name; + char *devname; + char *diskname; }; /* diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c index 25bfa59e79..8050e756ca 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c @@ -5,7 +5,7 @@ * * Copyright (c) 2003-2004, Keir Fraser & Steve Hand * Modifications by Mark A. Williamson are (c) Intel Research Cambridge - * Copyright (c) 2004, Christian Limpach + * Copyright (c) 2004-2005, Christian Limpach * * This file may be distributed separately from the Linux kernel, or * incorporated into other software packages, subject to the following license: @@ -49,7 +49,8 @@ static struct xlbd_type_info xlbd_ide_type = { .hardsect_size = 512, .max_sectors = 128, /* 'hwif->rqsize' if we knew it */ // XXXcl todo read_ahead[major] = 8; /* from drivers/ide/ide-probe.c */ - .name = "hd", + .devname = "ide", + .diskname = "hd", }; static struct xlbd_type_info xlbd_scsi_type = { @@ -59,7 +60,8 @@ static struct xlbd_type_info xlbd_scsi_type = { .hardsect_size = 512, .max_sectors = 128*8, /* XXX 128; */ // XXXcl todo read_ahead[major] = 0; /* XXX 8; -- guessing */ - .name = "sd", + .devname = "sd", + .diskname = "sd", }; static struct xlbd_type_info xlbd_vbd_type = { @@ -69,7 +71,8 @@ static struct xlbd_type_info xlbd_vbd_type = { .hardsect_size = 512, .max_sectors = 128, // XXXcl todo read_ahead[major] = 8; - .name = "xvd", + .devname = "xvd", + .diskname = "xvd", }; static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS + @@ -183,13 +186,13 @@ static struct xlbd_major_info *xlbd_get_major_info(int xd_device, int *minor) } major_info[mi_idx]->major = new_major; - if (register_blkdev(major_info[mi_idx]->major, major_info[mi_idx]->type->name)) { + if (register_blkdev(major_info[mi_idx]->major, major_info[mi_idx]->type->devname)) { printk(KERN_ALERT "XL VBD: can't get major %d with name %s\n", - major_info[mi_idx]->major, major_info[mi_idx]->type->name); + major_info[mi_idx]->major, major_info[mi_idx]->type->devname); goto out; } - devfs_mk_dir(major_info[mi_idx]->type->name); + devfs_mk_dir(major_info[mi_idx]->type->devname); return major_info[mi_idx]; @@ -226,7 +229,7 @@ static struct gendisk *xlvbd_get_gendisk(struct xlbd_major_info *mi, gd->first_minor = xd_minor; gd->fops = &xlvbd_block_fops; gd->private_data = di; - sprintf(gd->disk_name, "%s%c%d", mi->type->name, + sprintf(gd->disk_name, "%s%c%d", mi->type->diskname, 'a' + mi->index * mi->type->partn_per_major + (xd_minor >> mi->type->partn_shift), xd_minor & ((1 << mi->type->partn_shift) - 1)); From b5a0388318fa6d23425f64ae0f0779d96dce7295 Mon Sep 17 00:00:00 2001 From: "mafetter@fleming.research" Date: Sat, 12 Feb 2005 13:42:57 +0000 Subject: [PATCH 092/199] bitkeeper revision 1.1159.260.1 (420e07e16YlSevQI9RYNGLwarPr2gQ) Bug fix for shadow code. When update_va_mapping() updates a entry, the corresponding shadow entry may not be reachable via the shadow_linear_pg_table, even though it is currently shadowed, as the corresponding spde has not necessarily been faulted into place yet. --- xen/arch/x86/memory.c | 22 +++++++++++++++++++--- xen/include/xen/perfc_defn.h | 3 ++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 631e5c50c9..3961b37a89 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1573,10 +1573,26 @@ int do_update_va_mapping(unsigned long page_nr, &shadow_linear_pg_table[page_nr])))) ) { /* - * Since L2's are guranteed RW, failure indicates the page was not - * shadowed, so ignore. + * Since L2's are guranteed RW, failure indicates either that the + * page was not shadowed, or that the L2 entry has not yet been + * updated to reflect the shadow. */ - perfc_incrc(shadow_update_va_fail); + unsigned l2_idx = page_nr >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT); + l2_pgentry_t gpde = linear_l2_table[l2_idx]; + unsigned long gpfn = l2_pgentry_val(gpde) >> PAGE_SHIFT; + + if (get_shadow_status(&d->mm, gpfn)) + { + unsigned long *gl1e = map_domain_mem(gpfn << PAGE_SHIFT); + unsigned l1_idx = page_nr & (ENTRIES_PER_L1_PAGETABLE - 1); + gl1e[l1_idx] = sval; + unmap_domain_mem(gl1e); + put_shadow_status(&d->mm); + + perfc_incrc(shadow_update_va_fail1); + } + else + perfc_incrc(shadow_update_va_fail2); } /* diff --git a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h index f6868d78b9..d5dc9436ff 100644 --- a/xen/include/xen/perfc_defn.h +++ b/xen/include/xen/perfc_defn.h @@ -25,7 +25,8 @@ PERFCOUNTER_CPU( shadow_l2_table_count, "shadow_l2_table count" ) PERFCOUNTER_CPU( shadow_l1_table_count, "shadow_l1_table count" ) PERFCOUNTER_CPU( unshadow_table_count, "unshadow_table count" ) PERFCOUNTER_CPU( shadow_fixup_count, "shadow_fixup count" ) -PERFCOUNTER_CPU( shadow_update_va_fail, "shadow_update_va_fail" ) +PERFCOUNTER_CPU( shadow_update_va_fail1, "shadow_update_va_fail1" ) +PERFCOUNTER_CPU( shadow_update_va_fail2, "shadow_update_va_fail2" ) /* STATUS counters do not reset when 'P' is hit */ PERFSTATUS( shadow_l2_pages, "current # shadow L2 pages" ) From 50170099899745d7bfaedc6a25901f2561b46bc1 Mon Sep 17 00:00:00 2001 From: "mafetter@fleming.research" Date: Sat, 12 Feb 2005 13:44:54 +0000 Subject: [PATCH 093/199] bitkeeper revision 1.1159.260.2 (420e0856crqXXEkQoCUddas8u5ksXA) Rename check_pagetable() function to _check_pagetable to make it easier to selectively enable it during debugging. There's still the same check_pagetable macro, but now it's used both when SHADOW_DEBUG is enabled and disabled. --- xen/arch/x86/shadow.c | 2 +- xen/include/asm-x86/shadow.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 41ac65177a..01d67d43ad 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -794,7 +794,7 @@ static int check_l1_table( BUG(); \ } while ( 0 ) -int check_pagetable(struct mm_struct *m, pagetable_t pt, char *s) +int _check_pagetable(struct mm_struct *m, pagetable_t pt, char *s) { unsigned long gptbase = pagetable_val(pt); unsigned long gpfn, spfn; diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 33172926ef..97082e5964 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -573,7 +573,8 @@ static inline void shadow_mk_pagetable(struct mm_struct *mm) } #if SHADOW_DEBUG -extern int check_pagetable(struct mm_struct *m, pagetable_t pt, char *s); +extern int _check_pagetable(struct mm_struct *m, pagetable_t pt, char *s); +#define check_pagetable(m, pt, s) _check_pagetable(m, pt, s) #else #define check_pagetable(m, pt, s) ((void)0) #endif From 94c57a4ed99975a9f9adac521785f8dc8f1d0a95 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Fri, 18 Feb 2005 13:41:48 +0000 Subject: [PATCH 094/199] bitkeeper revision 1.1159.258.5 (4215f09cU1Zrw85yrXJiQPM7LeMJtw) nettel.patch, drm.patch, agpgart.patch: mvdir --- .rootkeys | 6 +++--- patches/{linux-2.6.9 => linux-2.6.10}/agpgart.patch | 0 patches/{linux-2.6.9 => linux-2.6.10}/drm.patch | 0 patches/{linux-2.6.9 => linux-2.6.10}/nettel.patch | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename patches/{linux-2.6.9 => linux-2.6.10}/agpgart.patch (100%) rename patches/{linux-2.6.9 => linux-2.6.10}/drm.patch (100%) rename patches/{linux-2.6.9 => linux-2.6.10}/nettel.patch (100%) diff --git a/.rootkeys b/.rootkeys index f876ba5eec..548d82aed1 100644 --- a/.rootkeys +++ b/.rootkeys @@ -291,9 +291,9 @@ 413cb3b5eKxnzoodEqaWn2wrPnHWnA netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c 413cb3b5F56TvQWAmO5TsuzhtzLFPQ netbsd-2.0-xen-sparse/sys/arch/xen/xen/xenkbc.c 413cb3b53nyOv1OIeDSsCXhBFDXvJA netbsd-2.0-xen-sparse/sys/nfs/files.nfs -413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.9/agpgart.patch -413aa1d0ewvSv-ohnNnQQNGsbPTTNA patches/linux-2.6.9/drm.patch -418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.9/nettel.patch +413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.10/agpgart.patch +413aa1d0ewvSv-ohnNnQQNGsbPTTNA patches/linux-2.6.10/drm.patch +418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.10/nettel.patch 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile 40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Rules.mk 4124b307nRyK3dhn1hAsvrY76NuV3g tools/check/Makefile diff --git a/patches/linux-2.6.9/agpgart.patch b/patches/linux-2.6.10/agpgart.patch similarity index 100% rename from patches/linux-2.6.9/agpgart.patch rename to patches/linux-2.6.10/agpgart.patch diff --git a/patches/linux-2.6.9/drm.patch b/patches/linux-2.6.10/drm.patch similarity index 100% rename from patches/linux-2.6.9/drm.patch rename to patches/linux-2.6.10/drm.patch diff --git a/patches/linux-2.6.9/nettel.patch b/patches/linux-2.6.10/nettel.patch similarity index 100% rename from patches/linux-2.6.9/nettel.patch rename to patches/linux-2.6.10/nettel.patch From 7100bc4659a58189f885b87ff146a5d886738dab Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Mon, 21 Feb 2005 19:13:13 +0000 Subject: [PATCH 095/199] bitkeeper revision 1.1159.258.6 (421a32c9eTLZXetUKq3j83jL31eC5A) Build AGP and DRM modules into linux 2.6-xen0 default kernel. WARNING: Not all of these drivers have been tested, and its possible that previously working X setups will now cause the machine to spontaneously reboot when X starts! If so, please report these problems, and disable the AGP/DRM module that is being used. Signed-off-by: ian.pratt@cl.cam.ac.uk --- .../arch/xen/configs/xen0_defconfig | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig index d41daac521..408113f920 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc3-xen0 -# Sun Dec 26 10:34:29 2004 +# Linux kernel version: 2.6.10-xen0 +# Mon Feb 21 13:46:38 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -13,15 +13,17 @@ CONFIG_NO_IDLE_HZ=y CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y +# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set +# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_WRITABLE_PAGETABLES=y CONFIG_XEN_SCRUB_PAGES=y -CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_X86=y # CONFIG_X86_64 is not set +CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y # # Code maturity level options @@ -48,7 +50,6 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -185,7 +186,6 @@ CONFIG_BINFMT_ELF=y # CONFIG_STANDALONE is not set CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set # # Memory Technology Devices (MTD) @@ -801,8 +801,28 @@ CONFIG_LEGACY_PTY_COUNT=256 # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_ATI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_INTEL_MCH=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +# CONFIG_AGP_EFFICEON is not set +CONFIG_DRM=y +CONFIG_DRM_TDFX=m +# CONFIG_DRM_GAMMA is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m # CONFIG_MWAVE is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HANGCHECK_TIMER is not set From 9c8f91343008a9358c3bc96aa9412f7a12a56834 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 22 Feb 2005 09:36:11 +0000 Subject: [PATCH 096/199] bitkeeper revision 1.1159.258.7 (421afd0bk-TdZ_Jc5UrN-eVwJPdgbw) Remove unnecessary irq enable/disable and flag test from do_upcall(). Signed-off-by: Keir Fraser --- .../arch/xen/kernel/evtchn.c | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c index e5aa5a1b18..22885955c9 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c @@ -92,42 +92,36 @@ void force_evtchn_callback(void) (void)HYPERVISOR_xen_version(0); } +/* NB. Interrupts are disabled on entry. */ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) { unsigned long l1, l2; unsigned int l1i, l2i, port; int irq; - unsigned long flags; shared_info_t *s = HYPERVISOR_shared_info; - local_irq_save(flags); - - while ( s->vcpu_data[0].evtchn_upcall_pending ) + s->vcpu_data[0].evtchn_upcall_pending = 0; + + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + l1 = xchg(&s->evtchn_pending_sel, 0); + while ( l1 != 0 ) { - s->vcpu_data[0].evtchn_upcall_pending = 0; - /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ - l1 = xchg(&s->evtchn_pending_sel, 0); - while ( (l1i = ffs(l1)) != 0 ) - { - l1i--; - l1 &= ~(1 << l1i); + l1i = __ffs(l1); + l1 &= ~(1 << l1i); - l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; - while ( (l2i = ffs(l2)) != 0 ) - { - l2i--; - l2 &= ~(1 << l2i); + l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; + while ( l2 != 0 ) + { + l2i = __ffs(l2); + l2 &= ~(1 << l2i); - port = (l1i << 5) + l2i; - if ( (irq = evtchn_to_irq[port]) != -1 ) - do_IRQ(irq, regs); - else - evtchn_device_upcall(port); - } + port = (l1i << 5) + l2i; + if ( (irq = evtchn_to_irq[port]) != -1 ) + do_IRQ(irq, regs); + else + evtchn_device_upcall(port); } } - - local_irq_restore(flags); } static int find_unbound_irq(void) From 594ca1303769fb8096a0eafdf7b14ef8116d870a Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 22 Feb 2005 23:30:56 +0000 Subject: [PATCH 097/199] bitkeeper revision 1.1159.258.8 (421bc0b0jvILWAafCXfC9uUwrkZb3A) Clean up task-switch path. Now differs more from native code, but it is a critical path. Also fixed a comment and FPU TS setting. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/process.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c index 5eaf9e384c..26dee14c3a 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c @@ -481,11 +481,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); /* - * We clobber FS and GS here so that we avoid a GPF when - * restoring previous task's FS/GS values in Xen when the LDT - * is switched. If we don't do this then we can end up - * erroneously re-flushing the page-update queue when we - * 'execute_multicall_list'. + * We clobber FS and GS here so that we avoid a GPF when restoring + * previous task's FS/GS values in Xen when the LDT is switched. */ __asm__ __volatile__ ( "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs" : : : @@ -501,7 +498,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas * synchronously trapping to Xen. */ if (prev_p->thread_info->status & TS_USEDFPU) { - save_init_fpu(prev_p); + __save_init_fpu(prev_p); /* _not_ save_init_fpu() */ queue_multicall0(__HYPERVISOR_fpu_taskswitch); } @@ -510,12 +507,6 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas * This is load_esp0(tss, next) with a multicall. */ tss->esp0 = next->esp0; - /* This can only happen when SEP is enabled, no need to test - * "SEP"arately */ - if (unlikely(tss->ss1 != next->sysenter_cs)) { - tss->ss1 = next->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, next->sysenter_cs, 0); - } queue_multicall2(__HYPERVISOR_stack_switch, tss->ss0, tss->esp0); /* @@ -549,7 +540,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas /* * Restore %fs and %gs if needed. */ - if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) { + if (unlikely(next->fs | next->gs)) { loadsegment(fs, next->fs); loadsegment(gs, next->gs); } From 71ebe65bbc592ee65306d84ffc1287ad92d10283 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 24 Feb 2005 08:59:56 +0000 Subject: [PATCH 098/199] bitkeeper revision 1.1159.258.9 (421d978cixdcn2ycn94dJci5cqGzjg) Build cleanups. Build dynamic libs as -fPIC always. Signed-off-by: Keir Fraser --- tools/Makefile | 1 + tools/Rules.mk | 9 +++++++++ tools/libxc/Makefile | 16 ---------------- tools/libxutil/Makefile | 16 ---------------- tools/misc/miniterm/Makefile | 3 +++ xen/Makefile | 4 ++-- 6 files changed, 15 insertions(+), 34 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index 907260707b..0140f8baae 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -21,6 +21,7 @@ install: $(MAKE) -C sv install clean: + $(MAKE) -C check clean $(MAKE) -C libxutil clean $(MAKE) -C libxc clean $(MAKE) -C misc clean diff --git a/tools/Rules.mk b/tools/Rules.mk index 2666f43842..eb89b3be05 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -4,6 +4,9 @@ XEN_XC = $(XEN_ROOT)/tools/python/xen/lowlevel/xc XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_LIBXUTIL = $(XEN_ROOT)/tools/libxutil +COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/) +TARGET_ARCH ?= $(COMPILE_ARCH) + ifeq ($(TARGET_ARCH),x86_32) CFLAGS += -m32 -march=i686 LDFLAGS += -m elf_i386 @@ -13,3 +16,9 @@ ifeq ($(TARGET_ARCH),x86_64) CFLAGS += -m64 LDFLAGS += -m elf_x86_64 endif + +%.opic: %.c + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 770b400326..01fd926cf4 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -1,12 +1,4 @@ -ifndef BUILD_PIC_LIBS -ifeq ($(wildcard /etc/debian_version),) -BUILD_PIC_LIBS=n -else -BUILD_PIC_LIBS=y -endif -endif - INSTALL = install INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DATA = $(INSTALL) -m0644 @@ -95,9 +87,6 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging -$(PIC_OBJS): %.opic: %.c - $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< - libxc.a: $(OBJS) $(AR) rc $@ $^ @@ -106,12 +95,7 @@ libxc.so: libxc.so.$(MAJOR) libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR) ln -sf $< $@ -ifeq ($(BUILD_PIC_LIBS),y) libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS) $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz -else -libxc.so.$(MAJOR).$(MINOR): $(LIB_OBJS) - $(CC) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz -endif -include $(DEPS) diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index 595cd97e83..a9be3e3977 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -1,12 +1,4 @@ -ifndef BUILD_PIC_LIBS -ifeq ($(wildcard /etc/debian_version),) -BUILD_PIC_LIBS=n -else -BUILD_PIC_LIBS=y -endif -endif - XEN_ROOT = ../.. INSTALL = install INSTALL_DATA = $(INSTALL) -m0644 @@ -51,22 +43,14 @@ LIB += libxutil.a all: check-for-zlib $(MAKE) $(LIB) -$(PIC_OBJS): %.opic: %.c - $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< - libxutil.so: libxutil.so.$(MAJOR) ln -sf $^ $@ libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) ln -sf $^ $@ -ifeq ($(BUILD_PIC_LIBS),y) libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ -else -libxutil.so.$(MAJOR).$(MINOR): $(LIB_OBJS) - $(CC) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^ -endif libxutil.a: $(LIB_OBJS) $(AR) rc $@ $^ diff --git a/tools/misc/miniterm/Makefile b/tools/misc/miniterm/Makefile index 4051eb61de..a9ae844e84 100644 --- a/tools/misc/miniterm/Makefile +++ b/tools/misc/miniterm/Makefile @@ -14,3 +14,6 @@ install: all clean: $(RM) *.o $(TARGET) *~ + +$(TARGET): $(TARGET).c + $(CC) $(CFLAGS) -o $@ $< diff --git a/xen/Makefile b/xen/Makefile index 57a89ad454..27b5c2e239 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -37,12 +37,12 @@ install: $(TARGET).gz $(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io $(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen -clean: +clean: delete-unfresh-files $(MAKE) -C tools clean $(MAKE) -C common clean $(MAKE) -C drivers clean $(MAKE) -C arch/$(TARGET_ARCH) clean - rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h + rm -f include/asm *.o $(TARGET)* *~ core rm -f include/asm-*/asm-offsets.h rm -f tools/figlet/*.o tools/figlet/figlet From a6cf90656b7903e5586c636c136623b163c18767 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 24 Feb 2005 10:30:14 +0000 Subject: [PATCH 099/199] bitkeeper revision 1.1159.258.10 (421dacb67rVw006uybBjh0HNKVaObw) Make mkelf32 byte-order clean. Signed-off-by: Keir Fraser --- xen/arch/x86/boot/mkelf32.c | 111 +++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/boot/mkelf32.c b/xen/arch/x86/boot/mkelf32.c index 4f32a7c055..3f1f98cc60 100644 --- a/xen/arch/x86/boot/mkelf32.c +++ b/xen/arch/x86/boot/mkelf32.c @@ -107,6 +107,94 @@ static Elf32_Shdr out_shdr[] = { } }; +#define swap16(_v) ((((u16)(_v)>>8)&0xff)|(((u16)(_v)&0xff)<<8)) +#define swap32(_v) (((u32)swap16((u16)(_v))<<16)|(u32)swap16((u32)((_v)>>16))) +#define swap64(_v) (((u64)swap32((u32)(_v))<<32)|(u64)swap32((u32)((_v)>>32))) + +static int big_endian; + +static void endianadjust_ehdr32(Elf32_Ehdr *eh) +{ + if ( !big_endian ) + return; + eh->e_type = swap16(eh->e_type); + eh->e_machine = swap16(eh->e_machine); + eh->e_version = swap32(eh->e_version); + eh->e_entry = swap32(eh->e_entry); + eh->e_phoff = swap32(eh->e_phoff); + eh->e_shoff = swap32(eh->e_shoff); + eh->e_flags = swap32(eh->e_flags); + eh->e_ehsize = swap16(eh->e_ehsize); + eh->e_phentsize = swap16(eh->e_phentsize); + eh->e_phnum = swap16(eh->e_phnum); + eh->e_shentsize = swap16(eh->e_shentsize); + eh->e_shnum = swap16(eh->e_shnum); + eh->e_shstrndx = swap16(eh->e_shstrndx); +} + +static void endianadjust_ehdr64(Elf64_Ehdr *eh) +{ + if ( !big_endian ) + return; + eh->e_type = swap16(eh->e_type); + eh->e_machine = swap16(eh->e_machine); + eh->e_version = swap32(eh->e_version); + eh->e_entry = swap64(eh->e_entry); + eh->e_phoff = swap64(eh->e_phoff); + eh->e_shoff = swap64(eh->e_shoff); + eh->e_flags = swap32(eh->e_flags); + eh->e_ehsize = swap16(eh->e_ehsize); + eh->e_phentsize = swap16(eh->e_phentsize); + eh->e_phnum = swap16(eh->e_phnum); + eh->e_shentsize = swap16(eh->e_shentsize); + eh->e_shnum = swap16(eh->e_shnum); + eh->e_shstrndx = swap16(eh->e_shstrndx); +} + +static void endianadjust_phdr32(Elf32_Phdr *ph) +{ + if ( !big_endian ) + return; + ph->p_type = swap32(ph->p_type); + ph->p_offset = swap32(ph->p_offset); + ph->p_vaddr = swap32(ph->p_vaddr); + ph->p_paddr = swap32(ph->p_paddr); + ph->p_filesz = swap32(ph->p_filesz); + ph->p_memsz = swap32(ph->p_memsz); + ph->p_flags = swap32(ph->p_flags); + ph->p_align = swap32(ph->p_align); +} + +static void endianadjust_phdr64(Elf64_Phdr *ph) +{ + if ( !big_endian ) + return; + ph->p_type = swap32(ph->p_type); + ph->p_flags = swap32(ph->p_flags); + ph->p_offset = swap64(ph->p_offset); + ph->p_vaddr = swap64(ph->p_vaddr); + ph->p_paddr = swap64(ph->p_paddr); + ph->p_filesz = swap64(ph->p_filesz); + ph->p_memsz = swap64(ph->p_memsz); + ph->p_align = swap64(ph->p_align); +} + +static void endianadjust_shdr32(Elf32_Shdr *sh) +{ + if ( !big_endian ) + return; + sh->sh_name = swap32(sh->sh_name); + sh->sh_type = swap32(sh->sh_type); + sh->sh_flags = swap32(sh->sh_flags); + sh->sh_addr = swap32(sh->sh_addr); + sh->sh_offset = swap32(sh->sh_offset); + sh->sh_size = swap32(sh->sh_size); + sh->sh_link = swap32(sh->sh_link); + sh->sh_info = swap32(sh->sh_info); + sh->sh_addralign = swap32(sh->sh_addralign); + sh->sh_entsize = swap32(sh->sh_entsize); +} + static void do_write(int fd, void *data, int len) { int done, left = len; @@ -155,7 +243,7 @@ int main(int argc, char **argv) char *inimage, *outimage; int infd, outfd; char buffer[1024]; - int bytes, todo; + int bytes, todo, i; Elf32_Ehdr in32_ehdr; Elf32_Phdr in32_phdr; @@ -189,6 +277,9 @@ int main(int argc, char **argv) return 1; } + big_endian = (*(u16 *)in32_ehdr.e_ident == ((ELFMAG0 << 8) | ELFMAG1)); + + endianadjust_ehdr32(&in32_ehdr); switch ( in32_ehdr.e_ident[EI_CLASS] ) { case ELFCLASS32: @@ -208,6 +299,7 @@ int main(int argc, char **argv) (void)lseek(infd, in32_ehdr.e_phoff, SEEK_SET); do_read(infd, &in32_phdr, sizeof(in32_phdr)); + endianadjust_phdr32(&in32_phdr); (void)lseek(infd, in32_phdr.p_offset, SEEK_SET); dat_siz = (u32)in32_phdr.p_filesz; @@ -217,6 +309,7 @@ int main(int argc, char **argv) case ELFCLASS64: (void)lseek(infd, 0, SEEK_SET); do_read(infd, &in64_ehdr, sizeof(in64_ehdr)); + endianadjust_ehdr64(&in64_ehdr); if ( in64_ehdr.e_phentsize != sizeof(in64_phdr) ) { @@ -234,6 +327,7 @@ int main(int argc, char **argv) (void)lseek(infd, in64_ehdr.e_phoff, SEEK_SET); do_read(infd, &in64_phdr, sizeof(in64_phdr)); + endianadjust_phdr64(&in64_phdr); (void)lseek(infd, in64_phdr.p_offset, SEEK_SET); dat_siz = (u32)in64_phdr.p_filesz; @@ -271,7 +365,10 @@ int main(int argc, char **argv) return 1; } + endianadjust_ehdr32(&out_ehdr); do_write(outfd, &out_ehdr, sizeof(out_ehdr)); + + endianadjust_phdr32(&out_phdr); do_write(outfd, &out_phdr, sizeof(out_phdr)); if ( (bytes = RAW_OFFSET - sizeof(out_ehdr) - sizeof(out_phdr)) < 0 ) @@ -289,7 +386,10 @@ int main(int argc, char **argv) do_write(outfd, buffer, todo); } + for ( i = 0; i < (sizeof(out_shdr) / sizeof(out_shdr[0])); i++ ) + endianadjust_shdr32(&out_shdr[i]); do_write(outfd, &out_shdr[0], sizeof(out_shdr)); + do_write(outfd, out_shstrtab, sizeof(out_shstrtab)); do_write(outfd, buffer, 4-((sizeof(out_shstrtab)+dat_siz)&3)); @@ -298,3 +398,12 @@ int main(int argc, char **argv) return 0; } + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + */ From 3979c1484a598a2e52322b6223a34ea32906feff Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 24 Feb 2005 11:09:14 +0000 Subject: [PATCH 100/199] bitkeeper revision 1.1159.258.11 (421db5das21KZ5OM9VgBIYQNaZthng) Fix console_use_vt feature that makes VT switchable at run time in Linux. Signed-off-by: Keir Fraser --- linux-2.6.10-xen-sparse/drivers/char/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.10-xen-sparse/drivers/char/tty_io.c b/linux-2.6.10-xen-sparse/drivers/char/tty_io.c index 636083c08a..2df07c8619 100644 --- a/linux-2.6.10-xen-sparse/drivers/char/tty_io.c +++ b/linux-2.6.10-xen-sparse/drivers/char/tty_io.c @@ -1772,7 +1772,7 @@ retry_open: goto got_driver; } #ifdef CONFIG_VT - if (device == MKDEV(TTY_MAJOR,0)) { + if (console_use_vt && (device == MKDEV(TTY_MAJOR,0))) { extern int fg_console; extern struct tty_driver *console_driver; driver = console_driver; From fff03211fe080ed863f8bd73da101e3b75596581 Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Fri, 25 Feb 2005 01:10:33 +0000 Subject: [PATCH 101/199] bitkeeper revision 1.1159.258.12 (421e7b09H0pvxw22WgYUuH1d447Oew) trivial fix --- tools/xfrd/xfrd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/xfrd/xfrd.c b/tools/xfrd/xfrd.c index 136a614aa3..656abc0bc4 100644 --- a/tools/xfrd/xfrd.c +++ b/tools/xfrd/xfrd.c @@ -49,8 +49,7 @@ #include "select.h" #define MODULE_NAME "XFRD" -#define DEBUG 1 -#undef DEBUG + #include "debug.h" /* From 0aeef37025910a47ba71852c59efe1fbc70f06bf Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Fri, 25 Feb 2005 01:18:50 +0000 Subject: [PATCH 102/199] bitkeeper revision 1.1159.258.13 (421e7cfaHXBVrm-2XYB50x2aleoG0A) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Jari Ruusu via Pasi Kärkkäinen [pasik@iki.fi] Small fix to 2.4 blkfront such that the capacity is reported correctly. Does 2.6 need a similar fix? Signed-off-by: ian@xensource.com --- linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c index e5d299ae16..74a43cdd4a 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c +++ b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c @@ -288,7 +288,7 @@ static int xlvbd_init_device(vdisk_t *xd) /* Need to skankily setup 'partition' information */ gd->part[minor].start_sect = 0; gd->part[minor].nr_sects = capacity; - gd->sizes[minor] = capacity; + gd->sizes[minor] = capacity >>(BLOCK_SIZE_BITS-9); gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS; } From 36222d3c275b8a938112ae75e9dc3e4337e686f8 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sat, 26 Feb 2005 18:18:12 +0000 Subject: [PATCH 103/199] bitkeeper revision 1.1159.258.14 (4220bd64Y3CN44gbDCh9mtv5s9QiDA) Fix ballooning where initial allocation is lower than max possible lowmem. Signed-off-by: Keir Fraser --- linux-2.4.29-xen-sparse/arch/xen/mm/init.c | 6 ++++++ linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c | 13 +++++++++++-- xen/arch/x86/domain.c | 3 ++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/mm/init.c b/linux-2.4.29-xen-sparse/arch/xen/mm/init.c index c68e655a06..a2363d0cce 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/mm/init.c +++ b/linux-2.4.29-xen-sparse/arch/xen/mm/init.c @@ -366,6 +366,12 @@ static int __init free_pages_init(void) /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); + /* XEN: init and count low-mem pages outside initial allocation. */ + for (pfn = boot_pfn; pfn < max_low_pfn; pfn++) { + ClearPageReserved(&mem_map[pfn]); + atomic_set(&mem_map[pfn].count, 1); + totalram_pages++; + } reservedpages = 0; for (pfn = 0; pfn < boot_pfn ; pfn++) { diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c index 70287cf453..78abb78eae 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c @@ -177,8 +177,10 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) pte = one_page_table_init(pmd); pte += pte_ofs; - /* XEN: Only map initial RAM allocation. */ - for (; pte_ofs < PTRS_PER_PTE && pfn < max_ram_pfn; pte++, pfn++, pte_ofs++) { + for (; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) { + /* XEN: Only map initial RAM allocation. */ + if (pfn >= max_ram_pfn) + break; if (pte_present(*pte)) continue; if (is_kernel_text(address)) @@ -627,6 +629,7 @@ void __init mem_init(void) int codesize, reservedpages, datasize, initsize; int tmp; int bad_ppro; + unsigned long pfn; #ifndef CONFIG_DISCONTIGMEM if (!mem_map) @@ -655,6 +658,12 @@ void __init mem_init(void) /* this will put all low memory onto the freelists */ totalram_pages += __free_all_bootmem(); + /* XEN: init and count low-mem pages outside initial allocation. */ + for (pfn = xen_start_info.nr_pages; pfn < max_low_pfn; pfn++) { + ClearPageReserved(&mem_map[pfn]); + atomic_set(&mem_map[pfn].count, 1); + totalram_pages++; + } reservedpages = 0; for (tmp = 0; tmp < max_low_pfn; tmp++) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index e4c427d402..21cfdd9515 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -764,6 +764,7 @@ int construct_dom0(struct domain *p, printk("done.\n"); /* Construct a frame-allocation list for the initial domain. */ + p->max_pages = ~0U; for ( mfn = (alloc_start>>PAGE_SHIFT); mfn < (alloc_end>>PAGE_SHIFT); mfn++ ) @@ -773,7 +774,7 @@ int construct_dom0(struct domain *p, page->u.inuse.type_info = 0; page->count_info = PGC_allocated | 1; list_add_tail(&page->list, &p->page_list); - p->tot_pages++; p->max_pages++; + p->tot_pages++; } mpt_alloc = (vpt_start - dsi.v_start) + alloc_start; From 8ed0d261a5ce2c6fea7688cee1d0effcba3128e1 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 26 Feb 2005 18:36:40 +0000 Subject: [PATCH 104/199] bitkeeper revision 1.1159.258.15 (4220c1b89PleMUER22Q6eIRqab93Dg) Typo in 2.6 file. Signed-off-by: Keir Fraser --- linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c index 78abb78eae..1ad543ccc2 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c @@ -661,7 +661,7 @@ void __init mem_init(void) /* XEN: init and count low-mem pages outside initial allocation. */ for (pfn = xen_start_info.nr_pages; pfn < max_low_pfn; pfn++) { ClearPageReserved(&mem_map[pfn]); - atomic_set(&mem_map[pfn].count, 1); + set_page_count(&mem_map[pfn], 1); totalram_pages++; } From 7ac608f74a2bce612ae8a10c633bf677fe8e8e95 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sun, 27 Feb 2005 10:37:32 +0000 Subject: [PATCH 105/199] bitkeeper revision 1.1159.258.16 (4221a2ecsI-7_TFUEYf9_8zVhzHq3Q) Fix 2.4 build, and a small 2.6 bootstrap tweak. Signed-off-by: Keir Fraser --- .rootkeys | 1 - .../include/asm-xen/synch_bitops.h | 83 ------------------- .../include/asm-xen/system.h | 16 ++++ linux-2.4.29-xen-sparse/mkbuildtree | 1 + .../arch/xen/i386/mm/init.c | 4 +- 5 files changed, 18 insertions(+), 87 deletions(-) delete mode 100644 linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h diff --git a/.rootkeys b/.rootkeys index 548d82aed1..5b0c95014a 100644 --- a/.rootkeys +++ b/.rootkeys @@ -107,7 +107,6 @@ 41224663YBCUMX1kVo_HRUtgaHTi7w linux-2.4.29-xen-sparse/include/asm-xen/queues.h 3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.29-xen-sparse/include/asm-xen/segment.h 3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.29-xen-sparse/include/asm-xen/smp.h -4062f7e2PzFOUGT0PaE7A0VprTU3JQ linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h 3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.29-xen-sparse/include/asm-xen/system.h 3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.29-xen-sparse/include/asm-xen/vga.h 40659defgWA92arexpMGn8X3QMDj3w linux-2.4.29-xen-sparse/include/asm-xen/xor.h diff --git a/linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h b/linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h deleted file mode 100644 index 8093de0ac9..0000000000 --- a/linux-2.4.29-xen-sparse/include/asm-xen/synch_bitops.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __XEN_SYNCH_BITOPS_H__ -#define __XEN_SYNCH_BITOPS_H__ - -/* - * Copyright 1992, Linus Torvalds. - * Heavily modified to provide guaranteed strong synchronisation - * when communicating with Xen or other guest OSes running on other CPUs. - */ - -#include - -#define ADDR (*(volatile long *) addr) - -static __inline__ void synch_set_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__ ( - "lock btsl %1,%0" - : "=m" (ADDR) : "Ir" (nr) : "memory" ); -} - -static __inline__ void synch_clear_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__ ( - "lock btrl %1,%0" - : "=m" (ADDR) : "Ir" (nr) : "memory" ); -} - -static __inline__ void synch_change_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__ ( - "lock btcl %1,%0" - : "=m" (ADDR) : "Ir" (nr) : "memory" ); -} - -static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr) -{ - int oldbit; - __asm__ __volatile__ ( - "lock btsl %2,%1\n\tsbbl %0,%0" - : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); - return oldbit; -} - -static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr) -{ - int oldbit; - __asm__ __volatile__ ( - "lock btrl %2,%1\n\tsbbl %0,%0" - : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); - return oldbit; -} - -static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__ ( - "lock btcl %2,%1\n\tsbbl %0,%0" - : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); - return oldbit; -} - -static __inline__ int synch_const_test_bit(int nr, const volatile void * addr) -{ - return ((1UL << (nr & 31)) & - (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static __inline__ int synch_var_test_bit(int nr, volatile void * addr) -{ - int oldbit; - __asm__ __volatile__ ( - "btl %2,%1\n\tsbbl %0,%0" - : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) ); - return oldbit; -} - -#define synch_test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - synch_const_test_bit((nr),(addr)) : \ - synch_var_test_bit((nr),(addr))) - -#endif /* __XEN_SYNCH_BITOPS_H__ */ diff --git a/linux-2.4.29-xen-sparse/include/asm-xen/system.h b/linux-2.4.29-xen-sparse/include/asm-xen/system.h index 9be6e291fe..fda33efd3a 100644 --- a/linux-2.4.29-xen-sparse/include/asm-xen/system.h +++ b/linux-2.4.29-xen-sparse/include/asm-xen/system.h @@ -113,6 +113,22 @@ static inline unsigned long _get_base(char * addr) #endif /* __KERNEL__ */ +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + * + * Taken from 2.6 for Xen. + */ +static inline unsigned long __ffs(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"rm" (word)); + return word; +} + static inline unsigned long get_limit(unsigned long segment) { unsigned long __limit; diff --git a/linux-2.4.29-xen-sparse/mkbuildtree b/linux-2.4.29-xen-sparse/mkbuildtree index d586153418..f72b2cd7b1 100755 --- a/linux-2.4.29-xen-sparse/mkbuildtree +++ b/linux-2.4.29-xen-sparse/mkbuildtree @@ -211,6 +211,7 @@ ln -sf ../../${LINUX_26}/include/asm-xen/gnttab.h ln -sf ../../${LINUX_26}/include/asm-xen/hypervisor.h ln -sf ../../${LINUX_26}/include/asm-xen/multicall.h ln -sf ../../${LINUX_26}/include/asm-xen/xen_proc.h +ln -sf ../../${LINUX_26}/include/asm-xen/asm-i386/synch_bitops.h mkdir -p linux-public && cd linux-public ln -sf ../../../${LINUX_26}/include/asm-xen/linux-public/privcmd.h diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c index 1ad543ccc2..08d4f0c0ce 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c @@ -179,9 +179,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) pte += pte_ofs; for (; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) { /* XEN: Only map initial RAM allocation. */ - if (pfn >= max_ram_pfn) - break; - if (pte_present(*pte)) + if ((pfn >= max_ram_pfn) || pte_present(*pte)) continue; if (is_kernel_text(address)) set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); From 126860c4eefb0ba87bec4d0437e65a81ddf93a18 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 1 Mar 2005 17:40:10 +0000 Subject: [PATCH 106/199] bitkeeper revision 1.1159.258.17 (4224a8faTVrzHrdNP0aTwjJrfZ4vnw) Fix another -Wall -Werror compile error. Signed-off-by: Rik van Riel Signed-off-by: Keir Fraser --- tools/libxutil/sxpr_parser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/libxutil/sxpr_parser.c b/tools/libxutil/sxpr_parser.c index 472088936d..d32ef959b3 100644 --- a/tools/libxutil/sxpr_parser.c +++ b/tools/libxutil/sxpr_parser.c @@ -43,6 +43,7 @@ */ #define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args) +#undef printf #define printf(fmt, args...) IOStream_print(iostdout, fmt, ##args) static void reset(Parser *z); From 7554eb1321a25e9db13a381cf52a5a8842e1a350 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Thu, 3 Mar 2005 11:43:19 +0000 Subject: [PATCH 107/199] bitkeeper revision 1.1159.258.18 (4226f857ltmzeYRsvtnlD8t5FVTvhw) Remove support for tgif as a tool. We don't use it and it's hard to find as and rpm. Signed-off-by: cl349@cl.cam.ac.uk --- BitKeeper/etc/logging_ok | 1 + docs/Makefile | 7 +------ docs/check_pkgs | 1 - docs/src/user.tex | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index f2a27dc63d..44556798fe 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -11,6 +11,7 @@ br260@labyrinth.cl.cam.ac.uk br260@laudney.cl.cam.ac.uk bren@anvil.research cl349@arcadians.cl.cam.ac.uk +cl349@firebug.cl.cam.ac.uk cl349@freefall.cl.cam.ac.uk cl349@labyrinth.cl.cam.ac.uk cwc22@centipede.cl.cam.ac.uk diff --git a/docs/Makefile b/docs/Makefile index d9ae6715ac..e05a84fad4 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -7,7 +7,6 @@ PS2PDF := ps2pdf DVIPS := dvips LATEX := latex FIG2DEV := fig2dev -TGIF := tgif LATEX2HTML := latex2html pkgdocdir := /usr/share/doc/xen @@ -17,8 +16,7 @@ DOC_PS := $(patsubst src/%.tex,ps/%.ps,$(DOC_TEX)) DOC_PDF := $(patsubst src/%.tex,pdf/%.pdf,$(DOC_TEX)) DOC_HTML := $(patsubst src/%.tex,html/%/index.html,$(DOC_TEX)) -GFX = $(patsubst %.obj, %.eps, $(wildcard figs/*.obj)) -GFX += $(patsubst %.fig, %.eps, $(wildcard figs/*.fig)) +GFX = $(patsubst %.fig, %.eps, $(wildcard figs/*.fig)) all: ps pdf html rm -f *.aux *.dvi *.bbl *.blg *.glo *.idx *.ilg *.log *.ind *.toc @@ -58,9 +56,6 @@ ps/%.ps: %.dvi %.eps: %.fig $(FIG2DEV) -L eps $< $@ -%.eps: %.obj - $(TGIF) -print -color -eps $< - html/%/index.html: src/%.tex $(INSTALL_DIR) $(@D) $(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \ diff --git a/docs/check_pkgs b/docs/check_pkgs index f3770cca66..e705720458 100644 --- a/docs/check_pkgs +++ b/docs/check_pkgs @@ -17,6 +17,5 @@ silent_which latex2html || exit 1 silent_which dvips || exit 1 silent_which ps2pdf || exit 1 silent_which fig2dev || exit 1 -silent_which tgif || exit 1 exit 0 diff --git a/docs/src/user.tex b/docs/src/user.tex index a50300327c..0e2c040ed6 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -229,7 +229,7 @@ tree. \item [$*$] Development installation of libcurl (e.g., libcurl-devel) \item [$*$] Development installation of zlib (e.g., zlib-dev). \item [$*$] Development installation of Python v2.2 or later (e.g., python-dev). -\item [$*$] \LaTeX, transfig and tgif are required to build the documentation. +\item [$*$] \LaTeX and transfig are required to build the documentation. \end{itemize} Once you have satisfied the relevant prerequisites, you can From 52da82dbd60e024458d4c345692577efb6e8a8a3 Mon Sep 17 00:00:00 2001 From: "rminnich@lanl.gov[iap10]" Date: Thu, 3 Mar 2005 16:07:46 +0000 Subject: [PATCH 108/199] bitkeeper revision 1.1159.258.19 (42273652yPWGOWH6C8w45TOchk7Jog) This patch enables argument passing to plan 9 domains, so that users can now have parameters for things like Venti etc. Signed-off-by: ron minnich Signed-off-by: ian.pratt@cl.cam.ac.uk --- BitKeeper/etc/logging_ok | 1 + tools/libxc/xc_plan9_build.c | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 44556798fe..d1c20d6e5f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -46,6 +46,7 @@ mwilli2@equilibrium.research.intel-research.net mwilli2@pug.(none) rac61@labyrinth.cl.cam.ac.uk rgr22@boulderdash.cl.cam.ac.uk +rminnich@lanl.gov rn@wyvis.camb.intel-research.net rn@wyvis.research.intel-research.net rneugeba@wyvis.research diff --git a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c index 33c9a54914..fc67a293ea 100755 --- a/tools/libxc/xc_plan9_build.c +++ b/tools/libxc/xc_plan9_build.c @@ -125,7 +125,8 @@ static int unsigned long tot_pages, unsigned long *virt_load_addr, unsigned long *ksize, unsigned long *symtab_addr, unsigned long *symtab_len, - unsigned long *first_data_page, unsigned long *pdb_page); + unsigned long *first_data_page, unsigned long *pdb_page, + const char *cmdline); #define P9ROUND (P9SIZE / 8) @@ -230,7 +231,7 @@ setup_guestos(int xc_handle, if (loadp9image(kernel_gfd, xc_handle, dom, cpage_array, tot_pages, virt_load_addr, &ksize, &symtab_addr, &symtab_len, - &first_data_page, &first_page_after_kernel)) + &first_data_page, &first_page_after_kernel, cmdline)) goto error_out; DPRINTF(("First data page is 0x%lx\n", first_data_page)); DPRINTF(("First page after kernel is 0x%lx\n", @@ -623,7 +624,7 @@ xc_plan9_build(int xc_handle, * Plan 9 memory layout (initial) * ---------------- * | info from xen| @0 - * ---------------- + * ---------------|<--- boot args (start at 0x1200 + 64) * | stack | * ----------------<--- page 2 * | empty | @@ -658,7 +659,8 @@ loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, unsigned long tot_pages, unsigned long *virt_load_addr, unsigned long *ksize, unsigned long *symtab_addr, unsigned long *symtab_len, - unsigned long *first_data_page, unsigned long *pdb_page) + unsigned long *first_data_page, unsigned long *pdb_page, + const char *cmdline) { unsigned long datapage; Exec ehdr; @@ -669,6 +671,7 @@ loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, PAGE *image = 0; unsigned long image_tot_pages = 0; unsigned long textround; + static PAGE args; ret = -1; @@ -736,6 +739,16 @@ loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, image, image_tot_pages * 4096, page_array, 0x100); DPRINTF(("done copying kernel to guest memory\n")); + /* now do the bootargs */ + /* in plan 9, the x=y bootargs start at 0x1200 + 64 in real memory */ + /* we'll copy to page 1, so we offset into the page struct at + * 0x200 + 64 + */ + memset(&args, 0, sizeof(args)); + memcpy(&args.data[0x200 + 64], cmdline, strlen(cmdline)); + printf("Copied :%s: to page for args\n", cmdline); + ret = memcpy_toguest(xc_handle, dom, &args, sizeof(args), page_array,1); + dumpit(xc_handle, dom, 0 /*0x100000>>12*/, 4, page_array) ; out: if (image) free(image); From 60f2a76e4aa8b8de9617e6739de599f555d8f8ef Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Thu, 3 Mar 2005 21:13:57 +0000 Subject: [PATCH 109/199] bitkeeper revision 1.1159.258.20 (42277e15JmrB3LkX2vA4MklHkX1hQA) Fix build Signed-off-by: ian@xensource.com --- tools/libxc/xc_plan9_build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c index fc67a293ea..3655a26f3e 100755 --- a/tools/libxc/xc_plan9_build.c +++ b/tools/libxc/xc_plan9_build.c @@ -748,7 +748,7 @@ loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, memcpy(&args.data[0x200 + 64], cmdline, strlen(cmdline)); printf("Copied :%s: to page for args\n", cmdline); ret = memcpy_toguest(xc_handle, dom, &args, sizeof(args), page_array,1); - dumpit(xc_handle, dom, 0 /*0x100000>>12*/, 4, page_array) ; + //dumpit(xc_handle, dom, 0 /*0x100000>>12*/, 4, page_array) ; out: if (image) free(image); From b819ef725ed198331dd24a4f95d8f9ddb7061014 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 4 Mar 2005 00:57:22 +0000 Subject: [PATCH 110/199] bitkeeper revision 1.1159.258.21 (4227b272juDzo6xMj-KE4nB4e0xsmA) xmexample updates. Signed-off-by: chris@xensource.com --- tools/examples/xmexample1 | 4 ++-- tools/examples/xmexample2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/examples/xmexample1 b/tools/examples/xmexample1 index cdf4b6c824..0fe27fbef6 100644 --- a/tools/examples/xmexample1 +++ b/tools/examples/xmexample1 @@ -8,7 +8,7 @@ #---------------------------------------------------------------------------- # Kernel image file. -kernel = "/boot/vmlinuz-2.6.9-xenU" +kernel = "/boot/vmlinuz-2.6.10-xenU" # Optional ramdisk. #ramdisk = "/boot/initrd.gz" @@ -42,7 +42,7 @@ name = "ExampleDomain" # where UNAME is the device, DEV is the device name the domain will see, # and MODE is r for read-only, w for read-write. -disk = [ 'phy:hda1,hda1,r' ] +disk = [ 'phy:hda1,hda1,w' ] #---------------------------------------------------------------------------- # Set the kernel command line for the new domain. diff --git a/tools/examples/xmexample2 b/tools/examples/xmexample2 index 61479ca5f0..1d4084ddc1 100644 --- a/tools/examples/xmexample2 +++ b/tools/examples/xmexample2 @@ -36,7 +36,7 @@ xm_vars.check() #---------------------------------------------------------------------------- # Kernel image file. -kernel = "/boot/vmlinuz-2.6.9-xenU" +kernel = "/boot/vmlinuz-2.6.10-xenU" # Optional ramdisk. #ramdisk = "/boot/initrd.gz" From b7c8087832883f882029465053493f232cfcb0cc Mon Sep 17 00:00:00 2001 From: "vh249@airwolf.cl.cam.ac.uk" Date: Mon, 7 Mar 2005 14:32:50 +0000 Subject: [PATCH 111/199] bitkeeper revision 1.1159.258.22 (422c6612riGtD5GGqVTNqhuli2WrwQ) fix spinlock still held while leaving function in case of error Signed-off-by: Vincent Hanquez --- BitKeeper/etc/logging_ok | 1 + linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index d1c20d6e5f..935727fd0b 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -63,4 +63,5 @@ tlh20@elite.cl.cam.ac.uk tlh20@labyrinth.cl.cam.ac.uk tw275@labyrinth.cl.cam.ac.uk tw275@striker.cl.cam.ac.uk +vh249@airwolf.cl.cam.ac.uk xenbk@gandalf.hpl.hp.com diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c index efd4663bcc..6d675b449a 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -354,22 +354,25 @@ int __direct_remap_area_pages(struct mm_struct *mm, { pgd_t * dir; unsigned long end = address + size; + int error; dir = pgd_offset(mm, address); if (address >= end) BUG(); spin_lock(&mm->page_table_lock); do { + error = -ENOMEM; pmd_t *pmd = pmd_alloc(mm, dir, address); if (!pmd) - return -ENOMEM; + break; + error = 0; direct_remap_area_pmd(mm, pmd, address, end - address, &v); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); spin_unlock(&mm->page_table_lock); - return 0; + return error; } From 39b6d495a8198d758004156c7f5933d84286bb45 Mon Sep 17 00:00:00 2001 From: "vh249@airwolf.cl.cam.ac.uk" Date: Tue, 8 Mar 2005 09:39:04 +0000 Subject: [PATCH 112/199] bitkeeper revision 1.1159.258.23 (422d72b8gvbXrWsyznqgyF7shPiduw) Fix error path handling not calling iounmap() after ioremap() Signed-off-by: Yann Droneaud Signed-off-by: Vincent Hanquez --- .../arch/xen/kernel/devmem.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c b/linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c index ffda098851..456091775b 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c @@ -43,7 +43,7 @@ static ssize_t read_mem(struct file * file, char __user * buf, size_t count, loff_t *ppos) { unsigned long i, p = *ppos; - ssize_t read = 0; + ssize_t read = -EFAULT; void *v; if ((v = ioremap(p, count)) == NULL) { @@ -60,12 +60,12 @@ static ssize_t read_mem(struct file * file, char __user * buf, return count; } if (copy_to_user(buf, v, count)) - return -EFAULT; - iounmap(v); + goto out; - read += count; + read = count; *ppos += read; - +out: + iounmap(v); return read; } @@ -73,18 +73,18 @@ static ssize_t write_mem(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - ssize_t written = 0; + ssize_t written = -EFAULT; void *v; if ((v = ioremap(p, count)) == NULL) return -EFAULT; if (copy_to_user(v, buf, count)) - return -EFAULT; - iounmap(v); + goto out; - written += count; + written = count; *ppos += written; - +out: + iounmap(v); return written; } From b2cc8f556c6982c55ea38fb0dfa3eb2249d5b95b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 8 Mar 2005 09:55:15 +0000 Subject: [PATCH 113/199] bitkeeper revision 1.1159.264.1 (422d7683GAA5eJb-zpm3NsgvYf9Q9A) Clean up timer upcalls to guest kernel. Only send an upcall when timestamp info actually changes. Signed-off-by: Keir Fraser --- BitKeeper/etc/logging_ok | 1 + xen/arch/x86/domain.c | 3 --- xen/arch/x86/time.c | 16 ++++++++++++++-- xen/common/domain.c | 3 --- xen/common/schedule.c | 18 +++++------------- xen/include/xen/sched.h | 3 +++ xen/include/xen/time.h | 3 ++- 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 935727fd0b..d54268186e 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -27,6 +27,7 @@ iap10@tetris.cl.cam.ac.uk jws22@gauntlet.cl.cam.ac.uk jws@cairnwell.research kaf24@camelot.eng.3leafnetworks.com +kaf24@firebug.cl.cam.ac.uk kaf24@freefall.cl.cam.ac.uk kaf24@labyrinth.cl.cam.ac.uk kaf24@penguin.local diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 21cfdd9515..9c81c9c718 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -869,9 +869,6 @@ int construct_dom0(struct domain *p, l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab); } - /* Set up shared-info area. */ - update_dom_time(p->shared_info); - p->shared_info->domain_time = 0; /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) p->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index be9f477ba5..685160cd14 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -14,7 +14,9 @@ * Copyright (C) 1991, 1992, 1995 Linus Torvalds */ +#include #include +#include #include #include #include @@ -274,12 +276,18 @@ s_time_t get_s_time(void) } -void update_dom_time(shared_info_t *si) +void update_dom_time(struct domain *d) { + shared_info_t *si = d->shared_info; unsigned long flags; + if ( d->last_propagated_timestamp == full_tsc_irq ) + return; + read_lock_irqsave(&time_lock, flags); + d->last_propagated_timestamp = full_tsc_irq; + si->time_version1++; wmb(); @@ -293,6 +301,8 @@ void update_dom_time(shared_info_t *si) si->time_version2++; read_unlock_irqrestore(&time_lock, flags); + + send_guest_virq(d, VIRQ_TIMER); } @@ -318,7 +328,9 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base) write_unlock_irq(&time_lock); - update_dom_time(current->shared_info); + /* Others will pick up the change at the next tick. */ + current->last_propagated_timestamp = 0; /* force propagation */ + update_dom_time(current); } diff --git a/xen/common/domain.c b/xen/common/domain.c index c2fe184267..47673b21ec 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -267,9 +267,6 @@ int final_setup_guestos(struct domain *p, dom0_builddomain_t *builddomain) if ( (rc = arch_final_setup_guestos(p,c)) != 0 ) goto out; - /* Set up the shared info structure. */ - update_dom_time(p->shared_info); - set_bit(DF_CONSTRUCTED, &p->flags); out: diff --git a/xen/common/schedule.c b/xen/common/schedule.c index ec215d5ed9..09c3e77ad9 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -358,10 +358,6 @@ void __enter_scheduler(void) spin_unlock_irq(&schedule_data[cpu].schedule_lock); - /* Ensure that the domain has an up-to-date time base. */ - if ( !is_idle_task(next) ) - update_dom_time(next->shared_info); - if ( unlikely(prev == next) ) return; @@ -399,10 +395,10 @@ void __enter_scheduler(void) */ clear_bit(DF_RUNNING, &prev->flags); - /* Mark a timer event for the newly-scheduled domain. */ + /* Ensure that the domain has an up-to-date time base. */ if ( !is_idle_task(next) ) - send_guest_virq(next, VIRQ_TIMER); - + update_dom_time(next); + schedule_tail(next); BUG(); @@ -439,10 +435,7 @@ static void t_timer_fn(unsigned long unused) TRACE_0D(TRC_SCHED_T_TIMER_FN); if ( !is_idle_task(d) ) - { - update_dom_time(d->shared_info); - send_guest_virq(d, VIRQ_TIMER); - } + update_dom_time(d); t_timer[d->processor].expires = NOW() + MILLISECS(10); add_ac_timer(&t_timer[d->processor]); @@ -453,8 +446,7 @@ static void dom_timer_fn(unsigned long data) { struct domain *d = (struct domain *)data; TRACE_0D(TRC_SCHED_DOM_TIMER_FN); - update_dom_time(d->shared_info); - send_guest_virq(d, VIRQ_TIMER); + update_dom_time(d); } /* Initialise the data structures. */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index d7e6f0be26..254169cd9f 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -102,6 +102,9 @@ struct domain u16 virq_to_evtchn[NR_VIRQS]; u32 pirq_mask[NR_PIRQS/32]; + /* Last point at which timestamp info was propagated to the guest. */ + u64 last_propagated_timestamp; + /* Physical I/O */ spinlock_t pcidev_lock; struct list_head pcidev_list; diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h index dd476f9298..e725c4ed94 100644 --- a/xen/include/xen/time.h +++ b/xen/include/xen/time.h @@ -52,7 +52,8 @@ s_time_t get_s_time(void); #define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000ULL ) #define MICROSECS(_us) (((s_time_t)(_us)) * 1000ULL ) -extern void update_dom_time(shared_info_t *si); +struct domain; +extern void update_dom_time(struct domain *d); extern void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base); From 8ea68d85e3bd918189fb8c91f0da49ef1921fa96 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 8 Mar 2005 13:40:59 +0000 Subject: [PATCH 114/199] bitkeeper revision 1.1159.258.25 (422dab6bOBL6I9LRZYfF0ExfT5VXww) Must always send VIRQ_TIMER to a blocked guest. Signed-off-by: Keir Fraser --- xen/arch/x86/time.c | 9 +++++---- xen/common/schedule.c | 11 ++++++----- xen/include/xen/time.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 685160cd14..06b0acf44a 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -276,13 +276,13 @@ s_time_t get_s_time(void) } -void update_dom_time(struct domain *d) +int update_dom_time(struct domain *d) { shared_info_t *si = d->shared_info; unsigned long flags; if ( d->last_propagated_timestamp == full_tsc_irq ) - return; + return 0; read_lock_irqsave(&time_lock, flags); @@ -302,7 +302,7 @@ void update_dom_time(struct domain *d) read_unlock_irqrestore(&time_lock, flags); - send_guest_virq(d, VIRQ_TIMER); + return 1; } @@ -330,7 +330,8 @@ void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base) /* Others will pick up the change at the next tick. */ current->last_propagated_timestamp = 0; /* force propagation */ - update_dom_time(current); + (void)update_dom_time(current); + send_guest_virq(current, VIRQ_TIMER); } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 09c3e77ad9..62f764e9d9 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -396,8 +396,8 @@ void __enter_scheduler(void) clear_bit(DF_RUNNING, &prev->flags); /* Ensure that the domain has an up-to-date time base. */ - if ( !is_idle_task(next) ) - update_dom_time(next); + if ( !is_idle_task(next) && update_dom_time(next) ) + send_guest_virq(next, VIRQ_TIMER); schedule_tail(next); @@ -434,8 +434,8 @@ static void t_timer_fn(unsigned long unused) TRACE_0D(TRC_SCHED_T_TIMER_FN); - if ( !is_idle_task(d) ) - update_dom_time(d); + if ( !is_idle_task(d) && update_dom_time(d) ) + send_guest_virq(d, VIRQ_TIMER); t_timer[d->processor].expires = NOW() + MILLISECS(10); add_ac_timer(&t_timer[d->processor]); @@ -446,7 +446,8 @@ static void dom_timer_fn(unsigned long data) { struct domain *d = (struct domain *)data; TRACE_0D(TRC_SCHED_DOM_TIMER_FN); - update_dom_time(d); + (void)update_dom_time(d); + send_guest_virq(d, VIRQ_TIMER); } /* Initialise the data structures. */ diff --git a/xen/include/xen/time.h b/xen/include/xen/time.h index e725c4ed94..4df2e96a55 100644 --- a/xen/include/xen/time.h +++ b/xen/include/xen/time.h @@ -53,7 +53,7 @@ s_time_t get_s_time(void); #define MICROSECS(_us) (((s_time_t)(_us)) * 1000ULL ) struct domain; -extern void update_dom_time(struct domain *d); +extern int update_dom_time(struct domain *d); extern void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base); From 8d8131c3cee9eb08d5192752c235bc331a415a01 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 8 Mar 2005 15:57:54 +0000 Subject: [PATCH 115/199] bitkeeper revision 1.1159.258.26 (422dcb82edKYqnLB0fr24Sf5anyo6Q) Fix parallel build in Xen directory. Signed-off-by: Keir Fraser --- xen/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/Makefile b/xen/Makefile index 27b5c2e239..04ce606de5 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -46,7 +46,8 @@ clean: delete-unfresh-files rm -f include/asm-*/asm-offsets.h rm -f tools/figlet/*.o tools/figlet/figlet -$(TARGET): delete-unfresh-files include/xen/compile.h +$(TARGET): delete-unfresh-files + $(MAKE) include/xen/compile.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm $(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s $(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h From b7630c6aab52b171cb351bcace9d14d669515f42 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 8 Mar 2005 17:11:49 +0000 Subject: [PATCH 116/199] bitkeeper revision 1.1159.258.27 (422ddcd5Cf-97FdGP6TJyFvIxer4Mg) Prevent buddy-allocator merges across Xen/Domain zones boundary. Signed-off-by: Keir Fraser --- xen/common/page_alloc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 1790e3520d..d8ac2d4ca0 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -392,6 +392,13 @@ void init_xenheap_pages(unsigned long ps, unsigned long pe) memguard_guard_range(__va(ps), pe - ps); + /* + * Yuk! Ensure there is a one-page buffer between Xen and Dom zones, to + * prevent merging of power-of-two blocks across the zone boundary. + */ + if ( !IS_XEN_HEAP_FRAME(phys_to_page(pe)) ) + pe -= PAGE_SIZE; + local_irq_save(flags); init_heap_pages(MEMZONE_XEN, phys_to_page(ps), (pe - ps) >> PAGE_SHIFT); local_irq_restore(flags); From 26c56cda54c09ff55ef4eabb1c47da66bffbabf5 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 00:27:17 +0000 Subject: [PATCH 117/199] bitkeeper revision 1.1159.258.28 (422e42e5yWRuW_i02udqDbLjol4GOQ) Support compiling kernels other than the XEN one. Signed-off-by: Christian Limpach --- netbsd-2.0-xen-sparse/Makefile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/netbsd-2.0-xen-sparse/Makefile b/netbsd-2.0-xen-sparse/Makefile index da82172aad..144d189364 100644 --- a/netbsd-2.0-xen-sparse/Makefile +++ b/netbsd-2.0-xen-sparse/Makefile @@ -7,18 +7,19 @@ TOPDIR ?= $(shell pwd) NETBSD_RELEASE ?= $(patsubst netbsd-%-xen%,%,$(notdir $(TOPDIR))) NETBSD_VER ?= $(patsubst netbsd-%-xen%,%,$(notdir $(TOPDIR))) +NETBSD_KERNEL ?= XEN clean: - @mkdir -p compile/XEN - cd compile/XEN && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbmake-xen cleandir + @mkdir -p compile/$(NETBSD_KERNEL) + cd compile/$(NETBSD_KERNEL) && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbmake-xen cleandir config: - @mkdir -p compile/XEN - cd compile/XEN && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbconfig-xen XEN + @mkdir -p compile/$(NETBSD_KERNEL) + cd compile/$(NETBSD_KERNEL) && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbconfig-xen $(NETBSD_KERNEL) netbsd: - cd compile/XEN && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbmake-xen dependall + cd compile/$(NETBSD_KERNEL) && TOPDIR=$(TOPDIR) NETBSD_VER=$(NETBSD_VER) ../../nbmake-xen dependall install: @mkdir -p $(dir $(INSTALL_PATH)/$(INSTALL_NAME)) - install -c compile/XEN/netbsd $(INSTALL_PATH)/$(INSTALL_NAME) + install -c compile/$(NETBSD_KERNEL)/netbsd $(INSTALL_PATH)/$(INSTALL_NAME) From 9c9ae3ef3e5238fad3c17a98574c35fe433ca5ad Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 00:29:54 +0000 Subject: [PATCH 118/199] bitkeeper revision 1.1159.258.29 (422e4382uaLzLWWGJwNl_pq0d8dMog) Support Xen-ifying a complete NetBSD source tree. Signed-off-by: Christian Limpach --- netbsd-2.0-xen-sparse/mkbuildtree | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/netbsd-2.0-xen-sparse/mkbuildtree b/netbsd-2.0-xen-sparse/mkbuildtree index 0d5330d115..ef85a8922a 100755 --- a/netbsd-2.0-xen-sparse/mkbuildtree +++ b/netbsd-2.0-xen-sparse/mkbuildtree @@ -85,6 +85,9 @@ popd >/dev/null # Get absolute path to the source directory AS=`pwd` +# Get name of sparse directory +SDN=$(basename $AS) + # Get path to source, relative to destination abs_to_rel ${AD} ${AS} RS=$DESTPATH @@ -96,12 +99,23 @@ for i in `find . -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done cd ${AD} # Remove old symlinks -for i in `find . -type l`; do rm -f $i; done - -# Create symlinks of files and directories which exist in the sparse source -relative_lndir ${RS} -rm -f mkbuildtree +find sys -type l | while read f +do + case $(readlink $f) in + */$SDN/*) + rm -f $f + ;; + esac +done +if [ -f ${AD}/BUILDING ]; then + # Create symlinks of files and directories which exist in the sparse source + (cd sys && relative_lndir ../${RS}/sys) +else + # Create symlinks of files and directories which exist in the sparse source + relative_lndir ${RS} + rm -f mkbuildtree +fi # Create links to the shared definitions of the Xen interface rm -rf ${AD}/sys/arch/xen/include/xen-public From 9fd655b0297bbcc9c8a5908a57d1b8f14a6a0f1a Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 00:30:50 +0000 Subject: [PATCH 119/199] bitkeeper revision 1.1159.258.30 (422e43bag8TDBzRIwsJaOhrjeAZ-gg) Enable vnd devices. Signed-off-by: Christian Limpach --- netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN b/netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN index e9b2cd83a3..77757a4341 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN @@ -153,7 +153,7 @@ include "arch/xen/conf/GENERIC.local" pseudo-device ccd 4 # concatenated/striped disk devices #pseudo-device cgd 4 # cryptographic disk devices #pseudo-device md 1 # memory disk device (ramdisk) -#pseudo-device vnd 4 # disk-like interface to files +pseudo-device vnd 4 # disk-like interface to files pseudo-device bpfilter 8 # Berkeley packet filter pseudo-device ipfilter # IP filter (firewall) and NAT From 97f5afbcf56c646f2f9ff951fedf88ae4ed3ac4f Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 00:37:56 +0000 Subject: [PATCH 120/199] bitkeeper revision 1.1159.258.31 (422e4564B542sr1LgKTQ3FWQwTZcZQ) Add support for read file operation handlers. Also fix fallback to default handlers. Signed-off-by: Christian Limpach --- .rootkeys | 2 + .../sys/miscfs/kernfs/kernfs.h | 205 +++ .../sys/miscfs/kernfs/kernfs_vnops.c | 1583 +++++++++++++++++ 3 files changed, 1790 insertions(+) create mode 100644 netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h create mode 100644 netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c diff --git a/.rootkeys b/.rootkeys index 5b0c95014a..d15fe9d75d 100644 --- a/.rootkeys +++ b/.rootkeys @@ -289,6 +289,8 @@ 413cb3b5rIKB3TbyhK3pbNyVkYysqA netbsd-2.0-xen-sparse/sys/arch/xen/xen/xen_debug.c 413cb3b5eKxnzoodEqaWn2wrPnHWnA netbsd-2.0-xen-sparse/sys/arch/xen/xen/xencons.c 413cb3b5F56TvQWAmO5TsuzhtzLFPQ netbsd-2.0-xen-sparse/sys/arch/xen/xen/xenkbc.c +422e4430vKaHLOOGS7X-SUUe3EBCgw netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h +422e4430-gOD358H8nGGnNWes08Nng netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c 413cb3b53nyOv1OIeDSsCXhBFDXvJA netbsd-2.0-xen-sparse/sys/nfs/files.nfs 413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.10/agpgart.patch 413aa1d0ewvSv-ohnNnQQNGsbPTTNA patches/linux-2.6.10/drm.patch diff --git a/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h b/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h new file mode 100644 index 0000000000..fbd416b983 --- /dev/null +++ b/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h @@ -0,0 +1,205 @@ +/* $NetBSD: kernfs.h,v 1.20.2.3 2004/05/23 10:46:05 tron Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software donated to Berkeley by + * Jan-Simon Pendry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kernfs.h 8.6 (Berkeley) 3/29/95 + */ + +#define _PATH_KERNFS "/kern" /* Default mountpoint */ + +#ifdef _KERNEL +#include + +/* + * The different types of node in a kernfs filesystem + */ +typedef enum { + KFSkern, /* the filesystem itself (.) */ + KFSroot, /* the filesystem root (..) */ + KFSnull, /* none aplicable */ + KFStime, /* boottime */ + KFSint, /* integer */ + KFSstring, /* string */ + KFShostname, /* hostname */ + KFSavenrun, /* loadavg */ + KFSdevice, /* device file (rootdev/rrootdev) */ + KFSmsgbuf, /* msgbuf */ + KFSipsecsadir, /* ipsec security association (top dir) */ + KFSipsecspdir, /* ipsec security policy (top dir) */ + KFSipsecsa, /* ipsec security association entry */ + KFSipsecsp, /* ipsec security policy entry */ + KFSsubdir, /* directory */ + KFSlasttype, /* last used type */ + KFSmaxtype = (1<<6) - 1 /* last possible type */ +} kfstype; + +/* + * Control data for the kern file system. + */ +struct kern_target { + u_char kt_type; + u_char kt_namlen; + const char *kt_name; + void *kt_data; + kfstype kt_tag; + u_char kt_vtype; + mode_t kt_mode; +}; + +struct dyn_kern_target { + struct kern_target dkt_kt; + SIMPLEQ_ENTRY(dyn_kern_target) dkt_queue; +}; + +struct kernfs_subdir { + SIMPLEQ_HEAD(,dyn_kern_target) ks_entries; + unsigned int ks_nentries; + unsigned int ks_dirs; + const struct kern_target *ks_parent; +}; + +struct kernfs_node { + LIST_ENTRY(kernfs_node) kfs_hash; /* hash chain */ + TAILQ_ENTRY(kernfs_node) kfs_list; /* flat list */ + struct vnode *kfs_vnode; /* vnode associated with this pfsnode */ + kfstype kfs_type; /* type of procfs node */ + mode_t kfs_mode; /* mode bits for stat() */ + long kfs_fileno; /* unique file id */ + u_int32_t kfs_value; /* SA id or SP id (KFSint) */ + const struct kern_target *kfs_kt; + void *kfs_v; /* pointer to secasvar/secpolicy/mbuf */ + long kfs_cookie; /* fileno cookie */ +}; + +struct kernfs_mount { + TAILQ_HEAD(, kernfs_node) nodelist; + long fileno_cookie; +}; + +#define UIO_MX 32 + +#define KERNFS_FILENO(kt, typ, cookie) \ + ((kt >= &kern_targets[0] && kt < &kern_targets[static_nkern_targets]) \ + ? 2 + ((kt) - &kern_targets[0]) \ + : (((cookie + 1) << 6) | (typ))) +#define KERNFS_TYPE_FILENO(typ, cookie) \ + (((cookie + 1) << 6) | (typ)) + +#define VFSTOKERNFS(mp) ((struct kernfs_mount *)((mp)->mnt_data)) +#define VTOKERN(vp) ((struct kernfs_node *)(vp)->v_data) +#define KERNFSTOV(kfs) ((kfs)->kfs_vnode) + +extern const struct kern_target kern_targets[]; +extern int nkern_targets; +extern const int static_nkern_targets; +extern int (**kernfs_vnodeop_p) __P((void *)); +extern struct vfsops kernfs_vfsops; +extern dev_t rrootdev; + +struct secasvar; +struct secpolicy; + +int kernfs_root __P((struct mount *, struct vnode **)); + +void kernfs_hashinit __P((void)); +void kernfs_hashreinit __P((void)); +void kernfs_hashdone __P((void)); +int kernfs_freevp __P((struct vnode *)); +int kernfs_allocvp __P((struct mount *, struct vnode **, kfstype, + const struct kern_target *, u_int32_t)); + +void kernfs_revoke_sa __P((struct secasvar *)); +void kernfs_revoke_sp __P((struct secpolicy *)); + +/* + * Data types for the kernfs file operations. + */ +typedef enum { + KERNFS_XREAD, + KERNFS_XWRITE, + KERNFS_FILEOP_CLOSE, + KERNFS_FILEOP_GETATTR, + KERNFS_FILEOP_IOCTL, + KERNFS_FILEOP_MMAP, + KERNFS_FILEOP_OPEN, + KERNFS_FILEOP_READ, + KERNFS_FILEOP_WRITE, +} kfsfileop; + +struct kernfs_fileop { + kfstype kf_type; + kfsfileop kf_fileop; + union { + void *_kf_genop; + int (*_kf_vop)(void *); + int (*_kf_xread) + (const struct kernfs_node *, int, char **, size_t, + size_t *); + int (*_kf_xwrite) + (const struct kernfs_node *, char *, size_t); + } _kf_opfn; + SPLAY_ENTRY(kernfs_fileop) kf_node; +}; +#define kf_genop _kf_opfn +#define kf_vop _kf_opfn._kf_vop +#define kf_xwrite _kf_opfn._kf_xwrite +#define kf_xread _kf_opfn._kf_xread + +typedef struct kern_target kernfs_parentdir_t; +typedef struct dyn_kern_target kernfs_entry_t; + +/* + * Functions for adding kernfs datatypes and nodes. + */ +kfstype kernfs_alloctype(int, const struct kernfs_fileop *); +#define KERNFS_ALLOCTYPE(kf) kernfs_alloctype(sizeof((kf)) / \ + sizeof((kf)[0]), (kf)) +#define KERNFS_ALLOCENTRY(dkt, m_type, m_flags) \ + dkt = (struct dyn_kern_target *)malloc( \ + sizeof(struct dyn_kern_target), (m_type), (m_flags)) +#define KERNFS_INITENTRY(dkt, type, name, data, tag, vtype, mode) do { \ + (dkt)->dkt_kt.kt_type = (type); \ + (dkt)->dkt_kt.kt_namlen = strlen((name)); \ + (dkt)->dkt_kt.kt_name = (name); \ + (dkt)->dkt_kt.kt_data = (data); \ + (dkt)->dkt_kt.kt_tag = (tag); \ + (dkt)->dkt_kt.kt_vtype = (vtype); \ + (dkt)->dkt_kt.kt_mode = (mode); \ +} while (/*CONSTCOND*/0) +#define KERNFS_ENTOPARENTDIR(dkt) &(dkt)->dkt_kt +int kernfs_addentry __P((kernfs_parentdir_t *, kernfs_entry_t *)); + +#ifdef SYSCTL_SETUP_PROTO +SYSCTL_SETUP_PROTO(sysctl_vfs_kernfs_setup); +#endif /* SYSCTL_SETUP_PROTO */ + +#endif /* _KERNEL */ diff --git a/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c b/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c new file mode 100644 index 0000000000..4ed109ece7 --- /dev/null +++ b/netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c @@ -0,0 +1,1583 @@ +/* $NetBSD: kernfs_vnops.c,v 1.98.2.3 2004/05/15 13:35:27 tron Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software donated to Berkeley by + * Jan-Simon Pendry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95 + */ + +/* + * Kernel parameter filesystem (/kern) + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.98.2.3 2004/05/15 13:35:27 tron Exp $"); + +#ifdef _KERNEL_OPT +#include "opt_ipsec.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef IPSEC +#include +#include +#include +#include +#include +#endif + +#include + +#define KSTRING 256 /* Largest I/O available via this filesystem */ +#define UIO_MX 32 + +#define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH) +#define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) +#define UREAD_MODE (S_IRUSR) +#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) +#define UDIR_MODE (S_IRUSR|S_IXUSR) + +#define N(s) sizeof(s)-1, s +const struct kern_target kern_targets[] = { +/* NOTE: The name must be less than UIO_MX-16 chars in length */ + /* name data tag type ro/rw */ + { DT_DIR, N("."), 0, KFSkern, VDIR, DIR_MODE }, + { DT_DIR, N(".."), 0, KFSroot, VDIR, DIR_MODE }, + { DT_REG, N("boottime"), &boottime.tv_sec, KFSint, VREG, READ_MODE }, + /* XXX cast away const */ + { DT_REG, N("copyright"), (void *)copyright, + KFSstring, VREG, READ_MODE }, + { DT_REG, N("hostname"), 0, KFShostname, VREG, WRITE_MODE }, + { DT_REG, N("hz"), &hz, KFSint, VREG, READ_MODE }, +#ifdef IPSEC + { DT_DIR, N("ipsecsa"), 0, KFSipsecsadir, VDIR, UDIR_MODE }, + { DT_DIR, N("ipsecsp"), 0, KFSipsecspdir, VDIR, UDIR_MODE }, +#endif + { DT_REG, N("loadavg"), 0, KFSavenrun, VREG, READ_MODE }, + { DT_REG, N("msgbuf"), 0, KFSmsgbuf, VREG, READ_MODE }, + { DT_REG, N("pagesize"), &uvmexp.pagesize, KFSint, VREG, READ_MODE }, + { DT_REG, N("physmem"), &physmem, KFSint, VREG, READ_MODE }, +#if 0 + { DT_DIR, N("root"), 0, KFSnull, VDIR, DIR_MODE }, +#endif + { DT_BLK, N("rootdev"), &rootdev, KFSdevice, VBLK, READ_MODE }, + { DT_CHR, N("rrootdev"), &rrootdev, KFSdevice, VCHR, READ_MODE }, + { DT_REG, N("time"), 0, KFStime, VREG, READ_MODE }, + /* XXX cast away const */ + { DT_REG, N("version"), (void *)version, + KFSstring, VREG, READ_MODE }, +}; +const struct kern_target subdir_targets[] = { +/* NOTE: The name must be less than UIO_MX-16 chars in length */ + /* name data tag type ro/rw */ + { DT_DIR, N("."), 0, KFSsubdir, VDIR, DIR_MODE }, + { DT_DIR, N(".."), 0, KFSkern, VDIR, DIR_MODE }, +}; +#ifdef IPSEC +const struct kern_target ipsecsa_targets[] = { +/* NOTE: The name must be less than UIO_MX-16 chars in length */ + /* name data tag type ro/rw */ + { DT_DIR, N("."), 0, KFSipsecsadir, VDIR, DIR_MODE }, + { DT_DIR, N(".."), 0, KFSkern, VDIR, DIR_MODE }, +}; +const struct kern_target ipsecsp_targets[] = { +/* NOTE: The name must be less than UIO_MX-16 chars in length */ + /* name data tag type ro/rw */ + { DT_DIR, N("."), 0, KFSipsecspdir, VDIR, DIR_MODE }, + { DT_DIR, N(".."), 0, KFSkern, VDIR, DIR_MODE }, +}; +const struct kern_target ipsecsa_kt = + { DT_DIR, N(""), 0, KFSipsecsa, VREG, UREAD_MODE }; +const struct kern_target ipsecsp_kt = + { DT_DIR, N(""), 0, KFSipsecsp, VREG, UREAD_MODE }; +#endif +#undef N +SIMPLEQ_HEAD(,dyn_kern_target) dyn_kern_targets = + SIMPLEQ_HEAD_INITIALIZER(dyn_kern_targets); +int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); +const int static_nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); +#ifdef IPSEC +int nipsecsa_targets = sizeof(ipsecsa_targets) / sizeof(ipsecsa_targets[0]); +int nipsecsp_targets = sizeof(ipsecsp_targets) / sizeof(ipsecsp_targets[0]); +int nkern_dirs = 4; /* 2 extra subdirs */ +#else +int nkern_dirs = 2; +#endif + +int kernfs_try_fileop(kfstype, kfsfileop, void *, int); +int kernfs_try_xread(kfstype, const struct kernfs_node *, int, char **, + size_t, size_t *, int); +int kernfs_try_xwrite(kfstype, const struct kernfs_node *, char *, + size_t, int); + +static int kernfs_default_xread(void *v); +static int kernfs_default_xwrite(void *v); +static int kernfs_default_fileop_getattr(void *); + +/* must include all fileop's */ +const struct kernfs_fileop kernfs_default_fileops[] = { + { .kf_fileop = KERNFS_XREAD }, + { .kf_fileop = KERNFS_XWRITE }, + { .kf_fileop = KERNFS_FILEOP_OPEN }, + { .kf_fileop = KERNFS_FILEOP_GETATTR, + .kf_genop = {kernfs_default_fileop_getattr} }, + { .kf_fileop = KERNFS_FILEOP_IOCTL }, + { .kf_fileop = KERNFS_FILEOP_MMAP }, + { .kf_fileop = KERNFS_FILEOP_CLOSE }, + { .kf_fileop = KERNFS_FILEOP_READ, .kf_genop = {kernfs_default_xread} }, + { .kf_fileop = KERNFS_FILEOP_WRITE, .kf_genop = {kernfs_default_xwrite} }, +}; + +int kernfs_lookup __P((void *)); +#define kernfs_create genfs_eopnotsupp +#define kernfs_mknod genfs_eopnotsupp +int kernfs_open __P((void *)); +int kernfs_close __P((void *)); +int kernfs_access __P((void *)); +int kernfs_getattr __P((void *)); +int kernfs_setattr __P((void *)); +int kernfs_read __P((void *)); +int kernfs_write __P((void *)); +#define kernfs_fcntl genfs_fcntl +int kernfs_ioctl __P((void *)); +#define kernfs_poll genfs_poll +#define kernfs_revoke genfs_revoke +int kernfs_mmap __P((void *)); +#define kernfs_fsync genfs_nullop +#define kernfs_seek genfs_nullop +#define kernfs_remove genfs_eopnotsupp +int kernfs_link __P((void *)); +#define kernfs_rename genfs_eopnotsupp +#define kernfs_mkdir genfs_eopnotsupp +#define kernfs_rmdir genfs_eopnotsupp +int kernfs_symlink __P((void *)); +int kernfs_readdir __P((void *)); +#define kernfs_readlink genfs_eopnotsupp +#define kernfs_abortop genfs_abortop +int kernfs_inactive __P((void *)); +int kernfs_reclaim __P((void *)); +#define kernfs_lock genfs_lock +#define kernfs_unlock genfs_unlock +#define kernfs_bmap genfs_badop +#define kernfs_strategy genfs_badop +int kernfs_print __P((void *)); +#define kernfs_islocked genfs_islocked +int kernfs_pathconf __P((void *)); +#define kernfs_advlock genfs_einval +#define kernfs_blkatoff genfs_eopnotsupp +#define kernfs_valloc genfs_eopnotsupp +#define kernfs_vfree genfs_nullop +#define kernfs_truncate genfs_eopnotsupp +#define kernfs_update genfs_nullop +#define kernfs_bwrite genfs_eopnotsupp +#define kernfs_putpages genfs_putpages + +static int kernfs_xread __P((struct kernfs_node *, int, char **, size_t, size_t *)); +static int kernfs_xwrite __P((const struct kernfs_node *, char *, size_t)); + +int (**kernfs_vnodeop_p) __P((void *)); +const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { + { &vop_default_desc, vn_default_error }, + { &vop_lookup_desc, kernfs_lookup }, /* lookup */ + { &vop_create_desc, kernfs_create }, /* create */ + { &vop_mknod_desc, kernfs_mknod }, /* mknod */ + { &vop_open_desc, kernfs_open }, /* open */ + { &vop_close_desc, kernfs_close }, /* close */ + { &vop_access_desc, kernfs_access }, /* access */ + { &vop_getattr_desc, kernfs_getattr }, /* getattr */ + { &vop_setattr_desc, kernfs_setattr }, /* setattr */ + { &vop_read_desc, kernfs_read }, /* read */ + { &vop_write_desc, kernfs_write }, /* write */ + { &vop_fcntl_desc, kernfs_fcntl }, /* fcntl */ + { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ + { &vop_poll_desc, kernfs_poll }, /* poll */ + { &vop_revoke_desc, kernfs_revoke }, /* revoke */ + { &vop_mmap_desc, kernfs_mmap }, /* mmap */ + { &vop_fsync_desc, kernfs_fsync }, /* fsync */ + { &vop_seek_desc, kernfs_seek }, /* seek */ + { &vop_remove_desc, kernfs_remove }, /* remove */ + { &vop_link_desc, kernfs_link }, /* link */ + { &vop_rename_desc, kernfs_rename }, /* rename */ + { &vop_mkdir_desc, kernfs_mkdir }, /* mkdir */ + { &vop_rmdir_desc, kernfs_rmdir }, /* rmdir */ + { &vop_symlink_desc, kernfs_symlink }, /* symlink */ + { &vop_readdir_desc, kernfs_readdir }, /* readdir */ + { &vop_readlink_desc, kernfs_readlink }, /* readlink */ + { &vop_abortop_desc, kernfs_abortop }, /* abortop */ + { &vop_inactive_desc, kernfs_inactive }, /* inactive */ + { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */ + { &vop_lock_desc, kernfs_lock }, /* lock */ + { &vop_unlock_desc, kernfs_unlock }, /* unlock */ + { &vop_bmap_desc, kernfs_bmap }, /* bmap */ + { &vop_strategy_desc, kernfs_strategy }, /* strategy */ + { &vop_print_desc, kernfs_print }, /* print */ + { &vop_islocked_desc, kernfs_islocked }, /* islocked */ + { &vop_pathconf_desc, kernfs_pathconf }, /* pathconf */ + { &vop_advlock_desc, kernfs_advlock }, /* advlock */ + { &vop_blkatoff_desc, kernfs_blkatoff }, /* blkatoff */ + { &vop_valloc_desc, kernfs_valloc }, /* valloc */ + { &vop_vfree_desc, kernfs_vfree }, /* vfree */ + { &vop_truncate_desc, kernfs_truncate }, /* truncate */ + { &vop_update_desc, kernfs_update }, /* update */ + { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */ + { &vop_putpages_desc, kernfs_putpages }, /* putpages */ + { NULL, NULL } +}; +const struct vnodeopv_desc kernfs_vnodeop_opv_desc = + { &kernfs_vnodeop_p, kernfs_vnodeop_entries }; + +static __inline int +kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b) +{ + if (a->kf_type < b->kf_type) + return -1; + if (a->kf_type > b->kf_type) + return 1; + if (a->kf_fileop < b->kf_fileop) + return -1; + if (a->kf_fileop > b->kf_fileop) + return 1; + return (0); +} + +SPLAY_HEAD(kfsfileoptree, kernfs_fileop) kfsfileoptree = + SPLAY_INITIALIZER(kfsfileoptree); +SPLAY_PROTOTYPE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare); +SPLAY_GENERATE(kfsfileoptree, kernfs_fileop, kf_node, kernfs_fileop_compare); + +kfstype +kernfs_alloctype(int nkf, const struct kernfs_fileop *kf) +{ + static u_char nextfreetype = KFSlasttype; + struct kernfs_fileop *dkf, *fkf, skf; + int i; + + /* XXX need to keep track of dkf's memory if we support + deallocating types */ + dkf = malloc(sizeof(kernfs_default_fileops), M_TEMP, M_WAITOK); + memcpy(dkf, kernfs_default_fileops, sizeof(kernfs_default_fileops)); + + for (i = 0; i < sizeof(kernfs_default_fileops) / + sizeof(kernfs_default_fileops[0]); i++) { + dkf[i].kf_type = nextfreetype; + SPLAY_INSERT(kfsfileoptree, &kfsfileoptree, &dkf[i]); + } + + for (i = 0; i < nkf; i++) { + skf.kf_type = nextfreetype; + skf.kf_fileop = kf[i].kf_fileop; + if ((fkf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf))) + fkf->kf_genop = kf[i].kf_genop; + } + + return nextfreetype++; +} + +int +kernfs_try_fileop(kfstype type, kfsfileop fileop, void *v, int error) +{ + const struct kernfs_fileop *kf; + struct kernfs_fileop skf; + + skf.kf_type = type; + skf.kf_fileop = fileop; + kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf); + if (kf == NULL) + kf = &kernfs_default_fileops[fileop]; + if (kf->kf_vop) + return kf->kf_vop(v); + return error; +} + +int +kernfs_try_xread(kfstype type, const struct kernfs_node *kfs, int off, + char **bufp, size_t len, size_t *wrlen, int error) +{ + const struct kernfs_fileop *kf; + struct kernfs_fileop skf; + + skf.kf_type = type; + skf.kf_fileop = KERNFS_XREAD; + kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf); + if (kf == NULL) + kf = &kernfs_default_fileops[KERNFS_XREAD]; + if (kf->kf_xread) + return kf->kf_xread(kfs, off, bufp, len, wrlen); + *wrlen = 0; + return error; +} + +int +kernfs_try_xwrite(kfstype type, const struct kernfs_node *kfs, char *buf, + size_t len, int error) +{ + const struct kernfs_fileop *kf; + struct kernfs_fileop skf; + + skf.kf_type = type; + skf.kf_fileop = KERNFS_XWRITE; + kf = SPLAY_FIND(kfsfileoptree, &kfsfileoptree, &skf); + if (kf == NULL) + kf = &kernfs_default_fileops[KERNFS_XWRITE]; + if (kf->kf_xwrite) + return kf->kf_xwrite(kfs, buf, len); + return error; +} + +int +kernfs_addentry(kernfs_parentdir_t *pkt, kernfs_entry_t *dkt) +{ + struct kernfs_subdir *ks, *parent; + + if (pkt == NULL) { + SIMPLEQ_INSERT_TAIL(&dyn_kern_targets, dkt, dkt_queue); + nkern_targets++; + if (dkt->dkt_kt.kt_vtype == VDIR) + nkern_dirs++; + } else { + parent = (struct kernfs_subdir *)pkt->kt_data; + SIMPLEQ_INSERT_TAIL(&parent->ks_entries, dkt, dkt_queue); + parent->ks_nentries++; + if (dkt->dkt_kt.kt_vtype == VDIR) + parent->ks_dirs++; + } + if (dkt->dkt_kt.kt_vtype == VDIR && dkt->dkt_kt.kt_data == NULL) { + ks = malloc(sizeof(struct kernfs_subdir), + M_TEMP, M_WAITOK); + SIMPLEQ_INIT(&ks->ks_entries); + ks->ks_nentries = 2; /* . and .. */ + ks->ks_dirs = 2; + ks->ks_parent = pkt ? pkt : &kern_targets[0]; + dkt->dkt_kt.kt_data = ks; + } + return 0; +} + +static int +kernfs_xread(kfs, off, bufp, len, wrlen) + struct kernfs_node *kfs; + int off; + char **bufp; + size_t len; + size_t *wrlen; +{ + const struct kern_target *kt; +#ifdef IPSEC + struct mbuf *m; +#endif + + kt = kfs->kfs_kt; + + switch (kfs->kfs_type) { + case KFStime: { + struct timeval tv; + + microtime(&tv); + snprintf(*bufp, len, "%ld %ld\n", tv.tv_sec, tv.tv_usec); + break; + } + + case KFSint: { + int *ip = kt->kt_data; + + snprintf(*bufp, len, "%d\n", *ip); + break; + } + + case KFSstring: { + char *cp = kt->kt_data; + + *bufp = cp; + break; + } + + case KFSmsgbuf: { + long n; + + /* + * deal with cases where the message buffer has + * become corrupted. + */ + if (!msgbufenabled || msgbufp->msg_magic != MSG_MAGIC) { + msgbufenabled = 0; + return (ENXIO); + } + + /* + * Note that reads of /kern/msgbuf won't necessarily yield + * consistent results, if the message buffer is modified + * while the read is in progress. The worst that can happen + * is that incorrect data will be read. There's no way + * that this can crash the system unless the values in the + * message buffer header are corrupted, but that'll cause + * the system to die anyway. + */ + if (off >= msgbufp->msg_bufs) { + *wrlen = 0; + return (0); + } + n = msgbufp->msg_bufx + off; + if (n >= msgbufp->msg_bufs) + n -= msgbufp->msg_bufs; + len = min(msgbufp->msg_bufs - n, msgbufp->msg_bufs - off); + *bufp = msgbufp->msg_bufc + n; + *wrlen = len; + return (0); + } + + case KFShostname: { + char *cp = hostname; + int xlen = hostnamelen; + + if (xlen >= (len - 2)) + return (EINVAL); + + memcpy(*bufp, cp, xlen); + (*bufp)[xlen] = '\n'; + (*bufp)[xlen+1] = '\0'; + len = strlen(*bufp); + break; + } + + case KFSavenrun: + averunnable.fscale = FSCALE; + snprintf(*bufp, len, "%d %d %d %ld\n", + averunnable.ldavg[0], averunnable.ldavg[1], + averunnable.ldavg[2], averunnable.fscale); + break; + +#ifdef IPSEC + case KFSipsecsa: + /* + * Note that SA configuration could be changed during the + * read operation, resulting in garbled output. + */ + m = key_setdumpsa_spi(htonl(kfs->kfs_value)); + if (!m) + return (ENOBUFS); + if (off >= m->m_pkthdr.len) { + *wrlen = 0; + m_freem(m); + return (0); + } + if (len > m->m_pkthdr.len - off) + len = m->m_pkthdr.len - off; + m_copydata(m, off, len, *bufp); + *wrlen = len; + m_freem(m); + return (0); + + case KFSipsecsp: + /* + * Note that SP configuration could be changed during the + * read operation, resulting in garbled output. + */ + if (!kfs->kfs_v) { + struct secpolicy *sp; + + sp = key_getspbyid(kfs->kfs_value); + if (sp) + kfs->kfs_v = sp; + else + return (ENOENT); + } + m = key_setdumpsp((struct secpolicy *)kfs->kfs_v, + SADB_X_SPDGET, 0, 0); + if (!m) + return (ENOBUFS); + if (off >= m->m_pkthdr.len) { + *wrlen = 0; + m_freem(m); + return (0); + } + if (len > m->m_pkthdr.len - off) + len = m->m_pkthdr.len - off; + m_copydata(m, off, len, *bufp); + *wrlen = len; + m_freem(m); + return (0); +#endif + + default: + return kernfs_try_xread(kfs->kfs_type, kfs, off, bufp, len, + wrlen, 0); + } + + len = strlen(*bufp); + if (len <= off) + *wrlen = 0; + else { + *bufp += off; + *wrlen = len - off; + } + return (0); +} + +static int +kernfs_xwrite(kfs, buf, len) + const struct kernfs_node *kfs; + char *buf; + size_t len; +{ + + switch (kfs->kfs_type) { + case KFShostname: + if (buf[len-1] == '\n') + --len; + memcpy(hostname, buf, len); + hostname[len] = '\0'; + hostnamelen = (size_t) len; + return (0); + + default: + return kernfs_try_xwrite(kfs->kfs_type, kfs, buf, len, EIO); + } +} + + +/* + * vp is the current namei directory + * ndp is the name to locate in that directory... + */ +int +kernfs_lookup(v) + void *v; +{ + struct vop_lookup_args /* { + struct vnode * a_dvp; + struct vnode ** a_vpp; + struct componentname * a_cnp; + } */ *ap = v; + struct componentname *cnp = ap->a_cnp; + struct vnode **vpp = ap->a_vpp; + struct vnode *dvp = ap->a_dvp; + const char *pname = cnp->cn_nameptr; + const struct kernfs_node *kfs; + const struct kern_target *kt; + const struct dyn_kern_target *dkt; + const struct kernfs_subdir *ks; + int error, i, wantpunlock; +#ifdef IPSEC + char *ep; + u_int32_t id; +#endif + + *vpp = NULLVP; + cnp->cn_flags &= ~PDIRUNLOCK; + + if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) + return (EROFS); + + if (cnp->cn_namelen == 1 && *pname == '.') { + *vpp = dvp; + VREF(dvp); + return (0); + } + + wantpunlock = (~cnp->cn_flags & (LOCKPARENT | ISLASTCN)); + kfs = VTOKERN(dvp); + switch (kfs->kfs_type) { + case KFSkern: + /* + * Shouldn't get here with .. in the root node. + */ + if (cnp->cn_flags & ISDOTDOT) + return (EIO); + + for (i = 0; i < static_nkern_targets; i++) { + kt = &kern_targets[i]; + if (cnp->cn_namelen == kt->kt_namlen && + memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) + goto found; + } + SIMPLEQ_FOREACH(dkt, &dyn_kern_targets, dkt_queue) { + if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen && + memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) { + kt = &dkt->dkt_kt; + goto found; + } + } + break; + + found: + error = kernfs_allocvp(dvp->v_mount, vpp, kt->kt_tag, kt, 0); + if ((error == 0) && wantpunlock) { + VOP_UNLOCK(dvp, 0); + cnp->cn_flags |= PDIRUNLOCK; + } + return (error); + + case KFSsubdir: + ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; + if (cnp->cn_flags & ISDOTDOT) { + kt = ks->ks_parent; + goto found; + } + + SIMPLEQ_FOREACH(dkt, &ks->ks_entries, dkt_queue) { + if (cnp->cn_namelen == dkt->dkt_kt.kt_namlen && + memcmp(dkt->dkt_kt.kt_name, pname, cnp->cn_namelen) == 0) { + kt = &dkt->dkt_kt; + goto found; + } + } + break; + +#ifdef IPSEC + case KFSipsecsadir: + if (cnp->cn_flags & ISDOTDOT) { + kt = &kern_targets[0]; + goto found; + } + + for (i = 2; i < nipsecsa_targets; i++) { + kt = &ipsecsa_targets[i]; + if (cnp->cn_namelen == kt->kt_namlen && + memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) + goto found; + } + + ep = NULL; + id = strtoul(pname, &ep, 10); + if (!ep || *ep || ep == pname) + break; + + error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsa, &ipsecsa_kt, id); + if ((error == 0) && wantpunlock) { + VOP_UNLOCK(dvp, 0); + cnp->cn_flags |= PDIRUNLOCK; + } + return (error); + + case KFSipsecspdir: + if (cnp->cn_flags & ISDOTDOT) { + kt = &kern_targets[0]; + goto found; + } + + for (i = 2; i < nipsecsp_targets; i++) { + kt = &ipsecsp_targets[i]; + if (cnp->cn_namelen == kt->kt_namlen && + memcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) + goto found; + } + + ep = NULL; + id = strtoul(pname, &ep, 10); + if (!ep || *ep || ep == pname) + break; + + error = kernfs_allocvp(dvp->v_mount, vpp, KFSipsecsp, &ipsecsp_kt, id); + if ((error == 0) && wantpunlock) { + VOP_UNLOCK(dvp, 0); + cnp->cn_flags |= PDIRUNLOCK; + } + return (error); +#endif + + default: + return (ENOTDIR); + } + + return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); +} + +int +kernfs_open(v) + void *v; +{ + struct vop_open_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); +#ifdef IPSEC + struct mbuf *m; + struct secpolicy *sp; +#endif + + switch (kfs->kfs_type) { +#ifdef IPSEC + case KFSipsecsa: + m = key_setdumpsa_spi(htonl(kfs->kfs_value)); + if (m) { + m_freem(m); + return (0); + } else + return (ENOENT); + + case KFSipsecsp: + sp = key_getspbyid(kfs->kfs_value); + if (sp) { + kfs->kfs_v = sp; + return (0); + } else + return (ENOENT); +#endif + + default: + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_OPEN, + v, 0); + } +} + +int +kernfs_close(v) + void *v; +{ + struct vop_close_args /* { + struct vnode *a_vp; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + switch (kfs->kfs_type) { +#ifdef IPSEC + case KFSipsecsp: + key_freesp((struct secpolicy *)kfs->kfs_v); + break; +#endif + + default: + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_CLOSE, + v, 0); + } + + return (0); +} + +int +kernfs_access(v) + void *v; +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct vattr va; + int error; + + if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred, ap->a_p)) != 0) + return (error); + + return (vaccess(va.va_type, va.va_mode, va.va_uid, va.va_gid, + ap->a_mode, ap->a_cred)); +} + +static int +kernfs_default_fileop_getattr(v) + void *v; +{ + struct vop_getattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct vattr *vap = ap->a_vap; + + vap->va_nlink = 1; + vap->va_bytes = vap->va_size = 0; + + return 0; +} + +int +kernfs_getattr(v) + void *v; +{ + struct vop_getattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + struct kernfs_subdir *ks; + struct vattr *vap = ap->a_vap; + int error = 0; + char strbuf[KSTRING], *buf; + size_t nread, total; + + VATTR_NULL(vap); + vap->va_type = ap->a_vp->v_type; + vap->va_uid = 0; + vap->va_gid = 0; + vap->va_mode = kfs->kfs_mode; + vap->va_fileid = kfs->kfs_fileno; + vap->va_flags = 0; + vap->va_size = 0; + vap->va_blocksize = DEV_BSIZE; + /* + * Make all times be current TOD, except for the "boottime" node. + * Avoid microtime(9), it's slow. + * We don't guard the read from time(9) with splclock(9) since we + * don't actually need to be THAT sure the access is atomic. + */ + if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 && + !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) { + TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime); + } else { + TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime); + } + vap->va_atime = vap->va_mtime = vap->va_ctime; + vap->va_gen = 0; + vap->va_flags = 0; + vap->va_rdev = 0; + vap->va_bytes = 0; + + switch (kfs->kfs_type) { + case KFSkern: + vap->va_nlink = nkern_dirs; + vap->va_bytes = vap->va_size = DEV_BSIZE; + break; + + case KFSroot: + vap->va_nlink = 1; + vap->va_bytes = vap->va_size = DEV_BSIZE; + break; + + case KFSsubdir: + ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; + vap->va_nlink = ks->ks_dirs; + vap->va_bytes = vap->va_size = DEV_BSIZE; + break; + + case KFSnull: + case KFStime: + case KFSint: + case KFSstring: + case KFShostname: + case KFSavenrun: + case KFSdevice: + case KFSmsgbuf: +#ifdef IPSEC + case KFSipsecsa: + case KFSipsecsp: +#endif + vap->va_nlink = 1; + total = 0; + do { + buf = strbuf; + error = kernfs_xread(kfs, total, &buf, + sizeof(strbuf), &nread); + total += nread; + } while (error == 0 && nread != 0); + vap->va_bytes = vap->va_size = total; + break; + +#ifdef IPSEC + case KFSipsecsadir: + case KFSipsecspdir: + vap->va_nlink = 2; + vap->va_bytes = vap->va_size = DEV_BSIZE; + break; +#endif + + default: + error = kernfs_try_fileop(kfs->kfs_type, + KERNFS_FILEOP_GETATTR, v, EINVAL); + break; + } + + return (error); +} + +/*ARGSUSED*/ +int +kernfs_setattr(v) + void *v; +{ + + /* + * Silently ignore attribute changes. + * This allows for open with truncate to have no + * effect until some data is written. I want to + * do it this way because all writes are atomic. + */ + return (0); +} + +static int +kernfs_default_xread(v) + void *v; +{ + struct vop_read_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap = v; + struct uio *uio = ap->a_uio; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + char strbuf[KSTRING], *buf; + off_t off; + size_t len; + int error; + + if (ap->a_vp->v_type == VDIR) + return (EOPNOTSUPP); + + off = uio->uio_offset; + buf = strbuf; + if ((error = kernfs_xread(kfs, off, &buf, sizeof(strbuf), &len)) == 0) + error = uiomove(buf, len, uio); + return (error); +} + +int +kernfs_read(v) + void *v; +{ + struct vop_read_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_READ, v, 0); +} + +static int +kernfs_default_xwrite(v) + void *v; +{ + struct vop_write_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + struct uio *uio = ap->a_uio; + int error, xlen; + char strbuf[KSTRING]; + + if (uio->uio_offset != 0) + return (EINVAL); + + xlen = min(uio->uio_resid, KSTRING-1); + if ((error = uiomove(strbuf, xlen, uio)) != 0) + return (error); + + if (uio->uio_resid != 0) + return (EIO); + + strbuf[xlen] = '\0'; + xlen = strlen(strbuf); + return (kernfs_xwrite(kfs, strbuf, xlen)); +} + +int +kernfs_write(v) + void *v; +{ + struct vop_write_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_WRITE, v, 0); +} + +int +kernfs_ioctl(v) + void *v; +{ + struct vop_ioctl_args /* { + const struct vnodeop_desc *a_desc; + struct vnode *a_vp; + u_long a_command; + void *a_data; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_IOCTL, v, + EPASSTHROUGH); +} + +int +kernfs_mmap(v) + void *v; +{ + struct vop_mmap_args /* { + const struct vnodeop_desc *a_desc; + struct vnode *a_vp; + int a_fflags; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + + return kernfs_try_fileop(kfs->kfs_type, KERNFS_FILEOP_MMAP, v, 0); +} + +static int +kernfs_setdirentfileno_kt(struct dirent *d, const struct kern_target *kt, + u_int32_t value, struct vop_readdir_args *ap) +{ + struct kernfs_node *kfs; + struct vnode *vp; + int error; + + if ((error = kernfs_allocvp(ap->a_vp->v_mount, &vp, kt->kt_tag, kt, + value)) != 0) + return error; + if (kt->kt_tag == KFSdevice) { + struct vattr va; + if ((error = VOP_GETATTR(vp, &va, ap->a_cred, + ap->a_uio->uio_segflg == UIO_USERSPACE ? + ap->a_uio->uio_procp : &proc0)) != 0) + return (error); + d->d_fileno = va.va_fileid; + } else { + kfs = VTOKERN(vp); + d->d_fileno = kfs->kfs_fileno; + } + vput(vp); + return 0; +} + +static int +kernfs_setdirentfileno(struct dirent *d, off_t entry, + struct kernfs_node *thisdir_kfs, const struct kern_target *parent_kt, + const struct kern_target *kt, struct vop_readdir_args *ap) +{ + const struct kern_target *ikt; + int error; + + switch (entry) { + case 0: + d->d_fileno = thisdir_kfs->kfs_fileno; + return 0; + case 1: + ikt = parent_kt; + break; + default: + ikt = kt; + break; + } + if (ikt != thisdir_kfs->kfs_kt) { + if ((error = kernfs_setdirentfileno_kt(d, ikt, 0, ap)) != 0) + return error; + } else + d->d_fileno = thisdir_kfs->kfs_fileno; + return 0; +} + +int +kernfs_readdir(v) + void *v; +{ + struct vop_readdir_args /* { + struct vnode *a_vp; + struct uio *a_uio; + struct ucred *a_cred; + int *a_eofflag; + off_t **a_cookies; + int a_*ncookies; + } */ *ap = v; + struct uio *uio = ap->a_uio; + struct dirent d; + struct kernfs_node *kfs = VTOKERN(ap->a_vp); + const struct kern_target *kt; + const struct dyn_kern_target *dkt = NULL; + const struct kernfs_subdir *ks; + off_t i, j; + int error; + off_t *cookies = NULL; + int ncookies = 0, n; +#ifdef IPSEC + struct secasvar *sav, *sav2; + struct secpolicy *sp; +#endif + + if (uio->uio_resid < UIO_MX) + return (EINVAL); + if (uio->uio_offset < 0) + return (EINVAL); + + error = 0; + i = uio->uio_offset; + memset(&d, 0, sizeof(d)); + d.d_reclen = UIO_MX; + ncookies = uio->uio_resid / UIO_MX; + + switch (kfs->kfs_type) { + case KFSkern: + if (i >= nkern_targets) + return (0); + + if (ap->a_ncookies) { + ncookies = min(ncookies, (nkern_targets - i)); + cookies = malloc(ncookies * sizeof(off_t), M_TEMP, + M_WAITOK); + *ap->a_cookies = cookies; + } + + n = 0; + for (; i < nkern_targets && uio->uio_resid >= UIO_MX; i++) { + if (i < static_nkern_targets) + kt = &kern_targets[i]; + else { + if (dkt == NULL) { + dkt = SIMPLEQ_FIRST(&dyn_kern_targets); + for (j = static_nkern_targets; j < i && + dkt != NULL; j++) + dkt = SIMPLEQ_NEXT(dkt, dkt_queue); + if (j != i) + break; + } else { + dkt = SIMPLEQ_NEXT(dkt, dkt_queue); + if (dkt == NULL) + break; + } + kt = &dkt->dkt_kt; + } + if (kt->kt_tag == KFSdevice) { + dev_t *dp = kt->kt_data; + struct vnode *fvp; + + if (*dp == NODEV || + !vfinddev(*dp, kt->kt_vtype, &fvp)) + continue; + } + d.d_namlen = kt->kt_namlen; + if ((error = kernfs_setdirentfileno(&d, i, kfs, + &kern_targets[0], kt, ap)) != 0) + break; + memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + } + ncookies = n; + break; + + case KFSroot: + if (i >= 2) + return 0; + + if (ap->a_ncookies) { + ncookies = min(ncookies, (2 - i)); + cookies = malloc(ncookies * sizeof(off_t), M_TEMP, + M_WAITOK); + *ap->a_cookies = cookies; + } + + n = 0; + for (; i < 2 && uio->uio_resid >= UIO_MX; i++) { + kt = &kern_targets[i]; + d.d_namlen = kt->kt_namlen; + d.d_fileno = KERNFS_FILENO(kt, kt->kt_tag, 0); + memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + } + ncookies = n; + break; + + case KFSsubdir: + ks = (struct kernfs_subdir *)kfs->kfs_kt->kt_data; + if (i >= ks->ks_nentries) + return (0); + + if (ap->a_ncookies) { + ncookies = min(ncookies, (ks->ks_nentries - i)); + cookies = malloc(ncookies * sizeof(off_t), M_TEMP, + M_WAITOK); + *ap->a_cookies = cookies; + } + + dkt = SIMPLEQ_FIRST(&ks->ks_entries); + for (j = 0; j < i && dkt != NULL; j++) + dkt = SIMPLEQ_NEXT(dkt, dkt_queue); + n = 0; + for (; i < ks->ks_nentries && uio->uio_resid >= UIO_MX; i++) { + if (i < 2) + kt = &subdir_targets[i]; + else { + /* check if ks_nentries lied to us */ + if (dkt == NULL) + break; + kt = &dkt->dkt_kt; + dkt = SIMPLEQ_NEXT(dkt, dkt_queue); + } + if (kt->kt_tag == KFSdevice) { + dev_t *dp = kt->kt_data; + struct vnode *fvp; + + if (*dp == NODEV || + !vfinddev(*dp, kt->kt_vtype, &fvp)) + continue; + } + d.d_namlen = kt->kt_namlen; + if ((error = kernfs_setdirentfileno(&d, i, kfs, + ks->ks_parent, kt, ap)) != 0) + break; + memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + } + ncookies = n; + break; + +#ifdef IPSEC + case KFSipsecsadir: + /* count SA in the system */ + n = 0; + TAILQ_FOREACH(sav, &satailq, tailq) { + for (sav2 = TAILQ_FIRST(&satailq); + sav2 != sav; + sav2 = TAILQ_NEXT(sav2, tailq)) { + if (sav->spi == sav2->spi) { + /* multiple SA with same SPI */ + break; + } + } + if (sav == sav2 || sav->spi != sav2->spi) + n++; + } + + if (i >= nipsecsa_targets + n) + return (0); + + if (ap->a_ncookies) { + ncookies = min(ncookies, (n - i)); + cookies = malloc(ncookies * sizeof(off_t), M_TEMP, + M_WAITOK); + *ap->a_cookies = cookies; + } + + n = 0; + for (; i < nipsecsa_targets && uio->uio_resid >= UIO_MX; i++) { + kt = &ipsecsa_targets[i]; + d.d_namlen = kt->kt_namlen; + if ((error = kernfs_setdirentfileno(&d, i, kfs, + &kern_targets[0], kt, ap)) != 0) + break; + memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + } + if (error) { + ncookies = n; + break; + } + + TAILQ_FOREACH(sav, &satailq, tailq) { + for (sav2 = TAILQ_FIRST(&satailq); + sav2 != sav; + sav2 = TAILQ_NEXT(sav2, tailq)) { + if (sav->spi == sav2->spi) { + /* multiple SA with same SPI */ + break; + } + } + if (sav != sav2 && sav->spi == sav2->spi) + continue; + if (uio->uio_resid < UIO_MX) + break; + if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsa_kt, + sav->spi, ap)) != 0) + break; + d.d_namlen = snprintf(d.d_name, sizeof(d.d_name), + "%u", ntohl(sav->spi)); + d.d_type = DT_REG; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + i++; + } + ncookies = n; + break; + + case KFSipsecspdir: + /* count SP in the system */ + n = 0; + TAILQ_FOREACH(sp, &sptailq, tailq) + n++; + + if (i >= nipsecsp_targets + n) + return (0); + + if (ap->a_ncookies) { + ncookies = min(ncookies, (n - i)); + cookies = malloc(ncookies * sizeof(off_t), M_TEMP, + M_WAITOK); + *ap->a_cookies = cookies; + } + + n = 0; + for (; i < nipsecsp_targets && uio->uio_resid >= UIO_MX; i++) { + kt = &ipsecsp_targets[i]; + d.d_namlen = kt->kt_namlen; + if ((error = kernfs_setdirentfileno(&d, i, kfs, + &kern_targets[0], kt, ap)) != 0) + break; + memcpy(d.d_name, kt->kt_name, kt->kt_namlen + 1); + d.d_type = kt->kt_type; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + } + if (error) { + ncookies = n; + break; + } + + TAILQ_FOREACH(sp, &sptailq, tailq) { + if (uio->uio_resid < UIO_MX) + break; + if ((error = kernfs_setdirentfileno_kt(&d, &ipsecsp_kt, + sp->id, ap)) != 0) + break; + d.d_namlen = snprintf(d.d_name, sizeof(d.d_name), + "%u", sp->id); + d.d_type = DT_REG; + if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) + break; + if (cookies) + *cookies++ = i + 1; + n++; + i++; + } + ncookies = n; + break; +#endif + + default: + error = ENOTDIR; + break; + } + + if (ap->a_ncookies) { + if (error) { + if (cookies) + free(*ap->a_cookies, M_TEMP); + *ap->a_ncookies = 0; + *ap->a_cookies = NULL; + } else + *ap->a_ncookies = ncookies; + } + + uio->uio_offset = i; + return (error); +} + +int +kernfs_inactive(v) + void *v; +{ + struct vop_inactive_args /* { + struct vnode *a_vp; + struct proc *a_p; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + const struct kernfs_node *kfs = VTOKERN(ap->a_vp); +#ifdef IPSEC + struct mbuf *m; + struct secpolicy *sp; +#endif + + VOP_UNLOCK(vp, 0); + switch (kfs->kfs_type) { +#ifdef IPSEC + case KFSipsecsa: + m = key_setdumpsa_spi(htonl(kfs->kfs_value)); + if (m) + m_freem(m); + else + vgone(vp); + break; + case KFSipsecsp: + sp = key_getspbyid(kfs->kfs_value); + if (sp) + key_freesp(sp); + else { + /* should never happen as we hold a refcnt */ + vgone(vp); + } + break; +#endif + default: + break; + } + return (0); +} + +int +kernfs_reclaim(v) + void *v; +{ + struct vop_reclaim_args /* { + struct vnode *a_vp; + } */ *ap = v; + + return (kernfs_freevp(ap->a_vp)); +} + +/* + * Return POSIX pathconf information applicable to special devices. + */ +int +kernfs_pathconf(v) + void *v; +{ + struct vop_pathconf_args /* { + struct vnode *a_vp; + int a_name; + register_t *a_retval; + } */ *ap = v; + + switch (ap->a_name) { + case _PC_LINK_MAX: + *ap->a_retval = LINK_MAX; + return (0); + case _PC_MAX_CANON: + *ap->a_retval = MAX_CANON; + return (0); + case _PC_MAX_INPUT: + *ap->a_retval = MAX_INPUT; + return (0); + case _PC_PIPE_BUF: + *ap->a_retval = PIPE_BUF; + return (0); + case _PC_CHOWN_RESTRICTED: + *ap->a_retval = 1; + return (0); + case _PC_VDISABLE: + *ap->a_retval = _POSIX_VDISABLE; + return (0); + case _PC_SYNC_IO: + *ap->a_retval = 1; + return (0); + default: + return (EINVAL); + } + /* NOTREACHED */ +} + +/* + * Print out the contents of a /dev/fd vnode. + */ +/* ARGSUSED */ +int +kernfs_print(v) + void *v; +{ + + printf("tag VT_KERNFS, kernfs vnode\n"); + return (0); +} + +int +kernfs_link(v) + void *v; +{ + struct vop_link_args /* { + struct vnode *a_dvp; + struct vnode *a_vp; + struct componentname *a_cnp; + } */ *ap = v; + + VOP_ABORTOP(ap->a_dvp, ap->a_cnp); + vput(ap->a_dvp); + return (EROFS); +} + +int +kernfs_symlink(v) + void *v; +{ + struct vop_symlink_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + char *a_target; + } */ *ap = v; + + VOP_ABORTOP(ap->a_dvp, ap->a_cnp); + vput(ap->a_dvp); + return (EROFS); +} From b375b7d603ba0c998aaac3dafdcf4806933ad7bb Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 00:44:59 +0000 Subject: [PATCH 121/199] bitkeeper revision 1.1159.258.32 (422e470bJa_VGcUAPdnpZWrD6n9uew) Export Xen provided command line as /kern/xen/cmdline. Signed-off-by: Christian Limpach --- netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c index 294f79830a..45a66af480 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/hypervisor.c @@ -52,7 +52,6 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.7.2.1 2004/05/22 15:58:54 he Exp $" #include #include -#ifdef DOM0OPS #include #include #include @@ -60,7 +59,6 @@ __KERNEL_RCSID(0, "$NetBSD: hypervisor.c,v 1.7.2.1 2004/05/22 15:58:54 he Exp $" #include #include #include -#endif #if NXENNET > 0 #include @@ -187,9 +185,9 @@ hypervisor_attach(parent, self, aux) hac.hac_xennpx.xa_device = "npx"; config_found(self, &hac.hac_xennpx, hypervisor_print); #endif + xenkernfs_init(); #ifdef DOM0OPS if (xen_start_info.flags & SIF_PRIVILEGED) { - xenkernfs_init(); xenprivcmd_init(); xenmachmem_init(); xenvfr_init(); @@ -222,8 +220,7 @@ hypervisor_notify_via_evtchn(unsigned int port) (void)HYPERVISOR_event_channel_op(&op); } -#ifdef DOM0OPS - +#define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH) #define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) kernfs_parentdir_t *kernxen_pkt; @@ -237,5 +234,9 @@ xenkernfs_init() KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE); kernfs_addentry(NULL, dkt); kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt); + + KERNFS_ALLOCENTRY(dkt, M_TEMP, M_WAITOK); + KERNFS_INITENTRY(dkt, DT_REG, "cmdline", xen_start_info.cmd_line, + KFSstring, VREG, READ_MODE); + kernfs_addentry(kernxen_pkt, dkt); } -#endif From 853a0f3ccab0931199577c3e28d2608f5422bf80 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 01:06:53 +0000 Subject: [PATCH 122/199] bitkeeper revision 1.1159.258.33 (422e4c2dbtydqXSZXhO6gOuY-qlS5A) Support Xen-ifying a complete NetBSD source tree. Signed-off-by: Christian Limpach --- netbsd-2.0-xen-sparse/mkbuildtree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbsd-2.0-xen-sparse/mkbuildtree b/netbsd-2.0-xen-sparse/mkbuildtree index ef85a8922a..bd99cbda9a 100755 --- a/netbsd-2.0-xen-sparse/mkbuildtree +++ b/netbsd-2.0-xen-sparse/mkbuildtree @@ -93,7 +93,7 @@ abs_to_rel ${AD} ${AS} RS=$DESTPATH # Remove old copies of files and directories at the destination -for i in `find . -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done +for i in `find sys -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done # We now work from the destination directory cd ${AD} From 06f98ccd3585ead4e6f71a73caef52e259f20aea Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 9 Mar 2005 02:02:39 +0000 Subject: [PATCH 123/199] bitkeeper revision 1.1159.258.34 (422e593fP_MDJ47j5LhtS8fQOVuyAQ) Update to NetBSD 2.0.1. Signed-off-by: Christian Limpach --- buildconfigs/Rules.mk | 2 +- buildconfigs/mk.netbsd-2.0-xenU | 2 +- netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S | 2 ++ netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c | 4 ++++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index cdb6b096e2..b0b0c4697f 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -27,7 +27,7 @@ linux-%.tar.bz2: # Expand NetBSD release to NetBSD version NETBSD_RELEASE ?= 2.0 NETBSD_VER ?= $(patsubst netbsd-%-xen-sparse,%,$(wildcard netbsd-$(NETBSD_RELEASE)*-xen-sparse)) -NETBSD_CVSSNAP ?= 20041103 +NETBSD_CVSSNAP ?= 20050309 # Setup NetBSD search path NETBSD_SRC_PATH ?= .:.. diff --git a/buildconfigs/mk.netbsd-2.0-xenU b/buildconfigs/mk.netbsd-2.0-xenU index acd7e5801a..2e272aa6b3 100644 --- a/buildconfigs/mk.netbsd-2.0-xenU +++ b/buildconfigs/mk.netbsd-2.0-xenU @@ -1,6 +1,6 @@ NETBSD_RELEASE ?= 2.0 -NETBSD_CVSSNAP ?= 20041103 +NETBSD_CVSSNAP ?= 20050309 EXTRAVERSION = xenU diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S index ed0946cb9b..ba26df3a57 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/locore.S @@ -249,6 +249,7 @@ _C_LABEL(biosextmem): .long REALEXTMEM #include #define __HYPERVISOR_yield 8 +#define __SCHEDOP_yield 0 .space 512 tmpstk: @@ -1592,6 +1593,7 @@ idle_loop: jmp idle_start 4: movl $__HYPERVISOR_yield,%eax + movl $__SCHEDOP_yield,%ebx TRAP_INSTR NENTRY(mpidle) idle_start: diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c index 5ec2d45271..801edd9dcb 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/i386/machdep.c @@ -854,6 +854,10 @@ haltsys: if (howto & RB_HALT) { printf("\n"); printf("The operating system has halted.\n"); + + /* XXX cngetc() below doesn't work, shutdown machine for now */ + HYPERVISOR_shutdown(); + printf("Please press any key to reboot.\n\n"); #ifdef BEEP_ONHALT From c3918e84f7b7e04a512b45127312f8f59f0fe243 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 14:27:50 +0000 Subject: [PATCH 124/199] bitkeeper revision 1.1159.258.35 (42305966D0gCjlR6KGQJ4LZR2FIX3g) Fix to xfrd stream handling which was messing up save/restore/migrate on some systems. Signed-off-by: ian@xensource.com --- tools/libxutil/file_stream.c | 26 ++++++++++++++++++-------- tools/xfrd/xfrd.c | 2 ++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tools/libxutil/file_stream.c b/tools/libxutil/file_stream.c index 40391f7fa6..b5526d84a1 100644 --- a/tools/libxutil/file_stream.c +++ b/tools/libxutil/file_stream.c @@ -69,18 +69,28 @@ IOStream *iostdout = &_iostdout; /** IOStream for stderr. */ IOStream *iostderr = &_iostderr; -/** Get the underlying FILE*. - * +/* Get the underlying FILE*. + * * @param s file stream * @return the stream s wraps */ static inline FILE *get_file(IOStream *s){ - switch((long)s->data){ - case 1: s->data = stdin; break; - case 2: s->data = stdout; break; - case 3: s->data = stderr; break; - } - return (FILE*)s->data; + FILE *data = NULL; + switch((long)s->data){ + case 1: + data = stdin; + break; + case 2: + data = stdout; + break; + case 3: + data = stderr; + break; + default: + data = (FILE*)s->data; + break; + } + return data; } /** Control buffering on the underlying stream, like setvbuf(). diff --git a/tools/xfrd/xfrd.c b/tools/xfrd/xfrd.c index 656abc0bc4..bd25ad8cd2 100644 --- a/tools/xfrd/xfrd.c +++ b/tools/xfrd/xfrd.c @@ -1007,6 +1007,8 @@ int xfrd_accept(Args *args, int sock){ } iprintf("> Accepted connection from %s:%d on %d\n", inet_ntoa(peer_in.sin_addr), htons(peer_in.sin_port), sock); + fflush(stdout); + fflush(stderr); pid = fork(); if(pid > 0){ // Parent, fork succeeded. From 15f6b230e351fa64b380ca1986724812c5b70a0f Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 14:35:37 +0000 Subject: [PATCH 125/199] bitkeeper revision 1.1159.258.36 (42305b3948mU75urrgzQftpV3eNPbg) Tidy up ugly warning in debug builds from xc_linux_restore. Signed-off-by: ian@xensource.com --- tools/libxc/xc_linux_restore.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 1db39317de..46373a2806 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -123,7 +123,7 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) /* A temporary mapping of the guest's suspend record. */ suspend_record_t *p_srec; - char *region_base; + char *region_base, *p_gdt; mmu_t *mmu = NULL; @@ -565,6 +565,13 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) ctxt.gdt_frames[i] = pfn_to_mfn_table[pfn]; } + /* Zero hypervisor GDT entries (supresses ugly warning) */ + p_gdt = xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_WRITE, ctxt.gdt_frames[0]); + memset( p_gdt + FIRST_RESERVED_GDT_ENTRY*8, 0, + NR_RESERVED_GDT_ENTRIES*8 ); + munmap( p_gdt, PAGE_SIZE ); + /* Uncanonicalise the page table base pointer. */ pfn = ctxt.pt_base >> PAGE_SHIFT; if ( (pfn >= nr_pfns) || ((pfn_type[pfn]<ABTYPE_MASK) != L2TAB) ) From 6c23763e5e9561ec315bb7de1a4426f9abd05291 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 14:53:08 +0000 Subject: [PATCH 126/199] bitkeeper revision 1.1159.258.37 (42305f54a6Tlb_891y3QBjoIVcCt3Q) Fix balloon driver in highmem builds -- must forcibly flush the kmap cache before relinquishing pages. This requires changes to generic files highmem.[ch]. Signed-off-by: Keir Fraser --- .rootkeys | 3 + .../include/linux/highmem.h | 137 ++++ linux-2.4.29-xen-sparse/mm/highmem.c | 7 + .../drivers/xen/balloon/balloon.c | 19 +- .../include/linux/highmem.h | 95 +++ linux-2.6.10-xen-sparse/mm/highmem.c | 614 ++++++++++++++++++ 6 files changed, 870 insertions(+), 5 deletions(-) create mode 100644 linux-2.4.29-xen-sparse/include/linux/highmem.h create mode 100644 linux-2.6.10-xen-sparse/include/linux/highmem.h create mode 100644 linux-2.6.10-xen-sparse/mm/highmem.c diff --git a/.rootkeys b/.rootkeys index d15fe9d75d..f5baebe00f 100644 --- a/.rootkeys +++ b/.rootkeys @@ -111,6 +111,7 @@ 3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.29-xen-sparse/include/asm-xen/vga.h 40659defgWA92arexpMGn8X3QMDj3w linux-2.4.29-xen-sparse/include/asm-xen/xor.h 3f056927gMHl7mWB89rb73JahbhQIA linux-2.4.29-xen-sparse/include/linux/blk.h +42305f54mFScQCttpj57EIm60BnxIg linux-2.4.29-xen-sparse/include/linux/highmem.h 419e0488SBzS3mdUhwgsES5a5e3abA linux-2.4.29-xen-sparse/include/linux/irq.h 4124f66fPHG6yvB_vXmesjvzrJ3yMg linux-2.4.29-xen-sparse/include/linux/mm.h 401c0590D_kwJDU59X8NyvqSv_Cl2A linux-2.4.29-xen-sparse/include/linux/sched.h @@ -247,10 +248,12 @@ 4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.10-xen-sparse/include/asm-xen/queues.h 3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.10-xen-sparse/include/asm-xen/xen_proc.h 419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.10-xen-sparse/include/linux/gfp.h +42305f545Vc5SLCUewZ2-n-P9JJhEQ linux-2.6.10-xen-sparse/include/linux/highmem.h 419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.10-xen-sparse/include/linux/irq.h 4124f66f4NaKNa0xPiGGykn9QaZk3w linux-2.6.10-xen-sparse/include/linux/skbuff.h 419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.10-xen-sparse/kernel/irq/manage.c 40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.10-xen-sparse/mkbuildtree +42305f54Q6xJ1bXcQJlCQq1m-e2C8g linux-2.6.10-xen-sparse/mm/highmem.c 412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.10-xen-sparse/mm/memory.c 410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.10-xen-sparse/mm/page_alloc.c 41505c572m-s9ATiO1LiD1GPznTTIg linux-2.6.10-xen-sparse/net/core/skbuff.c diff --git a/linux-2.4.29-xen-sparse/include/linux/highmem.h b/linux-2.4.29-xen-sparse/include/linux/highmem.h new file mode 100644 index 0000000000..7dab94f5eb --- /dev/null +++ b/linux-2.4.29-xen-sparse/include/linux/highmem.h @@ -0,0 +1,137 @@ +#ifndef _LINUX_HIGHMEM_H +#define _LINUX_HIGHMEM_H + +#include +#include + +#ifdef CONFIG_HIGHMEM + +extern struct page *highmem_start_page; + +#include + +/* declarations for linux/mm/highmem.c */ +unsigned int nr_free_highpages(void); +void kmap_flush_unused(void); + +extern struct buffer_head *create_bounce(int rw, struct buffer_head * bh_orig); + +static inline char *bh_kmap(struct buffer_head *bh) +{ + return kmap(bh->b_page) + bh_offset(bh); +} + +static inline void bh_kunmap(struct buffer_head *bh) +{ + kunmap(bh->b_page); +} + +/* + * remember to add offset! and never ever reenable interrupts between a + * bh_kmap_irq and bh_kunmap_irq!! + */ +static inline char *bh_kmap_irq(struct buffer_head *bh, unsigned long *flags) +{ + unsigned long addr; + + __save_flags(*flags); + + /* + * could be low + */ + if (!PageHighMem(bh->b_page)) + return bh->b_data; + + /* + * it's a highmem page + */ + __cli(); + addr = (unsigned long) kmap_atomic(bh->b_page, KM_BH_IRQ); + + if (addr & ~PAGE_MASK) + BUG(); + + return (char *) addr + bh_offset(bh); +} + +static inline void bh_kunmap_irq(char *buffer, unsigned long *flags) +{ + unsigned long ptr = (unsigned long) buffer & PAGE_MASK; + + kunmap_atomic((void *) ptr, KM_BH_IRQ); + __restore_flags(*flags); +} + +#else /* CONFIG_HIGHMEM */ + +static inline unsigned int nr_free_highpages(void) { return 0; } +static inline void kmap_flush_unused(void) { } + +static inline void *kmap(struct page *page) { return page_address(page); } + +#define kunmap(page) do { } while (0) + +#define kmap_atomic(page,idx) kmap(page) +#define kunmap_atomic(page,idx) kunmap(page) + +#define bh_kmap(bh) ((bh)->b_data) +#define bh_kunmap(bh) do { } while (0) +#define kmap_nonblock(page) kmap(page) +#define bh_kmap_irq(bh, flags) ((bh)->b_data) +#define bh_kunmap_irq(bh, flags) do { *(flags) = 0; } while (0) + +#endif /* CONFIG_HIGHMEM */ + +/* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ +static inline void clear_user_highpage(struct page *page, unsigned long vaddr) +{ + void *addr = kmap_atomic(page, KM_USER0); + clear_user_page(addr, vaddr); + kunmap_atomic(addr, KM_USER0); +} + +static inline void clear_highpage(struct page *page) +{ + clear_page(kmap(page)); + kunmap(page); +} + +/* + * Same but also flushes aliased cache contents to RAM. + */ +static inline void memclear_highpage_flush(struct page *page, unsigned int offset, unsigned int size) +{ + char *kaddr; + + if (offset + size > PAGE_SIZE) + out_of_line_bug(); + kaddr = kmap(page); + memset(kaddr + offset, 0, size); + flush_dcache_page(page); + flush_page_to_ram(page); + kunmap(page); +} + +static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr) +{ + char *vfrom, *vto; + + vfrom = kmap_atomic(from, KM_USER0); + vto = kmap_atomic(to, KM_USER1); + copy_user_page(vto, vfrom, vaddr); + kunmap_atomic(vfrom, KM_USER0); + kunmap_atomic(vto, KM_USER1); +} + +static inline void copy_highpage(struct page *to, struct page *from) +{ + char *vfrom, *vto; + + vfrom = kmap_atomic(from, KM_USER0); + vto = kmap_atomic(to, KM_USER1); + copy_page(vto, vfrom); + kunmap_atomic(vfrom, KM_USER0); + kunmap_atomic(vto, KM_USER1); +} + +#endif /* _LINUX_HIGHMEM_H */ diff --git a/linux-2.4.29-xen-sparse/mm/highmem.c b/linux-2.4.29-xen-sparse/mm/highmem.c index 6ff48a0cac..341e6e29a9 100644 --- a/linux-2.4.29-xen-sparse/mm/highmem.c +++ b/linux-2.4.29-xen-sparse/mm/highmem.c @@ -130,6 +130,13 @@ start: return vaddr; } +void kmap_flush_unused(void) +{ + spin_lock(&kmap_lock); + flush_all_zero_pkmaps(); + spin_unlock(&kmap_lock); +} + void fastcall *kmap_high(struct page *page, int nonblocking) { unsigned long vaddr; diff --git a/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c index ad951fa984..9e70f584e0 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c @@ -92,6 +92,7 @@ static struct timer_list balloon_timer; #define UNLIST_PAGE(p) ( list_del(&p->list) ) #define pte_offset_kernel pte_offset #define subsys_initcall(_fn) __initcall(_fn) +#define pfn_to_page(_pfn) (mem_map + (_pfn)) #endif #define IPRINTK(fmt, args...) \ @@ -245,11 +246,10 @@ static void balloon_process(void *unused) pfn = page - mem_map; mfn_list[i] = phys_to_machine_mapping[pfn]; - phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; if ( !PageHighMem(page) ) { - v = phys_to_virt((page - mem_map) << PAGE_SHIFT); + v = phys_to_virt(pfn << PAGE_SHIFT); scrub_pages(v, 1); queue_l1_entry_update(get_ptep((unsigned long)v), 0); } @@ -260,14 +260,23 @@ static void balloon_process(void *unused) scrub_pages(v, 1); kunmap(page); } -#endif - - balloon_append(page); +#endif } + /* Ensure that ballooned highmem pages don't have cached mappings. */ + kmap_flush_unused(); + /* Flush updates through and flush the TLB. */ xen_tlb_flush(); + /* No more mappings: invalidate pages in P2M and add to balloon. */ + for ( i = 0; i < debt; i++ ) + { + pfn = mfn_to_pfn(mfn_list[i]); + phys_to_machine_mapping[pfn] = INVALID_P2M_ENTRY; + balloon_append(pfn_to_page(pfn)); + } + if ( HYPERVISOR_dom_mem_op( MEMOP_decrease_reservation, mfn_list, debt, 0) != debt ) BUG(); diff --git a/linux-2.6.10-xen-sparse/include/linux/highmem.h b/linux-2.6.10-xen-sparse/include/linux/highmem.h new file mode 100644 index 0000000000..bbe2ce094e --- /dev/null +++ b/linux-2.6.10-xen-sparse/include/linux/highmem.h @@ -0,0 +1,95 @@ +#ifndef _LINUX_HIGHMEM_H +#define _LINUX_HIGHMEM_H + +#include +#include +#include + +#include + +#ifdef CONFIG_HIGHMEM + +extern struct page *highmem_start_page; + +#include + +/* declarations for linux/mm/highmem.c */ +unsigned int nr_free_highpages(void); +void kmap_flush_unused(void); + +#else /* CONFIG_HIGHMEM */ + +static inline unsigned int nr_free_highpages(void) { return 0; } +static inline void kmap_flush_unused(void) { } + +static inline void *kmap(struct page *page) +{ + might_sleep(); + return page_address(page); +} + +#define kunmap(page) do { (void) (page); } while (0) + +#define kmap_atomic(page, idx) page_address(page) +#define kunmap_atomic(addr, idx) do { } while (0) +#define kmap_atomic_to_page(ptr) virt_to_page(ptr) + +#endif /* CONFIG_HIGHMEM */ + +/* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */ +static inline void clear_user_highpage(struct page *page, unsigned long vaddr) +{ + void *addr = kmap_atomic(page, KM_USER0); + clear_user_page(addr, vaddr, page); + kunmap_atomic(addr, KM_USER0); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); +} + +static inline void clear_highpage(struct page *page) +{ + void *kaddr = kmap_atomic(page, KM_USER0); + clear_page(kaddr); + kunmap_atomic(kaddr, KM_USER0); +} + +/* + * Same but also flushes aliased cache contents to RAM. + */ +static inline void memclear_highpage_flush(struct page *page, unsigned int offset, unsigned int size) +{ + void *kaddr; + + BUG_ON(offset + size > PAGE_SIZE); + + kaddr = kmap_atomic(page, KM_USER0); + memset((char *)kaddr + offset, 0, size); + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_USER0); +} + +static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr) +{ + char *vfrom, *vto; + + vfrom = kmap_atomic(from, KM_USER0); + vto = kmap_atomic(to, KM_USER1); + copy_user_page(vto, vfrom, vaddr, to); + kunmap_atomic(vfrom, KM_USER0); + kunmap_atomic(vto, KM_USER1); + /* Make sure this page is cleared on other CPU's too before using it */ + smp_wmb(); +} + +static inline void copy_highpage(struct page *to, struct page *from) +{ + char *vfrom, *vto; + + vfrom = kmap_atomic(from, KM_USER0); + vto = kmap_atomic(to, KM_USER1); + copy_page(vto, vfrom); + kunmap_atomic(vfrom, KM_USER0); + kunmap_atomic(vto, KM_USER1); +} + +#endif /* _LINUX_HIGHMEM_H */ diff --git a/linux-2.6.10-xen-sparse/mm/highmem.c b/linux-2.6.10-xen-sparse/mm/highmem.c new file mode 100644 index 0000000000..96e7798983 --- /dev/null +++ b/linux-2.6.10-xen-sparse/mm/highmem.c @@ -0,0 +1,614 @@ +/* + * High memory handling common code and variables. + * + * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de + * Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de + * + * + * Redesigned the x86 32-bit VM architecture to deal with + * 64-bit physical space. With current x86 CPUs this + * means up to 64 Gigabytes physical RAM. + * + * Rewrote high memory support to move the page cache into + * high memory. Implemented permanent (schedulable) kmaps + * based on Linus' idea. + * + * Copyright (C) 1999 Ingo Molnar + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static mempool_t *page_pool, *isa_page_pool; + +static void *page_pool_alloc(int gfp_mask, void *data) +{ + int gfp = gfp_mask | (int) (long) data; + + return alloc_page(gfp); +} + +static void page_pool_free(void *page, void *data) +{ + __free_page(page); +} + +/* + * Virtual_count is not a pure "count". + * 0 means that it is not mapped, and has not been mapped + * since a TLB flush - it is usable. + * 1 means that there are no users, but it has been mapped + * since the last TLB flush - so we can't use it. + * n means that there are (n-1) current users of it. + */ +#ifdef CONFIG_HIGHMEM +static int pkmap_count[LAST_PKMAP]; +static unsigned int last_pkmap_nr; +static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; + +pte_t * pkmap_page_table; + +static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait); + +static void flush_all_zero_pkmaps(void) +{ + int i; + + flush_cache_kmaps(); + + for (i = 0; i < LAST_PKMAP; i++) { + struct page *page; + + /* + * zero means we don't have anything to do, + * >1 means that it is still in use. Only + * a count of 1 means that it is free but + * needs to be unmapped + */ + if (pkmap_count[i] != 1) + continue; + pkmap_count[i] = 0; + + /* sanity check */ + if (pte_none(pkmap_page_table[i])) + BUG(); + + /* + * Don't need an atomic fetch-and-clear op here; + * no-one has the page mapped, and cannot get at + * its virtual address (and hence PTE) without first + * getting the kmap_lock (which is held here). + * So no dangers, even with speculative execution. + */ + page = pte_page(pkmap_page_table[i]); + pte_clear(&pkmap_page_table[i]); + + set_page_address(page, NULL); + } + flush_tlb_kernel_range(PKMAP_ADDR(0), PKMAP_ADDR(LAST_PKMAP)); +} + +static inline unsigned long map_new_virtual(struct page *page) +{ + unsigned long vaddr; + int count; + +start: + count = LAST_PKMAP; + /* Find an empty entry */ + for (;;) { + last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK; + if (!last_pkmap_nr) { + flush_all_zero_pkmaps(); + count = LAST_PKMAP; + } + if (!pkmap_count[last_pkmap_nr]) + break; /* Found a usable entry */ + if (--count) + continue; + + /* + * Sleep for somebody else to unmap their entries + */ + { + DECLARE_WAITQUEUE(wait, current); + + __set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&pkmap_map_wait, &wait); + spin_unlock(&kmap_lock); + schedule(); + remove_wait_queue(&pkmap_map_wait, &wait); + spin_lock(&kmap_lock); + + /* Somebody else might have mapped it while we slept */ + if (page_address(page)) + return (unsigned long)page_address(page); + + /* Re-start */ + goto start; + } + } + vaddr = PKMAP_ADDR(last_pkmap_nr); + set_pte(&(pkmap_page_table[last_pkmap_nr]), mk_pte(page, kmap_prot)); + + pkmap_count[last_pkmap_nr] = 1; + set_page_address(page, (void *)vaddr); + + return vaddr; +} + +void kmap_flush_unused(void) +{ + spin_lock(&kmap_lock); + flush_all_zero_pkmaps(); + spin_unlock(&kmap_lock); +} + +EXPORT_SYMBOL(kmap_flush_unused); + +void fastcall *kmap_high(struct page *page) +{ + unsigned long vaddr; + + /* + * For highmem pages, we can't trust "virtual" until + * after we have the lock. + * + * We cannot call this from interrupts, as it may block + */ + spin_lock(&kmap_lock); + vaddr = (unsigned long)page_address(page); + if (!vaddr) + vaddr = map_new_virtual(page); + pkmap_count[PKMAP_NR(vaddr)]++; + if (pkmap_count[PKMAP_NR(vaddr)] < 2) + BUG(); + spin_unlock(&kmap_lock); + return (void*) vaddr; +} + +EXPORT_SYMBOL(kmap_high); + +void fastcall kunmap_high(struct page *page) +{ + unsigned long vaddr; + unsigned long nr; + int need_wakeup; + + spin_lock(&kmap_lock); + vaddr = (unsigned long)page_address(page); + if (!vaddr) + BUG(); + nr = PKMAP_NR(vaddr); + + /* + * A count must never go down to zero + * without a TLB flush! + */ + need_wakeup = 0; + switch (--pkmap_count[nr]) { + case 0: + BUG(); + case 1: + /* + * Avoid an unnecessary wake_up() function call. + * The common case is pkmap_count[] == 1, but + * no waiters. + * The tasks queued in the wait-queue are guarded + * by both the lock in the wait-queue-head and by + * the kmap_lock. As the kmap_lock is held here, + * no need for the wait-queue-head's lock. Simply + * test if the queue is empty. + */ + need_wakeup = waitqueue_active(&pkmap_map_wait); + } + spin_unlock(&kmap_lock); + + /* do wake-up, if needed, race-free outside of the spin lock */ + if (need_wakeup) + wake_up(&pkmap_map_wait); +} + +EXPORT_SYMBOL(kunmap_high); + +#define POOL_SIZE 64 + +static __init int init_emergency_pool(void) +{ + struct sysinfo i; + si_meminfo(&i); + si_swapinfo(&i); + + if (!i.totalhigh) + return 0; + + page_pool = mempool_create(POOL_SIZE, page_pool_alloc, page_pool_free, NULL); + if (!page_pool) + BUG(); + printk("highmem bounce pool size: %d pages\n", POOL_SIZE); + + return 0; +} + +__initcall(init_emergency_pool); + +/* + * highmem version, map in to vec + */ +static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom) +{ + unsigned long flags; + unsigned char *vto; + + local_irq_save(flags); + vto = kmap_atomic(to->bv_page, KM_BOUNCE_READ); + memcpy(vto + to->bv_offset, vfrom, to->bv_len); + kunmap_atomic(vto, KM_BOUNCE_READ); + local_irq_restore(flags); +} + +#else /* CONFIG_HIGHMEM */ + +#define bounce_copy_vec(to, vfrom) \ + memcpy(page_address((to)->bv_page) + (to)->bv_offset, vfrom, (to)->bv_len) + +#endif + +#define ISA_POOL_SIZE 16 + +/* + * gets called "every" time someone init's a queue with BLK_BOUNCE_ISA + * as the max address, so check if the pool has already been created. + */ +int init_emergency_isa_pool(void) +{ + if (isa_page_pool) + return 0; + + isa_page_pool = mempool_create(ISA_POOL_SIZE, page_pool_alloc, page_pool_free, (void *) __GFP_DMA); + if (!isa_page_pool) + BUG(); + + printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE); + return 0; +} + +/* + * Simple bounce buffer support for highmem pages. Depending on the + * queue gfp mask set, *to may or may not be a highmem page. kmap it + * always, it will do the Right Thing + */ +static void copy_to_high_bio_irq(struct bio *to, struct bio *from) +{ + unsigned char *vfrom; + struct bio_vec *tovec, *fromvec; + int i; + + __bio_for_each_segment(tovec, to, i, 0) { + fromvec = from->bi_io_vec + i; + + /* + * not bounced + */ + if (tovec->bv_page == fromvec->bv_page) + continue; + + /* + * fromvec->bv_offset and fromvec->bv_len might have been + * modified by the block layer, so use the original copy, + * bounce_copy_vec already uses tovec->bv_len + */ + vfrom = page_address(fromvec->bv_page) + tovec->bv_offset; + + flush_dcache_page(tovec->bv_page); + bounce_copy_vec(tovec, vfrom); + } +} + +static void bounce_end_io(struct bio *bio, mempool_t *pool, int err) +{ + struct bio *bio_orig = bio->bi_private; + struct bio_vec *bvec, *org_vec; + int i; + + if (test_bit(BIO_EOPNOTSUPP, &bio->bi_flags)) + set_bit(BIO_EOPNOTSUPP, &bio_orig->bi_flags); + + /* + * free up bounce indirect pages used + */ + __bio_for_each_segment(bvec, bio, i, 0) { + org_vec = bio_orig->bi_io_vec + i; + if (bvec->bv_page == org_vec->bv_page) + continue; + + mempool_free(bvec->bv_page, pool); + } + + bio_endio(bio_orig, bio_orig->bi_size, err); + bio_put(bio); +} + +static int bounce_end_io_write(struct bio *bio, unsigned int bytes_done,int err) +{ + if (bio->bi_size) + return 1; + + bounce_end_io(bio, page_pool, err); + return 0; +} + +static int bounce_end_io_write_isa(struct bio *bio, unsigned int bytes_done, int err) +{ + if (bio->bi_size) + return 1; + + bounce_end_io(bio, isa_page_pool, err); + return 0; +} + +static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err) +{ + struct bio *bio_orig = bio->bi_private; + + if (test_bit(BIO_UPTODATE, &bio->bi_flags)) + copy_to_high_bio_irq(bio_orig, bio); + + bounce_end_io(bio, pool, err); +} + +static int bounce_end_io_read(struct bio *bio, unsigned int bytes_done, int err) +{ + if (bio->bi_size) + return 1; + + __bounce_end_io_read(bio, page_pool, err); + return 0; +} + +static int bounce_end_io_read_isa(struct bio *bio, unsigned int bytes_done, int err) +{ + if (bio->bi_size) + return 1; + + __bounce_end_io_read(bio, isa_page_pool, err); + return 0; +} + +static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, + mempool_t *pool) +{ + struct page *page; + struct bio *bio = NULL; + int i, rw = bio_data_dir(*bio_orig); + struct bio_vec *to, *from; + + bio_for_each_segment(from, *bio_orig, i) { + page = from->bv_page; + + /* + * is destination page below bounce pfn? + */ + if (page_to_pfn(page) < q->bounce_pfn) + continue; + + /* + * irk, bounce it + */ + if (!bio) + bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt); + + to = bio->bi_io_vec + i; + + to->bv_page = mempool_alloc(pool, q->bounce_gfp); + to->bv_len = from->bv_len; + to->bv_offset = from->bv_offset; + + if (rw == WRITE) { + char *vto, *vfrom; + + flush_dcache_page(from->bv_page); + vto = page_address(to->bv_page) + to->bv_offset; + vfrom = kmap(from->bv_page) + from->bv_offset; + memcpy(vto, vfrom, to->bv_len); + kunmap(from->bv_page); + } + } + + /* + * no pages bounced + */ + if (!bio) + return; + + /* + * at least one page was bounced, fill in possible non-highmem + * pages + */ + bio_for_each_segment(from, *bio_orig, i) { + to = bio_iovec_idx(bio, i); + if (!to->bv_page) { + to->bv_page = from->bv_page; + to->bv_len = from->bv_len; + to->bv_offset = from->bv_offset; + } + } + + bio->bi_bdev = (*bio_orig)->bi_bdev; + bio->bi_flags |= (1 << BIO_BOUNCED); + bio->bi_sector = (*bio_orig)->bi_sector; + bio->bi_rw = (*bio_orig)->bi_rw; + + bio->bi_vcnt = (*bio_orig)->bi_vcnt; + bio->bi_idx = (*bio_orig)->bi_idx; + bio->bi_size = (*bio_orig)->bi_size; + + if (pool == page_pool) { + bio->bi_end_io = bounce_end_io_write; + if (rw == READ) + bio->bi_end_io = bounce_end_io_read; + } else { + bio->bi_end_io = bounce_end_io_write_isa; + if (rw == READ) + bio->bi_end_io = bounce_end_io_read_isa; + } + + bio->bi_private = *bio_orig; + *bio_orig = bio; +} + +void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) +{ + mempool_t *pool; + + /* + * for non-isa bounce case, just check if the bounce pfn is equal + * to or bigger than the highest pfn in the system -- in that case, + * don't waste time iterating over bio segments + */ + if (!(q->bounce_gfp & GFP_DMA)) { + if (q->bounce_pfn >= blk_max_pfn) + return; + pool = page_pool; + } else { + BUG_ON(!isa_page_pool); + pool = isa_page_pool; + } + + /* + * slow path + */ + __blk_queue_bounce(q, bio_orig, pool); +} + +EXPORT_SYMBOL(blk_queue_bounce); + +#if defined(HASHED_PAGE_VIRTUAL) + +#define PA_HASH_ORDER 7 + +/* + * Describes one page->virtual association + */ +struct page_address_map { + struct page *page; + void *virtual; + struct list_head list; +}; + +/* + * page_address_map freelist, allocated from page_address_maps. + */ +static struct list_head page_address_pool; /* freelist */ +static spinlock_t pool_lock; /* protects page_address_pool */ + +/* + * Hash table bucket + */ +static struct page_address_slot { + struct list_head lh; /* List of page_address_maps */ + spinlock_t lock; /* Protect this bucket's list */ +} ____cacheline_aligned_in_smp page_address_htable[1<lock, flags); + if (!list_empty(&pas->lh)) { + struct page_address_map *pam; + + list_for_each_entry(pam, &pas->lh, list) { + if (pam->page == page) { + ret = pam->virtual; + goto done; + } + } + } +done: + spin_unlock_irqrestore(&pas->lock, flags); + return ret; +} + +EXPORT_SYMBOL(page_address); + +void set_page_address(struct page *page, void *virtual) +{ + unsigned long flags; + struct page_address_slot *pas; + struct page_address_map *pam; + + BUG_ON(!PageHighMem(page)); + + pas = page_slot(page); + if (virtual) { /* Add */ + BUG_ON(list_empty(&page_address_pool)); + + spin_lock_irqsave(&pool_lock, flags); + pam = list_entry(page_address_pool.next, + struct page_address_map, list); + list_del(&pam->list); + spin_unlock_irqrestore(&pool_lock, flags); + + pam->page = page; + pam->virtual = virtual; + + spin_lock_irqsave(&pas->lock, flags); + list_add_tail(&pam->list, &pas->lh); + spin_unlock_irqrestore(&pas->lock, flags); + } else { /* Remove */ + spin_lock_irqsave(&pas->lock, flags); + list_for_each_entry(pam, &pas->lh, list) { + if (pam->page == page) { + list_del(&pam->list); + spin_unlock_irqrestore(&pas->lock, flags); + spin_lock_irqsave(&pool_lock, flags); + list_add_tail(&pam->list, &page_address_pool); + spin_unlock_irqrestore(&pool_lock, flags); + goto done; + } + } + spin_unlock_irqrestore(&pas->lock, flags); + } +done: + return; +} + +static struct page_address_map page_address_maps[LAST_PKMAP]; + +void __init page_address_init(void) +{ + int i; + + INIT_LIST_HEAD(&page_address_pool); + for (i = 0; i < ARRAY_SIZE(page_address_maps); i++) + list_add(&page_address_maps[i].list, &page_address_pool); + for (i = 0; i < ARRAY_SIZE(page_address_htable); i++) { + INIT_LIST_HEAD(&page_address_htable[i].lh); + spin_lock_init(&page_address_htable[i].lock); + } + spin_lock_init(&pool_lock); +} + +#endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ From 59f0cea86aa42e59cef1a61af9006677f7bcf954 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 10 Mar 2005 14:53:08 +0000 Subject: [PATCH 127/199] bitkeeper revision 1.1159.265.1 (42305f54c1QGh-jqx__ZfFdzrPJWDA) Make xend parent sleep a bit at start, so when it returns xend is running. Signed-off-by: Mike Wray --- tools/python/xen/xend/server/SrvDaemon.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index d54dec26bb..05eb1ed016 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -15,6 +15,7 @@ import pwd import re import StringIO import traceback +import time from twisted.internet import pollreactor pollreactor.install() @@ -516,8 +517,8 @@ class Daemon: self.install_child_reaper() if self.fork_pid(XEND_PID_FILE): - #Parent - pass + #Parent. Sleep to give child time to start. + time.sleep(1) else: # Child self.tracing(trace) From de18760cd769d9c072e43c2f586b3a9734fa67b6 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 16:08:08 +0000 Subject: [PATCH 128/199] bitkeeper revision 1.1159.266.1 (423070e8gpQdLbFsdaIs7JDG4U12ZA) A couple of fixes for 2.4. Signed-off-by: Keir Fraser --- linux-2.4.29-xen-sparse/arch/xen/mm/init.c | 7 +++---- linux-2.6.10-xen-sparse/drivers/xen/console/console.c | 6 +----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/mm/init.c b/linux-2.4.29-xen-sparse/arch/xen/mm/init.c index a2363d0cce..40a5af9273 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/mm/init.c +++ b/linux-2.4.29-xen-sparse/arch/xen/mm/init.c @@ -223,10 +223,9 @@ static void __init pagetable_init (void) pmd_t *kpmd, *pmd; pte_t *kpte, *pte, *pte_base; - end = (unsigned long)__va(max_low_pfn * PAGE_SIZE); - ram_end = (unsigned long)__va(xen_start_info.nr_pages * PAGE_SIZE); - if ( ram_end > end ) - ram_end = end; + ram_end = end = (unsigned long)__va(max_low_pfn * PAGE_SIZE); + if ( xen_start_info.nr_pages < max_low_pfn ) + ram_end = (unsigned long)__va(xen_start_info.nr_pages * PAGE_SIZE); pgd_base = init_mm.pgd; i = __pgd_offset(PAGE_OFFSET); diff --git a/linux-2.6.10-xen-sparse/drivers/xen/console/console.c b/linux-2.6.10-xen-sparse/drivers/xen/console/console.c index b9c09c3d73..f1fe3c517f 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/console/console.c @@ -66,10 +66,6 @@ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; static int __init xencons_setup(char *str) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - if (str[0] == '=') - str++; -#endif if ( !strcmp(str, "tty") ) xc_mode = XC_TTY; else if ( !strcmp(str, "ttyS") ) @@ -78,7 +74,7 @@ static int __init xencons_setup(char *str) xc_mode = XC_OFF; return 1; } -__setup("xencons", xencons_setup); +__setup("xencons=", xencons_setup); /* The kernel and user-land drivers share a common transmit buffer. */ #define WBUF_SIZE 4096 From 8e86d6ab9f4b3995436f548b3ef6494564dfd26a Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 17:37:10 +0000 Subject: [PATCH 129/199] bitkeeper revision 1.1159.258.40 (423085c6l2rF-ZZuQiNGB3ZR9Vzj7A) Tiny hack to fix install.sh for the case where /etc/init.d is a symlink. Signed-off-by: ian@xensource.com --- install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/install.sh b/install.sh index 09a59046f6..491e5ab56f 100755 --- a/install.sh +++ b/install.sh @@ -33,6 +33,8 @@ do done cd - cp -fdR $src/* $dst +# hack to fixup the case that init.d is a symlink +cp -fdR $src/etc/init.d/* $dst/etc/init.d/ echo "All done." echo "Checking to see whether prerequisite tools are installed..." From 1cfe7f0ac9ccd13d80df5d1ddddf1e22c63db810 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 17:49:06 +0000 Subject: [PATCH 130/199] bitkeeper revision 1.1159.267.1 (42308892nDLBoNRoKA_URBGXNhvEUg) Change blkif_pdev_t to u32 to allow configuring backend devices which use 32-bit numbers to identify devices. Signed-off-by: Christian Limpach --- linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c | 3 ++- xen/include/public/io/domain_controller.h | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c b/linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c index b530128366..1aa5acf0c9 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c @@ -129,7 +129,8 @@ void vbd_grow(blkif_be_vbd_grow_t *grow) return; } - x->extent.device = grow->extent.device; + /* Mask to 16-bit for compatibility with old tools */ + x->extent.device = grow->extent.device & 0xffff; x->extent.sector_start = grow->extent.sector_start; x->extent.sector_length = grow->extent.sector_length; x->next = (blkif_extent_le_t *)NULL; diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index c248f21419..61ba2d3776 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -81,7 +81,7 @@ typedef struct { /* These are used by both front-end and back-end drivers. */ #define blkif_vdev_t u16 -#define blkif_pdev_t u16 +#define blkif_pdev_t u32 #define blkif_sector_t u64 /* @@ -183,7 +183,6 @@ typedef struct { blkif_sector_t sector_start; /* 0 */ blkif_sector_t sector_length; /* 8 */ blkif_pdev_t device; /* 16 */ - u16 __pad; /* 18 */ } PACKED blkif_extent_t; /* 20 bytes */ /* Non-specific 'okay' return. */ From ccb808be8ea97f9d25370c9f1bd11aba2076fae2 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 10 Mar 2005 18:09:19 +0000 Subject: [PATCH 131/199] bitkeeper revision 1.1159.258.41 (42308d4fd_3EgH9VpgnqmZ0m3rv3ag) added tag RELEASE-2.0.5 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 22f47de447..35aefe6fd9 100644 --- a/.hgtags +++ b/.hgtags @@ -1,6 +1,7 @@ 42882b3e0dda89f3a8ec00da568f86e9b3c230f1 RELEASE-2.0.0 475a162b66e2c19b1e9468b234a4ba705334905e RELEASE-2.0.1 82ba8bd1ceb2e03af769775fb8bc890dcab04f72 RELEASE-2.0.3 +1a522944f76540ea9d73fcc1b0d13d0f670183f0 RELEASE-2.0.5 487b2ee37d1cecb5f3e7a546b05ad097a0226f2f beta1 3d330e41f41ce1bc118c02346e18949ad5d67f6b latest-semistable 30c521db4c71960b0cf1d9c9e1b658e77b535a3e latest-stable From ca7784e7731eb9e9827df986ce4a71afc25eca4b Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 00:16:05 +0000 Subject: [PATCH 132/199] bitkeeper revision 1.1159.268.1 (4230e3456i1RsGKcSPg-xYttkmeJEw) Update to Linux 2.6.11. Signed-off-by: Christian Limpach --- .rootkeys | 252 ++- .../include/linux/skbuff.h | 1189 ------------- linux-2.6.10-xen-sparse/net/core/skbuff.c | 1521 ----------------- .../arch/xen/Kconfig | 0 .../arch/xen/Kconfig.drivers | 0 .../arch/xen/Makefile | 0 .../arch/xen/boot/Makefile | 0 .../arch/xen/configs/xen0_defconfig | 0 .../arch/xen/configs/xenU_defconfig | 0 .../arch/xen/i386/Kconfig | 19 +- .../arch/xen/i386/Makefile | 0 .../arch/xen/i386/kernel/Makefile | 0 .../arch/xen/i386/kernel/cpu/Makefile | 0 .../arch/xen/i386/kernel/cpu/common.c | 89 +- .../arch/xen/i386/kernel/cpu/mtrr/Makefile | 0 .../arch/xen/i386/kernel/cpu/mtrr/main.c | 0 .../arch/xen/i386/kernel/entry.S | 7 +- .../arch/xen/i386/kernel/head.S | 0 .../arch/xen/i386/kernel/i386_ksyms.c | 2 - .../arch/xen/i386/kernel/ioport.c | 0 .../arch/xen/i386/kernel/ldt.c | 0 .../arch/xen/i386/kernel/microcode.c | 0 .../arch/xen/i386/kernel/pci-dma.c | 12 +- .../arch/xen/i386/kernel/process.c | 35 +- .../arch/xen/i386/kernel/setup.c | 84 +- .../arch/xen/i386/kernel/signal.c | 44 +- .../arch/xen/i386/kernel/time.c | 10 +- .../arch/xen/i386/kernel/timers/Makefile | 0 .../arch/xen/i386/kernel/timers/timer_tsc.c | 0 .../arch/xen/i386/kernel/traps.c | 47 +- .../arch/xen/i386/kernel/vsyscall.S | 0 .../arch/xen/i386/kernel/vsyscall.lds | 0 .../arch/xen/i386/mm/Makefile | 0 .../arch/xen/i386/mm/fault.c | 17 +- .../arch/xen/i386/mm/highmem.c | 6 +- .../arch/xen/i386/mm/hypervisor.c | 12 +- .../arch/xen/i386/mm/init.c | 26 +- .../arch/xen/i386/mm/ioremap.c | 17 +- .../arch/xen/i386/mm/pageattr.c | 49 +- .../arch/xen/i386/mm/pgtable.c | 45 +- .../arch/xen/i386/pci/Makefile | 0 .../arch/xen/i386/pci/direct.c | 0 .../arch/xen/i386/pci/irq.c | 4 +- .../arch/xen/kernel/Makefile | 0 .../arch/xen/kernel/ctrl_if.c | 0 .../arch/xen/kernel/devmem.c | 0 .../arch/xen/kernel/evtchn.c | 0 .../arch/xen/kernel/fixup.c | 0 .../arch/xen/kernel/gnttab.c | 0 .../arch/xen/kernel/reboot.c | 0 .../arch/xen/kernel/skbuff.c | 0 .../arch/xen/kernel/xen_proc.c | 0 .../drivers/Makefile | 3 + .../drivers/char/mem.c | 0 .../drivers/char/tty_io.c | 87 +- .../drivers/xen/Makefile | 0 .../drivers/xen/balloon/Makefile | 0 .../drivers/xen/balloon/balloon.c | 6 +- .../drivers/xen/blkback/Makefile | 0 .../drivers/xen/blkback/blkback.c | 0 .../drivers/xen/blkback/common.h | 0 .../drivers/xen/blkback/control.c | 0 .../drivers/xen/blkback/interface.c | 0 .../drivers/xen/blkback/vbd.c | 0 .../drivers/xen/blkfront/Kconfig | 0 .../drivers/xen/blkfront/Makefile | 0 .../drivers/xen/blkfront/blkfront.c | 0 .../drivers/xen/blkfront/block.h | 0 .../drivers/xen/blkfront/vbd.c | 0 .../drivers/xen/console/Makefile | 0 .../drivers/xen/console/console.c | 0 .../drivers/xen/evtchn/Makefile | 0 .../drivers/xen/evtchn/evtchn.c | 0 .../drivers/xen/netback/Makefile | 0 .../drivers/xen/netback/common.h | 0 .../drivers/xen/netback/control.c | 0 .../drivers/xen/netback/interface.c | 0 .../drivers/xen/netback/netback.c | 0 .../drivers/xen/netfront/Kconfig | 0 .../drivers/xen/netfront/Makefile | 0 .../drivers/xen/netfront/netfront.c | 0 .../drivers/xen/privcmd/Makefile | 0 .../drivers/xen/privcmd/privcmd.c | 0 .../include/asm-generic/pgtable.h | 0 .../include/asm-xen/asm-i386/desc.h | 9 + .../include/asm-xen/asm-i386/dma-mapping.h | 0 .../include/asm-xen/asm-i386/fixmap.h | 4 +- .../include/asm-xen/asm-i386/floppy.h | 0 .../include/asm-xen/asm-i386/highmem.h | 21 +- .../include/asm-xen/asm-i386/io.h | 0 .../asm-xen/asm-i386/mach-xen/irq_vectors.h | 0 .../asm-i386/mach-xen/setup_arch_post.h | 0 .../asm-i386/mach-xen/setup_arch_pre.h | 0 .../include/asm-xen/asm-i386/mmu_context.h | 0 .../include/asm-xen/asm-i386/msr.h | 0 .../include/asm-xen/asm-i386/page.h | 16 +- .../include/asm-xen/asm-i386/param.h | 0 .../include/asm-xen/asm-i386/pci.h | 0 .../include/asm-xen/asm-i386/pgalloc.h | 23 +- .../asm-xen/asm-i386/pgtable-2level-defs.h | 2 - .../include/asm-xen/asm-i386/pgtable-2level.h | 34 +- .../include/asm-xen/asm-i386/pgtable.h | 19 +- .../include/asm-xen/asm-i386/processor.h | 20 +- .../include/asm-xen/asm-i386/ptrace.h | 2 + .../include/asm-xen/asm-i386/segment.h | 0 .../include/asm-xen/asm-i386/setup.h | 0 .../include/asm-xen/asm-i386/synch_bitops.h | 0 .../include/asm-xen/asm-i386/system.h | 1 + .../include/asm-xen/asm-i386/tlbflush.h | 0 .../include/asm-xen/asm-i386/vga.h | 0 .../include/asm-xen/asm-i386/xor.h | 0 .../include/asm-xen/balloon.h | 0 .../include/asm-xen/ctrl_if.h | 0 .../include/asm-xen/evtchn.h | 0 .../include/asm-xen/foreign_page.h | 0 .../include/asm-xen/gnttab.h | 0 .../include/asm-xen/hypervisor.h | 5 +- .../include/asm-xen/linux-public/privcmd.h | 0 .../include/asm-xen/linux-public/suspend.h | 0 .../include/asm-xen/multicall.h | 0 .../include/asm-xen/queues.h | 0 .../include/asm-xen/xen_proc.h | 0 .../include/linux/gfp.h | 1 + .../include/linux/irq.h | 3 +- .../kernel/irq/manage.c | 2 + .../mkbuildtree | 0 .../mm/memory.c | 1126 ++++++++---- .../mm/page_alloc.c | 634 ++++--- 128 files changed, 1753 insertions(+), 3752 deletions(-) delete mode 100644 linux-2.6.10-xen-sparse/include/linux/skbuff.h delete mode 100644 linux-2.6.10-xen-sparse/net/core/skbuff.c rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/Kconfig (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/Kconfig.drivers (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/boot/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/configs/xen0_defconfig (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/configs/xenU_defconfig (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/Kconfig (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/cpu/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/cpu/common.c (89%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/cpu/mtrr/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/cpu/mtrr/main.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/entry.S (99%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/head.S (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/i386_ksyms.c (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/ioport.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/ldt.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/microcode.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/pci-dma.c (93%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/process.c (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/setup.c (96%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/signal.c (95%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/time.c (99%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/timers/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/timers/timer_tsc.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/traps.c (95%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/vsyscall.S (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/kernel/vsyscall.lds (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/fault.c (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/highmem.c (96%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/hypervisor.c (96%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/init.c (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/ioremap.c (96%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/pageattr.c (84%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/mm/pgtable.c (90%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/pci/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/pci/direct.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/i386/pci/irq.c (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/ctrl_if.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/devmem.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/evtchn.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/fixup.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/gnttab.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/reboot.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/skbuff.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/arch/xen/kernel/xen_proc.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/Makefile (94%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/char/mem.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/char/tty_io.c (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/balloon/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/balloon/balloon.c (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/blkback.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/common.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/control.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/interface.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkback/vbd.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkfront/Kconfig (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkfront/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkfront/blkfront.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkfront/block.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/blkfront/vbd.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/console/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/console/console.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/evtchn/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/evtchn/evtchn.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netback/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netback/common.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netback/control.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netback/interface.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netback/netback.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netfront/Kconfig (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netfront/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/netfront/netfront.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/privcmd/Makefile (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/drivers/xen/privcmd/privcmd.c (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-generic/pgtable.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/desc.h (94%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/dma-mapping.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/fixmap.h (96%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/floppy.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/highmem.h (85%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/io.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/mach-xen/irq_vectors.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/mmu_context.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/msr.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/page.h (93%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/param.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/pci.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/pgalloc.h (70%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/pgtable-2level-defs.h (90%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/pgtable-2level.h (83%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/pgtable.h (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/processor.h (97%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/ptrace.h (92%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/segment.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/setup.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/synch_bitops.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/system.h (99%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/tlbflush.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/vga.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/asm-i386/xor.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/balloon.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/ctrl_if.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/evtchn.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/foreign_page.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/gnttab.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/hypervisor.h (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/linux-public/privcmd.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/linux-public/suspend.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/multicall.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/queues.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/asm-xen/xen_proc.h (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/linux/gfp.h (98%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/linux/irq.h (99%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/kernel/irq/manage.c (99%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/mkbuildtree (100%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/mm/memory.c (66%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/mm/page_alloc.c (80%) diff --git a/.rootkeys b/.rootkeys index d15fe9d75d..8e29f01aa4 100644 --- a/.rootkeys +++ b/.rootkeys @@ -127,133 +127,131 @@ 3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.29-xen-sparse/mm/swapfile.c 41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.29-xen-sparse/mm/vmalloc.c 41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.29-xen-sparse/net/core/skbuff.c -40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.10-xen-sparse/arch/xen/Kconfig -40f56237utH41NPukqHksuNf29IC9A linux-2.6.10-xen-sparse/arch/xen/Kconfig.drivers -40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.10-xen-sparse/arch/xen/Makefile -40f56237JTc60m1FRlUxkUaGSQKrNw linux-2.6.10-xen-sparse/arch/xen/boot/Makefile -40f56237hRxbacU_3PdoAl6DjZ3Jnw linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig -40f56237wubfjJKlfIzZlI3ZM2VgGA linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig -40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.10-xen-sparse/arch/xen/i386/Kconfig -40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.10-xen-sparse/arch/xen/i386/Makefile -40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile -40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/Makefile -40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c -41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile -41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c -40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S -40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.10-xen-sparse/arch/xen/i386/kernel/head.S -40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c -40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ioport.c -40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c -41d54a76YMCA67S8J-TBT3J62Wx6yA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/microcode.c -4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c -40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c -40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c -40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c -40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c -40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/Makefile -40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c -40f562389xNa78YBZciUibQjyRU_Lg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c -40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.S -40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.lds -40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.10-xen-sparse/arch/xen/i386/mm/Makefile -40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c -4118cc35CbY8rfGVspF5O-7EkXBEAA linux-2.6.10-xen-sparse/arch/xen/i386/mm/highmem.c -40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c -40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c -41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c -413b5ab8LIowAnQrEmaOJSdmqm96jQ linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c -40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c -4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.10-xen-sparse/arch/xen/i386/pci/Makefile -4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.10-xen-sparse/arch/xen/i386/pci/direct.c -4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.10-xen-sparse/arch/xen/i386/pci/irq.c -40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile -40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.10-xen-sparse/arch/xen/kernel/ctrl_if.c -41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c -40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c -4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.10-xen-sparse/arch/xen/kernel/fixup.c -412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c -40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c -414c113396tK1HTVeUalm3u-1DF16g linux-2.6.10-xen-sparse/arch/xen/kernel/skbuff.c -3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.10-xen-sparse/arch/xen/kernel/xen_proc.c -41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.10-xen-sparse/drivers/Makefile -4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.10-xen-sparse/drivers/char/mem.c -4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.10-xen-sparse/drivers/char/tty_io.c -40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.10-xen-sparse/drivers/xen/Makefile -41768fbcncpBQf8s2l2-CwoSNIZ9uA linux-2.6.10-xen-sparse/drivers/xen/balloon/Makefile -3e6377f8i5e9eGz7Pw6fQuhuTQ7DQg linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c -410d0893otFGghmv4dUXDUBBdY5aIA linux-2.6.10-xen-sparse/drivers/xen/blkback/Makefile -4087cf0d1XgMkooTZAiJS6NrcpLQNQ linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c -4087cf0dZadZ8r6CEt4fNN350Yle3A linux-2.6.10-xen-sparse/drivers/xen/blkback/common.h -4087cf0dxlh29iw0w-9rxOCEGCjPcw linux-2.6.10-xen-sparse/drivers/xen/blkback/control.c -4087cf0dbuoH20fMjNZjcgrRK-1msQ linux-2.6.10-xen-sparse/drivers/xen/blkback/interface.c -4087cf0dk97tacDzxfByWV7JifUYqA linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c -40f56239Sfle6wGv5FS0wjS_HI150A linux-2.6.10-xen-sparse/drivers/xen/blkfront/Kconfig -40f562395atl9x4suKGhPkjqLOXESg linux-2.6.10-xen-sparse/drivers/xen/blkfront/Makefile -40f56239-JNIaTzlviVJohVdoYOUpw linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c -40f56239y9naBTXe40Pi2J_z3p-d1g linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h -40f56239BVfPsXBiWQitXgDRtOsiqg linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c -40f56239fsLjvtD8YBRAWphps4FDjg linux-2.6.10-xen-sparse/drivers/xen/console/Makefile -3e5a4e651TH-SXHoufurnWjgl5bfOA linux-2.6.10-xen-sparse/drivers/xen/console/console.c -40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6.10-xen-sparse/drivers/xen/evtchn/Makefile -40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.10-xen-sparse/drivers/xen/evtchn/evtchn.c -410a9817HEVJvred5Oy_uKH3HFJC5Q linux-2.6.10-xen-sparse/drivers/xen/netback/Makefile -4097ba831lpGeLlPg-bfV8XarVVuoQ linux-2.6.10-xen-sparse/drivers/xen/netback/common.h -4097ba83wvv8yi5P5xugCUBAdb6O-A linux-2.6.10-xen-sparse/drivers/xen/netback/control.c -4097ba83byY5bTSugJGZ1exTxIcMKw linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c -4087cf0dGmSbFhFZyIZBJzvqxY-qBw linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c -40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.10-xen-sparse/drivers/xen/netfront/Kconfig -40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.10-xen-sparse/drivers/xen/netfront/Makefile -405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c -4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.10-xen-sparse/drivers/xen/privcmd/Makefile -3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c -412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.10-xen-sparse/include/asm-generic/pgtable.h -40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h -4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h -40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h -41979925z1MsKU1SfuuheM1IFDQ_bA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/floppy.h -4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/highmem.h -40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h -40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h -40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h -40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h -4120f807GCO0uqsLqdZj9csxR1Wthw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mmu_context.h -40f5623aFTyFTR-vdiA-KaGxk5JOKQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/msr.h -40f5623adgjZq9nAgCt0IXdWl7udSA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h -40f5623a54NuG-7qHihGYmw4wWQnMA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/param.h -41137cc1kkvg0cg7uxddcEfjL7L67w linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pci.h -40f5623atCokYc2uCysSJ8jFO8TEsw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h -412e01beTwiaC8sYY4XJP8PxLST5CA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h -40f5623aEToIXouJgO-ao5d5pcEt1w linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h -40f5623aCCXRPlGpNthVXstGz9ZV3A linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h -40f5623aPCkQQfPtJSooGdhcatrvnQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/processor.h -412ea0afQL2CAI-f522TbLjLPMibPQ linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/ptrace.h -40f5623bzLvxr7WoJIxVf2OH4rCBJg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/segment.h -40f5623bG_LzgG6-qwk292nTc5Wabw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/setup.h -40f5623bgzm_9vwxpzJswlAxg298Gg linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h -40f5623bVdKP7Dt7qm8twu3NcnGNbA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h -40f5623bc8LKPRO09wY5dGDnY_YCpw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/tlbflush.h -41062ab7uFxnCq-KtPeAm-aV8CicgA linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/vga.h -40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/xor.h -41af4017PDMuSmMWtSRU5UC9Vylw5g linux-2.6.10-xen-sparse/include/asm-xen/balloon.h -40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.10-xen-sparse/include/asm-xen/ctrl_if.h -40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.10-xen-sparse/include/asm-xen/evtchn.h -419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.10-xen-sparse/include/asm-xen/foreign_page.h -412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h -40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h -3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.10-xen-sparse/include/asm-xen/linux-public/privcmd.h -3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.10-xen-sparse/include/asm-xen/linux-public/suspend.h -40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.10-xen-sparse/include/asm-xen/multicall.h -4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.10-xen-sparse/include/asm-xen/queues.h -3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.10-xen-sparse/include/asm-xen/xen_proc.h -419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.10-xen-sparse/include/linux/gfp.h -419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.10-xen-sparse/include/linux/irq.h -4124f66f4NaKNa0xPiGGykn9QaZk3w linux-2.6.10-xen-sparse/include/linux/skbuff.h -419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.10-xen-sparse/kernel/irq/manage.c -40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.10-xen-sparse/mkbuildtree -412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.10-xen-sparse/mm/memory.c -410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.10-xen-sparse/mm/page_alloc.c -41505c572m-s9ATiO1LiD1GPznTTIg linux-2.6.10-xen-sparse/net/core/skbuff.c +40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.11-xen-sparse/arch/xen/Kconfig +40f56237utH41NPukqHksuNf29IC9A linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers +40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.11-xen-sparse/arch/xen/Makefile +40f56237JTc60m1FRlUxkUaGSQKrNw linux-2.6.11-xen-sparse/arch/xen/boot/Makefile +40f56237hRxbacU_3PdoAl6DjZ3Jnw linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig +40f56237wubfjJKlfIzZlI3ZM2VgGA linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig +40f56237Mta0yHNaMS_qtM2rge0qYA linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig +40f56238u2CJdXNpjsZgHBxeVyY-2g linux-2.6.11-xen-sparse/arch/xen/i386/Makefile +40f56238eczveJ86k_4hNxCLRQIF-g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile +40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/Makefile +40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c +41ab440bnpxZdWShZrGgM9pPaz5rmA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile +41ab440bBKWz-aEOEojU4PAMXe3Ppg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c +40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S +40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.11-xen-sparse/arch/xen/i386/kernel/head.S +40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c +40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ioport.c +40f56238ue3YRsK52HG7iccNzP1AwQ linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c +41d54a76YMCA67S8J-TBT3J62Wx6yA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/microcode.c +4107adf1cNtsuOxOB4T6paAoY2R2PA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c +40f56238a8iOVDEoostsbun_sy2i4g linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c +40f56238YQIJoYG2ehDGEcdTgLmGbg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c +40f56238nWMQg7CKbyTy0KJNvCzbtg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/signal.c +40f56238qVGkpO_ycnQA8k03kQzAgA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c +40f56238NzTgeO63RGoxHrW5NQeO3Q linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/Makefile +40f56238BMqG5PuSHufpjbvp_helBw linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c +40f562389xNa78YBZciUibQjyRU_Lg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c +40f56238JypKAUG01ZojFwH7qnZ5uA linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.S +40f56238wi6AdNQjm0RT57bSkwb6hg linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.lds +40f56238a3w6-byOzexIlMgni76Lcg linux-2.6.11-xen-sparse/arch/xen/i386/mm/Makefile +40f56238ILx8xlbywNbzTdv5Zr4xXQ linux-2.6.11-xen-sparse/arch/xen/i386/mm/fault.c +4118cc35CbY8rfGVspF5O-7EkXBEAA linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c +40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c +40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c +41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c +413b5ab8LIowAnQrEmaOJSdmqm96jQ linux-2.6.11-xen-sparse/arch/xen/i386/mm/pageattr.c +40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c +4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile +4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c +4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c +40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.11-xen-sparse/arch/xen/kernel/Makefile +40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c +41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.11-xen-sparse/arch/xen/kernel/devmem.c +40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c +4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c +412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c +40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c +414c113396tK1HTVeUalm3u-1DF16g linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c +3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.11-xen-sparse/arch/xen/kernel/xen_proc.c +41261688yS8eAyy-7kzG4KBs0xbYCA linux-2.6.11-xen-sparse/drivers/Makefile +4108f5c1WfTIrs0HZFeV39sttekCTw linux-2.6.11-xen-sparse/drivers/char/mem.c +4111308bZAIzwf_Kzu6x1TZYZ3E0_Q linux-2.6.11-xen-sparse/drivers/char/tty_io.c +40f56239Dp_vMTgz8TEbvo1hjHGc3w linux-2.6.11-xen-sparse/drivers/xen/Makefile +41768fbcncpBQf8s2l2-CwoSNIZ9uA linux-2.6.11-xen-sparse/drivers/xen/balloon/Makefile +3e6377f8i5e9eGz7Pw6fQuhuTQ7DQg linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c +410d0893otFGghmv4dUXDUBBdY5aIA linux-2.6.11-xen-sparse/drivers/xen/blkback/Makefile +4087cf0d1XgMkooTZAiJS6NrcpLQNQ linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +4087cf0dZadZ8r6CEt4fNN350Yle3A linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h +4087cf0dxlh29iw0w-9rxOCEGCjPcw linux-2.6.11-xen-sparse/drivers/xen/blkback/control.c +4087cf0dbuoH20fMjNZjcgrRK-1msQ linux-2.6.11-xen-sparse/drivers/xen/blkback/interface.c +4087cf0dk97tacDzxfByWV7JifUYqA linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c +40f56239Sfle6wGv5FS0wjS_HI150A linux-2.6.11-xen-sparse/drivers/xen/blkfront/Kconfig +40f562395atl9x4suKGhPkjqLOXESg linux-2.6.11-xen-sparse/drivers/xen/blkfront/Makefile +40f56239-JNIaTzlviVJohVdoYOUpw linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c +40f56239y9naBTXe40Pi2J_z3p-d1g linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h +40f56239BVfPsXBiWQitXgDRtOsiqg linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +40f56239fsLjvtD8YBRAWphps4FDjg linux-2.6.11-xen-sparse/drivers/xen/console/Makefile +3e5a4e651TH-SXHoufurnWjgl5bfOA linux-2.6.11-xen-sparse/drivers/xen/console/console.c +40f56239KYxO0YabhPzCTeUuln-lnA linux-2.6.11-xen-sparse/drivers/xen/evtchn/Makefile +40f56239DoibTX6R-ZYd3QTXAB8_TA linux-2.6.11-xen-sparse/drivers/xen/evtchn/evtchn.c +410a9817HEVJvred5Oy_uKH3HFJC5Q linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile +4097ba831lpGeLlPg-bfV8XarVVuoQ linux-2.6.11-xen-sparse/drivers/xen/netback/common.h +4097ba83wvv8yi5P5xugCUBAdb6O-A linux-2.6.11-xen-sparse/drivers/xen/netback/control.c +4097ba83byY5bTSugJGZ1exTxIcMKw linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c +4087cf0dGmSbFhFZyIZBJzvqxY-qBw linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c +40f56239lrg_Ob0BJ8WBFS1zeg2CYw linux-2.6.11-xen-sparse/drivers/xen/netfront/Kconfig +40f56239Wd4k_ycG_mFsSO1r5xKdtQ linux-2.6.11-xen-sparse/drivers/xen/netfront/Makefile +405853f6nbeazrNyEWNHBuoSg2PiPA linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c +4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.11-xen-sparse/drivers/xen/privcmd/Makefile +3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c +412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.11-xen-sparse/include/asm-generic/pgtable.h +40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h +4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h +40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h +41979925z1MsKU1SfuuheM1IFDQ_bA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h +4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h +40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h +40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h +40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h +40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h +4120f807GCO0uqsLqdZj9csxR1Wthw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h +40f5623aFTyFTR-vdiA-KaGxk5JOKQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/msr.h +40f5623adgjZq9nAgCt0IXdWl7udSA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h +40f5623a54NuG-7qHihGYmw4wWQnMA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/param.h +41137cc1kkvg0cg7uxddcEfjL7L67w linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pci.h +40f5623atCokYc2uCysSJ8jFO8TEsw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h +412e01beTwiaC8sYY4XJP8PxLST5CA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h +40f5623aEToIXouJgO-ao5d5pcEt1w linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h +40f5623aCCXRPlGpNthVXstGz9ZV3A linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h +40f5623aPCkQQfPtJSooGdhcatrvnQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h +412ea0afQL2CAI-f522TbLjLPMibPQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/ptrace.h +40f5623bzLvxr7WoJIxVf2OH4rCBJg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/segment.h +40f5623bG_LzgG6-qwk292nTc5Wabw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/setup.h +40f5623bgzm_9vwxpzJswlAxg298Gg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h +40f5623bVdKP7Dt7qm8twu3NcnGNbA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h +40f5623bc8LKPRO09wY5dGDnY_YCpw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/tlbflush.h +41062ab7uFxnCq-KtPeAm-aV8CicgA linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/vga.h +40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/xor.h +41af4017PDMuSmMWtSRU5UC9Vylw5g linux-2.6.11-xen-sparse/include/asm-xen/balloon.h +40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.11-xen-sparse/include/asm-xen/ctrl_if.h +40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.11-xen-sparse/include/asm-xen/evtchn.h +419b4e9367PjTEvdjwavWN12BeBBXg linux-2.6.11-xen-sparse/include/asm-xen/foreign_page.h +412dfaeazclyNDM0cpnp60Yo4xulpQ linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h +40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h +3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h +3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h +40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.11-xen-sparse/include/asm-xen/multicall.h +4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.11-xen-sparse/include/asm-xen/queues.h +3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h +419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.11-xen-sparse/include/linux/gfp.h +419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.11-xen-sparse/include/linux/irq.h +419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.11-xen-sparse/kernel/irq/manage.c +40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.11-xen-sparse/mkbuildtree +412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.11-xen-sparse/mm/memory.c +410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.11-xen-sparse/mm/page_alloc.c 413cb1e4zst25MDYjg63Y-NGC5_pLg netbsd-2.0-xen-sparse/Makefile 413cb1e5c_Mkxf_X0zimEhTKI_l4DA netbsd-2.0-xen-sparse/mkbuildtree 413cb1e5kY_Zil7-b0kI6hvCIxBEYg netbsd-2.0-xen-sparse/nbconfig-xen diff --git a/linux-2.6.10-xen-sparse/include/linux/skbuff.h b/linux-2.6.10-xen-sparse/include/linux/skbuff.h deleted file mode 100644 index 57a2843faa..0000000000 --- a/linux-2.6.10-xen-sparse/include/linux/skbuff.h +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Definitions for the 'struct sk_buff' memory handlers. - * - * Authors: - * Alan Cox, - * Florian La Roche, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _LINUX_SKBUFF_H -#define _LINUX_SKBUFF_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define HAVE_ALLOC_SKB /* For the drivers to know */ -#define HAVE_ALIGNABLE_SKB /* Ditto 8) */ -#define SLAB_SKB /* Slabified skbuffs */ - -#define CHECKSUM_NONE 0 -#define CHECKSUM_HW 1 -#define CHECKSUM_UNNECESSARY 2 - -#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \ - ~(SMP_CACHE_BYTES - 1)) -#define SKB_MAX_ORDER(X, ORDER) (((PAGE_SIZE << (ORDER)) - (X) - \ - sizeof(struct skb_shared_info)) & \ - ~(SMP_CACHE_BYTES - 1)) -#define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0)) -#define SKB_MAX_ALLOC (SKB_MAX_ORDER(0, 2)) - -/* A. Checksumming of received packets by device. - * - * NONE: device failed to checksum this packet. - * skb->csum is undefined. - * - * UNNECESSARY: device parsed packet and wouldbe verified checksum. - * skb->csum is undefined. - * It is bad option, but, unfortunately, many of vendors do this. - * Apparently with secret goal to sell you new device, when you - * will add new protocol to your host. F.e. IPv6. 8) - * - * HW: the most generic way. Device supplied checksum of _all_ - * the packet as seen by netif_rx in skb->csum. - * NOTE: Even if device supports only some protocols, but - * is able to produce some skb->csum, it MUST use HW, - * not UNNECESSARY. - * - * B. Checksumming on output. - * - * NONE: skb is checksummed by protocol or csum is not required. - * - * HW: device is required to csum packet as seen by hard_start_xmit - * from skb->h.raw to the end and to record the checksum - * at skb->h.raw+skb->csum. - * - * Device must show its capabilities in dev->features, set - * at device setup time. - * NETIF_F_HW_CSUM - it is clever device, it is able to checksum - * everything. - * NETIF_F_NO_CSUM - loopback or reliable single hop media. - * NETIF_F_IP_CSUM - device is dumb. It is able to csum only - * TCP/UDP over IPv4. Sigh. Vendors like this - * way by an unknown reason. Though, see comment above - * about CHECKSUM_UNNECESSARY. 8) - * - * Any questions? No questions, good. --ANK - */ - -#ifdef __i386__ -#define NET_CALLER(arg) (*(((void **)&arg) - 1)) -#else -#define NET_CALLER(arg) __builtin_return_address(0) -#endif - -struct net_device; - -#ifdef CONFIG_NETFILTER -struct nf_conntrack { - atomic_t use; - void (*destroy)(struct nf_conntrack *); -}; - -#ifdef CONFIG_BRIDGE_NETFILTER -struct nf_bridge_info { - atomic_t use; - struct net_device *physindev; - struct net_device *physoutdev; -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - struct net_device *netoutdev; -#endif - unsigned int mask; - unsigned long data[32 / sizeof(unsigned long)]; -}; -#endif - -#endif - -struct sk_buff_head { - /* These two members must be first. */ - struct sk_buff *next; - struct sk_buff *prev; - - __u32 qlen; - spinlock_t lock; -}; - -struct sk_buff; - -/* To allow 64K frame to be packed as single skb without frag_list */ -#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) - -typedef struct skb_frag_struct skb_frag_t; - -struct skb_frag_struct { - struct page *page; - __u16 page_offset; - __u16 size; -}; - -/* This data is invariant across clones and lives at - * the end of the header data, ie. at skb->end. - */ -struct skb_shared_info { - atomic_t dataref; - unsigned int nr_frags; - unsigned short tso_size; - unsigned short tso_segs; - struct sk_buff *frag_list; - skb_frag_t frags[MAX_SKB_FRAGS]; -}; - -/** - * struct sk_buff - socket buffer - * @next: Next buffer in list - * @prev: Previous buffer in list - * @list: List we are on - * @sk: Socket we are owned by - * @stamp: Time we arrived - * @dev: Device we arrived on/are leaving by - * @input_dev: Device we arrived on - * @real_dev: The real device we are using - * @h: Transport layer header - * @nh: Network layer header - * @mac: Link layer header - * @dst: FIXME: Describe this field - * @cb: Control buffer. Free for use by every layer. Put private vars here - * @len: Length of actual data - * @data_len: Data length - * @mac_len: Length of link layer header - * @csum: Checksum - * @__unused: Dead field, may be reused - * @cloned: Head may be cloned (check refcnt to be sure) - * @pkt_type: Packet class - * @ip_summed: Driver fed us an IP checksum - * @priority: Packet queueing priority - * @users: User count - see {datagram,tcp}.c - * @protocol: Packet protocol from driver - * @security: Security level of packet - * @truesize: Buffer size - * @head: Head of buffer - * @data: Data head pointer - * @tail: Tail pointer - * @end: End pointer - * @destructor: Destruct function - * @nfmark: Can be used for communication between hooks - * @nfcache: Cache info - * @nfct: Associated connection, if any - * @nfctinfo: Relationship of this skb to the connection - * @nf_debug: Netfilter debugging - * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c - * @private: Data which is private to the HIPPI implementation - * @tc_index: Traffic control index - */ - -struct sk_buff { - /* These two members must be first. */ - struct sk_buff *next; - struct sk_buff *prev; - - struct sk_buff_head *list; - struct sock *sk; - struct timeval stamp; - struct net_device *dev; - struct net_device *input_dev; - struct net_device *real_dev; - - union { - struct tcphdr *th; - struct udphdr *uh; - struct icmphdr *icmph; - struct igmphdr *igmph; - struct iphdr *ipiph; - struct ipv6hdr *ipv6h; - unsigned char *raw; - } h; - - union { - struct iphdr *iph; - struct ipv6hdr *ipv6h; - struct arphdr *arph; - unsigned char *raw; - } nh; - - union { - unsigned char *raw; - } mac; - - struct dst_entry *dst; - struct sec_path *sp; - - /* - * This is the control buffer. It is free to use for every - * layer. Please put your private variables there. If you - * want to keep them across layers you have to do a skb_clone() - * first. This is owned by whoever has the skb queued ATM. - */ - char cb[40]; - - unsigned int len, - data_len, - mac_len, - csum; - unsigned char local_df, - cloned, - pkt_type, - ip_summed; - __u32 priority; - unsigned short protocol, - security; - - void (*destructor)(struct sk_buff *skb); -#ifdef CONFIG_NETFILTER - unsigned long nfmark; - __u32 nfcache; - __u32 nfctinfo; - struct nf_conntrack *nfct; -#ifdef CONFIG_NETFILTER_DEBUG - unsigned int nf_debug; -#endif -#ifdef CONFIG_BRIDGE_NETFILTER - struct nf_bridge_info *nf_bridge; -#endif -#endif /* CONFIG_NETFILTER */ -#if defined(CONFIG_HIPPI) - union { - __u32 ifield; - } private; -#endif -#ifdef CONFIG_NET_SCHED - __u32 tc_index; /* traffic control index */ -#ifdef CONFIG_NET_CLS_ACT - __u32 tc_verd; /* traffic control verdict */ - __u32 tc_classid; /* traffic control classid */ -#endif - -#endif - - - /* These elements must be at the end, see alloc_skb() for details. */ - unsigned int truesize; - atomic_t users; - unsigned char *head, - *data, - *tail, - *end; -}; - -#ifdef __KERNEL__ -/* - * Handling routines are only of interest to the kernel - */ -#include - -#include - -extern void __kfree_skb(struct sk_buff *skb); -extern struct sk_buff *alloc_skb(unsigned int size, int priority); -extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, - unsigned int size, int priority); -extern void kfree_skbmem(struct sk_buff *skb); -extern struct sk_buff *skb_clone(struct sk_buff *skb, int priority); -extern struct sk_buff *skb_copy(const struct sk_buff *skb, int priority); -extern struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask); -extern int pskb_expand_head(struct sk_buff *skb, - int nhead, int ntail, int gfp_mask); -extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, - unsigned int headroom); -extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, - int newheadroom, int newtailroom, - int priority); -extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad); -#define dev_kfree_skb(a) kfree_skb(a) -extern void skb_over_panic(struct sk_buff *skb, int len, - void *here); -extern void skb_under_panic(struct sk_buff *skb, int len, - void *here); - -/* Internal */ -#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) - -/** - * skb_queue_empty - check if a queue is empty - * @list: queue head - * - * Returns true if the queue is empty, false otherwise. - */ -static inline int skb_queue_empty(const struct sk_buff_head *list) -{ - return list->next == (struct sk_buff *)list; -} - -/** - * skb_get - reference buffer - * @skb: buffer to reference - * - * Makes another reference to a socket buffer and returns a pointer - * to the buffer. - */ -static inline struct sk_buff *skb_get(struct sk_buff *skb) -{ - atomic_inc(&skb->users); - return skb; -} - -/* - * If users == 1, we are the only owner and are can avoid redundant - * atomic change. - */ - -/** - * kfree_skb - free an sk_buff - * @skb: buffer to free - * - * Drop a reference to the buffer and free it if the usage count has - * hit zero. - */ -static inline void kfree_skb(struct sk_buff *skb) -{ - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - __kfree_skb(skb); -} - -/* Use this if you didn't touch the skb state [for fast switching] */ -static inline void kfree_skb_fast(struct sk_buff *skb) -{ - if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users)) - kfree_skbmem(skb); -} - -/** - * skb_cloned - is the buffer a clone - * @skb: buffer to check - * - * Returns true if the buffer was generated with skb_clone() and is - * one of multiple shared copies of the buffer. Cloned buffers are - * shared data so must not be written to under normal circumstances. - */ -static inline int skb_cloned(const struct sk_buff *skb) -{ - return skb->cloned && atomic_read(&skb_shinfo(skb)->dataref) != 1; -} - -/** - * skb_shared - is the buffer shared - * @skb: buffer to check - * - * Returns true if more than one person has a reference to this - * buffer. - */ -static inline int skb_shared(const struct sk_buff *skb) -{ - return atomic_read(&skb->users) != 1; -} - -/** - * skb_share_check - check if buffer is shared and if so clone it - * @skb: buffer to check - * @pri: priority for memory allocation - * - * If the buffer is shared the buffer is cloned and the old copy - * drops a reference. A new clone with a single reference is returned. - * If the buffer is not shared the original buffer is returned. When - * being called from interrupt status or with spinlocks held pri must - * be GFP_ATOMIC. - * - * NULL is returned on a memory allocation failure. - */ -static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri) -{ - might_sleep_if(pri & __GFP_WAIT); - if (skb_shared(skb)) { - struct sk_buff *nskb = skb_clone(skb, pri); - kfree_skb(skb); - skb = nskb; - } - return skb; -} - -/* - * Copy shared buffers into a new sk_buff. We effectively do COW on - * packets to handle cases where we have a local reader and forward - * and a couple of other messy ones. The normal one is tcpdumping - * a packet thats being forwarded. - */ - -/** - * skb_unshare - make a copy of a shared buffer - * @skb: buffer to check - * @pri: priority for memory allocation - * - * If the socket buffer is a clone then this function creates a new - * copy of the data, drops a reference count on the old copy and returns - * the new copy with the reference count at 1. If the buffer is not a clone - * the original buffer is returned. When called with a spinlock held or - * from interrupt state @pri must be %GFP_ATOMIC - * - * %NULL is returned on a memory allocation failure. - */ -static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri) -{ - might_sleep_if(pri & __GFP_WAIT); - if (skb_cloned(skb)) { - struct sk_buff *nskb = skb_copy(skb, pri); - kfree_skb(skb); /* Free our shared copy */ - skb = nskb; - } - return skb; -} - -/** - * skb_peek - * @list_: list to peek at - * - * Peek an &sk_buff. Unlike most other operations you _MUST_ - * be careful with this one. A peek leaves the buffer on the - * list and someone else may run off with it. You must hold - * the appropriate locks or have a private queue to do this. - * - * Returns %NULL for an empty list or a pointer to the head element. - * The reference count is not incremented and the reference is therefore - * volatile. Use with caution. - */ -static inline struct sk_buff *skb_peek(struct sk_buff_head *list_) -{ - struct sk_buff *list = ((struct sk_buff *)list_)->next; - if (list == (struct sk_buff *)list_) - list = NULL; - return list; -} - -/** - * skb_peek_tail - * @list_: list to peek at - * - * Peek an &sk_buff. Unlike most other operations you _MUST_ - * be careful with this one. A peek leaves the buffer on the - * list and someone else may run off with it. You must hold - * the appropriate locks or have a private queue to do this. - * - * Returns %NULL for an empty list or a pointer to the tail element. - * The reference count is not incremented and the reference is therefore - * volatile. Use with caution. - */ -static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_) -{ - struct sk_buff *list = ((struct sk_buff *)list_)->prev; - if (list == (struct sk_buff *)list_) - list = NULL; - return list; -} - -/** - * skb_queue_len - get queue length - * @list_: list to measure - * - * Return the length of an &sk_buff queue. - */ -static inline __u32 skb_queue_len(const struct sk_buff_head *list_) -{ - return list_->qlen; -} - -static inline void skb_queue_head_init(struct sk_buff_head *list) -{ - spin_lock_init(&list->lock); - list->prev = list->next = (struct sk_buff *)list; - list->qlen = 0; -} - -/* - * Insert an sk_buff at the start of a list. - * - * The "__skb_xxxx()" functions are the non-atomic ones that - * can only be called with interrupts disabled. - */ - -/** - * __skb_queue_head - queue a buffer at the list head - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the start of a list. This function takes no locks - * and you must therefore hold required locks before calling it. - * - * A buffer cannot be placed on two lists at the same time. - */ -extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk); -static inline void __skb_queue_head(struct sk_buff_head *list, - struct sk_buff *newsk) -{ - struct sk_buff *prev, *next; - - newsk->list = list; - list->qlen++; - prev = (struct sk_buff *)list; - next = prev->next; - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; -} - -/** - * __skb_queue_tail - queue a buffer at the list tail - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the end of a list. This function takes no locks - * and you must therefore hold required locks before calling it. - * - * A buffer cannot be placed on two lists at the same time. - */ -extern void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk); -static inline void __skb_queue_tail(struct sk_buff_head *list, - struct sk_buff *newsk) -{ - struct sk_buff *prev, *next; - - newsk->list = list; - list->qlen++; - next = (struct sk_buff *)list; - prev = next->prev; - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; -} - - -/** - * __skb_dequeue - remove from the head of the queue - * @list: list to dequeue from - * - * Remove the head of the list. This function does not take any locks - * so must be used with appropriate locks held only. The head item is - * returned or %NULL if the list is empty. - */ -extern struct sk_buff *skb_dequeue(struct sk_buff_head *list); -static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list) -{ - struct sk_buff *next, *prev, *result; - - prev = (struct sk_buff *) list; - next = prev->next; - result = NULL; - if (next != prev) { - result = next; - next = next->next; - list->qlen--; - next->prev = prev; - prev->next = next; - result->next = result->prev = NULL; - result->list = NULL; - } - return result; -} - - -/* - * Insert a packet on a list. - */ -extern void skb_insert(struct sk_buff *old, struct sk_buff *newsk); -static inline void __skb_insert(struct sk_buff *newsk, - struct sk_buff *prev, struct sk_buff *next, - struct sk_buff_head *list) -{ - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; - newsk->list = list; - list->qlen++; -} - -/* - * Place a packet after a given packet in a list. - */ -extern void skb_append(struct sk_buff *old, struct sk_buff *newsk); -static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - __skb_insert(newsk, old, old->next, old->list); -} - -/* - * remove sk_buff from list. _Must_ be called atomically, and with - * the list known.. - */ -extern void skb_unlink(struct sk_buff *skb); -static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) -{ - struct sk_buff *next, *prev; - - list->qlen--; - next = skb->next; - prev = skb->prev; - skb->next = skb->prev = NULL; - skb->list = NULL; - next->prev = prev; - prev->next = next; -} - - -/* XXX: more streamlined implementation */ - -/** - * __skb_dequeue_tail - remove from the tail of the queue - * @list: list to dequeue from - * - * Remove the tail of the list. This function does not take any locks - * so must be used with appropriate locks held only. The tail item is - * returned or %NULL if the list is empty. - */ -extern struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list); -static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list) -{ - struct sk_buff *skb = skb_peek_tail(list); - if (skb) - __skb_unlink(skb, list); - return skb; -} - - -static inline int skb_is_nonlinear(const struct sk_buff *skb) -{ - return skb->data_len; -} - -static inline unsigned int skb_headlen(const struct sk_buff *skb) -{ - return skb->len - skb->data_len; -} - -static inline int skb_pagelen(const struct sk_buff *skb) -{ - int i, len = 0; - - for (i = (int)skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) - len += skb_shinfo(skb)->frags[i].size; - return len + skb_headlen(skb); -} - -static inline void skb_fill_page_desc(struct sk_buff *skb, int i, - struct page *page, int off, int size) -{ - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - frag->page = page; - frag->page_offset = off; - frag->size = size; - skb_shinfo(skb)->nr_frags = i + 1; -} - -#define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) -#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list) -#define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) - -/* - * Add data to an sk_buff - */ -static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp = skb->tail; - SKB_LINEAR_ASSERT(skb); - skb->tail += len; - skb->len += len; - return tmp; -} - -/** - * skb_put - add data to a buffer - * @skb: buffer to use - * @len: amount of data to add - * - * This function extends the used data area of the buffer. If this would - * exceed the total buffer size the kernel will panic. A pointer to the - * first byte of the extra data is returned. - */ -static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp = skb->tail; - SKB_LINEAR_ASSERT(skb); - skb->tail += len; - skb->len += len; - if (unlikely(skb->tail>skb->end)) - skb_over_panic(skb, len, current_text_addr()); - return tmp; -} - -static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len) -{ - skb->data -= len; - skb->len += len; - return skb->data; -} - -/** - * skb_push - add data to the start of a buffer - * @skb: buffer to use - * @len: amount of data to add - * - * This function extends the used data area of the buffer at the buffer - * start. If this would exceed the total buffer headroom the kernel will - * panic. A pointer to the first byte of the extra data is returned. - */ -static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len) -{ - skb->data -= len; - skb->len += len; - if (unlikely(skb->datahead)) - skb_under_panic(skb, len, current_text_addr()); - return skb->data; -} - -static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) -{ - skb->len -= len; - BUG_ON(skb->len < skb->data_len); - return skb->data += len; -} - -/** - * skb_pull - remove data from the start of a buffer - * @skb: buffer to use - * @len: amount of data to remove - * - * This function removes data from the start of a buffer, returning - * the memory to the headroom. A pointer to the next data in the buffer - * is returned. Once the data has been pulled future pushes will overwrite - * the old data. - */ -static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) -{ - return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); -} - -extern unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta); - -static inline unsigned char *__pskb_pull(struct sk_buff *skb, unsigned int len) -{ - if (len > skb_headlen(skb) && - !__pskb_pull_tail(skb, len-skb_headlen(skb))) - return NULL; - skb->len -= len; - return skb->data += len; -} - -static inline unsigned char *pskb_pull(struct sk_buff *skb, unsigned int len) -{ - return unlikely(len > skb->len) ? NULL : __pskb_pull(skb, len); -} - -static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len) -{ - if (likely(len <= skb_headlen(skb))) - return 1; - if (unlikely(len > skb->len)) - return 0; - return __pskb_pull_tail(skb, len-skb_headlen(skb)) != NULL; -} - -/** - * skb_headroom - bytes at buffer head - * @skb: buffer to check - * - * Return the number of bytes of free space at the head of an &sk_buff. - */ -static inline int skb_headroom(const struct sk_buff *skb) -{ - return skb->data - skb->head; -} - -/** - * skb_tailroom - bytes at buffer end - * @skb: buffer to check - * - * Return the number of bytes of free space at the tail of an sk_buff - */ -static inline int skb_tailroom(const struct sk_buff *skb) -{ - return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail; -} - -/** - * skb_reserve - adjust headroom - * @skb: buffer to alter - * @len: bytes to move - * - * Increase the headroom of an empty &sk_buff by reducing the tail - * room. This is only allowed for an empty buffer. - */ -static inline void skb_reserve(struct sk_buff *skb, unsigned int len) -{ - skb->data += len; - skb->tail += len; -} - -/* - * CPUs often take a performance hit when accessing unaligned memory - * locations. The actual performance hit varies, it can be small if the - * hardware handles it or large if we have to take an exception and fix it - * in software. - * - * Since an ethernet header is 14 bytes network drivers often end up with - * the IP header at an unaligned offset. The IP header can be aligned by - * shifting the start of the packet by 2 bytes. Drivers should do this - * with: - * - * skb_reserve(NET_IP_ALIGN); - * - * The downside to this alignment of the IP header is that the DMA is now - * unaligned. On some architectures the cost of an unaligned DMA is high - * and this cost outweighs the gains made by aligning the IP header. - * - * Since this trade off varies between architectures, we allow NET_IP_ALIGN - * to be overridden. - */ -#ifndef NET_IP_ALIGN -#define NET_IP_ALIGN 2 -#endif - -extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); - -static inline void __skb_trim(struct sk_buff *skb, unsigned int len) -{ - if (!skb->data_len) { - skb->len = len; - skb->tail = skb->data + len; - } else - ___pskb_trim(skb, len, 0); -} - -/** - * skb_trim - remove end from a buffer - * @skb: buffer to alter - * @len: new length - * - * Cut the length of a buffer down by removing data from the tail. If - * the buffer is already under the length specified it is not modified. - */ -static inline void skb_trim(struct sk_buff *skb, unsigned int len) -{ - if (skb->len > len) - __skb_trim(skb, len); -} - - -static inline int __pskb_trim(struct sk_buff *skb, unsigned int len) -{ - if (!skb->data_len) { - skb->len = len; - skb->tail = skb->data+len; - return 0; - } - return ___pskb_trim(skb, len, 1); -} - -static inline int pskb_trim(struct sk_buff *skb, unsigned int len) -{ - return (len < skb->len) ? __pskb_trim(skb, len) : 0; -} - -/** - * skb_orphan - orphan a buffer - * @skb: buffer to orphan - * - * If a buffer currently has an owner then we call the owner's - * destructor function and make the @skb unowned. The buffer continues - * to exist but is no longer charged to its former owner. - */ -static inline void skb_orphan(struct sk_buff *skb) -{ - if (skb->destructor) - skb->destructor(skb); - skb->destructor = NULL; - skb->sk = NULL; -} - -/** - * __skb_queue_purge - empty a list - * @list: list to empty - * - * Delete all buffers on an &sk_buff list. Each buffer is removed from - * the list and one reference dropped. This function does not take the - * list lock and the caller must hold the relevant locks to use it. - */ -extern void skb_queue_purge(struct sk_buff_head *list); -static inline void __skb_queue_purge(struct sk_buff_head *list) -{ - struct sk_buff *skb; - while ((skb = __skb_dequeue(list)) != NULL) - kfree_skb(skb); -} - -/** - * __dev_alloc_skb - allocate an skbuff for sending - * @length: length to allocate - * @gfp_mask: get_free_pages mask, passed to alloc_skb - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned in there is no free memory. - */ -#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB -static inline struct sk_buff *__dev_alloc_skb(unsigned int length, - int gfp_mask) -{ - struct sk_buff *skb = alloc_skb(length + 16, gfp_mask); - if (likely(skb)) - skb_reserve(skb, 16); - return skb; -} -#else -extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask); -#endif - -/** - * dev_alloc_skb - allocate an skbuff for sending - * @length: length to allocate - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned in there is no free memory. Although this function - * allocates memory it can be called from an interrupt. - */ -static inline struct sk_buff *dev_alloc_skb(unsigned int length) -{ - return __dev_alloc_skb(length, GFP_ATOMIC); -} - -/** - * skb_cow - copy header of skb when it is required - * @skb: buffer to cow - * @headroom: needed headroom - * - * If the skb passed lacks sufficient headroom or its data part - * is shared, data is reallocated. If reallocation fails, an error - * is returned and original skb is not changed. - * - * The result is skb with writable area skb->head...skb->tail - * and at least @headroom of space at head. - */ -static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) -{ - int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb); - - if (delta < 0) - delta = 0; - - if (delta || skb_cloned(skb)) - return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC); - return 0; -} - -/** - * skb_padto - pad an skbuff up to a minimal size - * @skb: buffer to pad - * @len: minimal length - * - * Pads up a buffer to ensure the trailing bytes exist and are - * blanked. If the buffer already contains sufficient data it - * is untouched. Returns the buffer, which may be a replacement - * for the original, or NULL for out of memory - in which case - * the original buffer is still freed. - */ - -static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) -{ - unsigned int size = skb->len; - if (likely(size >= len)) - return skb; - return skb_pad(skb, len-size); -} - -static inline int skb_add_data(struct sk_buff *skb, - char __user *from, int copy) -{ - const int off = skb->len; - - if (skb->ip_summed == CHECKSUM_NONE) { - int err = 0; - unsigned int csum = csum_and_copy_from_user(from, - skb_put(skb, copy), - copy, 0, &err); - if (!err) { - skb->csum = csum_block_add(skb->csum, csum, off); - return 0; - } - } else if (!copy_from_user(skb_put(skb, copy), from, copy)) - return 0; - - __skb_trim(skb, off); - return -EFAULT; -} - -static inline int skb_can_coalesce(struct sk_buff *skb, int i, - struct page *page, int off) -{ - if (i) { - struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i - 1]; - - return page == frag->page && - off == frag->page_offset + frag->size; - } - return 0; -} - -/** - * skb_linearize - convert paged skb to linear one - * @skb: buffer to linarize - * @gfp: allocation mode - * - * If there is no free memory -ENOMEM is returned, otherwise zero - * is returned and the old skb data released. - */ -extern int __skb_linearize(struct sk_buff *skb, int gfp); -static inline int skb_linearize(struct sk_buff *skb, int gfp) -{ - return __skb_linearize(skb, gfp); -} - -static inline void *kmap_skb_frag(const skb_frag_t *frag) -{ -#ifdef CONFIG_HIGHMEM - BUG_ON(in_irq()); - - local_bh_disable(); -#endif - return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ); -} - -static inline void kunmap_skb_frag(void *vaddr) -{ - kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); -#ifdef CONFIG_HIGHMEM - local_bh_enable(); -#endif -} - -#define skb_queue_walk(queue, skb) \ - for (skb = (queue)->next, prefetch(skb->next); \ - (skb != (struct sk_buff *)(queue)); \ - skb = skb->next, prefetch(skb->next)) - - -extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, - int noblock, int *err); -extern unsigned int datagram_poll(struct file *file, struct socket *sock, - struct poll_table_struct *wait); -extern int skb_copy_datagram(const struct sk_buff *from, - int offset, char __user *to, int size); -extern int skb_copy_datagram_iovec(const struct sk_buff *from, - int offset, struct iovec *to, - int size); -extern int skb_copy_and_csum_datagram(const struct sk_buff *skb, - int offset, u8 __user *to, - int len, unsigned int *csump); -extern int skb_copy_and_csum_datagram_iovec(const - struct sk_buff *skb, - int hlen, - struct iovec *iov); -extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); -extern unsigned int skb_checksum(const struct sk_buff *skb, int offset, - int len, unsigned int csum); -extern int skb_copy_bits(const struct sk_buff *skb, int offset, - void *to, int len); -extern unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, - int offset, u8 *to, int len, - unsigned int csum); -extern void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to); -extern void skb_split(struct sk_buff *skb, - struct sk_buff *skb1, const u32 len); - -static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, - int len, void *buffer) -{ - int hlen = skb_headlen(skb); - - if (offset + len <= hlen) - return skb->data + offset; - - if (skb_copy_bits(skb, offset, buffer, len) < 0) - return NULL; - - return buffer; -} - -extern void skb_init(void); -extern void skb_add_mtu(int mtu); - -struct skb_iter { - /* Iteration functions set these */ - unsigned char *data; - unsigned int len; - - /* Private to iteration */ - unsigned int nextfrag; - struct sk_buff *fraglist; -}; - -/* Keep iterating until skb_iter_next returns false. */ -extern void skb_iter_first(const struct sk_buff *skb, struct skb_iter *i); -extern int skb_iter_next(const struct sk_buff *skb, struct skb_iter *i); -/* Call this if aborting loop before !skb_iter_next */ -extern void skb_iter_abort(const struct sk_buff *skb, struct skb_iter *i); - -#ifdef CONFIG_NETFILTER -static inline void nf_conntrack_put(struct nf_conntrack *nfct) -{ - if (nfct && atomic_dec_and_test(&nfct->use)) - nfct->destroy(nfct); -} -static inline void nf_conntrack_get(struct nf_conntrack *nfct) -{ - if (nfct) - atomic_inc(&nfct->use); -} -static inline void nf_reset(struct sk_buff *skb) -{ - nf_conntrack_put(skb->nfct); - skb->nfct = NULL; -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -} -static inline void nf_reset_debug(struct sk_buff *skb) -{ -#ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; -#endif -} - -#ifdef CONFIG_BRIDGE_NETFILTER -static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) -{ - if (nf_bridge && atomic_dec_and_test(&nf_bridge->use)) - kfree(nf_bridge); -} -static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) -{ - if (nf_bridge) - atomic_inc(&nf_bridge->use); -} -#endif /* CONFIG_BRIDGE_NETFILTER */ -#else /* CONFIG_NETFILTER */ -static inline void nf_reset(struct sk_buff *skb) {} -#endif /* CONFIG_NETFILTER */ - -#endif /* __KERNEL__ */ -#endif /* _LINUX_SKBUFF_H */ diff --git a/linux-2.6.10-xen-sparse/net/core/skbuff.c b/linux-2.6.10-xen-sparse/net/core/skbuff.c deleted file mode 100644 index 4e2936caab..0000000000 --- a/linux-2.6.10-xen-sparse/net/core/skbuff.c +++ /dev/null @@ -1,1521 +0,0 @@ -/* - * Routines having to do with the 'struct sk_buff' memory handlers. - * - * Authors: Alan Cox - * Florian La Roche - * - * Version: $Id: skbuff.c,v 1.90 2001/11/07 05:56:19 davem Exp $ - * - * Fixes: - * Alan Cox : Fixed the worst of the load - * balancer bugs. - * Dave Platt : Interrupt stacking fix. - * Richard Kooijman : Timestamp fixes. - * Alan Cox : Changed buffer format. - * Alan Cox : destructor hook for AF_UNIX etc. - * Linus Torvalds : Better skb_clone. - * Alan Cox : Added skb_copy. - * Alan Cox : Added all the changed routines Linus - * only put in the headers - * Ray VanTassle : Fixed --skb->lock in free - * Alan Cox : skb_copy copy arp field - * Andi Kleen : slabified it. - * Robert Olsson : Removed skb_head_pool - * - * NOTE: - * The __skb_ routines should be called with interrupts - * disabled, or you better be *real* sure that the operation is atomic - * with respect to whatever list is being frobbed (e.g. via lock_sock() - * or via disabling bottom half handlers, etc). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -/* - * The functions in this file will not compile correctly with gcc 2.4.x - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_NET_CLS_ACT -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -static kmem_cache_t *skbuff_head_cache; - -/* - * Keep out-of-line to prevent kernel bloat. - * __builtin_return_address is not used because it is not always - * reliable. - */ - -/** - * skb_over_panic - private function - * @skb: buffer - * @sz: size - * @here: address - * - * Out of line support code for skb_put(). Not user callable. - */ -void skb_over_panic(struct sk_buff *skb, int sz, void *here) -{ - printk(KERN_INFO "skput:over: %p:%d put:%d dev:%s", - here, skb->len, sz, skb->dev ? skb->dev->name : ""); - BUG(); -} - -/** - * skb_under_panic - private function - * @skb: buffer - * @sz: size - * @here: address - * - * Out of line support code for skb_push(). Not user callable. - */ - -void skb_under_panic(struct sk_buff *skb, int sz, void *here) -{ - printk(KERN_INFO "skput:under: %p:%d put:%d dev:%s", - here, skb->len, sz, skb->dev ? skb->dev->name : ""); - BUG(); -} - -/* Allocate a new skbuff. We do this ourselves so we can fill in a few - * 'private' fields and also do memory statistics to find all the - * [BEEP] leaks. - * - */ - -/** - * alloc_skb - allocate a network buffer - * @size: size to allocate - * @gfp_mask: allocation mask - * - * Allocate a new &sk_buff. The returned buffer has no headroom and a - * tail room of size bytes. The object has a reference count of one. - * The return is the buffer. On a failure the return is %NULL. - * - * Buffers may only be allocated from interrupts using a @gfp_mask of - * %GFP_ATOMIC. - */ -struct sk_buff *alloc_skb(unsigned int size, int gfp_mask) -{ - struct sk_buff *skb; - u8 *data; - - /* Get the HEAD */ - skb = kmem_cache_alloc(skbuff_head_cache, - gfp_mask & ~__GFP_DMA); - if (!skb) - goto out; - - /* Get the DATA. Size must match skb_add_mtu(). */ - size = SKB_DATA_ALIGN(size); - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (!data) - goto nodata; - - memset(skb, 0, offsetof(struct sk_buff, truesize)); - skb->truesize = size + sizeof(struct sk_buff); - atomic_set(&skb->users, 1); - skb->head = data; - skb->data = data; - skb->tail = data; - skb->end = data + size; - - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->tso_size = 0; - skb_shinfo(skb)->tso_segs = 0; - skb_shinfo(skb)->frag_list = NULL; -out: - return skb; -nodata: - kmem_cache_free(skbuff_head_cache, skb); - skb = NULL; - goto out; -} - -/** - * alloc_skb_from_cache - allocate a network buffer - * @cp: kmem_cache from which to allocate the data area - * (object size must be big enough for @size bytes + skb overheads) - * @size: size to allocate - * @gfp_mask: allocation mask - * - * Allocate a new &sk_buff. The returned buffer has no headroom and a - * tail room of size bytes. The object has a reference count of one. - * The return is the buffer. On a failure the return is %NULL. - * - * Buffers may only be allocated from interrupts using a @gfp_mask of - * %GFP_ATOMIC. - */ -struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, - unsigned int size, int gfp_mask) -{ - struct sk_buff *skb; - u8 *data; - - /* Get the HEAD */ - skb = kmem_cache_alloc(skbuff_head_cache, - gfp_mask & ~__GFP_DMA); - if (!skb) - goto out; - - /* Get the DATA. */ - size = SKB_DATA_ALIGN(size); - data = kmem_cache_alloc(cp, gfp_mask); - if (!data) - goto nodata; - - memset(skb, 0, offsetof(struct sk_buff, truesize)); - skb->truesize = size + sizeof(struct sk_buff); - atomic_set(&skb->users, 1); - skb->head = data; - skb->data = data; - skb->tail = data; - skb->end = data + size; - - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->tso_size = 0; - skb_shinfo(skb)->tso_segs = 0; - skb_shinfo(skb)->frag_list = NULL; -out: - return skb; -nodata: - kmem_cache_free(skbuff_head_cache, skb); - skb = NULL; - goto out; -} - - -static void skb_drop_fraglist(struct sk_buff *skb) -{ - struct sk_buff *list = skb_shinfo(skb)->frag_list; - - skb_shinfo(skb)->frag_list = NULL; - - do { - struct sk_buff *this = list; - list = list->next; - kfree_skb(this); - } while (list); -} - -static void skb_clone_fraglist(struct sk_buff *skb) -{ - struct sk_buff *list; - - for (list = skb_shinfo(skb)->frag_list; list; list = list->next) - skb_get(list); -} - -void skb_release_data(struct sk_buff *skb) -{ - if (!skb->cloned || - atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) { - if (skb_shinfo(skb)->nr_frags) { - int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - put_page(skb_shinfo(skb)->frags[i].page); - } - - if (skb_shinfo(skb)->frag_list) - skb_drop_fraglist(skb); - - kfree(skb->head); - } -} - -/* - * Free an skbuff by memory without cleaning the state. - */ -void kfree_skbmem(struct sk_buff *skb) -{ - skb_release_data(skb); - kmem_cache_free(skbuff_head_cache, skb); -} - -/** - * __kfree_skb - private function - * @skb: buffer - * - * Free an sk_buff. Release anything attached to the buffer. - * Clean the state. This is an internal helper function. Users should - * always call kfree_skb - */ - -void __kfree_skb(struct sk_buff *skb) -{ - if (skb->list) { - printk(KERN_WARNING "Warning: kfree_skb passed an skb still " - "on a list (from %p).\n", NET_CALLER(skb)); - BUG(); - } - - dst_release(skb->dst); -#ifdef CONFIG_XFRM - secpath_put(skb->sp); -#endif - if(skb->destructor) { - if (in_irq()) - printk(KERN_WARNING "Warning: kfree_skb on " - "hard IRQ %p\n", NET_CALLER(skb)); - skb->destructor(skb); - } -#ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); -#ifdef CONFIG_BRIDGE_NETFILTER - nf_bridge_put(skb->nf_bridge); -#endif -#endif -/* XXX: IS this still necessary? - JHS */ -#ifdef CONFIG_NET_SCHED - skb->tc_index = 0; -#ifdef CONFIG_NET_CLS_ACT - skb->tc_verd = 0; - skb->tc_classid = 0; -#endif -#endif - - kfree_skbmem(skb); -} - -/** - * skb_clone - duplicate an sk_buff - * @skb: buffer to clone - * @gfp_mask: allocation priority - * - * Duplicate an &sk_buff. The new one is not owned by a socket. Both - * copies share the same packet data but not structure. The new - * buffer has a reference count of 1. If the allocation fails the - * function returns %NULL otherwise the new buffer is returned. - * - * If this function is called from an interrupt gfp_mask() must be - * %GFP_ATOMIC. - */ - -struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) -{ - struct sk_buff *n = kmem_cache_alloc(skbuff_head_cache, gfp_mask); - - if (!n) - return NULL; - -#define C(x) n->x = skb->x - - n->next = n->prev = NULL; - n->list = NULL; - n->sk = NULL; - C(stamp); - C(dev); - C(real_dev); - C(h); - C(nh); - C(mac); - C(dst); - dst_clone(skb->dst); - C(sp); -#ifdef CONFIG_INET - secpath_get(skb->sp); -#endif - memcpy(n->cb, skb->cb, sizeof(skb->cb)); - C(len); - C(data_len); - C(csum); - C(local_df); - n->cloned = 1; - C(pkt_type); - C(ip_summed); - C(priority); - C(protocol); - C(security); - n->destructor = NULL; -#ifdef CONFIG_NETFILTER - C(nfmark); - C(nfcache); - C(nfct); - nf_conntrack_get(skb->nfct); - C(nfctinfo); -#ifdef CONFIG_NETFILTER_DEBUG - C(nf_debug); -#endif -#ifdef CONFIG_BRIDGE_NETFILTER - C(nf_bridge); - nf_bridge_get(skb->nf_bridge); -#endif -#endif /*CONFIG_NETFILTER*/ -#if defined(CONFIG_HIPPI) - C(private); -#endif -#ifdef CONFIG_NET_SCHED - C(tc_index); -#ifdef CONFIG_NET_CLS_ACT - n->tc_verd = SET_TC_VERD(skb->tc_verd,0); - n->tc_verd = CLR_TC_OK2MUNGE(skb->tc_verd); - n->tc_verd = CLR_TC_MUNGED(skb->tc_verd); - C(input_dev); - C(tc_classid); -#endif - -#endif - C(truesize); - atomic_set(&n->users, 1); - C(head); - C(data); - C(tail); - C(end); - - atomic_inc(&(skb_shinfo(skb)->dataref)); - skb->cloned = 1; - - return n; -} - -static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -{ - /* - * Shift between the two data areas in bytes - */ - unsigned long offset = new->data - old->data; - - new->list = NULL; - new->sk = NULL; - new->dev = old->dev; - new->real_dev = old->real_dev; - new->priority = old->priority; - new->protocol = old->protocol; - new->dst = dst_clone(old->dst); -#ifdef CONFIG_INET - new->sp = secpath_get(old->sp); -#endif - new->h.raw = old->h.raw + offset; - new->nh.raw = old->nh.raw + offset; - new->mac.raw = old->mac.raw + offset; - memcpy(new->cb, old->cb, sizeof(old->cb)); - new->local_df = old->local_df; - new->pkt_type = old->pkt_type; - new->stamp = old->stamp; - new->destructor = NULL; - new->security = old->security; -#ifdef CONFIG_NETFILTER - new->nfmark = old->nfmark; - new->nfcache = old->nfcache; - new->nfct = old->nfct; - nf_conntrack_get(old->nfct); - new->nfctinfo = old->nfctinfo; -#ifdef CONFIG_NETFILTER_DEBUG - new->nf_debug = old->nf_debug; -#endif -#ifdef CONFIG_BRIDGE_NETFILTER - new->nf_bridge = old->nf_bridge; - nf_bridge_get(old->nf_bridge); -#endif -#endif -#ifdef CONFIG_NET_SCHED -#ifdef CONFIG_NET_CLS_ACT - new->tc_verd = old->tc_verd; -#endif - new->tc_index = old->tc_index; -#endif - atomic_set(&new->users, 1); - skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size; - skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs; -} - -/** - * skb_copy - create private copy of an sk_buff - * @skb: buffer to copy - * @gfp_mask: allocation priority - * - * Make a copy of both an &sk_buff and its data. This is used when the - * caller wishes to modify the data and needs a private copy of the - * data to alter. Returns %NULL on failure or the pointer to the buffer - * on success. The returned buffer has a reference count of 1. - * - * As by-product this function converts non-linear &sk_buff to linear - * one, so that &sk_buff becomes completely private and caller is allowed - * to modify all the data of returned buffer. This means that this - * function is not recommended for use in circumstances when only - * header is going to be modified. Use pskb_copy() instead. - */ - -struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask) -{ - int headerlen = skb->data - skb->head; - /* - * Allocate the copy buffer - */ - struct sk_buff *n = alloc_skb(skb->end - skb->head + skb->data_len, - gfp_mask); - if (!n) - return NULL; - - /* Set the data pointer */ - skb_reserve(n, headerlen); - /* Set the tail pointer and length */ - skb_put(n, skb->len); - n->csum = skb->csum; - n->ip_summed = skb->ip_summed; - - if (skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len)) - BUG(); - - copy_skb_header(n, skb); - return n; -} - - -/** - * pskb_copy - create copy of an sk_buff with private head. - * @skb: buffer to copy - * @gfp_mask: allocation priority - * - * Make a copy of both an &sk_buff and part of its data, located - * in header. Fragmented data remain shared. This is used when - * the caller wishes to modify only header of &sk_buff and needs - * private copy of the header to alter. Returns %NULL on failure - * or the pointer to the buffer on success. - * The returned buffer has a reference count of 1. - */ - -struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask) -{ - /* - * Allocate the copy buffer - */ - struct sk_buff *n = alloc_skb(skb->end - skb->head, gfp_mask); - - if (!n) - goto out; - - /* Set the data pointer */ - skb_reserve(n, skb->data - skb->head); - /* Set the tail pointer and length */ - skb_put(n, skb_headlen(skb)); - /* Copy the bytes */ - memcpy(n->data, skb->data, n->len); - n->csum = skb->csum; - n->ip_summed = skb->ip_summed; - - n->data_len = skb->data_len; - n->len = skb->len; - - if (skb_shinfo(skb)->nr_frags) { - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; - get_page(skb_shinfo(n)->frags[i].page); - } - skb_shinfo(n)->nr_frags = i; - } - - if (skb_shinfo(skb)->frag_list) { - skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; - skb_clone_fraglist(n); - } - - copy_skb_header(n, skb); -out: - return n; -} - -/** - * pskb_expand_head - reallocate header of &sk_buff - * @skb: buffer to reallocate - * @nhead: room to add at head - * @ntail: room to add at tail - * @gfp_mask: allocation priority - * - * Expands (or creates identical copy, if &nhead and &ntail are zero) - * header of skb. &sk_buff itself is not changed. &sk_buff MUST have - * reference count of 1. Returns zero in the case of success or error, - * if expansion failed. In the last case, &sk_buff is not changed. - * - * All the pointers pointing into skb header may change and must be - * reloaded after call to this function. - */ - -int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask) -{ - int i; - u8 *data; - int size = nhead + (skb->end - skb->head) + ntail; - long off; - - if (skb_shared(skb)) - BUG(); - - size = SKB_DATA_ALIGN(size); - - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (!data) - goto nodata; - - /* Copy only real data... and, alas, header. This should be - * optimized for the cases when header is void. */ - memcpy(data + nhead, skb->head, skb->tail - skb->head); - memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - get_page(skb_shinfo(skb)->frags[i].page); - - if (skb_shinfo(skb)->frag_list) - skb_clone_fraglist(skb); - - skb_release_data(skb); - - off = (data + nhead) - skb->head; - - skb->head = data; - skb->end = data + size; - skb->data += off; - skb->tail += off; - skb->mac.raw += off; - skb->h.raw += off; - skb->nh.raw += off; - skb->cloned = 0; - atomic_set(&skb_shinfo(skb)->dataref, 1); - return 0; - -nodata: - return -ENOMEM; -} - -/* Make private copy of skb with writable head and some headroom */ - -struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) -{ - struct sk_buff *skb2; - int delta = headroom - skb_headroom(skb); - - if (delta <= 0) - skb2 = pskb_copy(skb, GFP_ATOMIC); - else { - skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2 && pskb_expand_head(skb2, SKB_DATA_ALIGN(delta), 0, - GFP_ATOMIC)) { - kfree_skb(skb2); - skb2 = NULL; - } - } - return skb2; -} - - -/** - * skb_copy_expand - copy and expand sk_buff - * @skb: buffer to copy - * @newheadroom: new free bytes at head - * @newtailroom: new free bytes at tail - * @gfp_mask: allocation priority - * - * Make a copy of both an &sk_buff and its data and while doing so - * allocate additional space. - * - * This is used when the caller wishes to modify the data and needs a - * private copy of the data to alter as well as more space for new fields. - * Returns %NULL on failure or the pointer to the buffer - * on success. The returned buffer has a reference count of 1. - * - * You must pass %GFP_ATOMIC as the allocation priority if this function - * is called from an interrupt. - * - * BUG ALERT: ip_summed is not copied. Why does this work? Is it used - * only by netfilter in the cases when checksum is recalculated? --ANK - */ -struct sk_buff *skb_copy_expand(const struct sk_buff *skb, - int newheadroom, int newtailroom, int gfp_mask) -{ - /* - * Allocate the copy buffer - */ - struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom, - gfp_mask); - int head_copy_len, head_copy_off; - - if (!n) - return NULL; - - skb_reserve(n, newheadroom); - - /* Set the tail pointer and length */ - skb_put(n, skb->len); - - head_copy_len = skb_headroom(skb); - head_copy_off = 0; - if (newheadroom <= head_copy_len) - head_copy_len = newheadroom; - else - head_copy_off = newheadroom - head_copy_len; - - /* Copy the linear header and data. */ - if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off, - skb->len + head_copy_len)) - BUG(); - - copy_skb_header(n, skb); - - return n; -} - -/** - * skb_pad - zero pad the tail of an skb - * @skb: buffer to pad - * @pad: space to pad - * - * Ensure that a buffer is followed by a padding area that is zero - * filled. Used by network drivers which may DMA or transfer data - * beyond the buffer end onto the wire. - * - * May return NULL in out of memory cases. - */ - -struct sk_buff *skb_pad(struct sk_buff *skb, int pad) -{ - struct sk_buff *nskb; - - /* If the skbuff is non linear tailroom is always zero.. */ - if (skb_tailroom(skb) >= pad) { - memset(skb->data+skb->len, 0, pad); - return skb; - } - - nskb = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + pad, GFP_ATOMIC); - kfree_skb(skb); - if (nskb) - memset(nskb->data+nskb->len, 0, pad); - return nskb; -} - -/* Trims skb to length len. It can change skb pointers, if "realloc" is 1. - * If realloc==0 and trimming is impossible without change of data, - * it is BUG(). - */ - -int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc) -{ - int offset = skb_headlen(skb); - int nfrags = skb_shinfo(skb)->nr_frags; - int i; - - for (i = 0; i < nfrags; i++) { - int end = offset + skb_shinfo(skb)->frags[i].size; - if (end > len) { - if (skb_cloned(skb)) { - if (!realloc) - BUG(); - if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) - return -ENOMEM; - } - if (len <= offset) { - put_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb)->nr_frags--; - } else { - skb_shinfo(skb)->frags[i].size = len - offset; - } - } - offset = end; - } - - if (offset < len) { - skb->data_len -= skb->len - len; - skb->len = len; - } else { - if (len <= skb_headlen(skb)) { - skb->len = len; - skb->data_len = 0; - skb->tail = skb->data + len; - if (skb_shinfo(skb)->frag_list && !skb_cloned(skb)) - skb_drop_fraglist(skb); - } else { - skb->data_len -= skb->len - len; - skb->len = len; - } - } - - return 0; -} - -/** - * __pskb_pull_tail - advance tail of skb header - * @skb: buffer to reallocate - * @delta: number of bytes to advance tail - * - * The function makes a sense only on a fragmented &sk_buff, - * it expands header moving its tail forward and copying necessary - * data from fragmented part. - * - * &sk_buff MUST have reference count of 1. - * - * Returns %NULL (and &sk_buff does not change) if pull failed - * or value of new tail of skb in the case of success. - * - * All the pointers pointing into skb header may change and must be - * reloaded after call to this function. - */ - -/* Moves tail of skb head forward, copying data from fragmented part, - * when it is necessary. - * 1. It may fail due to malloc failure. - * 2. It may change skb pointers. - * - * It is pretty complicated. Luckily, it is called only in exceptional cases. - */ -unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) -{ - /* If skb has not enough free space at tail, get new one - * plus 128 bytes for future expansions. If we have enough - * room at tail, reallocate without expansion only if skb is cloned. - */ - int i, k, eat = (skb->tail + delta) - skb->end; - - if (eat > 0 || skb_cloned(skb)) { - if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0, - GFP_ATOMIC)) - return NULL; - } - - if (skb_copy_bits(skb, skb_headlen(skb), skb->tail, delta)) - BUG(); - - /* Optimization: no fragments, no reasons to preestimate - * size of pulled pages. Superb. - */ - if (!skb_shinfo(skb)->frag_list) - goto pull_pages; - - /* Estimate size of pulled pages. */ - eat = delta; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size >= eat) - goto pull_pages; - eat -= skb_shinfo(skb)->frags[i].size; - } - - /* If we need update frag list, we are in troubles. - * Certainly, it possible to add an offset to skb data, - * but taking into account that pulling is expected to - * be very rare operation, it is worth to fight against - * further bloating skb head and crucify ourselves here instead. - * Pure masohism, indeed. 8)8) - */ - if (eat) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; - struct sk_buff *clone = NULL; - struct sk_buff *insp = NULL; - - do { - if (!list) - BUG(); - - if (list->len <= eat) { - /* Eaten as whole. */ - eat -= list->len; - list = list->next; - insp = list; - } else { - /* Eaten partially. */ - - if (skb_shared(list)) { - /* Sucks! We need to fork list. :-( */ - clone = skb_clone(list, GFP_ATOMIC); - if (!clone) - return NULL; - insp = list->next; - list = clone; - } else { - /* This may be pulled without - * problems. */ - insp = list; - } - if (!pskb_pull(list, eat)) { - if (clone) - kfree_skb(clone); - return NULL; - } - break; - } - } while (eat); - - /* Free pulled out fragments. */ - while ((list = skb_shinfo(skb)->frag_list) != insp) { - skb_shinfo(skb)->frag_list = list->next; - kfree_skb(list); - } - /* And insert new clone at head. */ - if (clone) { - clone->next = list; - skb_shinfo(skb)->frag_list = clone; - } - } - /* Success! Now we may commit changes to skb data. */ - -pull_pages: - eat = delta; - k = 0; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - if (skb_shinfo(skb)->frags[i].size <= eat) { - put_page(skb_shinfo(skb)->frags[i].page); - eat -= skb_shinfo(skb)->frags[i].size; - } else { - skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; - if (eat) { - skb_shinfo(skb)->frags[k].page_offset += eat; - skb_shinfo(skb)->frags[k].size -= eat; - eat = 0; - } - k++; - } - } - skb_shinfo(skb)->nr_frags = k; - - skb->tail += delta; - skb->data_len -= delta; - - return skb->tail; -} - -/* Copy some data bits from skb to kernel buffer. */ - -int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) -{ - int i, copy; - int start = skb_headlen(skb); - - if (offset > (int)skb->len - len) - goto fault; - - /* Copy header. */ - if ((copy = start - offset) > 0) { - if (copy > len) - copy = len; - memcpy(to, skb->data + offset, copy); - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - } - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - BUG_TRAP(start <= offset + len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end - offset) > 0) { - u8 *vaddr; - - if (copy > len) - copy = len; - - vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); - memcpy(to, - vaddr + skb_shinfo(skb)->frags[i].page_offset+ - offset - start, copy); - kunmap_skb_frag(vaddr); - - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - } - start = end; - } - - if (skb_shinfo(skb)->frag_list) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; - - for (; list; list = list->next) { - int end; - - BUG_TRAP(start <= offset + len); - - end = start + list->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - if (skb_copy_bits(list, offset - start, - to, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - } - start = end; - } - } - if (!len) - return 0; - -fault: - return -EFAULT; -} - -/* Keep iterating until skb_iter_next returns false. */ -void skb_iter_first(const struct sk_buff *skb, struct skb_iter *i) -{ - i->len = skb_headlen(skb); - i->data = (unsigned char *)skb->data; - i->nextfrag = 0; - i->fraglist = NULL; -} - -int skb_iter_next(const struct sk_buff *skb, struct skb_iter *i) -{ - /* Unmap previous, if not head fragment. */ - if (i->nextfrag) - kunmap_skb_frag(i->data); - - if (i->fraglist) { - fraglist: - /* We're iterating through fraglist. */ - if (i->nextfrag < skb_shinfo(i->fraglist)->nr_frags) { - i->data = kmap_skb_frag(&skb_shinfo(i->fraglist) - ->frags[i->nextfrag]); - i->len = skb_shinfo(i->fraglist)->frags[i->nextfrag] - .size; - i->nextfrag++; - return 1; - } - /* Fragments with fragments? Too hard! */ - BUG_ON(skb_shinfo(i->fraglist)->frag_list); - i->fraglist = i->fraglist->next; - if (!i->fraglist) - goto end; - - i->len = skb_headlen(i->fraglist); - i->data = i->fraglist->data; - i->nextfrag = 0; - return 1; - } - - if (i->nextfrag < skb_shinfo(skb)->nr_frags) { - i->data = kmap_skb_frag(&skb_shinfo(skb)->frags[i->nextfrag]); - i->len = skb_shinfo(skb)->frags[i->nextfrag].size; - i->nextfrag++; - return 1; - } - - i->fraglist = skb_shinfo(skb)->frag_list; - if (i->fraglist) - goto fraglist; - -end: - /* Bug trap for callers */ - i->data = NULL; - return 0; -} - -void skb_iter_abort(const struct sk_buff *skb, struct skb_iter *i) -{ - /* Unmap previous, if not head fragment. */ - if (i->data && i->nextfrag) - kunmap_skb_frag(i->data); - /* Bug trap for callers */ - i->data = NULL; -} - -/* Checksum skb data. */ - -unsigned int skb_checksum(const struct sk_buff *skb, int offset, - int len, unsigned int csum) -{ - int start = skb_headlen(skb); - int i, copy = start - offset; - int pos = 0; - - /* Checksum header. */ - if (copy > 0) { - if (copy > len) - copy = len; - csum = csum_partial(skb->data + offset, copy, csum); - if ((len -= copy) == 0) - return csum; - offset += copy; - pos = copy; - } - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - BUG_TRAP(start <= offset + len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end - offset) > 0) { - unsigned int csum2; - u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - if (copy > len) - copy = len; - vaddr = kmap_skb_frag(frag); - csum2 = csum_partial(vaddr + frag->page_offset + - offset - start, copy, 0); - kunmap_skb_frag(vaddr); - csum = csum_block_add(csum, csum2, pos); - if (!(len -= copy)) - return csum; - offset += copy; - pos += copy; - } - start = end; - } - - if (skb_shinfo(skb)->frag_list) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; - - for (; list; list = list->next) { - int end; - - BUG_TRAP(start <= offset + len); - - end = start + list->len; - if ((copy = end - offset) > 0) { - unsigned int csum2; - if (copy > len) - copy = len; - csum2 = skb_checksum(list, offset - start, - copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - pos += copy; - } - start = end; - } - } - if (len) - BUG(); - - return csum; -} - -/* Both of above in one bottle. */ - -unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, - u8 *to, int len, unsigned int csum) -{ - int start = skb_headlen(skb); - int i, copy = start - offset; - int pos = 0; - - /* Copy header. */ - if (copy > 0) { - if (copy > len) - copy = len; - csum = csum_partial_copy_nocheck(skb->data + offset, to, - copy, csum); - if ((len -= copy) == 0) - return csum; - offset += copy; - to += copy; - pos = copy; - } - - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - BUG_TRAP(start <= offset + len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end - offset) > 0) { - unsigned int csum2; - u8 *vaddr; - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - - if (copy > len) - copy = len; - vaddr = kmap_skb_frag(frag); - csum2 = csum_partial_copy_nocheck(vaddr + - frag->page_offset + - offset - start, to, - copy, 0); - kunmap_skb_frag(vaddr); - csum = csum_block_add(csum, csum2, pos); - if (!(len -= copy)) - return csum; - offset += copy; - to += copy; - pos += copy; - } - start = end; - } - - if (skb_shinfo(skb)->frag_list) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; - - for (; list; list = list->next) { - unsigned int csum2; - int end; - - BUG_TRAP(start <= offset + len); - - end = start + list->len; - if ((copy = end - offset) > 0) { - if (copy > len) - copy = len; - csum2 = skb_copy_and_csum_bits(list, - offset - start, - to, copy, 0); - csum = csum_block_add(csum, csum2, pos); - if ((len -= copy) == 0) - return csum; - offset += copy; - to += copy; - pos += copy; - } - start = end; - } - } - if (len) - BUG(); - return csum; -} - -void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) -{ - unsigned int csum; - long csstart; - - if (skb->ip_summed == CHECKSUM_HW) - csstart = skb->h.raw - skb->data; - else - csstart = skb_headlen(skb); - - if (csstart > skb_headlen(skb)) - BUG(); - - memcpy(to, skb->data, csstart); - - csum = 0; - if (csstart != skb->len) - csum = skb_copy_and_csum_bits(skb, csstart, to + csstart, - skb->len - csstart, 0); - - if (skb->ip_summed == CHECKSUM_HW) { - long csstuff = csstart + skb->csum; - - *((unsigned short *)(to + csstuff)) = csum_fold(csum); - } -} - -/** - * skb_dequeue - remove from the head of the queue - * @list: list to dequeue from - * - * Remove the head of the list. The list lock is taken so the function - * may be used safely with other locking list functions. The head item is - * returned or %NULL if the list is empty. - */ - -struct sk_buff *skb_dequeue(struct sk_buff_head *list) -{ - unsigned long flags; - struct sk_buff *result; - - spin_lock_irqsave(&list->lock, flags); - result = __skb_dequeue(list); - spin_unlock_irqrestore(&list->lock, flags); - return result; -} - -/** - * skb_dequeue_tail - remove from the tail of the queue - * @list: list to dequeue from - * - * Remove the tail of the list. The list lock is taken so the function - * may be used safely with other locking list functions. The tail item is - * returned or %NULL if the list is empty. - */ -struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) -{ - unsigned long flags; - struct sk_buff *result; - - spin_lock_irqsave(&list->lock, flags); - result = __skb_dequeue_tail(list); - spin_unlock_irqrestore(&list->lock, flags); - return result; -} - -/** - * skb_queue_purge - empty a list - * @list: list to empty - * - * Delete all buffers on an &sk_buff list. Each buffer is removed from - * the list and one reference dropped. This function takes the list - * lock and is atomic with respect to other list locking functions. - */ -void skb_queue_purge(struct sk_buff_head *list) -{ - struct sk_buff *skb; - while ((skb = skb_dequeue(list)) != NULL) - kfree_skb(skb); -} - -/** - * skb_queue_head - queue a buffer at the list head - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the start of the list. This function takes the - * list lock and can be used safely with other locking &sk_buff functions - * safely. - * - * A buffer cannot be placed on two lists at the same time. - */ -void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - __skb_queue_head(list, newsk); - spin_unlock_irqrestore(&list->lock, flags); -} - -/** - * skb_queue_tail - queue a buffer at the list tail - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the tail of the list. This function takes the - * list lock and can be used safely with other locking &sk_buff functions - * safely. - * - * A buffer cannot be placed on two lists at the same time. - */ -void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - __skb_queue_tail(list, newsk); - spin_unlock_irqrestore(&list->lock, flags); -} -/** - * skb_unlink - remove a buffer from a list - * @skb: buffer to remove - * - * Place a packet after a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls - * - * Works even without knowing the list it is sitting on, which can be - * handy at times. It also means that THE LIST MUST EXIST when you - * unlink. Thus a list must have its contents unlinked before it is - * destroyed. - */ -void skb_unlink(struct sk_buff *skb) -{ - struct sk_buff_head *list = skb->list; - - if (list) { - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - if (skb->list == list) - __skb_unlink(skb, skb->list); - spin_unlock_irqrestore(&list->lock, flags); - } -} - - -/** - * skb_append - append a buffer - * @old: buffer to insert after - * @newsk: buffer to insert - * - * Place a packet after a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls. - * A buffer cannot be placed on two lists at the same time. - */ - -void skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&old->list->lock, flags); - __skb_append(old, newsk); - spin_unlock_irqrestore(&old->list->lock, flags); -} - - -/** - * skb_insert - insert a buffer - * @old: buffer to insert before - * @newsk: buffer to insert - * - * Place a packet before a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls - * A buffer cannot be placed on two lists at the same time. - */ - -void skb_insert(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&old->list->lock, flags); - __skb_insert(newsk, old->prev, old, old->list); - spin_unlock_irqrestore(&old->list->lock, flags); -} - -#if 0 -/* - * Tune the memory allocator for a new MTU size. - */ -void skb_add_mtu(int mtu) -{ - /* Must match allocation in alloc_skb */ - mtu = SKB_DATA_ALIGN(mtu) + sizeof(struct skb_shared_info); - - kmem_add_cache_size(mtu); -} -#endif - -static inline void skb_split_inside_header(struct sk_buff *skb, - struct sk_buff* skb1, - const u32 len, const int pos) -{ - int i; - - memcpy(skb_put(skb1, pos - len), skb->data + len, pos - len); - - /* And move data appendix as is. */ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i]; - - skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags; - skb_shinfo(skb)->nr_frags = 0; - skb1->data_len = skb->data_len; - skb1->len += skb1->data_len; - skb->data_len = 0; - skb->len = len; - skb->tail = skb->data + len; -} - -static inline void skb_split_no_header(struct sk_buff *skb, - struct sk_buff* skb1, - const u32 len, int pos) -{ - int i, k = 0; - const int nfrags = skb_shinfo(skb)->nr_frags; - - skb_shinfo(skb)->nr_frags = 0; - skb1->len = skb1->data_len = skb->len - len; - skb->len = len; - skb->data_len = len - pos; - - for (i = 0; i < nfrags; i++) { - int size = skb_shinfo(skb)->frags[i].size; - - if (pos + size > len) { - skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i]; - - if (pos < len) { - /* Split frag. - * We have to variants in this case: - * 1. Move all the frag to the second - * part, if it is possible. F.e. - * this approach is mandatory for TUX, - * where splitting is expensive. - * 2. Split is accurately. We make this. - */ - get_page(skb_shinfo(skb)->frags[i].page); - skb_shinfo(skb1)->frags[0].page_offset += len - pos; - skb_shinfo(skb1)->frags[0].size -= len - pos; - skb_shinfo(skb)->frags[i].size = len - pos; - skb_shinfo(skb)->nr_frags++; - } - k++; - } else - skb_shinfo(skb)->nr_frags++; - pos += size; - } - skb_shinfo(skb1)->nr_frags = k; -} - -/** - * skb_split - Split fragmented skb to two parts at length len. - */ -void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) -{ - int pos = skb_headlen(skb); - - if (len < pos) /* Split line is inside header. */ - skb_split_inside_header(skb, skb1, len, pos); - else /* Second chunk has no header, nothing to copy. */ - skb_split_no_header(skb, skb1, len, pos); -} - -void __init skb_init(void) -{ - skbuff_head_cache = kmem_cache_create("skbuff_head_cache", - sizeof(struct sk_buff), - 0, - SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (!skbuff_head_cache) - panic("cannot create skbuff cache"); -} - -EXPORT_SYMBOL(___pskb_trim); -EXPORT_SYMBOL(__kfree_skb); -EXPORT_SYMBOL(__pskb_pull_tail); -EXPORT_SYMBOL(alloc_skb); -EXPORT_SYMBOL(pskb_copy); -EXPORT_SYMBOL(pskb_expand_head); -EXPORT_SYMBOL(skb_checksum); -EXPORT_SYMBOL(skb_clone); -EXPORT_SYMBOL(skb_clone_fraglist); -EXPORT_SYMBOL(skb_copy); -EXPORT_SYMBOL(skb_copy_and_csum_bits); -EXPORT_SYMBOL(skb_copy_and_csum_dev); -EXPORT_SYMBOL(skb_copy_bits); -EXPORT_SYMBOL(skb_copy_expand); -EXPORT_SYMBOL(skb_over_panic); -EXPORT_SYMBOL(skb_pad); -EXPORT_SYMBOL(skb_realloc_headroom); -EXPORT_SYMBOL(skb_under_panic); -EXPORT_SYMBOL(skb_dequeue); -EXPORT_SYMBOL(skb_dequeue_tail); -EXPORT_SYMBOL(skb_insert); -EXPORT_SYMBOL(skb_queue_purge); -EXPORT_SYMBOL(skb_queue_head); -EXPORT_SYMBOL(skb_queue_tail); -EXPORT_SYMBOL(skb_unlink); -EXPORT_SYMBOL(skb_append); -EXPORT_SYMBOL(skb_split); -EXPORT_SYMBOL(skb_iter_first); -EXPORT_SYMBOL(skb_iter_next); -EXPORT_SYMBOL(skb_iter_abort); diff --git a/linux-2.6.10-xen-sparse/arch/xen/Kconfig b/linux-2.6.11-xen-sparse/arch/xen/Kconfig similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/Kconfig rename to linux-2.6.11-xen-sparse/arch/xen/Kconfig diff --git a/linux-2.6.10-xen-sparse/arch/xen/Kconfig.drivers b/linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/Kconfig.drivers rename to linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers diff --git a/linux-2.6.10-xen-sparse/arch/xen/Makefile b/linux-2.6.11-xen-sparse/arch/xen/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/boot/Makefile b/linux-2.6.11-xen-sparse/arch/xen/boot/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/boot/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/boot/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/configs/xen0_defconfig rename to linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig diff --git a/linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/configs/xenU_defconfig rename to linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/Kconfig b/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig similarity index 98% rename from linux-2.6.10-xen-sparse/arch/xen/i386/Kconfig rename to linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig index 7a3a73d869..f6dd7b5203 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/Kconfig +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/Kconfig @@ -253,6 +253,10 @@ config RWSEM_XCHGADD_ALGORITHM depends on !M386 default y +config GENERIC_CALIBRATE_DELAY + bool + default y + config X86_PPRO_FENCE bool depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 @@ -398,6 +402,17 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. +config PREEMPT_BKL + bool "Preempt The Big Kernel Lock" + depends on PREEMPT + default y + help + This option reduces the latency of the kernel by making the + big kernel lock preemptible. + + Say Y here if you are building a kernel for a desktop system. + Say N if you are unsure. + #config X86_TSC # bool # depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ @@ -638,7 +653,7 @@ config REGPARM depends on EXPERIMENTAL default n help - Compile the kernel with -mregparm=3. This uses an different ABI + Compile the kernel with -mregparm=3. This uses a different ABI and passes the first three arguments of a function call in registers. This will probably break binary only modules. @@ -729,6 +744,8 @@ config PCI_DIRECT depends on PCI default y +source "drivers/pci/pcie/Kconfig" + source "drivers/pci/Kconfig" config ISA diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c similarity index 89% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c index a29a7f4e97..dc60f9d677 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/common.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/common.c @@ -10,6 +10,11 @@ #include #include #include +#ifdef CONFIG_X86_LOCAL_APIC +#include +#include +#include +#endif #include #include "cpu.h" @@ -277,8 +282,10 @@ void __init generic_identify(struct cpuinfo_x86 * c) /* AMD-defined flags: level 0x80000001 */ xlvl = cpuid_eax(0x80000000); if ( (xlvl & 0xffff0000) == 0x80000000 ) { - if ( xlvl >= 0x80000001 ) + if ( xlvl >= 0x80000001 ) { c->x86_capability[1] = cpuid_edx(0x80000001); + c->x86_capability[6] = cpuid_ecx(0x80000001); + } if ( xlvl >= 0x80000004 ) get_model_name(c); /* Default name */ } @@ -324,6 +331,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) c->x86_model = c->x86_mask = 0; /* So far unknown... */ c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ + c->x86_num_cores = 1; memset(&c->x86_capability, 0, sizeof c->x86_capability); if (!have_cpuid_p()) { @@ -337,21 +345,19 @@ void __init identify_cpu(struct cpuinfo_x86 *c) generic_identify(c); - printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n", - c->x86_capability[0], - c->x86_capability[1], - c->x86_capability[2], - c->x86_capability[3]); + printk(KERN_DEBUG "CPU: After generic identify, caps:"); + for (i = 0; i < NCAPINTS; i++) + printk(" %08lx", c->x86_capability[i]); + printk("\n"); if (this_cpu->c_identify) { this_cpu->c_identify(c); - printk(KERN_DEBUG "CPU: After vendor identify, caps: %08lx %08lx %08lx %08lx\n", - c->x86_capability[0], - c->x86_capability[1], - c->x86_capability[2], - c->x86_capability[3]); -} + printk(KERN_DEBUG "CPU: After vendor identify, caps:"); + for (i = 0; i < NCAPINTS; i++) + printk(" %08lx", c->x86_capability[i]); + printk("\n"); + } /* * Vendor-specific initialization. In this section we @@ -403,11 +409,10 @@ void __init identify_cpu(struct cpuinfo_x86 *c) /* Now the feature flags better reflect actual CPU features! */ - printk(KERN_DEBUG "CPU: After all inits, caps: %08lx %08lx %08lx %08lx\n", - c->x86_capability[0], - c->x86_capability[1], - c->x86_capability[2], - c->x86_capability[3]); + printk(KERN_DEBUG "CPU: After all inits, caps:"); + for (i = 0; i < NCAPINTS; i++) + printk(" %08lx", c->x86_capability[i]); + printk("\n"); /* * On SMP, boot_cpu_data holds the common feature set between @@ -437,6 +442,50 @@ void __init dodgy_tsc(void) cpu_devs[X86_VENDOR_CYRIX]->c_init(&boot_cpu_data); } +#ifdef CONFIG_X86_HT +void __init detect_ht(struct cpuinfo_x86 *c) +{ + u32 eax, ebx, ecx, edx; + int index_lsb, index_msb, tmp; + int cpu = smp_processor_id(); + + if (!cpu_has(c, X86_FEATURE_HT)) + return; + + cpuid(1, &eax, &ebx, &ecx, &edx); + smp_num_siblings = (ebx & 0xff0000) >> 16; + + if (smp_num_siblings == 1) { + printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); + } else if (smp_num_siblings > 1 ) { + index_lsb = 0; + index_msb = 31; + + if (smp_num_siblings > NR_CPUS) { + printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); + smp_num_siblings = 1; + return; + } + tmp = smp_num_siblings; + while ((tmp & 1) == 0) { + tmp >>=1 ; + index_lsb++; + } + tmp = smp_num_siblings; + while ((tmp & 0x80000000 ) == 0) { + tmp <<=1 ; + index_msb--; + } + if (index_lsb != index_msb ) + index_msb++; + phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); + + printk(KERN_INFO "CPU: Physical Processor ID: %d\n", + phys_proc_id[cpu]); + } +} +#endif + void __init print_cpu_info(struct cpuinfo_x86 *c) { char *vendor = NULL; @@ -460,7 +509,7 @@ void __init print_cpu_info(struct cpuinfo_x86 *c) printk("\n"); } -unsigned long cpu_initialized __initdata = 0; +cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; /* This is hacky. :) * We're emulating future behavior. @@ -533,7 +582,7 @@ void __init cpu_init (void) struct tss_struct * t = &per_cpu(init_tss, cpu); struct thread_struct *thread = ¤t->thread; - if (test_and_set_bit(cpu, &cpu_initialized)) { + if (cpu_test_and_set(cpu, cpu_initialized)) { printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); for (;;) local_irq_enable(); } @@ -601,6 +650,6 @@ void __init cpu_init (void) * Force FPU initialization: */ current_thread_info()->status = 0; - current->used_math = 0; + clear_used_math(); mxcsr_feature_mask_init(); } diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S similarity index 99% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S index 321f89e3d4..af2fad5236 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/entry.S @@ -198,6 +198,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) XEN_GET_VCPU_INFO(%esi) + XEN_BLOCK_EVENTS(%esi) cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_all need_resched: @@ -206,11 +207,7 @@ need_resched: jz restore_all testb $0xFF,EVENT_MASK(%esp) # interrupts off (exception path) ? jnz restore_all - movl $PREEMPT_ACTIVE,TI_preempt_count(%ebp) - XEN_UNBLOCK_EVENTS(%esi) - call schedule - XEN_BLOCK_EVENTS(%esi) - movl $0,TI_preempt_count(%ebp) + call preempt_schedule_irq jmp need_resched #endif diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/head.S b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/head.S similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/head.S rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/head.S diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c similarity index 98% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c index 90c816717a..0a326e4af6 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c @@ -61,7 +61,6 @@ extern unsigned long get_cmos_time(void); /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); -EXPORT_SYMBOL(MCA_bus); #ifdef CONFIG_DISCONTIGMEM EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(physnode_map); @@ -75,7 +74,6 @@ EXPORT_SYMBOL_GPL(kernel_fpu_begin); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(ioremap_nocache); EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(pm_idle); #ifdef CONFIG_APM diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ioport.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ioport.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ioport.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ioport.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/ldt.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/microcode.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/microcode.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/microcode.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/microcode.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c similarity index 93% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c index c346281405..f93554394d 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/pci-dma.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c @@ -36,6 +36,7 @@ xen_contig_memory(unsigned long vstart, unsigned int order) * hypercalls reduced. */ pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long pfn, i, flags; @@ -47,7 +48,8 @@ xen_contig_memory(unsigned long vstart, unsigned int order) /* 1. Zap current PTEs, giving away the underlying pages. */ for (i = 0; i < (1<pte_low >> PAGE_SHIFT; queue_l1_entry_update(pte, 0); @@ -63,7 +65,8 @@ xen_contig_memory(unsigned long vstart, unsigned int order) /* 3. Map the new extent in place of old pages. */ for (i = 0; i < (1<dma_mem = kmalloc(GFP_KERNEL, sizeof(struct dma_coherent_mem)); + dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); if (!dev->dma_mem) goto out; memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); - dev->dma_mem->bitmap = kmalloc(GFP_KERNEL, bitmap_size); + dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); if (!dev->dma_mem->bitmap) goto free1_out; memset(dev->dma_mem->bitmap, 0, bitmap_size); @@ -206,6 +209,7 @@ void dma_release_declared_memory(struct device *dev) if(!mem) return; dev->dma_mem = NULL; + iounmap(mem->virt_base); kfree(mem->bitmap); kfree(mem); } diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c similarity index 97% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c index 26dee14c3a..6500ff9a2c 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/process.c @@ -74,6 +74,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) * Powermanagement idle function, if any.. */ void (*pm_idle)(void); +static cpumask_t cpu_idle_map; void disable_hlt(void) { @@ -119,23 +120,39 @@ void xen_idle(void) */ void cpu_idle (void) { + int cpu = _smp_processor_id(); + /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { - /* - * Mark this as an RCU critical section so that - * synchronize_kernel() in the unload path waits - * for our completion. - */ - rcu_read_lock(); - irq_stat[smp_processor_id()].idle_timestamp = jiffies; + + if (cpu_isset(cpu, cpu_idle_map)) + cpu_clear(cpu, cpu_idle_map); + rmb(); + + irq_stat[cpu].idle_timestamp = jiffies; xen_idle(); - rcu_read_unlock(); } schedule(); } } +void cpu_idle_wait(void) +{ + int cpu; + cpumask_t map; + + for_each_online_cpu(cpu) + cpu_set(cpu, cpu_idle_map); + + wmb(); + do { + ssleep(1); + cpus_and(map, cpu_idle_map, cpu_online_map); + } while (!cpus_empty(map)); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); + /* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ /* Always use xen_idle() instead. */ void __init select_idle_routine(const struct cpuinfo_x86 *c) {} @@ -237,7 +254,7 @@ void flush_thread(void) * Forget coprocessor state.. */ clear_fpu(tsk); - tsk->used_math = 0; + clear_used_math(); } void release_thread(struct task_struct *dead_task) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c similarity index 96% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c index ab77b119b1..9b892b04ba 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -86,7 +87,6 @@ int __initdata acpi_force = 0; extern acpi_interrupt_flags acpi_sci_flags; #endif -int MCA_bus; /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; unsigned int machine_submodel_id; @@ -96,6 +96,9 @@ unsigned int mca_pentium_flag; /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0x10000000; +/* Boot loader ID as an integer, for the benefit of proc_dointvec */ +int bootloader_type; + /* user-defined highmem size */ static unsigned int highmem_pages = -1; @@ -694,6 +697,8 @@ static void __init parse_cmdline_early (char ** cmdline_p) saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; for (;;) { + if (c != ' ') + goto next_char; /* * "mem=nopentium" disables the 4MB page tables. * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM @@ -704,7 +709,7 @@ static void __init parse_cmdline_early (char ** cmdline_p) * HPA tells me bootloaders need to parse mem=, so no new * option should be mem= [also see Documentation/i386/boot.txt] */ - if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (!memcmp(from, "mem=", 4)) { if (to != command_line) to--; if (!memcmp(from+4, "nopentium", 9)) { @@ -731,7 +736,7 @@ static void __init parse_cmdline_early (char ** cmdline_p) } } - if (c == ' ' && !memcmp(from, "memmap=", 7)) { + else if (!memcmp(from, "memmap=", 7)) { if (to != command_line) to--; if (!memcmp(from+7, "exactmap", 8)) { @@ -764,6 +769,10 @@ static void __init parse_cmdline_early (char ** cmdline_p) } } + else if (!memcmp(from, "noexec=", 7)) + noexec_setup(from + 7); + + #ifdef CONFIG_X86_SMP /* * If the BIOS enumerates physical processors before logical, @@ -839,7 +848,7 @@ static void __init parse_cmdline_early (char ** cmdline_p) * This works even on boxes that have no highmem otherwise. * This also works to reduce highmem size on bigger boxes. */ - if (c == ' ' && !memcmp(from, "highmem=", 8)) + else if (!memcmp(from, "highmem=", 8)) highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; /* @@ -847,9 +856,10 @@ static void __init parse_cmdline_early (char ** cmdline_p) * bytes. This can be used to increase (or decrease) the * vmalloc area - the default is 128m. */ - if (c == ' ' && !memcmp(from, "vmalloc=", 8)) + else if (!memcmp(from, "vmalloc=", 8)) __VMALLOC_RESERVE = memparse(from+8, &from); + next_char: c = *(from++); if (!c) break; @@ -1191,9 +1201,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat /* * Request address space for all standard resources */ -static void __init register_memory(unsigned long max_low_pfn) +static void __init register_memory(void) { - unsigned long low_mem_size; + unsigned long gapstart, gapsize; + unsigned long long last; int i; if (efi_enabled) @@ -1208,10 +1219,46 @@ static void __init register_memory(unsigned long max_low_pfn) for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); - /* Tell the PCI layer not to allocate too close to the RAM area.. */ - low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; - if (low_mem_size > pci_mem_start) - pci_mem_start = low_mem_size; + /* + * Search for the bigest gap in the low 32 bits of the e820 + * memory space. + */ + last = 0x100000000ull; + gapstart = 0x10000000; + gapsize = 0x400000; + i = e820.nr_map; + while (--i >= 0) { + unsigned long long start = e820.map[i].addr; + unsigned long long end = start + e820.map[i].size; + + /* + * Since "last" is at most 4GB, we know we'll + * fit in 32 bits if this condition is true + */ + if (last > end) { + unsigned long gap = last - end; + + if (gap > gapsize) { + gapsize = gap; + gapstart = end; + } + } + if (start < last) + last = start; + } + + /* + * Start allocating dynamic PCI memory a bit into the gap, + * aligned up to the nearest megabyte. + * + * Question: should we try to pad it up a bit (do something + * like " + (gapsize >> 3)" in there too?). We now have the + * technology. + */ + pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; + + printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", + pci_mem_start, gapstart, gapsize); } /* Use inline assembly to define this because the nops are defined @@ -1323,6 +1370,15 @@ __setup("noreplacement", noreplacement_setup); static char * __init machine_specific_memory_setup(void); +#ifdef CONFIG_MCA +static void set_mca_bus(int x) +{ + MCA_bus = x; +} +#else +static void set_mca_bus(int x) { } +#endif + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1370,12 +1426,13 @@ void __init setup_arch(char **cmdline_p) ist_info = IST_INFO; saved_videomode = VIDEO_MODE; if( SYS_DESC_TABLE.length != 0 ) { - MCA_bus = SYS_DESC_TABLE.table[3] &0x2; + set_mca_bus(SYS_DESC_TABLE.table[3] & 0x2); machine_id = SYS_DESC_TABLE.table[0]; machine_submodel_id = SYS_DESC_TABLE.table[1]; BIOS_revision = SYS_DESC_TABLE.table[2]; } aux_device_present = AUX_DEVICE_INFO; + bootloader_type = LOADER_TYPE; #ifdef CONFIG_XEN_PHYSDEV_ACCESS /* This is drawn from a dump from vgacon:startup in standard Linux. */ @@ -1487,6 +1544,7 @@ void __init setup_arch(char **cmdline_p) /* * Parse the ACPI tables for possible boot-time SMP configuration. */ + acpi_boot_table_init(); acpi_boot_init(); #ifdef CONFIG_X86_LOCAL_APIC @@ -1498,7 +1556,7 @@ void __init setup_arch(char **cmdline_p) * conflicts. */ noirqdebug_setup(""); - register_memory(max_low_pfn); + register_memory(); /* If we are a privileged guest OS then we should request IO privs. */ if (xen_start_info.flags & SIF_PRIVILEGED) { diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/signal.c similarity index 95% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/signal.c index cdd26f714e..9e17fc80e9 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/signal.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/signal.c @@ -190,6 +190,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax if (verify_area(VERIFY_READ, buf, sizeof(*buf))) goto badframe; err |= restore_i387(buf); + } else { + struct task_struct *me = current; + if (used_math()) { + clear_fpu(me); + clear_used_math(); + } } } @@ -270,7 +276,6 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, struct pt_regs *regs, unsigned long mask) { int tmp, err = 0; - unsigned long eflags; tmp = 0; __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp)); @@ -292,16 +297,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, err |= __put_user(current->thread.error_code, &sc->err); err |= __put_user(regs->eip, &sc->eip); err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs); - - /* - * Iff TF was set because the program is being single-stepped by a - * debugger, don't save that information on the signal stack.. We - * don't want debugging to change state. - */ - eflags = regs->eflags; - if (current->ptrace & PT_DTRACE) - eflags &= ~TF_MASK; - err |= __put_user(eflags, &sc->eflags); + err |= __put_user(regs->eflags, &sc->eflags); err |= __put_user(regs->esp, &sc->esp_at_signal); err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss); @@ -369,20 +365,20 @@ static void setup_frame(int sig, struct k_sigaction *ka, ? current_thread_info()->exec_domain->signal_invmap[sig] : sig; - err |= __put_user(usig, &frame->sig); + err = __put_user(usig, &frame->sig); if (err) goto give_sigsegv; - err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]); + err = setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]); if (err) goto give_sigsegv; if (_NSIG_WORDS > 1) { - err |= __copy_to_user(&frame->extramask, &set->sig[1], + err = __copy_to_user(&frame->extramask, &set->sig[1], sizeof(frame->extramask)); + if (err) + goto give_sigsegv; } - if (err) - goto give_sigsegv; restorer = &__kernel_sigreturn; if (ka->sa.sa_flags & SA_RESTORER) @@ -424,11 +420,9 @@ static void setup_frame(int sig, struct k_sigaction *ka, * The tracer may want to single-step inside the * handler too. */ - if (regs->eflags & TF_MASK) { - regs->eflags &= ~TF_MASK; - if (current->ptrace & PT_DTRACE) - ptrace_notify(SIGTRAP); - } + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", @@ -519,11 +513,9 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * The tracer may want to single-step inside the * handler too. */ - if (regs->eflags & TF_MASK) { - regs->eflags &= ~TF_MASK; - if (current->ptrace & PT_DTRACE) - ptrace_notify(SIGTRAP); - } + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c similarity index 99% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c index 47eabac205..5d09ae6a0a 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -79,9 +80,9 @@ unsigned long cpu_khz; /* Detected as we calibrate the TSC */ extern unsigned long wall_jiffies; -spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(rtc_lock); -spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); extern struct init_timer_opts timer_tsc_init; @@ -562,12 +563,13 @@ static int timer_resume(struct sys_device *dev) hpet_reenable(); #endif sec = get_cmos_time() + clock_cmos_diff; - sleep_length = get_cmos_time() - sleep_start; + sleep_length = (get_cmos_time() - sleep_start) * HZ; write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = sec; xtime.tv_nsec = 0; write_sequnlock_irqrestore(&xtime_lock, flags); - jiffies += sleep_length * HZ; + jiffies += sleep_length; + wall_jiffies += sleep_length; return 0; } diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/timers/timer_tsc.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c similarity index 95% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c index 1936d96c37..47396aa186 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/traps.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/traps.c @@ -90,7 +90,7 @@ asmlinkage void machine_check(void); static int kstack_depth_to_print = 24; struct notifier_block *i386die_chain; -static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(die_notifier_lock); int register_die_notifier(struct notifier_block *nb) { @@ -303,7 +303,7 @@ void die(const char * str, struct pt_regs * regs, long err) }; static int die_counter; - if (die.lock_owner != smp_processor_id()) { + if (die.lock_owner != _smp_processor_id()) { console_verbose(); spin_lock_irq(&die.lock); die.lock_owner = smp_processor_id(); @@ -543,7 +543,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) printk("Do you have a strange power saving mode enabled?\n"); } -static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(nmi_print_lock); void die_nmi (struct pt_regs *regs, const char *msg) { @@ -674,7 +674,6 @@ fastcall void do_debug(struct pt_regs * regs, long error_code) { unsigned int condition; struct task_struct *tsk = current; - siginfo_t info; condition = HYPERVISOR_get_debugreg(6); @@ -699,36 +698,29 @@ fastcall void do_debug(struct pt_regs * regs, long error_code) /* Save debug status register where ptrace can see it */ tsk->thread.debugreg[6] = condition; - /* Mask out spurious TF errors due to lazy TF clearing */ + /* + * Single-stepping through TF: make sure we ignore any events in + * kernel space (but re-enable TF when returning to user mode). + * And if the event was due to a debugger (PT_DTRACE), clear the + * TF flag so that register information is correct. + */ if (condition & DR_STEP) { /* - * The TF error should be masked out only if the current - * process is not traced and if the TRAP flag has been set - * previously by a tracing process (condition detected by - * the PT_DTRACE flag); remember that the i386 TRAP flag - * can be modified by the process itself in user mode, - * allowing programs to debug themselves without the ptrace() - * interface. + * We already checked v86 mode above, so we can + * check for kernel mode by just checking the CPL + * of CS. */ if ((regs->xcs & 2) == 0) goto clear_TF_reenable; - if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE) - goto clear_TF; + + if (likely(tsk->ptrace & PT_DTRACE)) { + tsk->ptrace &= ~PT_DTRACE; + regs->eflags &= ~TF_MASK; + } } /* Ok, finally something we can handle */ - tsk->thread.trap_no = 1; - tsk->thread.error_code = error_code; - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_BRKPT; - - /* If this is a kernel mode trap, save the user PC on entry to - * the kernel, that's what the debugger can make sense of. - */ - info.si_addr = ((regs->xcs & 2) == 0) ? (void __user *)tsk->thread.eip - : (void __user *)regs->eip; - force_sig_info(SIGTRAP, &info, tsk); + send_sigtrap(tsk, regs, error_code); /* Disable additional traps. They'll be re-enabled when * the signal is delivered. @@ -743,7 +735,6 @@ debug_vm86: clear_TF_reenable: set_tsk_thread_flag(tsk, TIF_SINGLESTEP); -clear_TF: regs->eflags &= ~TF_MASK; return; } @@ -911,7 +902,7 @@ asmlinkage void math_state_restore(struct pt_regs regs) return; clts(); /* Allow maths ops (or we recurse) */ - if (!tsk->used_math) + if (!tsk_used_math(tsk)) init_fpu(tsk); restore_fpu(tsk); thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.S b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.S similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.S rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.S diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.lds b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.lds similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/kernel/vsyscall.lds rename to linux-2.6.11-xen-sparse/arch/xen/i386/kernel/vsyscall.lds diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/fault.c similarity index 97% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/fault.c index 9b5ba2b3d7..2d412dc366 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/fault.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/fault.c @@ -114,9 +114,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, } /* Decode the code segment base from the descriptor */ - base = (desc[0] >> 16) | - ((desc[1] & 0xff) << 16) | - (desc[1] & 0xff000000); + base = get_desc_base((unsigned long *)desc); if (seg & (1<<2)) { up(¤t->mm->context.sem); @@ -527,6 +525,7 @@ vmalloc_fault: */ int index = pgd_index(address); pgd_t *pgd, *pgd_k; + pud_t *pud, *pud_k; pmd_t *pmd, *pmd_k; pte_t *pte_k; @@ -538,11 +537,17 @@ vmalloc_fault: /* * set_pgd(pgd, *pgd_k); here would be useless on PAE - * and redundant with the set_pmd() on non-PAE. + * and redundant with the set_pmd() on non-PAE. As would + * set_pud. */ - pmd = pmd_offset(pgd, address); - pmd_k = pmd_offset(pgd_k, address); + pud = pud_offset(pgd, address); + pud_k = pud_offset(pgd_k, address); + if (!pud_present(*pud_k)) + goto no_context; + + pmd = pmd_offset(pud, address); + pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) goto no_context; set_pmd(pmd, *pmd_k); diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/highmem.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c similarity index 96% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/highmem.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c index 6b6fd16514..7f771f81fd 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/highmem.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c @@ -3,7 +3,7 @@ void *kmap(struct page *page) { might_sleep(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return page_address(page); return kmap_high(page); } @@ -12,7 +12,7 @@ void kunmap(struct page *page) { if (in_interrupt()) BUG(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return; kunmap_high(page); } @@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enum km_type type) /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ inc_preempt_count(); - if (page < highmem_start_page) + if (!PageHighMem(page)) return page_address(page); idx = type + KM_TYPE_NR*smp_processor_id(); diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c similarity index 96% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c index 81d0b8450c..6b19a2030a 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/hypervisor.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c @@ -120,12 +120,12 @@ void queue_l1_entry_update(pte_t *ptr, unsigned long val) spin_unlock_irqrestore(&update_lock, flags); } -void queue_l2_entry_update(pmd_t *ptr, unsigned long val) +void queue_l2_entry_update(pmd_t *ptr, pmd_t val) { unsigned long flags; spin_lock_irqsave(&update_lock, flags); update_queue[idx].ptr = virt_to_machine(ptr); - update_queue[idx].val = val; + update_queue[idx].val = val.pud.pgd.pgd; /* XXX pmd_val_ma */ increment_index(); spin_unlock_irqrestore(&update_lock, flags); } @@ -237,12 +237,12 @@ void xen_l1_entry_update(pte_t *ptr, unsigned long val) spin_unlock_irqrestore(&update_lock, flags); } -void xen_l2_entry_update(pmd_t *ptr, unsigned long val) +void xen_l2_entry_update(pmd_t *ptr, pmd_t val) { unsigned long flags; spin_lock_irqsave(&update_lock, flags); update_queue[idx].ptr = virt_to_machine(ptr); - update_queue[idx].val = val; + update_queue[idx].val = val.pud.pgd.pgd; /* XXX pmd_val_ma */ increment_index_and_flush(); spin_unlock_irqrestore(&update_lock, flags); } @@ -348,6 +348,7 @@ void xen_machphys_update(unsigned long mfn, unsigned long pfn) unsigned long allocate_empty_lowmem_region(unsigned long pages) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long *pfn_array; @@ -368,7 +369,8 @@ unsigned long allocate_empty_lowmem_region(unsigned long pages) for ( i = 0; i < (1<pte_low >> PAGE_SHIFT; queue_l1_entry_update(pte, 0); diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c similarity index 97% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c index 08d4f0c0ce..6548508bae 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/init.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/init.c @@ -55,15 +55,18 @@ static int noinline do_test_wp_bit(void); */ static pmd_t * __init one_md_table_init(pgd_t *pgd) { + pud_t *pud; pmd_t *pmd_table; #ifdef CONFIG_X86_PAE pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - if (pmd_table != pmd_offset(pgd, 0)) + pud = pud_offset(pgd, 0); + if (pmd_table != pmd_offset(pud, 0)) BUG(); #else - pmd_table = pmd_offset(pgd, 0); + pud = pud_offset(pgd, 0); + pmd_table = pmd_offset(pud, 0); #endif return pmd_table; @@ -102,6 +105,7 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; int pgd_idx, pmd_idx; unsigned long vaddr; @@ -114,8 +118,8 @@ static void __init page_table_range_init (unsigned long start, unsigned long end for ( ; (pgd_idx < PTRS_PER_PGD_NO_HV) && (vaddr != end); pgd++, pgd_idx++) { if (pgd_none(*pgd)) one_md_table_init(pgd); - - pmd = pmd_offset(pgd, vaddr); + pud = pud_offset(pgd, vaddr); + pmd = pmd_offset(pud, vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { if (pmd_none(*pmd)) one_page_table_init(pmd); @@ -128,7 +132,7 @@ static void __init page_table_range_init (unsigned long start, unsigned long end static inline int is_kernel_text(unsigned long addr) { - if (addr >= (unsigned long)_stext && addr <= (unsigned long)__init_end) + if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end) return 1; return 0; } @@ -249,7 +253,7 @@ EXPORT_SYMBOL(kmap_prot); EXPORT_SYMBOL(kmap_pte); #define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) void __init kmap_init(void) { @@ -265,6 +269,7 @@ void __init kmap_init(void) void __init permanent_kmaps_init(pgd_t *pgd_base) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; unsigned long vaddr; @@ -273,7 +278,8 @@ void __init permanent_kmaps_init(pgd_t *pgd_base) page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); pgd = swapper_pg_dir + pgd_index(vaddr); - pmd = pmd_offset(pgd, vaddr); + pud = pud_offset(pgd, vaddr); + pmd = pmd_offset(pud, vaddr); pte = pte_offset_kernel(pmd, vaddr); pkmap_page_table = pte; } @@ -464,7 +470,7 @@ u64 __supported_pte_mask = ~_PAGE_NX; * on Enable * off Disable */ -static int __init noexec_setup(char *str) +void __init noexec_setup(const char *str) { if (!strncmp(str, "on",2) && cpu_has_nx) { __supported_pte_mask |= _PAGE_NX; @@ -473,11 +479,8 @@ static int __init noexec_setup(char *str) disable_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 1; } -__setup("noexec=", noexec_setup); - int nx_enabled = 0; #ifdef CONFIG_X86_PAE @@ -607,7 +610,6 @@ void __init test_wp_bit(void) static void __init set_max_mapnr_init(void) { #ifdef CONFIG_HIGHMEM - highmem_start_page = pfn_to_page(highstart_pfn); max_mapnr = num_physpages = highend_pfn; #else max_mapnr = num_physpages = max_low_pfn; diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c similarity index 96% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c index 6d675b449a..e8d48949d3 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -121,7 +121,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l /* * Ok, go for it.. */ - area = get_vm_area(size, VM_IOREMAP); + area = get_vm_area(size, VM_IOREMAP | (flags << 20)); if (!area) return NULL; area->phys_addr = phys_addr; @@ -206,11 +206,12 @@ void iounmap(volatile void __iomem *addr) if (!p) { printk("__iounmap: bad address %p\n", addr); return; - } + } - if (p->flags && is_local_lowmem(p->phys_addr)) { + if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) { + /* p->size includes the guard page, but cpa doesn't like that */ change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)), - p->size >> PAGE_SHIFT, + (p->size - PAGE_SIZE) >> PAGE_SHIFT, PAGE_KERNEL); global_flush_tlb(); } @@ -361,8 +362,14 @@ int __direct_remap_area_pages(struct mm_struct *mm, BUG(); spin_lock(&mm->page_table_lock); do { + pud_t *pud; + pmd_t *pmd; + error = -ENOMEM; - pmd_t *pmd = pmd_alloc(mm, dir, address); + pud = pud_alloc(mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(mm, dir, address); if (!pmd) break; error = 0; diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pageattr.c similarity index 84% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/pageattr.c index 7c961c7a7d..1b79c7e684 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pageattr.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pageattr.c @@ -13,17 +13,21 @@ #include #include -static spinlock_t cpa_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(cpa_lock); static struct list_head df_list = LIST_HEAD_INIT(df_list); pte_t *lookup_address(unsigned long address) { - pgd_t *pgd = pgd_offset_k(address); + pgd_t *pgd = pgd_offset_k(address); + pud_t *pud; pmd_t *pmd; if (pgd_none(*pgd)) return NULL; - pmd = pmd_offset(pgd, address); + pud = pud_offset(pgd, address); + if (pud_none(*pud)) + return NULL; + pmd = pmd_offset(pud, address); if (pmd_none(*pmd)) return NULL; if (pmd_large(*pmd)) @@ -77,9 +81,11 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) spin_lock_irqsave(&pgd_lock, flags); for (page = pgd_list; page; page = (struct page *)page->index) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pgd = (pgd_t *)page_address(page) + pgd_index(address); - pmd = pmd_offset(pgd, address); + pud = pud_offset(pgd, address); + pmd = pmd_offset(pud, address); set_pte_atomic((pte_t *)pmd, pte); } spin_unlock_irqrestore(&pgd_lock, flags); @@ -92,7 +98,7 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) static inline void revert_page(struct page *kpte_page, unsigned long address) { pte_t *linear = (pte_t *) - pmd_offset(pgd_offset(&init_mm, address), address); + pmd_offset(pud_offset(pgd_offset_k(address), address), address); set_pmd_pte(linear, address, pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); @@ -105,10 +111,7 @@ __change_page_attr(struct page *page, pgprot_t prot) unsigned long address; struct page *kpte_page; -#ifdef CONFIG_HIGHMEM - if (page >= highmem_start_page) - BUG(); -#endif + BUG_ON(PageHighMem(page)); address = (unsigned long)page_address(page); kpte = lookup_address(address); @@ -117,27 +120,35 @@ __change_page_attr(struct page *page, pgprot_t prot) kpte_page = virt_to_page(kpte); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((pte_val(*kpte) & _PAGE_PSE) == 0) { - pte_t old = *kpte; - pte_t standard = mk_pte(page, PAGE_KERNEL); set_pte_batched(kpte, mk_pte(page, prot)); - if (pte_same(old,standard)) - get_page(kpte_page); } else { struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; - get_page(kpte_page); set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL)); + kpte_page = split; } + get_page(kpte_page); } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte_batched(kpte, mk_pte(page, PAGE_KERNEL)); __put_page(kpte_page); - } + } else + BUG(); - if (cpu_has_pse && (page_count(kpte_page) == 1)) { - list_add(&kpte_page->lru, &df_list); - revert_page(kpte_page, address); - } + /* + * If the pte was reserved, it means it was created at boot + * time (not via split_large_page) and in turn we must not + * replace it with a largepage. + */ + if (!PageReserved(kpte_page)) { + /* memleak and potential failed 2M page regeneration */ + BUG_ON(!page_count(kpte_page)); + + if (cpu_has_pse && (page_count(kpte_page) == 1)) { + list_add(&kpte_page->lru, &df_list); + revert_page(kpte_page, address); + } + } return 0; } diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c similarity index 90% rename from linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c index 0d8f833bd9..30e929ad51 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/mm/pgtable.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c @@ -65,6 +65,7 @@ void show_mem(void) static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -73,7 +74,12 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) BUG(); return; } - pmd = pmd_offset(pgd, vaddr); + pud = pud_offset(pgd, vaddr); + if (pud_none(*pud)) { + BUG(); + return; + } + pmd = pmd_offset(pud, vaddr); if (pmd_none(*pmd)) { BUG(); return; @@ -97,6 +103,7 @@ static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn, pgprot_t flags) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -105,7 +112,12 @@ static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn, BUG(); return; } - pmd = pmd_offset(pgd, vaddr); + pud = pud_offset(pgd, vaddr); + if (pud_none(*pud)) { + BUG(); + return; + } + pmd = pmd_offset(pud, vaddr); if (pmd_none(*pmd)) { BUG(); return; @@ -130,6 +142,7 @@ static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn, void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; if (vaddr & (PMD_SIZE-1)) { /* vaddr is misaligned */ @@ -145,7 +158,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) printk ("set_pmd_pfn: pgd_none\n"); return; /* BUG(); */ } - pmd = pmd_offset(pgd, vaddr); + pud = pud_offset(pgd, vaddr); + pmd = pmd_offset(pud, vaddr); set_pmd(pmd, pfn_pmd(pfn, flags)); /* * It's enough to flush this one mapping. @@ -178,9 +192,8 @@ void __set_fixmap_ma (enum fixed_addresses idx, unsigned long phys, pgprot_t fla pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); if (pte) { - clear_page(pte); make_page_readonly(pte); xen_flush_page_update_queue(); } @@ -216,13 +229,11 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) #ifdef CONFIG_HIGHPTE struct page *pte; - pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0); + pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); if (pte == NULL) return pte; - if (pte >= highmem_start_page) { - clear_highpage(pte); + if (pte >= highmem_start_page) return pte; - } /* not a highmem page -- free page and grab one from the cache */ __free_page(pte); #endif @@ -263,7 +274,7 @@ void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags) * recommendations and having no core impact whatsoever. * -- wli */ -spinlock_t pgd_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(pgd_lock); struct page *pgd_list; static inline void pgd_list_add(pgd_t *pgd) @@ -357,14 +368,15 @@ void pgd_free(pgd_t *pgd) if (PTRS_PER_PMD > 1) for (i = 0; i < USER_PTRS_PER_PGD; ++i) kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); - /* in the non-PAE case, clear_page_tables() clears user pgd entries */ + /* in the non-PAE case, clear_page_range() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); } void make_lowmem_page_readonly(void *va) { pgd_t *pgd = pgd_offset_k((unsigned long)va); - pmd_t *pmd = pmd_offset(pgd, (unsigned long)va); + pud_t *pud = pud_offset(pgd, (unsigned long)va); + pmd_t *pmd = pmd_offset(pud, (unsigned long)va); pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va); queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW); } @@ -372,7 +384,8 @@ void make_lowmem_page_readonly(void *va) void make_lowmem_page_writable(void *va) { pgd_t *pgd = pgd_offset_k((unsigned long)va); - pmd_t *pmd = pmd_offset(pgd, (unsigned long)va); + pud_t *pud = pud_offset(pgd, (unsigned long)va); + pmd_t *pmd = pmd_offset(pud, (unsigned long)va); pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va); queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW); } @@ -380,7 +393,8 @@ void make_lowmem_page_writable(void *va) void make_page_readonly(void *va) { pgd_t *pgd = pgd_offset_k((unsigned long)va); - pmd_t *pmd = pmd_offset(pgd, (unsigned long)va); + pud_t *pud = pud_offset(pgd, (unsigned long)va); + pmd_t *pmd = pmd_offset(pud, (unsigned long)va); pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va); queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW); if ( (unsigned long)va >= (unsigned long)high_memory ) @@ -397,7 +411,8 @@ void make_page_readonly(void *va) void make_page_writable(void *va) { pgd_t *pgd = pgd_offset_k((unsigned long)va); - pmd_t *pmd = pmd_offset(pgd, (unsigned long)va); + pud_t *pud = pud_offset(pgd, (unsigned long)va); + pmd_t *pmd = pmd_offset(pud, (unsigned long)va); pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va); queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW); if ( (unsigned long)va >= (unsigned long)high_memory ) diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/pci/Makefile b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/pci/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/i386/pci/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/pci/direct.c b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/i386/pci/direct.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/pci/direct.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/i386/pci/irq.c b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c similarity index 97% rename from linux-2.6.10-xen-sparse/arch/xen/i386/pci/irq.c rename to linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c index efd7e84040..3a5b7477a3 100644 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/pci/irq.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/pci/irq.c @@ -23,6 +23,8 @@ #include #include +static int pirq_enable_irq(struct pci_dev *dev); + /* * Never use: 0, 1, 2 (timer, keyboard, and cascade) * Avoid using: 13, 14 and 15 (FP error and IDE). @@ -88,7 +90,7 @@ void pcibios_penalize_isa_irq(int irq) pirq_penalize_isa_irq(irq); } -int pirq_enable_irq(struct pci_dev *dev) +static int pirq_enable_irq(struct pci_dev *dev) { int err; u8 pin; diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile b/linux-2.6.11-xen-sparse/arch/xen/kernel/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile rename to linux-2.6.11-xen-sparse/arch/xen/kernel/Makefile diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/ctrl_if.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/ctrl_if.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/ctrl_if.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/devmem.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/devmem.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/devmem.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/evtchn.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/evtchn.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/fixup.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/fixup.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/gnttab.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/skbuff.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/skbuff.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/skbuff.c diff --git a/linux-2.6.10-xen-sparse/arch/xen/kernel/xen_proc.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/xen_proc.c similarity index 100% rename from linux-2.6.10-xen-sparse/arch/xen/kernel/xen_proc.c rename to linux-2.6.11-xen-sparse/arch/xen/kernel/xen_proc.c diff --git a/linux-2.6.10-xen-sparse/drivers/Makefile b/linux-2.6.11-xen-sparse/drivers/Makefile similarity index 94% rename from linux-2.6.10-xen-sparse/drivers/Makefile rename to linux-2.6.11-xen-sparse/drivers/Makefile index 6aa99acc8b..5fab89854a 100644 --- a/linux-2.6.10-xen-sparse/drivers/Makefile +++ b/linux-2.6.11-xen-sparse/drivers/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_DIO) += dio/ obj-$(CONFIG_SBUS) += sbus/ obj-$(CONFIG_ZORRO) += zorro/ obj-$(CONFIG_MAC) += macintosh/ +obj-$(CONFIG_ATA_OVER_ETH) += block/aoe/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_USB) += usb/ @@ -60,4 +61,6 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ +obj-$(CONFIG_INFINIBAND) += infiniband/ obj-y += firmware/ +obj-$(CONFIG_CRYPTO) += crypto/ diff --git a/linux-2.6.10-xen-sparse/drivers/char/mem.c b/linux-2.6.11-xen-sparse/drivers/char/mem.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/char/mem.c rename to linux-2.6.11-xen-sparse/drivers/char/mem.c diff --git a/linux-2.6.10-xen-sparse/drivers/char/tty_io.c b/linux-2.6.11-xen-sparse/drivers/char/tty_io.c similarity index 98% rename from linux-2.6.10-xen-sparse/drivers/char/tty_io.c rename to linux-2.6.11-xen-sparse/drivers/char/tty_io.c index 2df07c8619..a8d33b5288 100644 --- a/linux-2.6.10-xen-sparse/drivers/char/tty_io.c +++ b/linux-2.6.11-xen-sparse/drivers/char/tty_io.c @@ -251,7 +251,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) * callers who will do ldisc lookups and cannot sleep. */ -static spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ @@ -329,7 +329,7 @@ void tty_ldisc_put(int disc) EXPORT_SYMBOL_GPL(tty_ldisc_put); -void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) +static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) { tty->ldisc = *ld; tty->ldisc.refcount = 0; @@ -585,7 +585,7 @@ restart: /* * This routine returns a tty driver structure, given a device number */ -struct tty_driver *get_tty_driver(dev_t device, int *index) +static struct tty_driver *get_tty_driver(dev_t device, int *index) { struct tty_driver *p; @@ -692,7 +692,7 @@ static struct file_operations hung_up_tty_fops = { .release = tty_release, }; -static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(redirect_lock); static struct file *redirect; /** @@ -746,7 +746,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); * but doesn't hold any locks, so we need to make sure we have the appropriate * locks for what we're doing.. */ -void do_tty_hangup(void *data) +static void do_tty_hangup(void *data) { struct tty_struct *tty = (struct tty_struct *) data; struct file * cons_filp = NULL; @@ -920,9 +920,11 @@ void disassociate_ctty(int on_exit) lock_kernel(); + down(&tty_sem); tty = current->signal->tty; if (tty) { tty_pgrp = tty->pgrp; + up(&tty_sem); if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) tty_vhangup(tty); } else { @@ -930,6 +932,7 @@ void disassociate_ctty(int on_exit) kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); } + up(&tty_sem); unlock_kernel(); return; } @@ -939,15 +942,19 @@ void disassociate_ctty(int on_exit) kill_pg(tty_pgrp, SIGCONT, on_exit); } + /* Must lock changes to tty_old_pgrp */ + down(&tty_sem); current->signal->tty_old_pgrp = 0; tty->session = 0; tty->pgrp = -1; + /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); do_each_task_pid(current->signal->session, PIDTYPE_SID, p) { p->signal->tty = NULL; } while_each_task_pid(current->signal->session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); + up(&tty_sem); unlock_kernel(); } @@ -1013,7 +1020,7 @@ static ssize_t tty_read(struct file * file, char __user * buf, size_t count, tty_ldisc_deref(ld); unlock_kernel(); if (i > 0) - inode->i_atime = CURRENT_TIME; + inode->i_atime = current_fs_time(inode->i_sb); return i; } @@ -1042,8 +1049,13 @@ static inline ssize_t do_tty_write( * * But if TTY_NO_WRITE_SPLIT is set, we should use a * big chunk-size.. + * + * The default chunk-size is 2kB, because the NTTY + * layer has problems with bigger chunks. It will + * claim to be able to handle more characters than + * it actually does. */ - chunk = 4096; + chunk = 2048; if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags)) chunk = 65536; if (count < chunk) @@ -1090,7 +1102,8 @@ static inline ssize_t do_tty_write( cond_resched(); } if (written) { - file->f_dentry->d_inode->i_mtime = CURRENT_TIME; + struct inode *inode = file->f_dentry->d_inode; + inode->i_mtime = current_fs_time(inode->i_sb); ret = written; } up(&tty->atomic_write); @@ -1173,12 +1186,6 @@ static int init_dev(struct tty_driver *driver, int idx, struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; int retval=0; - /* - * Check whether we need to acquire the tty semaphore to avoid - * race conditions. For now, play it safe. - */ - down(&tty_sem); - /* check whether we're reopening an existing tty */ if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { tty = devpts_get_tty(idx); @@ -1367,7 +1374,6 @@ success: /* All paths come through here to release the semaphore */ end_init: - up(&tty_sem); return retval; /* Release locally allocated memory ... nothing placed in slots */ @@ -1563,9 +1569,14 @@ static void release_dev(struct file * filp) * each iteration we avoid any problems. */ while (1) { + /* Guard against races with tty->count changes elsewhere and + opens on /dev/tty */ + + down(&tty_sem); tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); + up(&tty_sem); do_sleep = 0; if (tty_closing) { @@ -1601,6 +1612,8 @@ static void release_dev(struct file * filp) * both sides, and we've completed the last operation that could * block, so it's safe to proceed with closing. */ + + down(&tty_sem); if (pty_master) { if (--o_tty->count < 0) { printk(KERN_WARNING "release_dev: bad pty slave count " @@ -1614,7 +1627,8 @@ static void release_dev(struct file * filp) tty->count, tty_name(tty, buf)); tty->count = 0; } - + up(&tty_sem); + /* * We've decremented tty->count, so we need to remove this file * descriptor off the tty->tty_files list; this serves two @@ -1761,10 +1775,14 @@ retry_open: noctty = filp->f_flags & O_NOCTTY; index = -1; retval = 0; + + down(&tty_sem); if (device == MKDEV(TTYAUX_MAJOR,0)) { - if (!current->signal->tty) + if (!current->signal->tty) { + up(&tty_sem); return -ENXIO; + } driver = current->signal->tty->driver; index = current->signal->tty->index; filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ @@ -1789,14 +1807,18 @@ retry_open: noctty = 1; goto got_driver; } + up(&tty_sem); return -ENODEV; } driver = get_tty_driver(device, &index); - if (!driver) + if (!driver) { + up(&tty_sem); return -ENODEV; + } got_driver: retval = init_dev(driver, index, &tty); + up(&tty_sem); if (retval) return retval; @@ -1882,7 +1904,10 @@ static int ptmx_open(struct inode * inode, struct file * filp) } up(&allocated_ptys_lock); + down(&tty_sem); retval = init_dev(ptm_driver, index, &tty); + up(&tty_sem); + if (retval) goto out; @@ -2505,28 +2530,6 @@ out: tty_ldisc_deref(disc); } -/* - * Call the ldisc flush directly from a driver. This function may - * return an error and need retrying by the user. - */ - -int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count) -{ - int ret = 0; - struct tty_ldisc *disc; - - disc = tty_ldisc_ref(tty); - if(test_bit(TTY_DONT_FLIP, &tty->flags)) - ret = -EAGAIN; - else if(disc == NULL) - ret = -EIO; - else - disc->receive_buf(tty, cp, fp, count); - tty_ldisc_deref(disc); - return ret; - -} - /* * Routine which returns the baud rate of the tty * @@ -2905,8 +2908,8 @@ void __init console_init(void) So I haven't moved it. dwmw2 */ rs_360_init(); #endif - call = &__con_initcall_start; - while (call < &__con_initcall_end) { + call = __con_initcall_start; + while (call < __con_initcall_end) { (*call)(); call++; } diff --git a/linux-2.6.10-xen-sparse/drivers/xen/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/balloon/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/balloon/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/balloon/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/balloon/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c similarity index 98% rename from linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c rename to linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c index ad951fa984..ee725d3d9d 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c @@ -137,12 +137,16 @@ static struct page *balloon_retrieve(void) static inline pte_t *get_ptep(unsigned long addr) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pgd = pgd_offset_k(addr); if ( pgd_none(*pgd) || pgd_bad(*pgd) ) BUG(); - pmd = pmd_offset(pgd, addr); + pud = pud_offset(pgd, addr); + if ( pud_none(*pud) || pud_bad(*pud) ) BUG(); + + pmd = pmd_offset(pud, addr); if ( pmd_none(*pmd) || pmd_bad(*pmd) ) BUG(); return pte_offset_kernel(pmd, addr); diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/blkback/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/common.h rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/control.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/control.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/control.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/control.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/interface.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/interface.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/interface.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkback/vbd.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/Kconfig b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/Kconfig similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkfront/Kconfig rename to linux-2.6.11-xen-sparse/drivers/xen/blkfront/Kconfig diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkfront/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/blkfront/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkfront/block.h rename to linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/blkfront/vbd.c rename to linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/console/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/console/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/console/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/console/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/console/console.c b/linux-2.6.11-xen-sparse/drivers/xen/console/console.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/console/console.c rename to linux-2.6.11-xen-sparse/drivers/xen/console/console.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/evtchn/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/evtchn/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/evtchn/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/evtchn/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6.11-xen-sparse/drivers/xen/evtchn/evtchn.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/evtchn/evtchn.c rename to linux-2.6.11-xen-sparse/drivers/xen/evtchn/evtchn.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netback/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/netback/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/common.h b/linux-2.6.11-xen-sparse/drivers/xen/netback/common.h similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netback/common.h rename to linux-2.6.11-xen-sparse/drivers/xen/netback/common.h diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/control.c b/linux-2.6.11-xen-sparse/drivers/xen/netback/control.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netback/control.c rename to linux-2.6.11-xen-sparse/drivers/xen/netback/control.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c rename to linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c rename to linux-2.6.11-xen-sparse/drivers/xen/netback/netback.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/Kconfig b/linux-2.6.11-xen-sparse/drivers/xen/netfront/Kconfig similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netfront/Kconfig rename to linux-2.6.11-xen-sparse/drivers/xen/netfront/Kconfig diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/netfront/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netfront/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/netfront/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c rename to linux-2.6.11-xen-sparse/drivers/xen/netfront/netfront.c diff --git a/linux-2.6.10-xen-sparse/drivers/xen/privcmd/Makefile b/linux-2.6.11-xen-sparse/drivers/xen/privcmd/Makefile similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/privcmd/Makefile rename to linux-2.6.11-xen-sparse/drivers/xen/privcmd/Makefile diff --git a/linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c similarity index 100% rename from linux-2.6.10-xen-sparse/drivers/xen/privcmd/privcmd.c rename to linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c diff --git a/linux-2.6.10-xen-sparse/include/asm-generic/pgtable.h b/linux-2.6.11-xen-sparse/include/asm-generic/pgtable.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-generic/pgtable.h rename to linux-2.6.11-xen-sparse/include/asm-generic/pgtable.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h similarity index 94% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h index 3cebc41697..abc3987d71 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/desc.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h @@ -128,6 +128,15 @@ static inline void load_LDT(mm_context_t *pc) put_cpu(); } +static inline unsigned long get_desc_base(unsigned long *desc) +{ + unsigned long base; + base = ((desc[0] >> 16) & 0x0000ffff) | + ((desc[1] << 16) & 0x00ff0000) | + (desc[1] & 0xff000000); + return base; +} + #endif /* !__ASSEMBLY__ */ #endif diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h similarity index 96% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h index cf12d309e3..f86762fd1e 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/fixmap.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h @@ -122,7 +122,9 @@ extern void __set_fixmap_ma (enum fixed_addresses idx, #define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP) #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) -#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) +#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) +#define FIXADDR_BOOT_START (FIXADDR_TOP - __FIXADDR_BOOT_SIZE) #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/floppy.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/floppy.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/highmem.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h similarity index 85% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/highmem.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h index f608a13755..8273e2db97 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/highmem.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h @@ -40,16 +40,27 @@ extern void kmap_init(void); * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#if NR_CPUS <= 32 -#define PKMAP_BASE (HYPERVISOR_VIRT_START - (1<<23)) -#else -#define PKMAP_BASE (HYPERVISOR_VIRT_START - (1<<23) - 0x200000UL) -#endif #ifdef CONFIG_X86_PAE #define LAST_PKMAP 512 #else #define LAST_PKMAP 1024 #endif +/* + * Ordering is: + * + * FIXADDR_TOP + * fixed_addresses + * FIXADDR_START + * temp fixed addresses + * FIXADDR_BOOT_START + * Persistent kmap area + * PKMAP_BASE + * VMALLOC_END + * Vmalloc area + * VMALLOC_START + * high_memory + */ +#define PKMAP_BASE ( (FIXADDR_BOOT_START - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK ) #define LAST_PKMAP_MASK (LAST_PKMAP-1) #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/io.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mmu_context.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/mmu_context.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/msr.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/msr.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/msr.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/msr.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h similarity index 93% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h index da282bd498..4b5ed479e1 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/page.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/page.h @@ -41,6 +41,9 @@ #else +#define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) +#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE + /* * On older X86 processors it's not a win to use MMX here it seems. * Maybe the K6-III ? @@ -81,11 +84,12 @@ typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long long pmd; } pmd_t; typedef struct { unsigned long long pgd; } pgd_t; typedef struct { unsigned long long pgprot; } pgprot_t; +#define pmd_val(x) ((x).pmd) #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) +#define __pmd(x) ((pmd_t) { (x) } ) #define HPAGE_SHIFT 21 #else typedef struct { unsigned long pte_low; } pte_t; -typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define boot_pte_t pte_t /* or would you rather have a typedef */ @@ -104,13 +108,12 @@ typedef struct { unsigned long pgprot; } pgprot_t; #endif -static inline unsigned long pmd_val(pmd_t x) +static inline unsigned long pgd_val(pgd_t x) { - unsigned long ret = x.pmd; + unsigned long ret = x.pgd; if (ret) ret = machine_to_phys(ret); return ret; } -#define pgd_val(x) ({ BUG(); (unsigned long)0; }) #define pgprot_val(x) ((x).pgprot) static inline pte_t __pte(unsigned long x) @@ -119,12 +122,11 @@ static inline pte_t __pte(unsigned long x) return ((pte_t) { (x) }); } #define __pte_ma(x) ((pte_t) { (x) } ) -static inline pmd_t __pmd(unsigned long x) +static inline pgd_t __pgd(unsigned long x) { if ((x & 1)) x = phys_to_machine(x); - return ((pmd_t) { (x) }); + return ((pgd_t) { (x) }); } -#define __pgd(x) ({ BUG(); (pgprot_t) { 0 }; }) #define __pgprot(x) ((pgprot_t) { (x) } ) #endif /* !__ASSEMBLY__ */ diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/param.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/param.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/param.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/param.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pci.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pci.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pci.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pci.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h similarity index 70% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h index e9bf5f50b5..520e98d072 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgalloc.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgalloc.h @@ -11,17 +11,15 @@ #define pmd_populate_kernel(mm, pmd, pte) \ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) -static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) -{ - set_pmd(pmd, __pmd(_PAGE_TABLE + - ((unsigned long long)page_to_pfn(pte) << - (unsigned long long) PAGE_SHIFT))); - flush_page_update_queue(); -} +#define pmd_populate(mm, pmd, pte) do { \ + set_pmd(pmd, __pmd(_PAGE_TABLE + \ + ((unsigned long long)page_to_pfn(pte) << \ + (unsigned long long) PAGE_SHIFT))); \ + flush_page_update_queue(); \ +} while (0) /* * Allocate and free page tables. */ - extern pgd_t *pgd_alloc(struct mm_struct *); extern void pgd_free(pgd_t *pgd); @@ -39,16 +37,15 @@ extern void pte_free(struct page *pte); #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) +#ifdef CONFIG_X86_PAE /* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - * (In the PAE case we free the pmds as part of the pgd.) + * In the PAE case we free the pmds as part of the pgd. */ - #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) #define __pmd_free_tlb(tlb,x) do { } while (0) -#define pgd_populate(mm, pmd, pte) BUG() +#define pud_populate(mm, pmd, pte) BUG() +#endif #define check_pgt_cache() do { } while (0) diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h similarity index 90% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h index 2afc4fba6f..2be63665a4 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level-defs.h @@ -13,8 +13,6 @@ * the i386 is two-level, so we don't really have any * PMD directory physically. */ -#define PMD_SHIFT 22 -#define PTRS_PER_PMD 1 #define PTRS_PER_PTE 1024 diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h similarity index 83% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h index 36a2420a29..ac4fc891e8 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable-2level.h @@ -1,23 +1,13 @@ #ifndef _I386_PGTABLE_2LEVEL_H #define _I386_PGTABLE_2LEVEL_H +#include + #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) -#define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -/* - * The "pgd_xxx()" functions here are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) - */ -static inline int pgd_none(pgd_t pgd) { return 0; } -static inline int pgd_bad(pgd_t pgd) { return 0; } -static inline int pgd_present(pgd_t pgd) { return 1; } -#define pgd_clear(xp) do { } while (0) - /* * Certain architectures need to do special things when PTEs * within a page table are directly modified. Thus, the following @@ -27,20 +17,7 @@ static inline int pgd_present(pgd_t pgd) { return 1; } queue_l1_entry_update(pteptr, (pteval).pte_low) #define set_pte(pteptr, pteval) (*(pteptr) = pteval) #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) -/* - * (pmds are folded into pgds so this doesn't get actually called, - * but the define is needed for a generic inline function.) - */ -#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval).pmd) -#define set_pgd(pgdptr, pgdval) ((void)0) - -#define pgd_page(pgd) \ -((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) - -static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) dir; -} +#define set_pmd(pmdptr, pmdval) xen_l2_entry_update((pmdptr), (pmdval)) /* * A note on implementation of this atomic 'get-and-clear' operation. @@ -98,6 +75,11 @@ static inline pte_t ptep_get_and_clear(pte_t *xp) #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)) +#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) + +#define pmd_page_kernel(pmd) \ +((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) + /* * All present user pages are user-executable: */ diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h similarity index 97% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h index 3c0ae34e97..ddbb68e681 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -54,12 +54,12 @@ void paging_init(void); */ #ifdef CONFIG_X86_PAE # include +# define PMD_SIZE (1UL << PMD_SHIFT) +# define PMD_MASK (~(PMD_SIZE-1)) #else # include #endif -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -316,20 +316,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define page_pte(page) page_pte_prot(page, __pgprot(0)) -#define pmd_page_kernel(pmd) \ -((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) - #define pmd_clear(xp) do { \ set_pmd(xp, __pmd(0)); \ xen_flush_page_update_queue(); \ } while (0) -#ifndef CONFIG_DISCONTIGMEM -#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) -#endif /* !CONFIG_DISCONTIGMEM */ - #define pmd_large(pmd) \ - ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) +((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) /* * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD] @@ -338,6 +331,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * control the given virtual address */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define pgd_index_k(addr) pgd_index(addr) /* * pgd_offset() returns a (pgd_t *) @@ -391,6 +385,8 @@ extern pte_t *lookup_address(unsigned long address); static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;} #endif +extern void noexec_setup(const char *str); + #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)),KM_PTE0) + \ @@ -463,7 +459,8 @@ void make_pages_writable(void *va, unsigned int nr); #define arbitrary_virt_to_machine(__va) \ ({ \ pgd_t *__pgd = pgd_offset_k((unsigned long)(__va)); \ - pmd_t *__pmd = pmd_offset(__pgd, (unsigned long)(__va)); \ + pud_t *__pud = pud_offset(__pgd, (unsigned long)(__va)); \ + pmd_t *__pmd = pmd_offset(__pud, (unsigned long)(__va)); \ pte_t *__pte = pte_offset_kernel(__pmd, (unsigned long)(__va)); \ unsigned long __pa = (*(unsigned long *)__pte) & PAGE_MASK; \ __pa | ((unsigned long)(__va) & (PAGE_SIZE-1)); \ diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/processor.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h similarity index 97% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/processor.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h index 53b71d3113..a6a5a9cf83 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/processor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/processor.h @@ -65,6 +65,7 @@ struct cpuinfo_x86 { int f00f_bug; int coma_bug; unsigned long loops_per_jiffy; + unsigned char x86_num_cores; } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -97,6 +98,7 @@ extern struct cpuinfo_x86 cpu_data[]; #define current_cpu_data boot_cpu_data #endif +extern int phys_proc_id[NR_CPUS]; extern char ignore_fpu_irq; extern void identify_cpu(struct cpuinfo_x86 *); @@ -104,6 +106,12 @@ extern void print_cpu_info(struct cpuinfo_x86 *); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); extern void dodgy_tsc(void); +#ifdef CONFIG_X86_HT +extern void detect_ht(struct cpuinfo_x86 *c); +#else +static inline void detect_ht(struct cpuinfo_x86 *c) {} +#endif + /* * EFLAGS bits */ @@ -127,6 +135,8 @@ extern void dodgy_tsc(void); /* * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. */ static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) { @@ -135,7 +145,7 @@ static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) "=b" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (op)); + : "0" (op), "c"(0)); } /* @@ -270,11 +280,6 @@ static inline void clear_in_cr4 (unsigned long mask) outb((data), 0x23); \ } while (0) -/* - * Bus types (default is ISA, but people can check others with these..) - */ -extern int MCA_bus; - static inline void __monitor(const void *eax, unsigned long ecx, unsigned long edx) { @@ -299,6 +304,9 @@ extern unsigned int machine_submodel_id; extern unsigned int BIOS_revision; extern unsigned int mca_pentium_flag; +/* Boot loader type from the setup header */ +extern int bootloader_type; + /* * User space process size: 3GB (default). */ diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/ptrace.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/ptrace.h similarity index 92% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/ptrace.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/ptrace.h index 2036837c50..aa2e6248a9 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/ptrace.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/ptrace.h @@ -55,6 +55,8 @@ struct pt_regs { #define PTRACE_SET_THREAD_AREA 26 #ifdef __KERNEL__ +struct task_struct; +extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (2 & (regs)->xcs)) #define instruction_pointer(regs) ((regs)->eip) #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/segment.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/segment.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/segment.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/segment.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/setup.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/setup.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/setup.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/setup.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/synch_bitops.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h similarity index 99% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h index b8eb62d37a..b1badb3b67 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/system.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/system.h @@ -517,5 +517,6 @@ void disable_hlt(void); void enable_hlt(void); extern int es7000_plat; +void cpu_idle_wait(void); #endif diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/tlbflush.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/tlbflush.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/tlbflush.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/tlbflush.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/vga.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/vga.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/vga.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/vga.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/xor.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/xor.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/xor.h rename to linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/xor.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/balloon.h b/linux-2.6.11-xen-sparse/include/asm-xen/balloon.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/balloon.h rename to linux-2.6.11-xen-sparse/include/asm-xen/balloon.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/ctrl_if.h b/linux-2.6.11-xen-sparse/include/asm-xen/ctrl_if.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/ctrl_if.h rename to linux-2.6.11-xen-sparse/include/asm-xen/ctrl_if.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6.11-xen-sparse/include/asm-xen/evtchn.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/evtchn.h rename to linux-2.6.11-xen-sparse/include/asm-xen/evtchn.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/foreign_page.h b/linux-2.6.11-xen-sparse/include/asm-xen/foreign_page.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/foreign_page.h rename to linux-2.6.11-xen-sparse/include/asm-xen/foreign_page.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h b/linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h rename to linux-2.6.11-xen-sparse/include/asm-xen/gnttab.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h similarity index 98% rename from linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h rename to linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h index ef755a4e7d..9882429a96 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h @@ -38,6 +38,7 @@ #include #include #include +#include /* arch/xen/i386/kernel/setup.c */ union xen_start_info_union @@ -66,7 +67,7 @@ void lgdt_finish(void); extern unsigned int mmu_update_queue_idx; void queue_l1_entry_update(pte_t *ptr, unsigned long val); -void queue_l2_entry_update(pmd_t *ptr, unsigned long val); +void queue_l2_entry_update(pmd_t *ptr, pmd_t val); void queue_pt_switch(unsigned long ptr); void queue_tlb_flush(void); void queue_invlpg(unsigned long ptr); @@ -77,7 +78,7 @@ void queue_pte_unpin(unsigned long ptr); void queue_set_ldt(unsigned long ptr, unsigned long bytes); void queue_machphys_update(unsigned long mfn, unsigned long pfn); void xen_l1_entry_update(pte_t *ptr, unsigned long val); -void xen_l2_entry_update(pmd_t *ptr, unsigned long val); +void xen_l2_entry_update(pmd_t *ptr, pmd_t val); void xen_pt_switch(unsigned long ptr); void xen_tlb_flush(void); void xen_invlpg(unsigned long ptr); diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/linux-public/privcmd.h b/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/linux-public/privcmd.h rename to linux-2.6.11-xen-sparse/include/asm-xen/linux-public/privcmd.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/linux-public/suspend.h b/linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/linux-public/suspend.h rename to linux-2.6.11-xen-sparse/include/asm-xen/linux-public/suspend.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/multicall.h b/linux-2.6.11-xen-sparse/include/asm-xen/multicall.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/multicall.h rename to linux-2.6.11-xen-sparse/include/asm-xen/multicall.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/queues.h b/linux-2.6.11-xen-sparse/include/asm-xen/queues.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/queues.h rename to linux-2.6.11-xen-sparse/include/asm-xen/queues.h diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/xen_proc.h b/linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h similarity index 100% rename from linux-2.6.10-xen-sparse/include/asm-xen/xen_proc.h rename to linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h diff --git a/linux-2.6.10-xen-sparse/include/linux/gfp.h b/linux-2.6.11-xen-sparse/include/linux/gfp.h similarity index 98% rename from linux-2.6.10-xen-sparse/include/linux/gfp.h rename to linux-2.6.11-xen-sparse/include/linux/gfp.h index 6b1642d379..42fe579514 100644 --- a/linux-2.6.10-xen-sparse/include/linux/gfp.h +++ b/linux-2.6.11-xen-sparse/include/linux/gfp.h @@ -37,6 +37,7 @@ struct vm_area_struct; #define __GFP_NORETRY 0x1000 /* Do not retry. Might fail */ #define __GFP_NO_GROW 0x2000 /* Slab internal usage */ #define __GFP_COMP 0x4000 /* Add compound page metadata */ +#define __GFP_ZERO 0x8000 /* Return zeroed page on success */ #define __GFP_BITS_SHIFT 16 /* Room for 16 __GFP_FOO bits */ #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1) diff --git a/linux-2.6.10-xen-sparse/include/linux/irq.h b/linux-2.6.11-xen-sparse/include/linux/irq.h similarity index 99% rename from linux-2.6.10-xen-sparse/include/linux/irq.h rename to linux-2.6.11-xen-sparse/include/linux/irq.h index 12584aa5b4..2e0aeb9d39 100644 --- a/linux-2.6.10-xen-sparse/include/linux/irq.h +++ b/linux-2.6.11-xen-sparse/include/linux/irq.h @@ -59,9 +59,10 @@ typedef struct hw_interrupt_type hw_irq_controller; * Pad this out to 32 bytes for cache and indexing reasons. */ typedef struct irq_desc { - unsigned int status; /* IRQ status */ hw_irq_controller *handler; + void *handler_data; struct irqaction *action; /* IRQ action list */ + unsigned int status; /* IRQ status */ unsigned int depth; /* nested irq disables */ unsigned int irq_count; /* For detecting broken interrupts */ unsigned int irqs_unhandled; diff --git a/linux-2.6.10-xen-sparse/kernel/irq/manage.c b/linux-2.6.11-xen-sparse/kernel/irq/manage.c similarity index 99% rename from linux-2.6.10-xen-sparse/kernel/irq/manage.c rename to linux-2.6.11-xen-sparse/kernel/irq/manage.c index fb7f365b3d..47678cdd25 100644 --- a/linux-2.6.10-xen-sparse/kernel/irq/manage.c +++ b/linux-2.6.11-xen-sparse/kernel/irq/manage.c @@ -15,6 +15,8 @@ #ifdef CONFIG_SMP +cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL }; + /** * synchronize_irq - wait for pending IRQ handlers (on other CPUs) * diff --git a/linux-2.6.10-xen-sparse/mkbuildtree b/linux-2.6.11-xen-sparse/mkbuildtree similarity index 100% rename from linux-2.6.10-xen-sparse/mkbuildtree rename to linux-2.6.11-xen-sparse/mkbuildtree diff --git a/linux-2.6.10-xen-sparse/mm/memory.c b/linux-2.6.11-xen-sparse/mm/memory.c similarity index 66% rename from linux-2.6.10-xen-sparse/mm/memory.c rename to linux-2.6.11-xen-sparse/mm/memory.c index cd10d79d94..1ff6332578 100644 --- a/linux-2.6.10-xen-sparse/mm/memory.c +++ b/linux-2.6.11-xen-sparse/mm/memory.c @@ -34,6 +34,8 @@ * * 16.07.99 - Support of BIGMEM added by Gerhard Wichert, Siemens AG * (Gerhard.Wichert@pdb.siemens.de) + * + * Aug/Sep 2004 Changed to four level page tables (Andi Kleen) */ #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include @@ -74,84 +77,120 @@ unsigned long num_physpages; * and ZONE_HIGHMEM. */ void * high_memory; -struct page *highmem_start_page; unsigned long vmalloc_earlyreserve; EXPORT_SYMBOL(num_physpages); -EXPORT_SYMBOL(highmem_start_page); EXPORT_SYMBOL(high_memory); EXPORT_SYMBOL(vmalloc_earlyreserve); -/* - * We special-case the C-O-W ZERO_PAGE, because it's such - * a common occurrence (no need to read the page to know - * that it's zero - better for the cache and memory subsystem). - */ -static inline void copy_cow_page(struct page * from, struct page * to, unsigned long address) -{ - if (from == ZERO_PAGE(address)) { - clear_user_highpage(to, address); - return; - } - copy_user_highpage(to, from, address); -} - /* * Note: this doesn't free the actual pages themselves. That * has been handled earlier when unmapping all the memory regions. */ -static inline void free_one_pmd(struct mmu_gather *tlb, pmd_t * dir) +static inline void clear_pmd_range(struct mmu_gather *tlb, pmd_t *pmd, unsigned long start, unsigned long end) { struct page *page; - if (pmd_none(*dir)) + if (pmd_none(*pmd)) return; - if (unlikely(pmd_bad(*dir))) { - pmd_ERROR(*dir); - pmd_clear(dir); + if (unlikely(pmd_bad(*pmd))) { + pmd_ERROR(*pmd); + pmd_clear(pmd); return; } - page = pmd_page(*dir); - pmd_clear(dir); - dec_page_state(nr_page_table_pages); - tlb->mm->nr_ptes--; - pte_free_tlb(tlb, page); + if (!((start | end) & ~PMD_MASK)) { + /* Only clear full, aligned ranges */ + page = pmd_page(*pmd); + pmd_clear(pmd); + dec_page_state(nr_page_table_pages); + tlb->mm->nr_ptes--; + pte_free_tlb(tlb, page); + } } -static inline void free_one_pgd(struct mmu_gather *tlb, pgd_t * dir) +static inline void clear_pud_range(struct mmu_gather *tlb, pud_t *pud, unsigned long start, unsigned long end) { - int j; - pmd_t * pmd; + unsigned long addr = start, next; + pmd_t *pmd, *__pmd; - if (pgd_none(*dir)) + if (pud_none(*pud)) return; - if (unlikely(pgd_bad(*dir))) { - pgd_ERROR(*dir); - pgd_clear(dir); + if (unlikely(pud_bad(*pud))) { + pud_ERROR(*pud); + pud_clear(pud); return; } - pmd = pmd_offset(dir, 0); - pgd_clear(dir); - for (j = 0; j < PTRS_PER_PMD ; j++) - free_one_pmd(tlb, pmd+j); - pmd_free_tlb(tlb, pmd); + + pmd = __pmd = pmd_offset(pud, start); + do { + next = (addr + PMD_SIZE) & PMD_MASK; + if (next > end || next <= addr) + next = end; + + clear_pmd_range(tlb, pmd, addr, next); + pmd++; + addr = next; + } while (addr && (addr < end)); + + if (!((start | end) & ~PUD_MASK)) { + /* Only clear full, aligned ranges */ + pud_clear(pud); + pmd_free_tlb(tlb, __pmd); + } +} + + +static inline void clear_pgd_range(struct mmu_gather *tlb, pgd_t *pgd, unsigned long start, unsigned long end) +{ + unsigned long addr = start, next; + pud_t *pud, *__pud; + + if (pgd_none(*pgd)) + return; + if (unlikely(pgd_bad(*pgd))) { + pgd_ERROR(*pgd); + pgd_clear(pgd); + return; + } + + pud = __pud = pud_offset(pgd, start); + do { + next = (addr + PUD_SIZE) & PUD_MASK; + if (next > end || next <= addr) + next = end; + + clear_pud_range(tlb, pud, addr, next); + pud++; + addr = next; + } while (addr && (addr < end)); + + if (!((start | end) & ~PGDIR_MASK)) { + /* Only clear full, aligned ranges */ + pgd_clear(pgd); + pud_free_tlb(tlb, __pud); + } } /* - * This function clears all user-level page tables of a process - this - * is needed by execve(), so that old pages aren't in the way. + * This function clears user-level page tables of a process. * * Must be called with pagetable lock held. */ -void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr) +void clear_page_range(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - pgd_t * page_dir = tlb->mm->pgd; + unsigned long addr = start, next; + pgd_t * pgd = pgd_offset(tlb->mm, start); + unsigned long i; - page_dir += first; - do { - free_one_pgd(tlb, page_dir); - page_dir++; - } while (--nr); + for (i = pgd_index(start); i <= pgd_index(end-1); i++) { + next = (addr + PGDIR_SIZE) & PGDIR_MASK; + if (next > end || next <= addr) + next = end; + + clear_pgd_range(tlb, pgd, addr, next); + pgd++; + addr = next; + } } pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address) @@ -204,165 +243,212 @@ pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned lon out: return pte_offset_kernel(pmd, address); } -#define PTE_TABLE_MASK ((PTRS_PER_PTE-1) * sizeof(pte_t)) -#define PMD_TABLE_MASK ((PTRS_PER_PMD-1) * sizeof(pmd_t)) /* * copy one vm_area from one task to the other. Assumes the page tables * already present in the new task to be cleared in the whole range * covered by this vma. * - * 08Jan98 Merged into one routine from several inline routines to reduce - * variable count and make things faster. -jj - * * dst->page_table_lock is held on entry and exit, - * but may be dropped within pmd_alloc() and pte_alloc_map(). + * but may be dropped within p[mg]d_alloc() and pte_alloc_map(). */ -int copy_page_range(struct mm_struct *dst, struct mm_struct *src, - struct vm_area_struct *vma) + +static inline void +copy_swap_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, pte_t pte) { - pgd_t * src_pgd, * dst_pgd; - unsigned long address = vma->vm_start; - unsigned long end = vma->vm_end; - unsigned long cow; + if (pte_file(pte)) + return; + swap_duplicate(pte_to_swp_entry(pte)); + if (list_empty(&dst_mm->mmlist)) { + spin_lock(&mmlist_lock); + list_add(&dst_mm->mmlist, &src_mm->mmlist); + spin_unlock(&mmlist_lock); + } +} + +static inline void +copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pte_t *dst_pte, pte_t *src_pte, unsigned long vm_flags, + unsigned long addr) +{ + pte_t pte = *src_pte; + struct page *page; + unsigned long pfn; + + /* pte contains position in swap, so copy. */ + if (!pte_present(pte)) { + copy_swap_pte(dst_mm, src_mm, pte); + set_pte(dst_pte, pte); + return; + } + pfn = pte_pfn(pte); + /* the pte points outside of valid memory, the + * mapping is assumed to be good, meaningful + * and not mapped via rmap - duplicate the + * mapping as is. + */ + page = NULL; + if (pfn_valid(pfn)) + page = pfn_to_page(pfn); + + if (!page || PageReserved(page)) { + set_pte(dst_pte, pte); + return; + } + + /* + * If it's a COW mapping, write protect it both + * in the parent and the child + */ + if ((vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) { + ptep_set_wrprotect(src_pte); + pte = *src_pte; + } + + /* + * If it's a shared mapping, mark it clean in + * the child + */ + if (vm_flags & VM_SHARED) + pte = pte_mkclean(pte); + pte = pte_mkold(pte); + get_page(page); + dst_mm->rss++; + if (PageAnon(page)) + dst_mm->anon_rss++; + set_pte(dst_pte, pte); + page_dup_rmap(page); +} + +static int copy_pte_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pmd_t *dst_pmd, pmd_t *src_pmd, struct vm_area_struct *vma, + unsigned long addr, unsigned long end) +{ + pte_t *src_pte, *dst_pte; + pte_t *s, *d; + unsigned long vm_flags = vma->vm_flags; + + d = dst_pte = pte_alloc_map(dst_mm, dst_pmd, addr); + if (!dst_pte) + return -ENOMEM; + + spin_lock(&src_mm->page_table_lock); + s = src_pte = pte_offset_map_nested(src_pmd, addr); + for (; addr < end; addr += PAGE_SIZE, s++, d++) { + if (pte_none(*s)) + continue; + copy_one_pte(dst_mm, src_mm, d, s, vm_flags, addr); + } + pte_unmap_nested(src_pte); + pte_unmap(dst_pte); + spin_unlock(&src_mm->page_table_lock); + cond_resched_lock(&dst_mm->page_table_lock); + return 0; +} + +static int copy_pmd_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pud_t *dst_pud, pud_t *src_pud, struct vm_area_struct *vma, + unsigned long addr, unsigned long end) +{ + pmd_t *src_pmd, *dst_pmd; + int err = 0; + unsigned long next; + + src_pmd = pmd_offset(src_pud, addr); + dst_pmd = pmd_alloc(dst_mm, dst_pud, addr); + if (!dst_pmd) + return -ENOMEM; + + for (; addr < end; addr = next, src_pmd++, dst_pmd++) { + next = (addr + PMD_SIZE) & PMD_MASK; + if (next > end || next <= addr) + next = end; + if (pmd_none(*src_pmd)) + continue; + if (pmd_bad(*src_pmd)) { + pmd_ERROR(*src_pmd); + pmd_clear(src_pmd); + continue; + } + err = copy_pte_range(dst_mm, src_mm, dst_pmd, src_pmd, + vma, addr, next); + if (err) + break; + } + return err; +} + +static int copy_pud_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, + pgd_t *dst_pgd, pgd_t *src_pgd, struct vm_area_struct *vma, + unsigned long addr, unsigned long end) +{ + pud_t *src_pud, *dst_pud; + int err = 0; + unsigned long next; + + src_pud = pud_offset(src_pgd, addr); + dst_pud = pud_alloc(dst_mm, dst_pgd, addr); + if (!dst_pud) + return -ENOMEM; + + for (; addr < end; addr = next, src_pud++, dst_pud++) { + next = (addr + PUD_SIZE) & PUD_MASK; + if (next > end || next <= addr) + next = end; + if (pud_none(*src_pud)) + continue; + if (pud_bad(*src_pud)) { + pud_ERROR(*src_pud); + pud_clear(src_pud); + continue; + } + err = copy_pmd_range(dst_mm, src_mm, dst_pud, src_pud, + vma, addr, next); + if (err) + break; + } + return err; +} + +int copy_page_range(struct mm_struct *dst, struct mm_struct *src, + struct vm_area_struct *vma) +{ + pgd_t *src_pgd, *dst_pgd; + unsigned long addr, start, end, next; + int err = 0; if (is_vm_hugetlb_page(vma)) return copy_hugetlb_page_range(dst, src, vma); - cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; - src_pgd = pgd_offset(src, address)-1; - dst_pgd = pgd_offset(dst, address)-1; + start = vma->vm_start; + src_pgd = pgd_offset(src, start); + dst_pgd = pgd_offset(dst, start); - for (;;) { - pmd_t * src_pmd, * dst_pmd; - - src_pgd++; dst_pgd++; - - /* copy_pmd_range */ - + end = vma->vm_end; + addr = start; + while (addr && (addr < end-1)) { + next = (addr + PGDIR_SIZE) & PGDIR_MASK; + if (next > end || next <= addr) + next = end; if (pgd_none(*src_pgd)) - goto skip_copy_pmd_range; - if (unlikely(pgd_bad(*src_pgd))) { + goto next_pgd; + if (pgd_bad(*src_pgd)) { pgd_ERROR(*src_pgd); pgd_clear(src_pgd); -skip_copy_pmd_range: address = (address + PGDIR_SIZE) & PGDIR_MASK; - if (!address || (address >= end)) - goto out; - continue; + goto next_pgd; } + err = copy_pud_range(dst, src, dst_pgd, src_pgd, + vma, addr, next); + if (err) + break; - src_pmd = pmd_offset(src_pgd, address); - dst_pmd = pmd_alloc(dst, dst_pgd, address); - if (!dst_pmd) - goto nomem; - - do { - pte_t * src_pte, * dst_pte; - - /* copy_pte_range */ - - if (pmd_none(*src_pmd)) - goto skip_copy_pte_range; - if (unlikely(pmd_bad(*src_pmd))) { - pmd_ERROR(*src_pmd); - pmd_clear(src_pmd); -skip_copy_pte_range: - address = (address + PMD_SIZE) & PMD_MASK; - if (address >= end) - goto out; - goto cont_copy_pmd_range; - } - - dst_pte = pte_alloc_map(dst, dst_pmd, address); - if (!dst_pte) - goto nomem; - spin_lock(&src->page_table_lock); - src_pte = pte_offset_map_nested(src_pmd, address); - do { - pte_t pte = *src_pte; - struct page *page; - unsigned long pfn; - - /* copy_one_pte */ - - if (pte_none(pte)) - goto cont_copy_pte_range_noset; - /* pte contains position in swap, so copy. */ - if (!pte_present(pte)) { - if (!pte_file(pte)) { - swap_duplicate(pte_to_swp_entry(pte)); - if (list_empty(&dst->mmlist)) { - spin_lock(&mmlist_lock); - list_add(&dst->mmlist, - &src->mmlist); - spin_unlock(&mmlist_lock); - } - } - set_pte(dst_pte, pte); - goto cont_copy_pte_range_noset; - } - pfn = pte_pfn(pte); - /* the pte points outside of valid memory, the - * mapping is assumed to be good, meaningful - * and not mapped via rmap - duplicate the - * mapping as is. - */ - page = NULL; - if (pfn_valid(pfn)) - page = pfn_to_page(pfn); - - if (!page || PageReserved(page)) { - set_pte(dst_pte, pte); - goto cont_copy_pte_range_noset; - } - - /* - * If it's a COW mapping, write protect it both - * in the parent and the child - */ - if (cow) { - ptep_set_wrprotect(src_pte); - pte = *src_pte; - } - - /* - * If it's a shared mapping, mark it clean in - * the child - */ - if (vma->vm_flags & VM_SHARED) - pte = pte_mkclean(pte); - pte = pte_mkold(pte); - get_page(page); - dst->rss++; - if (PageAnon(page)) - dst->anon_rss++; - set_pte(dst_pte, pte); - page_dup_rmap(page); -cont_copy_pte_range_noset: - address += PAGE_SIZE; - if (address >= end) { - pte_unmap_nested(src_pte); - pte_unmap(dst_pte); - goto out_unlock; - } - src_pte++; - dst_pte++; - } while ((unsigned long)src_pte & PTE_TABLE_MASK); - pte_unmap_nested(src_pte-1); - pte_unmap(dst_pte-1); - spin_unlock(&src->page_table_lock); - cond_resched_lock(&dst->page_table_lock); -cont_copy_pmd_range: - src_pmd++; - dst_pmd++; - } while ((unsigned long)src_pmd & PMD_TABLE_MASK); +next_pgd: + src_pgd++; + dst_pgd++; + addr = next; } -out_unlock: - spin_unlock(&src->page_table_lock); -out: - return 0; -nomem: - return -ENOMEM; + + return err; } static void zap_pte_range(struct mmu_gather *tlb, @@ -449,23 +535,23 @@ static void zap_pte_range(struct mmu_gather *tlb, } static void zap_pmd_range(struct mmu_gather *tlb, - pgd_t * dir, unsigned long address, + pud_t *pud, unsigned long address, unsigned long size, struct zap_details *details) { pmd_t * pmd; unsigned long end; - if (pgd_none(*dir)) + if (pud_none(*pud)) return; - if (unlikely(pgd_bad(*dir))) { - pgd_ERROR(*dir); - pgd_clear(dir); + if (unlikely(pud_bad(*pud))) { + pud_ERROR(*pud); + pud_clear(pud); return; } - pmd = pmd_offset(dir, address); + pmd = pmd_offset(pud, address); end = address + size; - if (end > ((address + PGDIR_SIZE) & PGDIR_MASK)) - end = ((address + PGDIR_SIZE) & PGDIR_MASK); + if (end > ((address + PUD_SIZE) & PUD_MASK)) + end = ((address + PUD_SIZE) & PUD_MASK); do { zap_pte_range(tlb, pmd, address, end - address, details); address = (address + PMD_SIZE) & PMD_MASK; @@ -473,36 +559,54 @@ static void zap_pmd_range(struct mmu_gather *tlb, } while (address && (address < end)); } +static void zap_pud_range(struct mmu_gather *tlb, + pgd_t * pgd, unsigned long address, + unsigned long end, struct zap_details *details) +{ + pud_t * pud; + + if (pgd_none(*pgd)) + return; + if (unlikely(pgd_bad(*pgd))) { + pgd_ERROR(*pgd); + pgd_clear(pgd); + return; + } + pud = pud_offset(pgd, address); + do { + zap_pmd_range(tlb, pud, address, end - address, details); + address = (address + PUD_SIZE) & PUD_MASK; + pud++; + } while (address && (address < end)); +} + static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma, unsigned long address, unsigned long end, struct zap_details *details) { - pgd_t * dir; + unsigned long next; + pgd_t *pgd; + int i; BUG_ON(address >= end); - dir = pgd_offset(vma->vm_mm, address); + pgd = pgd_offset(vma->vm_mm, address); tlb_start_vma(tlb, vma); - do { - zap_pmd_range(tlb, dir, address, end - address, details); - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); + for (i = pgd_index(address); i <= pgd_index(end-1); i++) { + next = (address + PGDIR_SIZE) & PGDIR_MASK; + if (next <= address || next > end) + next = end; + zap_pud_range(tlb, pgd, address, next, details); + address = next; + pgd++; + } tlb_end_vma(tlb, vma); } -/* Dispose of an entire struct mmu_gather per rescheduling point */ -#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) -#define ZAP_BLOCK_SIZE (FREE_PTE_NR * PAGE_SIZE) -#endif - -/* For UP, 256 pages at a time gives nice low latency */ -#if !defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) -#define ZAP_BLOCK_SIZE (256 * PAGE_SIZE) -#endif - +#ifdef CONFIG_PREEMPT +# define ZAP_BLOCK_SIZE (8 * PAGE_SIZE) +#else /* No preempt: go for improved straight-line efficiency */ -#if !defined(CONFIG_PREEMPT) -#define ZAP_BLOCK_SIZE (1024 * PAGE_SIZE) +# define ZAP_BLOCK_SIZE (1024 * PAGE_SIZE) #endif /** @@ -541,7 +645,8 @@ int unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm, unsigned long tlb_start = 0; /* For tlb_finish_mmu */ int tlb_start_valid = 0; int ret = 0; - int atomic = details && details->atomic; + spinlock_t *i_mmap_lock = details? details->i_mmap_lock: NULL; + int fullmm = tlb_is_full_mm(*tlbp); for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) { unsigned long start; @@ -579,16 +684,29 @@ int unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm, zap_bytes -= block; if ((long)zap_bytes > 0) continue; - if (!atomic && need_resched()) { - int fullmm = tlb_is_full_mm(*tlbp); - tlb_finish_mmu(*tlbp, tlb_start, start); - cond_resched_lock(&mm->page_table_lock); - *tlbp = tlb_gather_mmu(mm, fullmm); - tlb_start_valid = 0; + + tlb_finish_mmu(*tlbp, tlb_start, start); + + if (need_resched() || + need_lockbreak(&mm->page_table_lock) || + (i_mmap_lock && need_lockbreak(i_mmap_lock))) { + if (i_mmap_lock) { + /* must reset count of rss freed */ + *tlbp = tlb_gather_mmu(mm, fullmm); + details->break_addr = start; + goto out; + } + spin_unlock(&mm->page_table_lock); + cond_resched(); + spin_lock(&mm->page_table_lock); } + + *tlbp = tlb_gather_mmu(mm, fullmm); + tlb_start_valid = 0; zap_bytes = ZAP_BLOCK_SIZE; } } +out: return ret; } @@ -617,6 +735,7 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address, tlb = tlb_gather_mmu(mm, 0); unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details); tlb_finish_mmu(tlb, address, end); + acct_update_integrals(); spin_unlock(&mm->page_table_lock); } @@ -624,10 +743,11 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address, * Do a quick page-table lookup for a single page. * mm->page_table_lock must be held. */ -struct page * -follow_page(struct mm_struct *mm, unsigned long address, int write) +static struct page * +__follow_page(struct mm_struct *mm, unsigned long address, int read, int write) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *ptep, pte; unsigned long pfn; @@ -641,13 +761,15 @@ follow_page(struct mm_struct *mm, unsigned long address, int write) if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) goto out; - pmd = pmd_offset(pgd, address); - if (pmd_none(*pmd)) + pud = pud_offset(pgd, address); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + goto out; + + pmd = pmd_offset(pud, address); + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto out; if (pmd_huge(*pmd)) return follow_huge_pmd(mm, address, pmd, write); - if (unlikely(pmd_bad(*pmd))) - goto out; ptep = pte_offset_map(pmd, address); if (!ptep) @@ -658,6 +780,8 @@ follow_page(struct mm_struct *mm, unsigned long address, int write) if (pte_present(pte)) { if (write && !pte_write(pte)) goto out; + if (read && !pte_read(pte)) + goto out; pfn = pte_pfn(pte); if (pfn_valid(pfn)) { page = pfn_to_page(pfn); @@ -672,6 +796,20 @@ out: return NULL; } +struct page * +follow_page(struct mm_struct *mm, unsigned long address, int write) +{ + return __follow_page(mm, address, /*read*/0, write); +} + +int +check_user_page_readable(struct mm_struct *mm, unsigned long address) +{ + return __follow_page(mm, address, /*read*/1, /*write*/0) != NULL; +} + +EXPORT_SYMBOL(check_user_page_readable); + /* * Given a physical address, is there a useful struct page pointing to * it? This may become more complex in the future if we start dealing @@ -691,6 +829,7 @@ untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma, unsigned long address) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; /* Check if the vma is for an anonymous mapping. */ @@ -702,8 +841,12 @@ untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma, if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) return 1; + pud = pud_offset(pgd, address); + if (pud_none(*pud) || unlikely(pud_bad(*pud))) + return 1; + /* Check if page middle directory entry exists. */ - pmd = pmd_offset(pgd, address); + pmd = pmd_offset(pud, address); if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) return 1; @@ -735,6 +878,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long pg = start & PAGE_MASK; struct vm_area_struct *gate_vma = get_gate_vma(tsk); pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; if (write) /* user gate pages are read-only */ @@ -744,7 +888,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, else pgd = pgd_offset_gate(mm, pg); BUG_ON(pgd_none(*pgd)); - pmd = pmd_offset(pgd, pg); + pud = pud_offset(pgd, pg); + BUG_ON(pud_none(*pud)); + pmd = pmd_offset(pud, pg); BUG_ON(pmd_none(*pmd)); pte = pte_offset_map(pmd, pg); BUG_ON(pte_none(*pte)); @@ -774,6 +920,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, do { struct page *map; int lookup_write = write; + + cond_resched_lock(&mm->page_table_lock); while (!(map = follow_page(mm, start, lookup_write))) { /* * Shortcut for anonymous pages. We don't want @@ -857,16 +1005,16 @@ static void zeromap_pte_range(pte_t * pte, unsigned long address, } while (address && (address < end)); } -static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, - unsigned long size, pgprot_t prot) +static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, + unsigned long address, unsigned long size, pgprot_t prot) { unsigned long base, end; - base = address & PGDIR_MASK; - address &= ~PGDIR_MASK; + base = address & PUD_MASK; + address &= ~PUD_MASK; end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; + if (end > PUD_SIZE) + end = PUD_SIZE; do { pte_t * pte = pte_alloc_map(mm, pmd, base + address); if (!pte) @@ -879,31 +1027,65 @@ static inline int zeromap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned return 0; } -int zeromap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, pgprot_t prot) +static inline int zeromap_pud_range(struct mm_struct *mm, pud_t * pud, + unsigned long address, + unsigned long size, pgprot_t prot) { + unsigned long base, end; int error = 0; - pgd_t * dir; - unsigned long beg = address; - unsigned long end = address + size; - struct mm_struct *mm = vma->vm_mm; - dir = pgd_offset(mm, address); - flush_cache_range(vma, beg, end); - if (address >= end) - BUG(); - - spin_lock(&mm->page_table_lock); + base = address & PGDIR_MASK; + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; do { - pmd_t *pmd = pmd_alloc(mm, dir, address); + pmd_t * pmd = pmd_alloc(mm, pud, base + address); error = -ENOMEM; if (!pmd) break; - error = zeromap_pmd_range(mm, pmd, address, end - address, prot); + error = zeromap_pmd_range(mm, pmd, base + address, + end - address, prot); if (error) break; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; + address = (address + PUD_SIZE) & PUD_MASK; + pud++; } while (address && (address < end)); + return 0; +} + +int zeromap_page_range(struct vm_area_struct *vma, unsigned long address, + unsigned long size, pgprot_t prot) +{ + int i; + int error = 0; + pgd_t * pgd; + unsigned long beg = address; + unsigned long end = address + size; + unsigned long next; + struct mm_struct *mm = vma->vm_mm; + + pgd = pgd_offset(mm, address); + flush_cache_range(vma, beg, end); + BUG_ON(address >= end); + BUG_ON(end > vma->vm_end); + + spin_lock(&mm->page_table_lock); + for (i = pgd_index(address); i <= pgd_index(end-1); i++) { + pud_t *pud = pud_alloc(mm, pgd, address); + error = -ENOMEM; + if (!pud) + break; + next = (address + PGDIR_SIZE) & PGDIR_MASK; + if (next <= beg || next > end) + next = end; + error = zeromap_pud_range(mm, pud, address, + next - address, prot); + if (error) + break; + address = next; + pgd++; + } /* * Why flush? zeromap_pte_range has a BUG_ON for !pte_none() */ @@ -917,8 +1099,9 @@ int zeromap_page_range(struct vm_area_struct *vma, unsigned long address, unsign * mappings are removed. any references to nonexistent pages results * in null mappings (currently treated as "copy-on-access") */ -static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size, - unsigned long pfn, pgprot_t prot) +static inline void +remap_pte_range(pte_t * pte, unsigned long address, unsigned long size, + unsigned long pfn, pgprot_t prot) { unsigned long end; @@ -936,11 +1119,38 @@ static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned } while (address && (address < end)); } -static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long pfn, pgprot_t prot) +static inline int +remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, + unsigned long size, unsigned long pfn, pgprot_t prot) { unsigned long base, end; + base = address & PUD_MASK; + address &= ~PUD_MASK; + end = address + size; + if (end > PUD_SIZE) + end = PUD_SIZE; + pfn -= (address >> PAGE_SHIFT); + do { + pte_t * pte = pte_alloc_map(mm, pmd, base + address); + if (!pte) + return -ENOMEM; + remap_pte_range(pte, base + address, end - address, + (address >> PAGE_SHIFT) + pfn, prot); + pte_unmap(pte); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static inline int remap_pud_range(struct mm_struct *mm, pud_t * pud, + unsigned long address, unsigned long size, + unsigned long pfn, pgprot_t prot) +{ + unsigned long base, end; + int error; + base = address & PGDIR_MASK; address &= ~PGDIR_MASK; end = address + size; @@ -948,31 +1158,36 @@ static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned lo end = PGDIR_SIZE; pfn -= address >> PAGE_SHIFT; do { - pte_t * pte = pte_alloc_map(mm, pmd, base + address); - if (!pte) - return -ENOMEM; - remap_pte_range(pte, base + address, end - address, pfn + (address >> PAGE_SHIFT), prot); - pte_unmap(pte); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; + pmd_t *pmd = pmd_alloc(mm, pud, base+address); + error = -ENOMEM; + if (!pmd) + break; + error = remap_pmd_range(mm, pmd, base + address, end - address, + (address >> PAGE_SHIFT) + pfn, prot); + if (error) + break; + address = (address + PUD_SIZE) & PUD_MASK; + pud++; } while (address && (address < end)); - return 0; + return error; } /* Note: this is only safe if the mm semaphore is held when called. */ -int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) +int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) { int error = 0; - pgd_t * dir; + pgd_t *pgd; unsigned long beg = from; unsigned long end = from + size; + unsigned long next; struct mm_struct *mm = vma->vm_mm; + int i; pfn -= from >> PAGE_SHIFT; - dir = pgd_offset(mm, from); + pgd = pgd_offset(mm, from); flush_cache_range(vma, beg, end); - if (from >= end) - BUG(); + BUG_ON(from >= end); /* * Physically remapped pages are special. Tell the @@ -983,25 +1198,32 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned lon * this region. */ vma->vm_flags |= VM_IO | VM_RESERVED; + spin_lock(&mm->page_table_lock); - do { - pmd_t *pmd = pmd_alloc(mm, dir, from); + for (i = pgd_index(beg); i <= pgd_index(end-1); i++) { + pud_t *pud = pud_alloc(mm, pgd, from); error = -ENOMEM; - if (!pmd) + if (!pud) break; - error = remap_pmd_range(mm, pmd, from, end - from, pfn + (from >> PAGE_SHIFT), prot); + next = (from + PGDIR_SIZE) & PGDIR_MASK; + if (next > end || next <= from) + next = end; + error = remap_pud_range(mm, pud, from, end - from, + pfn + (from >> PAGE_SHIFT), prot); if (error) break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (from && (from < end)); + from = next; + pgd++; + } /* * Why flush? remap_pte_range has a BUG_ON for !pte_none() */ flush_tlb_range(vma, beg, end); spin_unlock(&mm->page_table_lock); + return error; } + EXPORT_SYMBOL(remap_pfn_range); /* @@ -1098,11 +1320,16 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, if (unlikely(anon_vma_prepare(vma))) goto no_new_page; - new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); - if (!new_page) - goto no_new_page; - copy_cow_page(old_page,new_page,address); - + if (old_page == ZERO_PAGE(address)) { + new_page = alloc_zeroed_user_highpage(vma, address); + if (!new_page) + goto no_new_page; + } else { + new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); + if (!new_page) + goto no_new_page; + copy_user_highpage(new_page, old_page, address); + } /* * Re-check the pte - we dropped the lock */ @@ -1111,9 +1338,11 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, if (likely(pte_same(*page_table, pte))) { if (PageAnon(old_page)) mm->anon_rss--; - if (PageReserved(old_page)) + if (PageReserved(old_page)) { ++mm->rss; - else + acct_update_integrals(); + update_mem_hiwater(); + } else page_remove_rmap(old_page); break_cow(vma, new_page, address, page_table); lru_cache_add_active(new_page); @@ -1134,17 +1363,112 @@ no_new_page: } /* - * Helper function for unmap_mapping_range(). + * Helper functions for unmap_mapping_range(). + * + * __ Notes on dropping i_mmap_lock to reduce latency while unmapping __ + * + * We have to restart searching the prio_tree whenever we drop the lock, + * since the iterator is only valid while the lock is held, and anyway + * a later vma might be split and reinserted earlier while lock dropped. + * + * The list of nonlinear vmas could be handled more efficiently, using + * a placeholder, but handle it in the same way until a need is shown. + * It is important to search the prio_tree before nonlinear list: a vma + * may become nonlinear and be shifted from prio_tree to nonlinear list + * while the lock is dropped; but never shifted from list to prio_tree. + * + * In order to make forward progress despite restarting the search, + * vm_truncate_count is used to mark a vma as now dealt with, so we can + * quickly skip it next time around. Since the prio_tree search only + * shows us those vmas affected by unmapping the range in question, we + * can't efficiently keep all vmas in step with mapping->truncate_count: + * so instead reset them all whenever it wraps back to 0 (then go to 1). + * mapping->truncate_count and vma->vm_truncate_count are protected by + * i_mmap_lock. + * + * In order to make forward progress despite repeatedly restarting some + * large vma, note the break_addr set by unmap_vmas when it breaks out: + * and restart from that address when we reach that vma again. It might + * have been split or merged, shrunk or extended, but never shifted: so + * restart_addr remains valid so long as it remains in the vma's range. + * unmap_mapping_range forces truncate_count to leap over page-aligned + * values so we can save vma's restart_addr in its truncate_count field. */ -static inline void unmap_mapping_range_list(struct prio_tree_root *root, +#define is_restart_addr(truncate_count) (!((truncate_count) & ~PAGE_MASK)) + +static void reset_vma_truncate_counts(struct address_space *mapping) +{ + struct vm_area_struct *vma; + struct prio_tree_iter iter; + + vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX) + vma->vm_truncate_count = 0; + list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list) + vma->vm_truncate_count = 0; +} + +static int unmap_mapping_range_vma(struct vm_area_struct *vma, + unsigned long start_addr, unsigned long end_addr, + struct zap_details *details) +{ + unsigned long restart_addr; + int need_break; + +again: + restart_addr = vma->vm_truncate_count; + if (is_restart_addr(restart_addr) && start_addr < restart_addr) { + start_addr = restart_addr; + if (start_addr >= end_addr) { + /* Top of vma has been split off since last time */ + vma->vm_truncate_count = details->truncate_count; + return 0; + } + } + + details->break_addr = end_addr; + zap_page_range(vma, start_addr, end_addr - start_addr, details); + + /* + * We cannot rely on the break test in unmap_vmas: + * on the one hand, we don't want to restart our loop + * just because that broke out for the page_table_lock; + * on the other hand, it does no test when vma is small. + */ + need_break = need_resched() || + need_lockbreak(details->i_mmap_lock); + + if (details->break_addr >= end_addr) { + /* We have now completed this vma: mark it so */ + vma->vm_truncate_count = details->truncate_count; + if (!need_break) + return 0; + } else { + /* Note restart_addr in vma's truncate_count field */ + vma->vm_truncate_count = details->break_addr; + if (!need_break) + goto again; + } + + spin_unlock(details->i_mmap_lock); + cond_resched(); + spin_lock(details->i_mmap_lock); + return -EINTR; +} + +static inline void unmap_mapping_range_tree(struct prio_tree_root *root, struct zap_details *details) { struct vm_area_struct *vma; struct prio_tree_iter iter; pgoff_t vba, vea, zba, zea; +restart: vma_prio_tree_foreach(vma, &iter, root, details->first_index, details->last_index) { + /* Skip quickly over those we have already dealt with */ + if (vma->vm_truncate_count == details->truncate_count) + continue; + vba = vma->vm_pgoff; vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1; /* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */ @@ -1154,9 +1478,35 @@ static inline void unmap_mapping_range_list(struct prio_tree_root *root, zea = details->last_index; if (zea > vea) zea = vea; - zap_page_range(vma, + + if (unmap_mapping_range_vma(vma, ((zba - vba) << PAGE_SHIFT) + vma->vm_start, - (zea - zba + 1) << PAGE_SHIFT, details); + ((zea - vba + 1) << PAGE_SHIFT) + vma->vm_start, + details) < 0) + goto restart; + } +} + +static inline void unmap_mapping_range_list(struct list_head *head, + struct zap_details *details) +{ + struct vm_area_struct *vma; + + /* + * In nonlinear VMAs there is no correspondence between virtual address + * offset and file offset. So we must perform an exhaustive search + * across *all* the pages in each nonlinear VMA, not just the pages + * whose virtual address lies outside the file truncation point. + */ +restart: + list_for_each_entry(vma, head, shared.vm_set.list) { + /* Skip quickly over those we have already dealt with */ + if (vma->vm_truncate_count == details->truncate_count) + continue; + details->nonlinear_vma = vma; + if (unmap_mapping_range_vma(vma, vma->vm_start, + vma->vm_end, details) < 0) + goto restart; } } @@ -1195,32 +1545,34 @@ void unmap_mapping_range(struct address_space *mapping, details.nonlinear_vma = NULL; details.first_index = hba; details.last_index = hba + hlen - 1; - details.atomic = 1; /* A spinlock is held */ if (details.last_index < details.first_index) details.last_index = ULONG_MAX; + details.i_mmap_lock = &mapping->i_mmap_lock; spin_lock(&mapping->i_mmap_lock); - /* Protect against page fault */ - atomic_inc(&mapping->truncate_count); + + /* serialize i_size write against truncate_count write */ + smp_wmb(); + /* Protect against page faults, and endless unmapping loops */ + mapping->truncate_count++; + /* + * For archs where spin_lock has inclusive semantics like ia64 + * this smp_mb() will prevent to read pagetable contents + * before the truncate_count increment is visible to + * other cpus. + */ + smp_mb(); + if (unlikely(is_restart_addr(mapping->truncate_count))) { + if (mapping->truncate_count == 0) + reset_vma_truncate_counts(mapping); + mapping->truncate_count++; + } + details.truncate_count = mapping->truncate_count; if (unlikely(!prio_tree_empty(&mapping->i_mmap))) - unmap_mapping_range_list(&mapping->i_mmap, &details); - - /* - * In nonlinear VMAs there is no correspondence between virtual address - * offset and file offset. So we must perform an exhaustive search - * across *all* the pages in each nonlinear VMA, not just the pages - * whose virtual address lies outside the file truncation point. - */ - if (unlikely(!list_empty(&mapping->i_mmap_nonlinear))) { - struct vm_area_struct *vma; - list_for_each_entry(vma, &mapping->i_mmap_nonlinear, - shared.vm_set.list) { - details.nonlinear_vma = vma; - zap_page_range(vma, vma->vm_start, - vma->vm_end - vma->vm_start, &details); - } - } + unmap_mapping_range_tree(&mapping->i_mmap, &details); + if (unlikely(!list_empty(&mapping->i_mmap_nonlinear))) + unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details); spin_unlock(&mapping->i_mmap_lock); } EXPORT_SYMBOL(unmap_mapping_range); @@ -1395,6 +1747,9 @@ static int do_swap_page(struct mm_struct * mm, remove_exclusive_swap_page(page); mm->rss++; + acct_update_integrals(); + update_mem_hiwater(); + pte = mk_pte(page, vma->vm_page_prot); if (write_access && can_share_swap_page(page)) { pte = maybe_mkwrite(pte_mkdirty(pte), vma); @@ -1445,10 +1800,9 @@ do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(anon_vma_prepare(vma))) goto no_mem; - page = alloc_page_vma(GFP_HIGHUSER, vma, addr); + page = alloc_zeroed_user_highpage(vma, addr); if (!page) goto no_mem; - clear_user_highpage(page, addr); spin_lock(&mm->page_table_lock); page_table = pte_offset_map(pmd, addr); @@ -1460,11 +1814,13 @@ do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, goto out; } mm->rss++; + acct_update_integrals(); + update_mem_hiwater(); entry = maybe_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)), vma); lru_cache_add_active(page); - mark_page_accessed(page); + SetPageReferenced(page); page_add_anon_rmap(page, vma, addr); } @@ -1499,7 +1855,7 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, struct page * new_page; struct address_space *mapping = NULL; pte_t entry; - int sequence = 0; + unsigned int sequence = 0; int ret = VM_FAULT_MINOR; int anon = 0; @@ -1511,11 +1867,19 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, if (vma->vm_file) { mapping = vma->vm_file->f_mapping; - sequence = atomic_read(&mapping->truncate_count); + sequence = mapping->truncate_count; + smp_rmb(); /* serializes i_size against truncate_count */ } - smp_rmb(); /* Prevent CPU from reordering lock-free ->nopage() */ retry: + cond_resched(); new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret); + /* + * No smp_rmb is needed here as long as there's a full + * spin_lock/unlock sequence inside the ->nopage callback + * (for the pagecache lookup) that acts as an implicit + * smp_mb() and prevents the i_size read to happen + * after the next truncate_count read. + */ /* no page was available -- either SIGBUS or OOM */ if (new_page == NOPAGE_SIGBUS) @@ -1546,9 +1910,8 @@ retry: * invalidated this page. If unmap_mapping_range got called, * retry getting the page. */ - if (mapping && - (unlikely(sequence != atomic_read(&mapping->truncate_count)))) { - sequence = atomic_read(&mapping->truncate_count); + if (mapping && unlikely(sequence != mapping->truncate_count)) { + sequence = mapping->truncate_count; spin_unlock(&mm->page_table_lock); page_cache_release(new_page); goto retry; @@ -1569,6 +1932,9 @@ retry: if (pte_none(*page_table)) { if (!PageReserved(new_page)) ++mm->rss; + acct_update_integrals(); + update_mem_hiwater(); + flush_icache_page(vma, new_page); entry = mk_pte(new_page, vma->vm_page_prot); if (write_access) @@ -1693,13 +2059,14 @@ static inline int handle_pte_fault(struct mm_struct *mm, * By the time we get here, we already hold the mm semaphore */ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, - unsigned long address, int write_access) + unsigned long address, int write_access) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; + pte_t *pte; __set_current_state(TASK_RUNNING); - pgd = pgd_offset(mm, address); inc_page_state(pgfault); @@ -1710,18 +2077,61 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, * We need the page table lock to synchronize with kswapd * and the SMP-safe atomic PTE updates. */ + pgd = pgd_offset(mm, address); spin_lock(&mm->page_table_lock); - pmd = pmd_alloc(mm, pgd, address); - if (pmd) { - pte_t * pte = pte_alloc_map(mm, pmd, address); - if (pte) - return handle_pte_fault(mm, vma, address, write_access, pte, pmd); - } + pud = pud_alloc(mm, pgd, address); + if (!pud) + goto oom; + + pmd = pmd_alloc(mm, pud, address); + if (!pmd) + goto oom; + + pte = pte_alloc_map(mm, pmd, address); + if (!pte) + goto oom; + + return handle_pte_fault(mm, vma, address, write_access, pte, pmd); + + oom: spin_unlock(&mm->page_table_lock); return VM_FAULT_OOM; } +#ifndef __ARCH_HAS_4LEVEL_HACK +/* + * Allocate page upper directory. + * + * We've already handled the fast-path in-line, and we own the + * page table lock. + * + * On a two-level or three-level page table, this ends up actually being + * entirely optimized away. + */ +pud_t fastcall *__pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +{ + pud_t *new; + + spin_unlock(&mm->page_table_lock); + new = pud_alloc_one(mm, address); + spin_lock(&mm->page_table_lock); + if (!new) + return NULL; + + /* + * Because we dropped the lock, we should re-check the + * entry, as somebody else could have populated it.. + */ + if (pgd_present(*pgd)) { + pud_free(new); + goto out; + } + pgd_populate(mm, pgd, new); + out: + return pud_offset(pgd, address); +} + /* * Allocate page middle directory. * @@ -1731,7 +2141,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, * On a two-level page table, this ends up actually being entirely * optimized away. */ -pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) { pmd_t *new; @@ -1745,14 +2155,38 @@ pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long addr * Because we dropped the lock, we should re-check the * entry, as somebody else could have populated it.. */ - if (pgd_present(*pgd)) { + if (pud_present(*pud)) { pmd_free(new); goto out; } - pgd_populate(mm, pgd, new); -out: - return pmd_offset(pgd, address); + pud_populate(mm, pud, new); + out: + return pmd_offset(pud, address); } +#else +pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) +{ + pmd_t *new; + + spin_unlock(&mm->page_table_lock); + new = pmd_alloc_one(mm, address); + spin_lock(&mm->page_table_lock); + if (!new) + return NULL; + + /* + * Because we dropped the lock, we should re-check the + * entry, as somebody else could have populated it.. + */ + if (pgd_present(*pud)) { + pmd_free(new); + goto out; + } + pgd_populate(mm, pud, new); +out: + return pmd_offset(pud, address); +} +#endif int make_pages_present(unsigned long addr, unsigned long end) { @@ -1783,17 +2217,21 @@ struct page * vmalloc_to_page(void * vmalloc_addr) unsigned long addr = (unsigned long) vmalloc_addr; struct page *page = NULL; pgd_t *pgd = pgd_offset_k(addr); + pud_t *pud; pmd_t *pmd; pte_t *ptep, pte; if (!pgd_none(*pgd)) { - pmd = pmd_offset(pgd, addr); - if (!pmd_none(*pmd)) { - ptep = pte_offset_map(pmd, addr); - pte = *ptep; - if (pte_present(pte)) - page = pte_page(pte); - pte_unmap(ptep); + pud = pud_offset(pgd, addr); + if (!pud_none(*pud)) { + pmd = pmd_offset(pud, addr); + if (!pmd_none(*pmd)) { + ptep = pte_offset_map(pmd, addr); + pte = *ptep; + if (pte_present(pte)) + page = pte_page(pte); + pte_unmap(ptep); + } } } return page; @@ -1811,7 +2249,23 @@ unsigned long vmalloc_to_pfn(void * vmalloc_addr) EXPORT_SYMBOL(vmalloc_to_pfn); -#if !defined(CONFIG_ARCH_GATE_AREA) +/* + * update_mem_hiwater + * - update per process rss and vm high water data + */ +void update_mem_hiwater(void) +{ + struct task_struct *tsk = current; + + if (tsk->mm) { + if (tsk->mm->hiwater_rss < tsk->mm->rss) + tsk->mm->hiwater_rss = tsk->mm->rss; + if (tsk->mm->hiwater_vm < tsk->mm->total_vm) + tsk->mm->hiwater_vm = tsk->mm->total_vm; + } +} + +#if !defined(__HAVE_ARCH_GATE_AREA) #if defined(AT_SYSINFO_EHDR) struct vm_area_struct gate_vma; @@ -1837,7 +2291,7 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk) #endif } -int in_gate_area(struct task_struct *task, unsigned long addr) +int in_gate_area_no_task(unsigned long addr) { #ifdef AT_SYSINFO_EHDR if ((addr >= FIXADDR_USER_START) && (addr < FIXADDR_USER_END)) @@ -1846,4 +2300,4 @@ int in_gate_area(struct task_struct *task, unsigned long addr) return 0; } -#endif +#endif /* __HAVE_ARCH_GATE_AREA */ diff --git a/linux-2.6.10-xen-sparse/mm/page_alloc.c b/linux-2.6.11-xen-sparse/mm/page_alloc.c similarity index 80% rename from linux-2.6.10-xen-sparse/mm/page_alloc.c rename to linux-2.6.11-xen-sparse/mm/page_alloc.c index 6676de084c..4d55438fc3 100644 --- a/linux-2.6.10-xen-sparse/mm/page_alloc.c +++ b/linux-2.6.11-xen-sparse/mm/page_alloc.c @@ -32,17 +32,27 @@ #include #include #include +#include #include +#include "internal.h" -nodemask_t node_online_map = NODE_MASK_NONE; +/* MCD - HACK: Find somewhere to initialize this EARLY, or make this initializer cleaner */ +nodemask_t node_online_map = { { [0] = 1UL } }; nodemask_t node_possible_map = NODE_MASK_ALL; struct pglist_data *pgdat_list; unsigned long totalram_pages; unsigned long totalhigh_pages; long nr_swap_pages; -int numnodes = 1; -int sysctl_lower_zone_protection = 0; +/* + * results with 256, 32 in the lowmem_reserve sysctl: + * 1G machine -> (16M dma, 800M-16M normal, 1G-800M high) + * 1G machine -> (16M dma, 784M normal, 224M high) + * NORMAL allocation will leave 784M/256 of ram reserved in the ZONE_DMA + * HIGHMEM allocation will leave 224M/32 of ram reserved in ZONE_NORMAL + * HIGHMEM allocation will (224M+784M)/256 of ram reserved in ZONE_DMA + */ +int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 }; EXPORT_SYMBOL(totalram_pages); EXPORT_SYMBOL(nr_swap_pages); @@ -69,6 +79,10 @@ static int bad_range(struct zone *zone, struct page *page) return 1; if (page_to_pfn(page) < zone->zone_start_pfn) return 1; +#ifdef CONFIG_HOLES_IN_ZONE + if (!pfn_valid(page_to_pfn(page))) + return 1; +#endif if (zone != page_zone(page)) return 1; return 0; @@ -156,6 +170,45 @@ static void destroy_compound_page(struct page *page, unsigned long order) } #endif /* CONFIG_HUGETLB_PAGE */ +/* + * function for dealing with page's order in buddy system. + * zone->lock is already acquired when we use these. + * So, we don't need atomic page->flags operations here. + */ +static inline unsigned long page_order(struct page *page) { + return page->private; +} + +static inline void set_page_order(struct page *page, int order) { + page->private = order; + __SetPagePrivate(page); +} + +static inline void rmv_page_order(struct page *page) +{ + __ClearPagePrivate(page); + page->private = 0; +} + +/* + * This function checks whether a page is free && is the buddy + * we can do coalesce a page and its buddy if + * (a) the buddy is free && + * (b) the buddy is on the buddy system && + * (c) a page and its buddy have the same order. + * for recording page's order, we use page->private and PG_private. + * + */ +static inline int page_is_buddy(struct page *page, int order) +{ + if (PagePrivate(page) && + (page_order(page) == order) && + !PageReserved(page) && + page_count(page) == 0) + return 1; + return 0; +} + /* * Freeing function for a buddy system allocator. * @@ -168,9 +221,10 @@ static void destroy_compound_page(struct page *page, unsigned long order) * at the bottom level available, and propagating the changes upward * as necessary, plus some accounting needed to play nicely with other * parts of the VM system. - * At each level, we keep one bit for each pair of blocks, which - * is set to 1 iff only one of the pair is allocated. So when we - * are allocating or freeing one, we can derive the state of the + * At each level, we keep a list of pages, which are heads of continuous + * free pages of length of (1 << order) and marked with PG_Private.Page's + * order is recorded in page->private field. + * So when we are allocating or freeing one, we can derive the state of the * other. That is, if we allocate a small block, and both were * free, the remainder of the region must be split into blocks. * If a block is freed, and its buddy is also free, then this @@ -180,42 +234,44 @@ static void destroy_compound_page(struct page *page, unsigned long order) */ static inline void __free_pages_bulk (struct page *page, struct page *base, - struct zone *zone, struct free_area *area, unsigned int order) + struct zone *zone, unsigned int order) { - unsigned long page_idx, index, mask; + unsigned long page_idx; + struct page *coalesced; + int order_size = 1 << order; - if (order) + if (unlikely(order)) destroy_compound_page(page, order); - mask = (~0UL) << order; + page_idx = page - base; - if (page_idx & ~mask) - BUG(); - index = page_idx >> (1 + order); - zone->free_pages += 1 << order; + BUG_ON(page_idx & (order_size - 1)); + BUG_ON(bad_range(zone, page)); + + zone->free_pages += order_size; while (order < MAX_ORDER-1) { - struct page *buddy1, *buddy2; + struct free_area *area; + struct page *buddy; + int buddy_idx; - BUG_ON(area >= zone->free_area + MAX_ORDER); - if (!__test_and_change_bit(index, area->map)) - /* - * the buddy page is still allocated. - */ + buddy_idx = (page_idx ^ (1 << order)); + buddy = base + buddy_idx; + if (bad_range(zone, buddy)) + break; + if (!page_is_buddy(buddy, order)) break; - /* Move the buddy up one level. */ - buddy1 = base + (page_idx ^ (1 << order)); - buddy2 = base + page_idx; - BUG_ON(bad_range(zone, buddy1)); - BUG_ON(bad_range(zone, buddy2)); - list_del(&buddy1->lru); - mask <<= 1; + list_del(&buddy->lru); + area = zone->free_area + order; + area->nr_free--; + rmv_page_order(buddy); + page_idx &= buddy_idx; order++; - area++; - index >>= 1; - page_idx &= mask; } - list_add(&(base + page_idx)->lru, &area->free_list); + coalesced = base + page_idx; + set_page_order(coalesced, order); + list_add(&coalesced->lru, &zone->free_area[order].free_list); + zone->free_area[order].nr_free++; } static inline void free_pages_check(const char *function, struct page *page) @@ -253,12 +309,10 @@ free_pages_bulk(struct zone *zone, int count, struct list_head *list, unsigned int order) { unsigned long flags; - struct free_area *area; struct page *base, *page = NULL; int ret = 0; base = zone->zone_mem_map; - area = zone->free_area + order; spin_lock_irqsave(&zone->lock, flags); zone->all_unreclaimable = 0; zone->pages_scanned = 0; @@ -266,7 +320,7 @@ free_pages_bulk(struct zone *zone, int count, page = list_entry(list->prev, struct page, lru); /* have to delete it as __free_pages_bulk list manipulates */ list_del(&page->lru); - __free_pages_bulk(page, base, zone, area, order); + __free_pages_bulk(page, base, zone, order); ret++; } spin_unlock_irqrestore(&zone->lock, flags); @@ -282,6 +336,13 @@ void __free_pages_ok(struct page *page, unsigned int order) return; mod_page_state(pgfree, 1 << order); + +#ifndef CONFIG_MMU + if (order > 0) + for (i = 1 ; i < (1 << order) ; ++i) + __put_page(page + i); +#endif + for (i = 0 ; i < (1 << order) ; ++i) free_pages_check(__FUNCTION__, page + i); list_add(&page->lru, &list); @@ -289,8 +350,6 @@ void __free_pages_ok(struct page *page, unsigned int order) free_pages_bulk(page_zone(page), 1, &list, order); } -#define MARK_USED(index, order, area) \ - __change_bit((index) >> (1+(order)), (area)->map) /* * The order of subdivision here is critical for the IO subsystem. @@ -308,7 +367,7 @@ void __free_pages_ok(struct page *page, unsigned int order) */ static inline struct page * expand(struct zone *zone, struct page *page, - unsigned long index, int low, int high, struct free_area *area) + int low, int high, struct free_area *area) { unsigned long size = 1 << high; @@ -318,12 +377,13 @@ expand(struct zone *zone, struct page *page, size >>= 1; BUG_ON(bad_range(zone, &page[size])); list_add(&page[size].lru, &area->free_list); - MARK_USED(index + size, high, area); + area->nr_free++; + set_page_order(&page[size], high); } return page; } -static inline void set_page_refs(struct page *page, int order) +void set_page_refs(struct page *page, int order) { #ifdef CONFIG_MMU set_page_count(page, 1); @@ -333,9 +393,10 @@ static inline void set_page_refs(struct page *page, int order) /* * We need to reference all the pages for this order, otherwise if * anyone accesses one of the pages with (get/put) it will be freed. + * - eg: access_process_vm() */ for (i = 0; i < (1 << order); i++) - set_page_count(page+i, 1); + set_page_count(page + i, 1); #endif /* CONFIG_MMU */ } @@ -361,6 +422,7 @@ static void prep_new_page(struct page *page, int order) 1 << PG_checked | 1 << PG_mappedtodisk); page->private = 0; set_page_refs(page, order); + kernel_map_pages(page, 1 << order, 1); } /* @@ -372,7 +434,6 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order) struct free_area * area; unsigned int current_order; struct page *page; - unsigned int index; for (current_order = order; current_order < MAX_ORDER; ++current_order) { area = zone->free_area + current_order; @@ -381,11 +442,10 @@ static struct page *__rmqueue(struct zone *zone, unsigned int order) page = list_entry(area->free_list.next, struct page, lru); list_del(&page->lru); - index = page - zone->zone_mem_map; - if (current_order != MAX_ORDER-1) - MARK_USED(index, current_order, area); + rmv_page_order(page); + area->nr_free--; zone->free_pages -= 1UL << order; - return expand(zone, page, index, order, current_order, area); + return expand(zone, page, order, current_order, area); } return NULL; @@ -438,26 +498,30 @@ static void __drain_pages(unsigned int cpu) #endif /* CONFIG_PM || CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_PM -int is_head_of_free_region(struct page *page) + +void mark_free_pages(struct zone *zone) { - struct zone *zone = page_zone(page); - unsigned long flags; + unsigned long zone_pfn, flags; int order; struct list_head *curr; - /* - * Should not matter as we need quiescent system for - * suspend anyway, but... - */ + if (!zone->spanned_pages) + return; + spin_lock_irqsave(&zone->lock, flags); + for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn) + ClearPageNosaveFree(pfn_to_page(zone_pfn + zone->zone_start_pfn)); + for (order = MAX_ORDER - 1; order >= 0; --order) - list_for_each(curr, &zone->free_area[order].free_list) - if (page == list_entry(curr, struct page, lru)) { - spin_unlock_irqrestore(&zone->lock, flags); - return 1 << order; - } + list_for_each(curr, &zone->free_area[order].free_list) { + unsigned long start_pfn, i; + + start_pfn = page_to_pfn(list_entry(curr, struct page, lru)); + + for (i=0; i < (1<lock, flags); - return 0; } /* @@ -537,12 +601,20 @@ void fastcall free_cold_page(struct page *page) free_hot_cold_page(page, 1); } +static inline void prep_zero_page(struct page *page, int order, int gfp_flags) +{ + int i; + + BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); + for(i = 0; i < (1 << order); i++) + clear_highpage(page + i); +} + /* * Really, prep_compound_page() should be called from __rmqueue_bulk(). But * we cheat by calling it from here, in the order > 0 path. Saves a branch * or two. */ - static struct page * buffered_rmqueue(struct zone *zone, int order, int gfp_flags) { @@ -577,42 +649,64 @@ buffered_rmqueue(struct zone *zone, int order, int gfp_flags) BUG_ON(bad_range(zone, page)); mod_page_state_zone(zone, pgalloc, 1 << order); prep_new_page(page, order); + + if (gfp_flags & __GFP_ZERO) + prep_zero_page(page, order, gfp_flags); + if (order && (gfp_flags & __GFP_COMP)) prep_compound_page(page, order); } return page; } +/* + * Return 1 if free pages are above 'mark'. This takes into account the order + * of the allocation. + */ +int zone_watermark_ok(struct zone *z, int order, unsigned long mark, + int classzone_idx, int can_try_harder, int gfp_high) +{ + /* free_pages my go negative - that's OK */ + long min = mark, free_pages = z->free_pages - (1 << order) + 1; + int o; + + if (gfp_high) + min -= min / 2; + if (can_try_harder) + min -= min / 4; + + if (free_pages <= min + z->lowmem_reserve[classzone_idx]) + return 0; + for (o = 0; o < order; o++) { + /* At the next order, this order's pages become unavailable */ + free_pages -= z->free_area[o].nr_free << o; + + /* Require fewer higher order pages to be free */ + min >>= 1; + + if (free_pages <= min) + return 0; + } + return 1; +} + /* * This is the 'heart' of the zoned buddy allocator. - * - * Herein lies the mysterious "incremental min". That's the - * - * local_low = z->pages_low; - * min += local_low; - * - * thing. The intent here is to provide additional protection to low zones for - * allocation requests which _could_ use higher zones. So a GFP_HIGHMEM - * request is not allowed to dip as deeply into the normal zone as a GFP_KERNEL - * request. This preserves additional space in those lower zones for requests - * which really do need memory from those zones. It means that on a decent - * sized machine, GFP_HIGHMEM and GFP_KERNEL requests basically leave the DMA - * zone untouched. */ struct page * fastcall __alloc_pages(unsigned int gfp_mask, unsigned int order, struct zonelist *zonelist) { const int wait = gfp_mask & __GFP_WAIT; - unsigned long min; struct zone **zones, *z; struct page *page; struct reclaim_state reclaim_state; struct task_struct *p = current; int i; - int alloc_type; + int classzone_idx; int do_retry; int can_try_harder; + int did_some_progress; might_sleep_if(wait); @@ -630,13 +724,14 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order, return NULL; } - alloc_type = zone_idx(zones[0]); + classzone_idx = zone_idx(zones[0]); + restart: /* Go through the zonelist once, looking for a zone with enough free */ for (i = 0; (z = zones[i]) != NULL; i++) { - min = z->pages_low + (1<protection[alloc_type]; - if (z->free_pages < min) + if (!zone_watermark_ok(z, order, z->pages_low, + classzone_idx, 0, 0)) continue; page = buffered_rmqueue(z, order, gfp_mask); @@ -645,21 +740,16 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order, } for (i = 0; (z = zones[i]) != NULL; i++) - wakeup_kswapd(z); + wakeup_kswapd(z, order); /* * Go through the zonelist again. Let __GFP_HIGH and allocations * coming from realtime tasks to go deeper into reserves */ for (i = 0; (z = zones[i]) != NULL; i++) { - min = z->pages_min; - if (gfp_mask & __GFP_HIGH) - min /= 2; - if (can_try_harder) - min -= min / 4; - min += (1<protection[alloc_type]; - - if (z->free_pages < min) + if (!zone_watermark_ok(z, order, z->pages_min, + classzone_idx, can_try_harder, + gfp_mask & __GFP_HIGH)) continue; page = buffered_rmqueue(z, order, gfp_mask); @@ -668,7 +758,7 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order, } /* This allocation should allow future memory freeing. */ - if ((p->flags & (PF_MEMALLOC | PF_MEMDIE)) && !in_interrupt()) { + if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE))) && !in_interrupt()) { /* go through the zonelist yet again, ignoring mins */ for (i = 0; (z = zones[i]) != NULL; i++) { page = buffered_rmqueue(z, order, gfp_mask); @@ -683,31 +773,56 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order, goto nopage; rebalance: + cond_resched(); + /* We now go into synchronous reclaim */ p->flags |= PF_MEMALLOC; reclaim_state.reclaimed_slab = 0; p->reclaim_state = &reclaim_state; - try_to_free_pages(zones, gfp_mask, order); + did_some_progress = try_to_free_pages(zones, gfp_mask, order); p->reclaim_state = NULL; p->flags &= ~PF_MEMALLOC; - /* go through the zonelist yet one more time */ - for (i = 0; (z = zones[i]) != NULL; i++) { - min = z->pages_min; - if (gfp_mask & __GFP_HIGH) - min /= 2; - if (can_try_harder) - min -= min / 4; - min += (1<protection[alloc_type]; + cond_resched(); - if (z->free_pages < min) - continue; + if (likely(did_some_progress)) { + /* + * Go through the zonelist yet one more time, keep + * very high watermark here, this is only to catch + * a parallel oom killing, we must fail if we're still + * under heavy pressure. + */ + for (i = 0; (z = zones[i]) != NULL; i++) { + if (!zone_watermark_ok(z, order, z->pages_min, + classzone_idx, can_try_harder, + gfp_mask & __GFP_HIGH)) + continue; - page = buffered_rmqueue(z, order, gfp_mask); - if (page) - goto got_pg; + page = buffered_rmqueue(z, order, gfp_mask); + if (page) + goto got_pg; + } + } else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) { + /* + * Go through the zonelist yet one more time, keep + * very high watermark here, this is only to catch + * a parallel oom killing, we must fail if we're still + * under heavy pressure. + */ + for (i = 0; (z = zones[i]) != NULL; i++) { + if (!zone_watermark_ok(z, order, z->pages_high, + classzone_idx, 0, 0)) + continue; + + page = buffered_rmqueue(z, order, gfp_mask); + if (page) + goto got_pg; + } + + out_of_memory(gfp_mask); + goto restart; } /* @@ -739,7 +854,6 @@ nopage: return NULL; got_pg: zone_statistics(zonelist, z); - kernel_map_pages(page, 1 << order, 1); return page; } @@ -769,12 +883,9 @@ fastcall unsigned long get_zeroed_page(unsigned int gfp_mask) */ BUG_ON(gfp_mask & __GFP_HIGHMEM); - page = alloc_pages(gfp_mask, 0); - if (page) { - void *address = page_address(page); - clear_page(address); - return (unsigned long) address; - } + page = alloc_pages(gfp_mask | __GFP_ZERO, 0); + if (page) + return (unsigned long) page_address(page); return 0; } @@ -902,8 +1013,7 @@ static void show_node(struct zone *zone) * The result is unavoidably approximate - it can change * during and after execution of this function. */ -DEFINE_PER_CPU(struct page_state, page_states) = {0}; -EXPORT_PER_CPU_SYMBOL(page_states); +static DEFINE_PER_CPU(struct page_state, page_states) = {0}; atomic_t nr_pagecache = ATOMIC_INIT(0); EXPORT_SYMBOL(nr_pagecache); @@ -916,18 +1026,18 @@ void __get_page_state(struct page_state *ret, int nr) int cpu = 0; memset(ret, 0, sizeof(*ret)); + + cpu = first_cpu(cpu_online_map); while (cpu < NR_CPUS) { unsigned long *in, *out, off; - if (!cpu_possible(cpu)) { - cpu++; - continue; - } - in = (unsigned long *)&per_cpu(page_states, cpu); - cpu++; - if (cpu < NR_CPUS && cpu_possible(cpu)) + + cpu = next_cpu(cpu, cpu_online_map); + + if (cpu < NR_CPUS) prefetch(&per_cpu(page_states, cpu)); + out = (unsigned long *)ret; for (off = 0; off < nr; off++) *out++ += *in++; @@ -954,18 +1064,28 @@ unsigned long __read_page_state(unsigned offset) unsigned long ret = 0; int cpu; - for (cpu = 0; cpu < NR_CPUS; cpu++) { + for_each_online_cpu(cpu) { unsigned long in; - if (!cpu_possible(cpu)) - continue; - in = (unsigned long)&per_cpu(page_states, cpu) + offset; ret += *((unsigned long *)in); } return ret; } +void __mod_page_state(unsigned offset, unsigned long delta) +{ + unsigned long flags; + void* ptr; + + local_irq_save(flags); + ptr = &__get_cpu_var(page_states); + *(unsigned long*)(ptr + offset) += delta; + local_irq_restore(flags); +} + +EXPORT_SYMBOL(__mod_page_state); + void __get_zone_counts(unsigned long *active, unsigned long *inactive, unsigned long *free, struct pglist_data *pgdat) { @@ -1119,14 +1239,13 @@ void show_free_areas(void) zone->pages_scanned, (zone->all_unreclaimable ? "yes" : "no") ); - printk("protections[]:"); + printk("lowmem_reserve[]:"); for (i = 0; i < MAX_NR_ZONES; i++) - printk(" %lu", zone->protection[i]); + printk(" %lu", zone->lowmem_reserve[i]); printk("\n"); } for_each_zone(zone) { - struct list_head *elem; unsigned long nr, flags, order, total = 0; show_node(zone); @@ -1138,9 +1257,7 @@ void show_free_areas(void) spin_lock_irqsave(&zone->lock, flags); for (order = 0; order < MAX_ORDER; order++) { - nr = 0; - list_for_each(elem, &zone->free_area[order].free_list) - ++nr; + nr = zone->free_area[order].nr_free; total += nr << order; printk("%lu*%lukB ", nr, K(1UL) << order); } @@ -1182,13 +1299,13 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli } #ifdef CONFIG_NUMA -#define MAX_NODE_LOAD (numnodes) +#define MAX_NODE_LOAD (num_online_nodes()) static int __initdata node_load[MAX_NUMNODES]; /** * find_next_best_node - find the next node that should appear in a given * node's fallback list * @node: node whose fallback list we're appending - * @used_node_mask: pointer to the bitmap of already used nodes + * @used_node_mask: nodemask_t of already used nodes * * We use a number of factors to determine which is the next node that should * appear on a given node's fallback list. The node should not have appeared @@ -1199,24 +1316,24 @@ static int __initdata node_load[MAX_NUMNODES]; * on them otherwise. * It returns -1 if no node is found. */ -static int __init find_next_best_node(int node, void *used_node_mask) +static int __init find_next_best_node(int node, nodemask_t *used_node_mask) { int i, n, val; int min_val = INT_MAX; int best_node = -1; - for (i = 0; i < numnodes; i++) { + for_each_online_node(i) { cpumask_t tmp; /* Start from local node */ - n = (node+i)%numnodes; + n = (node+i) % num_online_nodes(); /* Don't want a node to appear more than once */ - if (test_bit(n, used_node_mask)) + if (node_isset(n, *used_node_mask)) continue; /* Use the local node if we haven't already */ - if (!test_bit(node, used_node_mask)) { + if (!node_isset(node, *used_node_mask)) { best_node = node; break; } @@ -1240,7 +1357,7 @@ static int __init find_next_best_node(int node, void *used_node_mask) } if (best_node >= 0) - set_bit(best_node, used_node_mask); + node_set(best_node, *used_node_mask); return best_node; } @@ -1250,7 +1367,7 @@ static void __init build_zonelists(pg_data_t *pgdat) int i, j, k, node, local_node; int prev_node, load; struct zonelist *zonelist; - DECLARE_BITMAP(used_mask, MAX_NUMNODES); + nodemask_t used_mask; /* initialize zonelists */ for (i = 0; i < GFP_ZONETYPES; i++) { @@ -1261,10 +1378,10 @@ static void __init build_zonelists(pg_data_t *pgdat) /* NUMA-aware ordering of nodes */ local_node = pgdat->node_id; - load = numnodes; + load = num_online_nodes(); prev_node = local_node; - bitmap_zero(used_mask, MAX_NUMNODES); - while ((node = find_next_best_node(local_node, used_mask)) >= 0) { + nodes_clear(used_mask); + while ((node = find_next_best_node(local_node, &used_mask)) >= 0) { /* * We don't want to pressure a particular node. * So adding penalty to the first node in same @@ -1320,11 +1437,17 @@ static void __init build_zonelists(pg_data_t *pgdat) * zones coming right after the local ones are those from * node N+1 (modulo N) */ - for (node = local_node + 1; node < numnodes; node++) - j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); - for (node = 0; node < local_node; node++) - j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); - + for (node = local_node + 1; node < MAX_NUMNODES; node++) { + if (!node_online(node)) + continue; + j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); + } + for (node = 0; node < local_node; node++) { + if (!node_online(node)) + continue; + j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); + } + zonelist->zones[j] = NULL; } } @@ -1335,9 +1458,9 @@ void __init build_all_zonelists(void) { int i; - for(i = 0 ; i < numnodes ; i++) + for_each_online_node(i) build_zonelists(NODE_DATA(i)); - printk("Built %i zonelists\n", numnodes); + printk("Built %i zonelists\n", num_online_nodes()); } /* @@ -1429,49 +1552,13 @@ void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone, } } -/* - * Page buddy system uses "index >> (i+1)", where "index" is - * at most "size-1". - * - * The extra "+3" is to round down to byte size (8 bits per byte - * assumption). Thus we get "(size-1) >> (i+4)" as the last byte - * we can access. - * - * The "+1" is because we want to round the byte allocation up - * rather than down. So we should have had a "+7" before we shifted - * down by three. Also, we have to add one as we actually _use_ the - * last bit (it's [0,n] inclusive, not [0,n[). - * - * So we actually had +7+1 before we shift down by 3. But - * (n+8) >> 3 == (n >> 3) + 1 (modulo overflows, which we do not have). - * - * Finally, we LONG_ALIGN because all bitmap operations are on longs. - */ -unsigned long pages_to_bitmap_size(unsigned long order, unsigned long nr_pages) -{ - unsigned long bitmap_size; - - bitmap_size = (nr_pages-1) >> (order+4); - bitmap_size = LONG_ALIGN(bitmap_size+1); - - return bitmap_size; -} - -void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone, unsigned long size) +void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone, + unsigned long size) { int order; - for (order = 0; ; order++) { - unsigned long bitmap_size; - + for (order = 0; order < MAX_ORDER ; order++) { INIT_LIST_HEAD(&zone->free_area[order].free_list); - if (order == MAX_ORDER-1) { - zone->free_area[order].map = NULL; - break; - } - - bitmap_size = pages_to_bitmap_size(order, size); - zone->free_area[order].map = - (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size); + zone->free_area[order].nr_free = 0; } } @@ -1496,6 +1583,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, pgdat->nr_zones = 0; init_waitqueue_head(&pgdat->kswapd_wait); + pgdat->kswapd_max_order = 0; for (j = 0; j < MAX_NR_ZONES; j++) { struct zone *zone = pgdat->node_zones + j; @@ -1583,7 +1671,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat, zone->zone_start_pfn = zone_start_pfn; if ((zone_start_pfn) & (zone_required_alignment-1)) - printk("BUG: wrong zone alignment, it will crash\n"); + printk(KERN_CRIT "BUG: wrong zone alignment, it will crash\n"); memmap_init(size, nid, j, zone_start_pfn); @@ -1659,8 +1747,7 @@ static void frag_stop(struct seq_file *m, void *arg) } /* - * This walks the freelist for each zone. Whilst this is slow, I'd rather - * be slow here than slow down the fast path by keeping stats - mjbligh + * This walks the free areas for each zone. */ static int frag_show(struct seq_file *m, void *arg) { @@ -1676,14 +1763,8 @@ static int frag_show(struct seq_file *m, void *arg) spin_lock_irqsave(&zone->lock, flags); seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name); - for (order = 0; order < MAX_ORDER; ++order) { - unsigned long nr_bufs = 0; - struct list_head *elem; - - list_for_each(elem, &(zone->free_area[order].free_list)) - ++nr_bufs; - seq_printf(m, "%6lu ", nr_bufs); - } + for (order = 0; order < MAX_ORDER; ++order) + seq_printf(m, "%6lu ", zone->free_area[order].nr_free); spin_unlock_irqrestore(&zone->lock, flags); seq_putc(m, '\n'); } @@ -1799,14 +1880,28 @@ static int page_alloc_cpu_notify(struct notifier_block *self, { int cpu = (unsigned long)hcpu; long *count; + unsigned long *src, *dest; if (action == CPU_DEAD) { + int i; + /* Drain local pagecache count. */ count = &per_cpu(nr_pagecache_local, cpu); atomic_add(*count, &nr_pagecache); *count = 0; local_irq_disable(); __drain_pages(cpu); + + /* Add dead cpu's page_states to our own. */ + dest = (unsigned long *)&__get_cpu_var(page_states); + src = (unsigned long *)&per_cpu(page_states, cpu); + + for (i = 0; i < sizeof(struct page_state)/sizeof(unsigned long); + i++) { + dest[i] += src[i]; + src[i] = 0; + } + local_irq_enable(); } return NOTIFY_OK; @@ -1818,87 +1913,29 @@ void __init page_alloc_init(void) hotcpu_notifier(page_alloc_cpu_notify, 0); } -static unsigned long higherzone_val(struct zone *z, int max_zone, - int alloc_type) -{ - int z_idx = zone_idx(z); - struct zone *higherzone; - unsigned long pages; - - /* there is no higher zone to get a contribution from */ - if (z_idx == MAX_NR_ZONES-1) - return 0; - - higherzone = &z->zone_pgdat->node_zones[z_idx+1]; - - /* We always start with the higher zone's protection value */ - pages = higherzone->protection[alloc_type]; - - /* - * We get a lower-zone-protection contribution only if there are - * pages in the higher zone and if we're not the highest zone - * in the current zonelist. e.g., never happens for GFP_DMA. Happens - * only for ZONE_DMA in a GFP_KERNEL allocation and happens for ZONE_DMA - * and ZONE_NORMAL for a GFP_HIGHMEM allocation. - */ - if (higherzone->present_pages && z_idx < alloc_type) - pages += higherzone->pages_low * sysctl_lower_zone_protection; - - return pages; -} - /* - * setup_per_zone_protection - called whenver min_free_kbytes or - * sysctl_lower_zone_protection changes. Ensures that each zone - * has a correct pages_protected value, so an adequate number of + * setup_per_zone_lowmem_reserve - called whenever + * sysctl_lower_zone_reserve_ratio changes. Ensures that each zone + * has a correct pages reserved value, so an adequate number of * pages are left in the zone after a successful __alloc_pages(). - * - * This algorithm is way confusing. I tries to keep the same behavior - * as we had with the incremental min iterative algorithm. */ -static void setup_per_zone_protection(void) +static void setup_per_zone_lowmem_reserve(void) { struct pglist_data *pgdat; - struct zone *zones, *zone; - int max_zone; - int i, j; + int j, idx; for_each_pgdat(pgdat) { - zones = pgdat->node_zones; + for (j = 0; j < MAX_NR_ZONES; j++) { + struct zone * zone = pgdat->node_zones + j; + unsigned long present_pages = zone->present_pages; - for (i = 0, max_zone = 0; i < MAX_NR_ZONES; i++) - if (zones[i].present_pages) - max_zone = i; + zone->lowmem_reserve[j] = 0; - /* - * For each of the different allocation types: - * GFP_DMA -> GFP_KERNEL -> GFP_HIGHMEM - */ - for (i = 0; i < GFP_ZONETYPES; i++) { - /* - * For each of the zones: - * ZONE_HIGHMEM -> ZONE_NORMAL -> ZONE_DMA - */ - for (j = MAX_NR_ZONES-1; j >= 0; j--) { - zone = &zones[j]; + for (idx = j-1; idx >= 0; idx--) { + struct zone * lower_zone = pgdat->node_zones + idx; - /* - * We never protect zones that don't have memory - * in them (j>max_zone) or zones that aren't in - * the zonelists for a certain type of - * allocation (j>=i). We have to assign these - * to zero because the lower zones take - * contributions from the higher zones. - */ - if (j > max_zone || j >= i) { - zone->protection[i] = 0; - continue; - } - /* - * The contribution of the next higher zone - */ - zone->protection[i] = higherzone_val(zone, - max_zone, i); + lower_zone->lowmem_reserve[j] = present_pages / sysctl_lowmem_reserve_ratio[idx]; + present_pages += lower_zone->present_pages; } } } @@ -1993,7 +2030,7 @@ static int __init init_per_zone_pages_min(void) if (min_free_kbytes > 65536) min_free_kbytes = 65536; setup_per_zone_pages_min(); - setup_per_zone_protection(); + setup_per_zone_lowmem_reserve(); return 0; } module_init(init_per_zone_pages_min) @@ -2008,44 +2045,62 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, { proc_dointvec(table, write, file, buffer, length, ppos); setup_per_zone_pages_min(); - setup_per_zone_protection(); return 0; } /* - * lower_zone_protection_sysctl_handler - just a wrapper around - * proc_dointvec() so that we can call setup_per_zone_protection() - * whenever sysctl_lower_zone_protection changes. + * lowmem_reserve_ratio_sysctl_handler - just a wrapper around + * proc_dointvec() so that we can call setup_per_zone_lowmem_reserve() + * whenever sysctl_lowmem_reserve_ratio changes. + * + * The reserve ratio obviously has absolutely no relation with the + * pages_min watermarks. The lowmem reserve ratio can only make sense + * if in function of the boot time zone sizes. */ -int lower_zone_protection_sysctl_handler(ctl_table *table, int write, +int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { proc_dointvec_minmax(table, write, file, buffer, length, ppos); - setup_per_zone_protection(); + setup_per_zone_lowmem_reserve(); return 0; } +__initdata int hashdist = HASHDIST_DEFAULT; + +#ifdef CONFIG_NUMA +static int __init set_hashdist(char *str) +{ + if (!str) + return 0; + hashdist = simple_strtoul(str, &str, 0); + return 1; +} +__setup("hashdist=", set_hashdist); +#endif + /* * allocate a large system hash table from bootmem * - it is assumed that the hash table must contain an exact power-of-2 * quantity of entries + * - limit is the number of hash buckets, not the total allocation size */ void *__init alloc_large_system_hash(const char *tablename, unsigned long bucketsize, unsigned long numentries, int scale, - int consider_highmem, + int flags, unsigned int *_hash_shift, - unsigned int *_hash_mask) + unsigned int *_hash_mask, + unsigned long limit) { - unsigned long long max; + unsigned long long max = limit; unsigned long log2qty, size; - void *table; + void *table = NULL; /* allow the kernel cmdline to have a say */ if (!numentries) { /* round applicable memory size up to nearest megabyte */ - numentries = consider_highmem ? nr_all_pages : nr_kernel_pages; + numentries = (flags & HASH_HIGHMEM) ? nr_all_pages : nr_kernel_pages; numentries += (1UL << (20 - PAGE_SHIFT)) - 1; numentries >>= 20 - PAGE_SHIFT; numentries <<= 20 - PAGE_SHIFT; @@ -2059,9 +2114,11 @@ void *__init alloc_large_system_hash(const char *tablename, /* rounded up to nearest power of 2 in size */ numentries = 1UL << (long_log2(numentries) + 1); - /* limit allocation size to 1/16 total memory */ - max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4; - do_div(max, bucketsize); + /* limit allocation size to 1/16 total memory by default */ + if (max == 0) { + max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4; + do_div(max, bucketsize); + } if (numentries > max) numentries = max; @@ -2070,7 +2127,16 @@ void *__init alloc_large_system_hash(const char *tablename, do { size = bucketsize << log2qty; - table = alloc_bootmem(size); + if (flags & HASH_EARLY) + table = alloc_bootmem(size); + else if (hashdist) + table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL); + else { + unsigned long order; + for (order = 0; ((1UL << order) << PAGE_SHIFT) < size; order++) + ; + table = (void*) __get_free_pages(GFP_ATOMIC, order); + } } while (!table && size > PAGE_SIZE && --log2qty); if (!table) From 4b1ec4c60ad721e7fa2161d32852ef0e45753daa Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 00:28:04 +0000 Subject: [PATCH 133/199] bitkeeper revision 1.1159.258.43 (4230e614QJDirekggk8u5NMTqkptrQ) Update to Linux 2.6.11. Signed-off-by: Christian Limpach --- .rootkeys | 4 ++-- .../include/linux/highmem.h | 15 +++++++++++++-- .../mm/highmem.c | 4 ++-- 3 files changed, 17 insertions(+), 6 deletions(-) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/include/linux/highmem.h (88%) rename {linux-2.6.10-xen-sparse => linux-2.6.11-xen-sparse}/mm/highmem.c (99%) diff --git a/.rootkeys b/.rootkeys index 46d3689876..442995412d 100644 --- a/.rootkeys +++ b/.rootkeys @@ -128,8 +128,6 @@ 3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.29-xen-sparse/mm/swapfile.c 41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.29-xen-sparse/mm/vmalloc.c 41505c57WAd5l1rlfCLNSCpx9J13vA linux-2.4.29-xen-sparse/net/core/skbuff.c -42305f545Vc5SLCUewZ2-n-P9JJhEQ linux-2.6.10-xen-sparse/include/linux/highmem.h -42305f54Q6xJ1bXcQJlCQq1m-e2C8g linux-2.6.10-xen-sparse/mm/highmem.c 40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.11-xen-sparse/arch/xen/Kconfig 40f56237utH41NPukqHksuNf29IC9A linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers 40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.11-xen-sparse/arch/xen/Makefile @@ -250,9 +248,11 @@ 4122466356eIBnC9ot44WSVVIFyhQA linux-2.6.11-xen-sparse/include/asm-xen/queues.h 3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.11-xen-sparse/include/asm-xen/xen_proc.h 419b4e93z2S0gR17XTy8wg09JEwAhg linux-2.6.11-xen-sparse/include/linux/gfp.h +42305f545Vc5SLCUewZ2-n-P9JJhEQ linux-2.6.11-xen-sparse/include/linux/highmem.h 419dfc609zbti8rqL60tL2dHXQ_rvQ linux-2.6.11-xen-sparse/include/linux/irq.h 419dfc6awx7w88wk6cG9P3mPidX6LQ linux-2.6.11-xen-sparse/kernel/irq/manage.c 40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.11-xen-sparse/mkbuildtree +42305f54Q6xJ1bXcQJlCQq1m-e2C8g linux-2.6.11-xen-sparse/mm/highmem.c 412f46c0LJuKAgSPGoC0Z1DEkLfuLA linux-2.6.11-xen-sparse/mm/memory.c 410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.11-xen-sparse/mm/page_alloc.c 413cb1e4zst25MDYjg63Y-NGC5_pLg netbsd-2.0-xen-sparse/Makefile diff --git a/linux-2.6.10-xen-sparse/include/linux/highmem.h b/linux-2.6.11-xen-sparse/include/linux/highmem.h similarity index 88% rename from linux-2.6.10-xen-sparse/include/linux/highmem.h rename to linux-2.6.11-xen-sparse/include/linux/highmem.h index bbe2ce094e..54c3fa78af 100644 --- a/linux-2.6.10-xen-sparse/include/linux/highmem.h +++ b/linux-2.6.11-xen-sparse/include/linux/highmem.h @@ -9,8 +9,6 @@ #ifdef CONFIG_HIGHMEM -extern struct page *highmem_start_page; - #include /* declarations for linux/mm/highmem.c */ @@ -46,6 +44,19 @@ static inline void clear_user_highpage(struct page *page, unsigned long vaddr) smp_wmb(); } +#ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE +static inline struct page * +alloc_zeroed_user_highpage(struct vm_area_struct *vma, unsigned long vaddr) +{ + struct page *page = alloc_page_vma(GFP_HIGHUSER, vma, vaddr); + + if (page) + clear_user_highpage(page, vaddr); + + return page; +} +#endif + static inline void clear_highpage(struct page *page) { void *kaddr = kmap_atomic(page, KM_USER0); diff --git a/linux-2.6.10-xen-sparse/mm/highmem.c b/linux-2.6.11-xen-sparse/mm/highmem.c similarity index 99% rename from linux-2.6.10-xen-sparse/mm/highmem.c rename to linux-2.6.11-xen-sparse/mm/highmem.c index 96e7798983..846297fb25 100644 --- a/linux-2.6.10-xen-sparse/mm/highmem.c +++ b/linux-2.6.11-xen-sparse/mm/highmem.c @@ -53,7 +53,7 @@ static void page_pool_free(void *page, void *data) #ifdef CONFIG_HIGHMEM static int pkmap_count[LAST_PKMAP]; static unsigned int last_pkmap_nr; -static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock); pte_t * pkmap_page_table; @@ -434,7 +434,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, * at least one page was bounced, fill in possible non-highmem * pages */ - bio_for_each_segment(from, *bio_orig, i) { + __bio_for_each_segment(from, *bio_orig, i, 0) { to = bio_iovec_idx(bio, i); if (!to->bv_page) { to->bv_page = from->bv_page; From 1f702950d8def4021179517d27c1764e8c0d11f4 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 00:28:36 +0000 Subject: [PATCH 134/199] bitkeeper revision 1.1159.258.44 (4230e634q8GsmA11oFHvaUsWO4vUpA) Change cli() to local_irq_disable(). Signed-off-by: Christian Limpach --- linux-2.6.11-xen-sparse/drivers/xen/console/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/console/console.c b/linux-2.6.11-xen-sparse/drivers/xen/console/console.c index f1fe3c517f..fb276216be 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/console/console.c @@ -234,7 +234,7 @@ void xencons_force_flush(void) * We use dangerous control-interface functions that require a quiescent * system and no interrupts. Try to ensure this with a global cli(). */ - cli(); + local_irq_disable(); /* XXXsmp */ /* Spin until console data is flushed through to the domain controller. */ while ( (wc != wp) && !ctrl_if_transmitter_empty() ) From 0680eec01927469e1985f486d77ffdbdb8747981 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 00:30:35 +0000 Subject: [PATCH 135/199] bitkeeper revision 1.1159.258.45 (4230e6ab4xRdK4pchNbpgZE-preulA) Fix one more pud merge incident. Signed-off-by: Christian Limpach --- linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c index e8d48949d3..8a0df417ed 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -369,7 +369,7 @@ int __direct_remap_area_pages(struct mm_struct *mm, pud = pud_alloc(mm, dir, address); if (!pud) break; - pmd = pmd_alloc(mm, dir, address); + pmd = pmd_alloc(mm, pud, address); if (!pmd) break; error = 0; From e2c9e3be0174050cfc1c02e1b49a00d07df064da Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 01:02:01 +0000 Subject: [PATCH 136/199] bitkeeper revision 1.1159.258.46 (4230ee09rYvY_HWitF9h5VHJ0NfurA) Update to Linux 2.6.11. Signed-off-by: Christian Limpach --- .rootkeys | 5 +- patches/linux-2.6.10/drm.patch | 12 -- .../agpgart.patch | 188 +++++++++--------- .../nettel.patch | 14 +- 4 files changed, 103 insertions(+), 116 deletions(-) delete mode 100644 patches/linux-2.6.10/drm.patch rename patches/{linux-2.6.10 => linux-2.6.11}/agpgart.patch (57%) rename patches/{linux-2.6.10 => linux-2.6.11}/nettel.patch (52%) diff --git a/.rootkeys b/.rootkeys index 442995412d..a495f8ea15 100644 --- a/.rootkeys +++ b/.rootkeys @@ -293,9 +293,8 @@ 422e4430vKaHLOOGS7X-SUUe3EBCgw netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs.h 422e4430-gOD358H8nGGnNWes08Nng netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c 413cb3b53nyOv1OIeDSsCXhBFDXvJA netbsd-2.0-xen-sparse/sys/nfs/files.nfs -413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.10/agpgart.patch -413aa1d0ewvSv-ohnNnQQNGsbPTTNA patches/linux-2.6.10/drm.patch -418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.10/nettel.patch +413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.11/agpgart.patch +418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.11/nettel.patch 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile 40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Rules.mk 4124b307nRyK3dhn1hAsvrY76NuV3g tools/check/Makefile diff --git a/patches/linux-2.6.10/drm.patch b/patches/linux-2.6.10/drm.patch deleted file mode 100644 index f39d5cb3d0..0000000000 --- a/patches/linux-2.6.10/drm.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -ur linux-2.6.9/drivers/char/drm/ati_pcigart.h linux-2.6.9-new/drivers/char/drm/ati_pcigart.h ---- linux-2.6.9/drivers/char/drm/ati_pcigart.h 2004-10-18 22:55:07.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/drm/ati_pcigart.h 2004-11-28 19:42:41.000000000 +0000 -@@ -158,7 +158,7 @@ - ret = 1; - - #if defined(__i386__) || defined(__x86_64__) -- asm volatile ( "wbinvd" ::: "memory" ); -+ wbinvd(); - #else - mb(); - #endif diff --git a/patches/linux-2.6.10/agpgart.patch b/patches/linux-2.6.11/agpgart.patch similarity index 57% rename from patches/linux-2.6.10/agpgart.patch rename to patches/linux-2.6.11/agpgart.patch index 249afd6f0b..4335ddb3cf 100644 --- a/patches/linux-2.6.10/agpgart.patch +++ b/patches/linux-2.6.11/agpgart.patch @@ -1,7 +1,7 @@ -diff -ur linux-2.6.9/drivers/char/agp/ali-agp.c linux-2.6.9-new/drivers/char/agp/ali-agp.c ---- linux-2.6.9/drivers/char/agp/ali-agp.c 2004-10-18 22:54:38.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/ali-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -150,7 +150,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/ali-agp.c linux-2.6.11/drivers/char/agp/ali-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/ali-agp.c 2005-03-02 07:38:13.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/ali-agp.c 2005-03-11 00:35:21.320192760 +0000 +@@ -150,7 +150,7 @@ static void *m1541_alloc_page(void) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | @@ -10,7 +10,7 @@ diff -ur linux-2.6.9/drivers/char/agp/ali-agp.c linux-2.6.9-new/drivers/char/agp return addr; } -@@ -174,7 +174,7 @@ +@@ -174,7 +174,7 @@ static void m1541_destroy_page(void * ad pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | @@ -19,10 +19,10 @@ diff -ur linux-2.6.9/drivers/char/agp/ali-agp.c linux-2.6.9-new/drivers/char/agp agp_generic_destroy_page(addr); } -diff -ur linux-2.6.9/drivers/char/agp/amd-k7-agp.c linux-2.6.9-new/drivers/char/agp/amd-k7-agp.c ---- linux-2.6.9/drivers/char/agp/amd-k7-agp.c 2004-10-18 22:55:36.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/amd-k7-agp.c 2004-11-28 19:36:39.000000000 +0000 -@@ -43,7 +43,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/amd-k7-agp.c linux-2.6.11/drivers/char/agp/amd-k7-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/amd-k7-agp.c 2005-03-02 07:38:33.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/amd-k7-agp.c 2005-03-11 00:35:21.321192788 +0000 +@@ -43,7 +43,7 @@ static int amd_create_page_map(struct am SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); @@ -31,7 +31,7 @@ diff -ur linux-2.6.9/drivers/char/agp/amd-k7-agp.c linux-2.6.9-new/drivers/char/ PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); -@@ -152,7 +152,7 @@ +@@ -154,7 +154,7 @@ static int amd_create_gatt_table(void) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; @@ -40,19 +40,19 @@ diff -ur linux-2.6.9/drivers/char/agp/amd-k7-agp.c linux-2.6.9-new/drivers/char/ /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its -@@ -165,7 +165,7 @@ +@@ -167,7 +167,7 @@ static int amd_create_gatt_table(void) /* Calculate the agp offset */ for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, + writel(virt_to_bus(amd_irongate_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); + readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } - -diff -ur linux-2.6.9/drivers/char/agp/amd64-agp.c linux-2.6.9-new/drivers/char/agp/amd64-agp.c ---- linux-2.6.9/drivers/char/agp/amd64-agp.c 2004-10-18 22:54:38.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/amd64-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -212,7 +212,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/amd64-agp.c linux-2.6.11/drivers/char/agp/amd64-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/amd64-agp.c 2005-03-02 07:38:13.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/amd64-agp.c 2005-03-11 00:35:21.322192816 +0000 +@@ -218,7 +218,7 @@ static struct aper_size_info_32 amd_8151 static int amd_8151_configure(void) { @@ -61,7 +61,7 @@ diff -ur linux-2.6.9/drivers/char/agp/amd64-agp.c linux-2.6.9-new/drivers/char/a /* Configure AGP regs in each x86-64 host bridge. */ for_each_nb() { -@@ -521,7 +521,7 @@ +@@ -590,7 +590,7 @@ static void __devexit agp_amd64_remove(s { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); @@ -70,22 +70,22 @@ diff -ur linux-2.6.9/drivers/char/agp/amd64-agp.c linux-2.6.9-new/drivers/char/a amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); -diff -ur linux-2.6.9/drivers/char/agp/ati-agp.c linux-2.6.9-new/drivers/char/agp/ati-agp.c ---- linux-2.6.9/drivers/char/agp/ati-agp.c 2004-10-18 22:54:40.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/ati-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -64,7 +64,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/ati-agp.c linux-2.6.11/drivers/char/agp/ati-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/ati-agp.c 2005-03-02 07:38:13.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/ati-agp.c 2005-03-11 00:41:25.848450763 +0000 +@@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_ - /* CACHE_FLUSH(); */ - global_cache_flush(); + SetPageReserved(virt_to_page(page_map->real)); + err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL || err) { ClearPageReserved(virt_to_page(page_map->real)); -diff -ur linux-2.6.9/drivers/char/agp/backend.c linux-2.6.9-new/drivers/char/agp/backend.c ---- linux-2.6.9/drivers/char/agp/backend.c 2004-10-18 22:54:39.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/backend.c 2004-11-28 19:32:03.000000000 +0000 -@@ -142,7 +142,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/backend.c linux-2.6.11/drivers/char/agp/backend.c +--- pristine-linux-2.6.11/drivers/char/agp/backend.c 2005-03-02 07:38:13.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/backend.c 2005-03-11 00:35:21.323192844 +0000 +@@ -142,7 +142,7 @@ static int agp_backend_initialize(struct return -ENOMEM; } @@ -94,7 +94,7 @@ diff -ur linux-2.6.9/drivers/char/agp/backend.c linux-2.6.9-new/drivers/char/agp bridge->scratch_page = bridge->driver->mask_memory(bridge->scratch_page_real, 0); } -@@ -186,7 +186,7 @@ +@@ -186,7 +186,7 @@ static int agp_backend_initialize(struct err_out: if (bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( @@ -103,7 +103,7 @@ diff -ur linux-2.6.9/drivers/char/agp/backend.c linux-2.6.9-new/drivers/char/agp if (got_gatt) bridge->driver->free_gatt_table(); if (got_keylist) { -@@ -211,7 +211,7 @@ +@@ -211,7 +211,7 @@ static void agp_backend_cleanup(struct a if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( @@ -111,11 +111,11 @@ diff -ur linux-2.6.9/drivers/char/agp/backend.c linux-2.6.9-new/drivers/char/agp + bus_to_virt(bridge->scratch_page_real)); } - static const drm_agp_t drm_agp = { -diff -ur linux-2.6.9/drivers/char/agp/efficeon-agp.c linux-2.6.9-new/drivers/char/agp/efficeon-agp.c ---- linux-2.6.9/drivers/char/agp/efficeon-agp.c 2004-10-18 22:53:06.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/efficeon-agp.c 2004-11-28 19:38:28.000000000 +0000 -@@ -219,7 +219,7 @@ + /* XXX Kludge alert: agpgart isn't ready for multiple bridges yet */ +diff -rup pristine-linux-2.6.11/drivers/char/agp/efficeon-agp.c linux-2.6.11/drivers/char/agp/efficeon-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/efficeon-agp.c 2005-03-02 07:37:30.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/efficeon-agp.c 2005-03-11 00:35:21.324192872 +0000 +@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(vo efficeon_private.l1_table[index] = page; @@ -124,10 +124,10 @@ diff -ur linux-2.6.9/drivers/char/agp/efficeon-agp.c linux-2.6.9-new/drivers/cha pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); -diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp/generic.c ---- linux-2.6.9/drivers/char/agp/generic.c 2004-10-18 22:53:50.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/generic.c 2004-11-28 19:32:03.000000000 +0000 -@@ -128,7 +128,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/generic.c linux-2.6.11/drivers/char/agp/generic.c +--- pristine-linux-2.6.11/drivers/char/agp/generic.c 2005-03-02 07:37:55.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/generic.c 2005-03-11 00:44:53.858248651 +0000 +@@ -151,7 +151,7 @@ void agp_free_memory(struct agp_memory * } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { @@ -136,16 +136,16 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp } } agp_free_key(curr->key); -@@ -182,7 +182,7 @@ +@@ -204,7 +204,7 @@ struct agp_memory *agp_allocate_memory(s + agp_free_memory(new); return NULL; } - new->memory[i] = -- agp_bridge->driver->mask_memory(virt_to_phys(addr), type); -+ agp_bridge->driver->mask_memory(virt_to_bus(addr), type); +- new->memory[i] = virt_to_phys(addr); ++ new->memory[i] = virt_to_bus(addr); new->page_count++; } -@@ -637,6 +637,7 @@ +@@ -659,6 +659,7 @@ int agp_generic_create_gatt_table(void) int i; void *temp; struct page *page; @@ -153,7 +153,7 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp /* The generic routines can't handle 2 level gatt's */ if (agp_bridge->driver->size_type == LVL2_APER_SIZE) -@@ -675,8 +676,10 @@ +@@ -697,8 +698,10 @@ int agp_generic_create_gatt_table(void) break; } @@ -166,7 +166,7 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp if (table == NULL) { i++; -@@ -707,7 +710,9 @@ +@@ -729,7 +732,9 @@ int agp_generic_create_gatt_table(void) size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; @@ -177,7 +177,7 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp } if (table == NULL) -@@ -722,7 +727,7 @@ +@@ -744,7 +749,7 @@ int agp_generic_create_gatt_table(void) agp_gatt_table = (void *)table; agp_bridge->driver->cache_flush(); @@ -186,7 +186,7 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp (PAGE_SIZE * (1 << page_order))); agp_bridge->driver->cache_flush(); -@@ -730,11 +735,12 @@ +@@ -752,11 +757,12 @@ int agp_generic_create_gatt_table(void) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); @@ -200,8 +200,8 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp + agp_bridge->gatt_bus_addr = virt_to_bus(table); /* AK: bogus, should encode addresses > 4GB */ - for (i = 0; i < num_entries; i++) -@@ -786,7 +792,8 @@ + for (i = 0; i < num_entries; i++) { +@@ -810,7 +816,8 @@ int agp_generic_free_gatt_table(void) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); @@ -211,31 +211,31 @@ diff -ur linux-2.6.9/drivers/char/agp/generic.c linux-2.6.9-new/drivers/char/agp agp_gatt_table = NULL; agp_bridge->gatt_table = NULL; -diff -ur linux-2.6.9/drivers/char/agp/hp-agp.c linux-2.6.9-new/drivers/char/agp/hp-agp.c ---- linux-2.6.9/drivers/char/agp/hp-agp.c 2004-10-18 22:54:55.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/hp-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -110,7 +110,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/hp-agp.c linux-2.6.11/drivers/char/agp/hp-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/hp-agp.c 2005-03-02 07:38:19.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/hp-agp.c 2005-03-11 00:47:41.424653508 +0000 +@@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; -- hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE)); -+ hp->io_pdir = bus_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE)); +- hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); ++ hp->io_pdir = bus_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { -@@ -248,7 +248,7 @@ - agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS); +@@ -248,7 +248,7 @@ hp_zx1_configure (void) + agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); if (hp->io_pdir_owner) { -- OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir)); -+ OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_bus(hp->io_pdir)); - OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps); - OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1)); - OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1); -diff -ur linux-2.6.9/drivers/char/agp/i460-agp.c linux-2.6.9-new/drivers/char/agp/i460-agp.c ---- linux-2.6.9/drivers/char/agp/i460-agp.c 2004-10-18 22:54:32.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/i460-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -371,7 +371,7 @@ +- writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); ++ writel(virt_to_bus(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); + readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); + writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); + readl(hp->ioc_regs+HP_ZX1_TCNFG); +diff -rup pristine-linux-2.6.11/drivers/char/agp/i460-agp.c linux-2.6.11/drivers/char/agp/i460-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/i460-agp.c 2005-03-02 07:38:10.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/i460-agp.c 2005-03-11 00:35:21.327192957 +0000 +@@ -371,7 +371,7 @@ static int i460_alloc_large_page (struct } memset(lp->alloced_map, 0, map_size); @@ -244,7 +244,7 @@ diff -ur linux-2.6.9/drivers/char/agp/i460-agp.c linux-2.6.9-new/drivers/char/ag lp->refcount = 0; atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; -@@ -382,7 +382,7 @@ +@@ -382,7 +382,7 @@ static void i460_free_large_page (struct kfree(lp->alloced_map); lp->alloced_map = NULL; @@ -253,10 +253,10 @@ diff -ur linux-2.6.9/drivers/char/agp/i460-agp.c linux-2.6.9-new/drivers/char/ag atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } -diff -ur linux-2.6.9/drivers/char/agp/intel-agp.c linux-2.6.9-new/drivers/char/agp/intel-agp.c ---- linux-2.6.9/drivers/char/agp/intel-agp.c 2004-10-18 22:54:08.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/intel-agp.c 2004-11-28 19:37:22.000000000 +0000 -@@ -285,7 +285,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/intel-agp.c linux-2.6.11/drivers/char/agp/intel-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/intel-agp.c 2005-03-02 07:38:09.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/intel-agp.c 2005-03-11 00:35:21.328192985 +0000 +@@ -285,7 +285,7 @@ static struct agp_memory *alloc_agpphysm if (new == NULL) return NULL; @@ -265,7 +265,7 @@ diff -ur linux-2.6.9/drivers/char/agp/intel-agp.c linux-2.6.9-new/drivers/char/a if (pg_count == 4) { /* kludge to get 4 physical pages for ARGB cursor */ new->memory[1] = new->memory[0] + PAGE_SIZE; -@@ -328,10 +328,10 @@ +@@ -328,10 +328,10 @@ static void intel_i810_free_by_type(stru agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { if (curr->page_count == 4) @@ -278,19 +278,19 @@ diff -ur linux-2.6.9/drivers/char/agp/intel-agp.c linux-2.6.9-new/drivers/char/a vfree(curr->memory); } kfree(curr); -diff -ur linux-2.6.9/drivers/char/agp/intel-mch-agp.c linux-2.6.9-new/drivers/char/agp/intel-mch-agp.c ---- linux-2.6.9/drivers/char/agp/intel-mch-agp.c 2004-10-18 22:53:13.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/intel-mch-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -51,7 +51,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/intel-mch-agp.c linux-2.6.11/drivers/char/agp/intel-mch-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/intel-mch-agp.c 2005-03-02 07:37:48.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/intel-mch-agp.c 2005-03-11 00:49:37.713063638 +0000 +@@ -51,7 +51,7 @@ static struct agp_memory *alloc_agpphysm if (new == NULL) return NULL; -- new->memory[0] = agp_bridge->driver->mask_memory(virt_to_phys(addr), type); -+ new->memory[0] = agp_bridge->driver->mask_memory(virt_to_bus(addr), type); +- new->memory[0] = virt_to_phys(addr); ++ new->memory[0] = virt_to_bus(addr); new->page_count = 1; new->num_scratch_pages = 1; new->type = AGP_PHYS_MEMORY; -@@ -63,7 +63,7 @@ +@@ -63,7 +63,7 @@ static void intel_i810_free_by_type(stru { agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { @@ -299,10 +299,10 @@ diff -ur linux-2.6.9/drivers/char/agp/intel-mch-agp.c linux-2.6.9-new/drivers/ch vfree(curr->memory); } kfree(curr); -diff -ur linux-2.6.9/drivers/char/agp/sworks-agp.c linux-2.6.9-new/drivers/char/agp/sworks-agp.c ---- linux-2.6.9/drivers/char/agp/sworks-agp.c 2004-10-18 22:53:50.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/sworks-agp.c 2004-11-28 19:38:02.000000000 +0000 -@@ -51,7 +51,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/sworks-agp.c linux-2.6.11/drivers/char/agp/sworks-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/sworks-agp.c 2005-03-02 07:38:37.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/sworks-agp.c 2005-03-11 00:35:21.330193041 +0000 +@@ -51,7 +51,7 @@ static int serverworks_create_page_map(s } SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); @@ -311,7 +311,7 @@ diff -ur linux-2.6.9/drivers/char/agp/sworks-agp.c linux-2.6.9-new/drivers/char/ PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); -@@ -162,7 +162,7 @@ +@@ -162,7 +162,7 @@ static int serverworks_create_gatt_table /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); @@ -320,7 +320,7 @@ diff -ur linux-2.6.9/drivers/char/agp/sworks-agp.c linux-2.6.9-new/drivers/char/ } retval = serverworks_create_gatt_pages(value->num_entries / 1024); -@@ -174,7 +174,7 @@ +@@ -174,7 +174,7 @@ static int serverworks_create_gatt_table agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; @@ -329,7 +329,7 @@ diff -ur linux-2.6.9/drivers/char/agp/sworks-agp.c linux-2.6.9-new/drivers/char/ /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its -@@ -187,7 +187,7 @@ +@@ -187,7 +187,7 @@ static int serverworks_create_gatt_table /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++) @@ -338,10 +338,10 @@ diff -ur linux-2.6.9/drivers/char/agp/sworks-agp.c linux-2.6.9-new/drivers/char/ return 0; } -diff -ur linux-2.6.9/drivers/char/agp/uninorth-agp.c linux-2.6.9-new/drivers/char/agp/uninorth-agp.c ---- linux-2.6.9/drivers/char/agp/uninorth-agp.c 2004-10-18 22:54:29.000000000 +0100 -+++ linux-2.6.9-new/drivers/char/agp/uninorth-agp.c 2004-11-28 19:32:03.000000000 +0000 -@@ -200,7 +200,7 @@ +diff -rup pristine-linux-2.6.11/drivers/char/agp/uninorth-agp.c linux-2.6.11/drivers/char/agp/uninorth-agp.c +--- pristine-linux-2.6.11/drivers/char/agp/uninorth-agp.c 2005-03-02 07:38:09.000000000 +0000 ++++ linux-2.6.11/drivers/char/agp/uninorth-agp.c 2005-03-11 00:35:21.330193041 +0000 +@@ -200,7 +200,7 @@ static int uninorth_create_gatt_table(vo agp_bridge->gatt_table_real = (u32 *) table; agp_bridge->gatt_table = (u32 *)table; @@ -350,9 +350,9 @@ diff -ur linux-2.6.9/drivers/char/agp/uninorth-agp.c linux-2.6.9-new/drivers/cha for (i = 0; i < num_entries; i++) { agp_bridge->gatt_table[i] = -diff -ur linux-2.6.9/include/asm-i386/agp.h linux-2.6.9-new/include/asm-i386/agp.h ---- linux-2.6.9/include/asm-i386/agp.h 2004-10-18 22:53:06.000000000 +0100 -+++ linux-2.6.9-new/include/asm-i386/agp.h 2004-11-28 19:32:03.000000000 +0000 +diff -rup pristine-linux-2.6.11/include/asm-i386/agp.h linux-2.6.11/include/asm-i386/agp.h +--- pristine-linux-2.6.11/include/asm-i386/agp.h 2005-03-02 07:37:31.000000000 +0000 ++++ linux-2.6.11/include/asm-i386/agp.h 2005-03-11 00:35:21.331193069 +0000 @@ -3,6 +3,7 @@ #include @@ -361,7 +361,7 @@ diff -ur linux-2.6.9/include/asm-i386/agp.h linux-2.6.9-new/include/asm-i386/agp /* * Functions to keep the agpgart mappings coherent with the MMU. -@@ -19,6 +20,6 @@ +@@ -19,6 +20,6 @@ int unmap_page_from_agp(struct page *pag /* Could use CLFLUSH here if the cpu supports it. But then it would need to be called for each cacheline of the whole page so it may not be worth it. Would need a page for it. */ diff --git a/patches/linux-2.6.10/nettel.patch b/patches/linux-2.6.11/nettel.patch similarity index 52% rename from patches/linux-2.6.10/nettel.patch rename to patches/linux-2.6.11/nettel.patch index e8dd94a33a..319023e54b 100644 --- a/patches/linux-2.6.10/nettel.patch +++ b/patches/linux-2.6.11/nettel.patch @@ -1,7 +1,7 @@ -diff -ur linux-2.6.9/drivers/mtd/maps/nettel.c linux-2.6.9-new/drivers/mtd/maps/nettel.c ---- linux-2.6.9/drivers/mtd/maps/nettel.c 2004-10-18 22:53:44.000000000 +0100 -+++ linux-2.6.9-new/drivers/mtd/maps/nettel.c 2004-11-28 19:45:35.000000000 +0000 -@@ -270,7 +270,7 @@ +diff -rup pristine-linux-2.6.11/drivers/mtd/maps/nettel.c linux-2.6.11/drivers/mtd/maps/nettel.c +--- pristine-linux-2.6.11/drivers/mtd/maps/nettel.c 2005-03-02 07:37:50.000000000 +0000 ++++ linux-2.6.11/drivers/mtd/maps/nettel.c 2005-03-11 00:52:55.635506733 +0000 +@@ -270,7 +270,7 @@ int __init nettel_init(void) maxsize = AMD_WINDOW_MAXSIZE; *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize); @@ -9,8 +9,8 @@ diff -ur linux-2.6.9/drivers/mtd/maps/nettel.c linux-2.6.9-new/drivers/mtd/maps/ + wbinvd(); nettel_amd_map.phys = amdaddr; - nettel_amd_map.virt = (unsigned long) -@@ -382,7 +382,7 @@ + nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize); +@@ -380,7 +380,7 @@ int __init nettel_init(void) */ intel1addr = intel0addr + intel0size; *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize); @@ -19,7 +19,7 @@ diff -ur linux-2.6.9/drivers/mtd/maps/nettel.c linux-2.6.9-new/drivers/mtd/maps/ maxsize += intel0size; -@@ -408,7 +408,7 @@ +@@ -405,7 +405,7 @@ int __init nettel_init(void) intel1size = intel_mtd->size - intel0size; if (intel1size > 0) { *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size); From 0646bb185d9f3318bc950fdeb8f5d5e09d73f928 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 01:23:38 +0000 Subject: [PATCH 137/199] bitkeeper revision 1.1159.258.47 (4230f31aZ2VYmMntbEMp_f1tNZA6WA) Update to Linux 2.6.11. Signed-off-by: Christian Limpach --- .../arch/xen/configs/xen0_defconfig | 28 +++++++++++++------ .../arch/xen/configs/xenU_defconfig | 25 +++++++++++------ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig index 408113f920..2cd0df6262 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-xen0 -# Mon Feb 21 13:46:38 2005 +# Linux kernel version: 2.6.11-xen0 +# Fri Mar 11 01:02:42 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -13,12 +13,10 @@ CONFIG_NO_IDLE_HZ=y CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_PHYSDEV_ACCESS=y CONFIG_XEN_BLKDEV_BACKEND=y -# CONFIG_XEN_BLKDEV_TAP_BE is not set CONFIG_XEN_NETDEV_BACKEND=y CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set -# CONFIG_XEN_BLKDEV_TAP is not set CONFIG_XEN_WRITABLE_PAGETABLES=y CONFIG_XEN_SCRUB_PAGES=y CONFIG_X86=y @@ -105,6 +103,7 @@ CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y @@ -116,6 +115,7 @@ CONFIG_X86_USE_PPRO_CHECKSUM=y # CONFIG_HPET_EMULATE_RTC is not set # CONFIG_SMP is not set CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y CONFIG_MICROCODE=y CONFIG_X86_CPUID=y @@ -212,6 +212,7 @@ CONFIG_BLK_CPQ_CISS_DA=y # CONFIG_CISS_SCSI_TAPE is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -231,6 +232,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -322,6 +324,7 @@ CONFIG_BLK_DEV_SD=y # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -358,6 +361,7 @@ CONFIG_SCSI_SATA=y CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_NV is not set CONFIG_SCSI_SATA_PROMISE=y +# CONFIG_SCSI_SATA_QSTOR is not set CONFIG_SCSI_SATA_SX4=y CONFIG_SCSI_SATA_SIL=y # CONFIG_SCSI_SATA_SIS is not set @@ -395,7 +399,6 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set # CONFIG_SCSI_SEAGATE is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC395x is not set @@ -533,14 +536,11 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m # CONFIG_IP_NF_TARGET_REDIRECT is not set # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_LOCAL is not set # CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_FTP=m # CONFIG_IP_NF_MANGLE is not set # CONFIG_IP_NF_RAW is not set # CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set # # Bridge: Netfilter Configuration @@ -737,6 +737,7 @@ CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # @@ -813,7 +814,7 @@ CONFIG_AGP_SIS=m CONFIG_AGP_SWORKS=m CONFIG_AGP_VIA=m # CONFIG_AGP_EFFICEON is not set -CONFIG_DRM=y +CONFIG_DRM=m CONFIG_DRM_TDFX=m # CONFIG_DRM_GAMMA is not set CONFIG_DRM_R128=m @@ -903,6 +904,10 @@ CONFIG_REISERFS_FS=y # CONFIG_REISERFS_PROC_INFO is not set # CONFIG_REISERFS_FS_XATTR is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1069,6 +1074,11 @@ CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set +# +# Hardware crypto devices +# +# CONFIG_CRYPTO_DEV_PADLOCK is not set + # # Library routines # diff --git a/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig b/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig index 63450b421c..5d2a503c0a 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig +++ b/linux-2.6.11-xen-sparse/arch/xen/configs/xenU_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10-rc3-xenU -# Sun Dec 26 10:35:15 2004 +# Linux kernel version: 2.6.11-xenU +# Fri Mar 11 01:20:28 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -12,16 +12,14 @@ CONFIG_NO_IDLE_HZ=y # # CONFIG_XEN_PRIVILEGED_GUEST is not set # CONFIG_XEN_PHYSDEV_ACCESS is not set -# CONFIG_XEN_BLKDEV_BACKEND is not set -# CONFIG_XEN_NETDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y # CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set CONFIG_XEN_WRITABLE_PAGETABLES=y CONFIG_XEN_SCRUB_PAGES=y -CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y CONFIG_X86=y # CONFIG_X86_64 is not set +CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y # # Code maturity level options @@ -47,7 +45,6 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -103,6 +100,7 @@ CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y @@ -114,6 +112,7 @@ CONFIG_X86_USE_PPRO_CHECKSUM=y # CONFIG_HPET_EMULATE_RTC is not set # CONFIG_SMP is not set CONFIG_PREEMPT=y +CONFIG_PREEMPT_BKL=y CONFIG_X86_CPUID=y # @@ -155,12 +154,12 @@ CONFIG_BINFMT_ELF=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=m @@ -179,6 +178,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # SCSI device support @@ -207,6 +207,7 @@ CONFIG_BLK_DEV_SD=m # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -339,6 +340,10 @@ CONFIG_REISERFS_FS=y # CONFIG_REISERFS_PROC_INFO is not set # CONFIG_REISERFS_FS_XATTR is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -409,7 +414,6 @@ CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -# CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -503,6 +507,11 @@ CONFIG_CRYPTO_MD5=m CONFIG_CRYPTO_CRC32C=m # CONFIG_CRYPTO_TEST is not set +# +# Hardware crypto devices +# +# CONFIG_CRYPTO_DEV_PADLOCK is not set + # # Library routines # From 601dcfbbeccda1317bf2139981fd60315baabc81 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 01:52:33 +0000 Subject: [PATCH 138/199] bitkeeper revision 1.1159.258.48 (4230f9e1A3LEMmDHzcYXsKwP-EpzRg) Fix fallout from Update to Linux 2.6.11. Signed-off-by: Christian Limpach --- linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h | 2 +- linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c | 2 ++ linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c | 8 ++++++-- linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c | 4 ++++ linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h | 3 +++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h b/linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h index 9ddd30bf73..750ebfeae0 100644 --- a/linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h +++ b/linux-2.4.29-xen-sparse/include/asm-xen/pgtable-2level.h @@ -36,7 +36,7 @@ static inline int pgd_present(pgd_t pgd) { return 1; } #define set_pte(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low) #define set_pte_atomic(pteptr, pteval) queue_l1_entry_update(pteptr, (pteval).pte_low) -#define set_pmd(pmdptr, pmdval) queue_l2_entry_update((pmdptr), (pmdval).pmd) +#define set_pmd(pmdptr, pmdval) queue_l2_entry_update((pmdptr), (pmdval)) #define set_pgd(pgdptr, pgdval) ((void)0) #define pgd_page(pgd) \ diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c index f93554394d..8cb2c64959 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/pci-dma.c @@ -17,6 +17,8 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) #define pte_offset_kernel pte_offset +#define pud_t pgd_t +#define pud_offset(d, va) d #endif struct dma_coherent_mem { diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c index 6b19a2030a..022831606a 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/hypervisor.c @@ -49,8 +49,12 @@ static spinlock_t update_lock = SPIN_LOCK_UNLOCKED; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) #define QUEUE_SIZE 2048 #define pte_offset_kernel pte_offset +#define pmd_val_ma(v) (v).pmd; +#define pud_t pgd_t +#define pud_offset(d, va) d #else #define QUEUE_SIZE 128 +#define pmd_val_ma(v) (v).pud.pgd.pgd; #endif static mmu_update_t update_queue[QUEUE_SIZE]; @@ -125,7 +129,7 @@ void queue_l2_entry_update(pmd_t *ptr, pmd_t val) unsigned long flags; spin_lock_irqsave(&update_lock, flags); update_queue[idx].ptr = virt_to_machine(ptr); - update_queue[idx].val = val.pud.pgd.pgd; /* XXX pmd_val_ma */ + update_queue[idx].val = pmd_val_ma(val); increment_index(); spin_unlock_irqrestore(&update_lock, flags); } @@ -242,7 +246,7 @@ void xen_l2_entry_update(pmd_t *ptr, pmd_t val) unsigned long flags; spin_lock_irqsave(&update_lock, flags); update_queue[idx].ptr = virt_to_machine(ptr); - update_queue[idx].val = val.pud.pgd.pgd; /* XXX pmd_val_ma */ + update_queue[idx].val = pmd_val_ma(val); increment_index_and_flush(); spin_unlock_irqrestore(&update_lock, flags); } diff --git a/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c index 6909fabaa7..ff82cd2f0a 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/balloon/balloon.c @@ -91,6 +91,10 @@ static struct timer_list balloon_timer; #define LIST_TO_PAGE(l) ( list_entry(l, struct page, list) ) #define UNLIST_PAGE(p) ( list_del(&p->list) ) #define pte_offset_kernel pte_offset +#define pud_t pgd_t +#define pud_offset(d, va) d +#define pud_none(d) 0 +#define pud_bad(d) 0 #define subsys_initcall(_fn) __initcall(_fn) #define pfn_to_page(_pfn) (mem_map + (_pfn)) #endif diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h index 9882429a96..2d5a88a56d 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h @@ -30,6 +30,7 @@ #ifndef __HYPERVISOR_H__ #define __HYPERVISOR_H__ +#include #include #include #include @@ -38,7 +39,9 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include +#endif /* arch/xen/i386/kernel/setup.c */ union xen_start_info_union From fd4de8dfe367478e34d88c3cb128065a553f4b32 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 11 Mar 2005 12:54:24 +0000 Subject: [PATCH 139/199] bitkeeper revision 1.1159.265.2 (42319500DXIXjiTkjszNpliySomMvA) Add support for setting the listen address for consoles and the event port. Signed-off-by: Mike Wray --- tools/examples/xend-config.sxp | 14 ++++- tools/python/xen/xend/XendRoot.py | 75 +++++++++++++++++++---- tools/python/xen/xend/server/SrvDaemon.py | 12 ++-- tools/python/xen/xend/server/console.py | 5 +- tools/python/xen/xend/server/params.py | 6 +- 5 files changed, 88 insertions(+), 24 deletions(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index a62b112519..8aa6ccaa7e 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -3,11 +3,23 @@ # Port xend should use for the HTTP interface. (xend-port 8000) -# Address xend should listen on. +# Port xend should use for the event interface. +(xend-event-port 8001) + +# Address xend should listen on for HTTP connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. (xend-address '') +# The port xend should start from when allocating a port +# for a domain console. +(console-port-base 9600) + +# Address xend should listen on for console connections. +# Specifying 'localhost' prevents remote connections. +# Specifying the empty string '' allows all connections. +(console-address '') + ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. #(network-script network-route) diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index dea3eeeb2f..c8236a4ecd 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -2,6 +2,11 @@ """Xend root class. Creates the event server and handles configuration. + +Other classes get config variables by importing this module, +using instance() to get a XendRoot instance, and then +the config functions (e.g. get_xend_port()) to get +configured values. """ import os @@ -34,17 +39,33 @@ class XendRoot: """Where block control scripts live.""" block_script_dir = "/etc/xen/scripts" + """Default path to the log file. """ logfile_default = "/var/log/xend.log" loglevel_default = 'DEBUG' + """Default interface address xend listens at. """ + xend_address_default = '' + + """Default port xend serves HTTP at. """ + xend_port_default = '8000' + + """Default port xend serves events at. """ + xend_event_port_default = '8001' + + """Default inteface address xend listens at for consoles.""" + console_address_default = '' + + """Default port xend serves consoles at. """ + console_port_base_default = '9600' + components = {} def __init__(self): self.dbroot = None self.config_path = None self.config = None - self.logger = None + self.logging = None self.configure() eserver.subscribe('xend.*', self.event_handler) #eserver.subscribe('xend.domain.created', self.event_handler) @@ -73,9 +94,9 @@ class XendRoot: def _format(self, msg, args): if args: - return str(msg) - else: return str(msg) % args + else: + return str(msg) def _log(self, mode, fmt, args): """Logging function that uses the logger if it exists, otherwise @@ -90,7 +111,7 @@ class XendRoot: if log: getattr(log, mode)(fmt, *args) else: - print >>stderr, "xend", "[%s]" % level, self._format(msg, args) + print >>sys.stderr, "xend", "[%s]" % level, self._format(fmt, args) def logDebug(self, fmt, *args): """Log a debug message. @@ -132,7 +153,6 @@ class XendRoot: self.configure_logger() self.dbroot = self.get_config_value("dbroot", self.dbroot_default) - def configure_logger(self): logfile = self.get_config_value("logfile", self.logfile_default) loglevel = self.get_config_value("loglevel", self.loglevel_default) @@ -146,7 +166,7 @@ class XendRoot: def get_logger(self): """Get the logger. """ - return self.logging.getLogger() + return self.logging and self.logging.getLogger() def get_dbroot(self): """Get the path to the database root. @@ -160,14 +180,20 @@ class XendRoot: """ self.config_path = os.getenv(self.config_var, self.config_default) if os.path.exists(self.config_path): - fin = file(self.config_path, 'rb') + #self.logInfo('Reading config file %s', self.config_path) try: - config = sxp.parse(fin) + fin = file(self.config_path, 'rb') + try: + config = sxp.parse(fin) + finally: + fin.close() config.insert(0, 'xend-config') self.config = config - finally: - fin.close() + except Exception, ex: + self.logError('Reading config file %s: %s', self.config_path, str(ex)) + raise else: + self.logError('Config file does not exist: %s', self.config_path) self.config = ['xend-config'] def get_config(self, name=None): @@ -193,10 +219,35 @@ class XendRoot: return sxp.child_value(self.config, name, val=val) def get_xend_port(self): - return int(self.get_config_value('xend-port', '8000')) + """Get the port xend listens at for its HTTP interface. + """ + return int(self.get_config_value('xend-port', self.xend_port_default)) + + def get_xend_event_port(self): + """Get the port xend listens at for connection to its event server. + """ + return int(self.get_config_value('xend-event-port', self.xend_event_port_default)) def get_xend_address(self): - return self.get_config_value('xend-address', '') + """Get the address xend listens at for its HTTP and event ports. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the HTTP and event ports. + """ + return self.get_config_value('xend-address', self.xend_address_default) + + def get_console_address(self): + """Get the address xend listens at for its console ports. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the console ports. + """ + return self.get_config_value('console-address', self.console_address_default) + + def get_console_port_base(self): + """Get the base port number used to generate console ports for domains. + """ + return int(self.get_config_value('console-port-base', self.console_port_base_default)) def get_block_script(self, type): return self.get_config_value('block-%s' % type, '') diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 05eb1ed016..9bf5fd9bb0 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -596,10 +596,10 @@ class Daemon: def set_user(self): # Set the UID. try: - os.setuid(pwd.getpwnam(USER)[2]) + os.setuid(pwd.getpwnam(XEND_USER)[2]) return 0 except KeyError, error: - print "Error: no such user '%s'" % USER + print "Error: no such user '%s'" % XEND_USER return 1 def stop(self): @@ -609,7 +609,7 @@ class Daemon: xroot = XendRoot.instance() log.info("Xend Daemon started") self.createFactories() - self.listenEvent() + self.listenEvent(xroot) self.listenNotifier() self.listenVirq() SrvServer.create(bridge=1) @@ -622,9 +622,11 @@ class Daemon: self.netifCF = netif.NetifControllerFactory() self.consoleCF = console.ConsoleControllerFactory() - def listenEvent(self): + def listenEvent(self, xroot): protocol = EventFactory(self) - return reactor.listenTCP(EVENT_PORT, protocol) + port = xroot.get_xend_event_port() + interface = xroot.get_xend_address() + return reactor.listenTCP(port, protocol, interface=interface) def listenNotifier(self): protocol = NotifierProtocol(self.channelF) diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py index ea4bf49921..3e76c6ccef 100755 --- a/tools/python/xen/xend/server/console.py +++ b/tools/python/xen/xend/server/console.py @@ -11,6 +11,8 @@ from xen.xend.XendError import XendError from xen.xend import EventServer eserver = EventServer.instance() from xen.xend.XendLogging import log +from xen.xend import XendRoot +xroot = XendRoot.instance() import controller from messages import * @@ -191,7 +193,8 @@ class ConsoleController(controller.Controller): pass else: f = ConsoleFactory(self, self.idx) - self.listener = reactor.listenTCP(self.console_port, f) + interface = xroot.get_console_address() + self.listener = reactor.listenTCP(self.console_port, f, interface=interface) def connect(self, addr, conn): """Connect a TCP connection to the console. diff --git a/tools/python/xen/xend/server/params.py b/tools/python/xen/xend/server/params.py index bb5277aecd..0f8632a4f2 100644 --- a/tools/python/xen/xend/server/params.py +++ b/tools/python/xen/xend/server/params.py @@ -3,9 +3,5 @@ XEND_PID_FILE = '/var/run/xend.pid' XFRD_PID_FILE = '/var/run/xfrd.pid' XEND_TRACE_FILE = '/var/log/xend.trace' -USER = 'root' - -EVENT_PORT = 8001 - -CONSOLE_PORT_BASE = 9600 +XEND_USER = 'root' From ddc8c34b8fd4e78e813a9164611aff495335f1ab Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 11 Mar 2005 12:56:17 +0000 Subject: [PATCH 140/199] bitkeeper revision 1.1159.265.3 (42319571gIMQdofIDztktCfg053n-A) Fix some errors in default error handling. Signed-off-by: Mike Wray --- tools/python/xen/xend/Args.py | 5 +++++ tools/python/xen/xend/server/SrvBase.py | 3 ++- tools/python/xen/xend/server/SrvDir.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/Args.py b/tools/python/xen/xend/Args.py index 3e16844f74..480aa7ac21 100644 --- a/tools/python/xen/xend/Args.py +++ b/tools/python/xen/xend/Args.py @@ -78,6 +78,8 @@ class Args: val = str(v) elif type == 'sxpr': val = self.sxpr(v) + elif type == 'bool': + val = self.bool(v) else: raise ArgError('invalid type:' + str(type)) return val @@ -86,6 +88,9 @@ class Args: except StandardError, ex: raise ArgError(str(ex)) + def bool(self, v): + return (v.lower() in ['on', 'yes', '1', 'true']) + def sxpr(self, v): if isinstance(v, types.ListType): val = v diff --git a/tools/python/xen/xend/server/SrvBase.py b/tools/python/xen/xend/server/SrvBase.py index b32d102273..5990733d75 100644 --- a/tools/python/xen/xend/server/SrvBase.py +++ b/tools/python/xen/xend/server/SrvBase.py @@ -106,7 +106,8 @@ class SrvBase(resource.Resource): try: val = op_method(op, req) except Exception, err: - return self._perform_err(err, op, req) + self._perform_err(err, op, req) + return '' if isinstance(val, defer.Deferred): val.addCallback(self._perform_cb, op, req, dfr=1) diff --git a/tools/python/xen/xend/server/SrvDir.py b/tools/python/xen/xend/server/SrvDir.py index 106c5ef268..712521c7b3 100644 --- a/tools/python/xen/xend/server/SrvDir.py +++ b/tools/python/xen/xend/server/SrvDir.py @@ -88,7 +88,7 @@ class SrvDir(SrvBase): req.write('') return '' except Exception, ex: - self._perform_err(ex, req) + self._perform_err(ex, "GET", req) def ls(self, req, use_sxp=0): url = req.prePathURL() From e77f3b1346b71c111431e510387179e060ab494b Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Fri, 11 Mar 2005 14:55:06 +0000 Subject: [PATCH 141/199] bitkeeper revision 1.1159.258.50 (4231b14a0Nqrojj7aAwM5Ge5I8cg9w) Change defaults in /etc/xen/xend-config.sxp : * xend will now only listen on localhost for conenctions from 'xm'. * consoles are only available from localhost too Signed-off-by: ian.pratt@cl.cam.ac.uk --- tools/examples/xend-config.sxp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 8aa6ccaa7e..8d670c3d16 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -9,7 +9,7 @@ # Address xend should listen on for HTTP connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. -(xend-address '') +(xend-address 'localhost') # The port xend should start from when allocating a port # for a domain console. @@ -18,7 +18,7 @@ # Address xend should listen on for console connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. -(console-address '') +(console-address 'localhost') ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. From b7df222032d7012801264b5c55035587dcb8ee9f Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 11 Mar 2005 17:01:00 +0000 Subject: [PATCH 142/199] bitkeeper revision 1.1159.269.2 (4231ceccPlcoLKWWixfu3trU9tb-_A) Improve error reporting for save/restore/migrate. Signed-off-by: Mike Wray --- tools/python/xen/xend/XendMigrate.py | 158 +++++++++++++--------- tools/python/xen/xend/server/SrvDomain.py | 17 --- 2 files changed, 91 insertions(+), 84 deletions(-) diff --git a/tools/python/xen/xend/XendMigrate.py b/tools/python/xen/xend/XendMigrate.py index a1c261deb5..f2570ae02b 100644 --- a/tools/python/xen/xend/XendMigrate.py +++ b/tools/python/xen/xend/XendMigrate.py @@ -6,12 +6,14 @@ import errno import sys import socket import time +import types from twisted.internet import reactor from twisted.internet import defer #defer.Deferred.debug = 1 from twisted.internet.protocol import Protocol from twisted.internet.protocol import ClientFactory +from twisted.python.failure import Failure import sxp import XendDB @@ -45,11 +47,9 @@ class Xfrd(Protocol): sxp.show(req, out=self.transport) def loseConnection(self): - print 'Xfrd>loseConnection>' self.transport.loseConnection() def connectionLost(self, reason): - print 'Xfrd>connectionLost>', reason self.xinfo.connectionLost(reason) def dataReceived(self, data): @@ -70,17 +70,15 @@ class XfrdClientFactory(ClientFactory): self.xinfo = xinfo def startedConnecting(self, connector): - print 'Started to connect', 'self=', self, 'connector=', connector + pass def buildProtocol(self, addr): - print 'buildProtocol>', addr return Xfrd(self.xinfo) def clientConnectionLost(self, connector, reason): - print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason + pass def clientConnectionFailed(self, connector, reason): - print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason self.xinfo.error(reason) class XfrdInfo: @@ -90,7 +88,7 @@ class XfrdInfo: """Suspend timeout (seconds). We set a timeout because suspending a domain can hang.""" - timeout = 30 + timeout = 10 def __init__(self): from xen.xend import XendDomain @@ -98,6 +96,9 @@ class XfrdInfo: self.deferred = defer.Deferred() self.suspended = {} self.paused = {} + self.state = 'init' + # List of errors encountered. + self.errors = [] def vmconfig(self): dominfo = self.xd.domain_get(self.src_dom) @@ -107,12 +108,38 @@ class XfrdInfo: val = None return val + def add_error(self, err): + """Add an error to the error list. + Returns the error added (which may have been unwrapped if it + was a Twisted Failure). + """ + while isinstance(err, Failure): + err = err.value + if err not in self.errors: + self.errors.append(err) + return err + + def error_summary(self, msg=None): + """Get a XendError summarising the errors (if any). + """ + if msg is None: + msg = "errors" + if self.errors: + errmsg = msg + ': ' + ', '.join(map(str, self.errors)) + else: + errmsg = msg + return XendError(errmsg) + + def get_errors(self): + """Get the list of errors. + """ + return self.errors + def error(self, err): - print 'Error>', err self.state = 'error' + self.add_error(err) if not self.deferred.called: - print 'Error> calling errback' - self.deferred.errback(err) + self.deferred.errback(self.error_summary()) def dispatch(self, xfrd, val): @@ -139,28 +166,23 @@ class XfrdInfo: cbok(val) def unknown(self, xfrd, val): - print 'unknown>', val xfrd.loseConnection() return None def xfr_err(self, xfrd, val): # If we get an error with non-zero code the operation failed. # An error with code zero indicates hello success. - print 'xfr_err>', val v = sxp.child0(val) - print 'xfr_err>', type(v), v err = int(sxp.child0(val)) if not err: return - self.error(err); + self.error("transfer daemon (xfrd) error: " + str(err)) xfrd.loseConnection() return None def xfr_progress(self, xfrd, val): - print 'xfr_progress>', val return None def xfr_vm_destroy(self, xfrd, val): - print 'xfr_vm_destroy>', val try: vmid = sxp.child0(val) val = self.xd.domain_destroy(vmid) @@ -168,28 +190,32 @@ class XfrdInfo: del self.paused[vmid] if vmid in self.suspended: del self.suspended[vmid] - except: + except StandardError, err: + self.add_error("vm_destroy failed") + self.add_error(err) val = errno.EINVAL return ['xfr.err', val] def xfr_vm_pause(self, xfrd, val): - print 'xfr_vm_pause>', val try: vmid = sxp.child0(val) val = self.xd.domain_pause(vmid) self.paused[vmid] = 1 - except: + except StandardError, err: + self.add_error("vm_pause failed") + self.add_error(err) val = errno.EINVAL return ['xfr.err', val] def xfr_vm_unpause(self, xfrd, val): - print 'xfr_vm_unpause>', val try: vmid = sxp.child0(val) val = self.xd.domain_unpause(vmid) if vmid in self.paused: del self.paused[vmid] - except: + except StandardError, err: + self.add_error("vm_unpause failed") + self.add_error(err) val = errno.EINVAL return ['xfr.err', val] @@ -199,7 +225,6 @@ class XfrdInfo: Suspending can hang, so we set a timeout and fail if it takes too long. """ - print 'xfr_vm_suspend>', val try: vmid = sxp.child0(val) d = defer.Deferred() @@ -208,15 +233,15 @@ class XfrdInfo: # the domain died. Set a timeout and error handler so the subscriptions # will be cleaned up if suspending hangs or there is an error. def onSuspended(e, v): - print 'xfr_vm_suspend>onSuspended>', e, v if v[1] != vmid: return subscribe(on=0) - d.callback(v) + if not d.called: + d.callback(v) def onDied(e, v): - print 'xfr_vm_suspend>onDied>', e, v if v[1] != vmid: return - d.errback(XendError('Domain died')) + if not d.called: + d.errback(XendError('Domain %s died while suspending' % vmid)) def subscribe(on=1): if on: @@ -227,24 +252,25 @@ class XfrdInfo: action('xend.domain.died', onDied) def cberr(err): - print 'xfr_vm_suspend>cberr>', err subscribe(on=0) + self.add_error("suspend failed") + self.add_error(err) return err + d.addErrback(cberr) + d.setTimeout(self.timeout) subscribe() val = self.xd.domain_shutdown(vmid, reason='suspend') self.suspended[vmid] = 1 - d.addErrback(cberr) - d.setTimeout(self.timeout) return d except Exception, err: - print 'xfr_vm_suspend> Exception', err + self.add_error("suspend failed") + self.add_error(err) traceback.print_exc() val = errno.EINVAL return ['xfr.err', val] def connectionLost(self, reason=None): - print 'XfrdInfo>connectionLost>', reason for vmid in self.suspended: try: self.xd.domain_destroy(vmid) @@ -279,7 +305,7 @@ class XendMigrateInfo(XfrdInfo): ['id', self.xid ], ['state', self.state ], ['live', self.live ], - ['resource', self.resource] ] + ['resource', self.resource ] ] sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ] sxpr.append(sxpr_src) sxpr_dst = ['dst', ['host', self.dst_host] ] @@ -291,12 +317,12 @@ class XendMigrateInfo(XfrdInfo): def request(self, xfrd): vmconfig = self.vmconfig() if not vmconfig: + self.error(XendError("vm config not found")) xfrd.loseConnection() return - log.info('Migrate BEGIN: ' + str(self.sxpr())) + log.info('Migrate BEGIN: %s' % str(self.sxpr())) eserver.inject('xend.domain.migrate', - [ self.dominfo.name, self.dominfo.id, - "begin", self.sxpr() ]) + [ self.dominfo.name, self.dominfo.id, "begin", self.sxpr() ]) xfrd.request(['xfr.migrate', self.src_dom, vmconfig, @@ -305,19 +331,6 @@ class XendMigrateInfo(XfrdInfo): self.live, self.resource ]) -## def xfr_vm_suspend(self, xfrd, val): -## def cbok(val): -## # Special case for localhost: destroy devices early. -## if self.dst_host in ["localhost", "127.0.0.1"]: -## self.dominfo.restart_cancel() -## self.dominfo.cleanup() -## self.dominfo.destroy_console() -## return val - -## d = XfrdInfo.xfr_vm_suspend(self, xfrd, val) -## d.addCallback(cbok) -## return d - def xfr_migrate_ok(self, xfrd, val): dom = int(sxp.child0(val)) self.state = 'ok' @@ -327,17 +340,15 @@ class XendMigrateInfo(XfrdInfo): self.deferred.callback(self) def connectionLost(self, reason=None): - print 'XfrdMigrateInfo>connectionLost>', reason XfrdInfo.connectionLost(self, reason) if self.state =='ok': log.info('Migrate OK: ' + str(self.sxpr())) else: self.state = 'error' - self.error(XendError("migrate failed")) + self.error("migrate failed") log.info('Migrate ERROR: ' + str(self.sxpr())) eserver.inject('xend.domain.migrate', - [ self.dominfo.name, self.dominfo.id, - self.state, self.sxpr() ]) + [ self.dominfo.name, self.dominfo.id, self.state, self.sxpr() ]) class XendSaveInfo(XfrdInfo): """Representation of a save in-progress and its interaction with xfrd. @@ -361,16 +372,15 @@ class XendSaveInfo(XfrdInfo): return sxpr def request(self, xfrd): - print '***request>', self.vmconfig() vmconfig = self.vmconfig() if not vmconfig: + self.error(XendError("vm config not found")) xfrd.loseConnection() return - print '***request> begin' log.info('Save BEGIN: ' + str(self.sxpr())) eserver.inject('xend.domain.save', - [self.dominfo.name, self.dominfo.id, - "begin", self.sxpr()]) + [ self.dominfo.name, self.dominfo.id, + "begin", self.sxpr() ]) xfrd.request(['xfr.save', self.src_dom, vmconfig, self.file ]) def xfr_save_ok(self, xfrd, val): @@ -380,13 +390,12 @@ class XendSaveInfo(XfrdInfo): self.deferred.callback(self) def connectionLost(self, reason=None): - print 'XfrdSaveInfo>connectionLost>', reason XfrdInfo.connectionLost(self, reason) if self.state =='ok': log.info('Save OK: ' + str(self.sxpr())) else: self.state = 'error' - self.error(XendError("save failed")) + self.error("save failed") log.info('Save ERROR: ' + str(self.sxpr())) eserver.inject('xend.domain.save', [ self.dominfo.name, self.dominfo.id, @@ -409,8 +418,9 @@ class XendRestoreInfo(XfrdInfo): return sxpr def request(self, xfrd): - print '***request>', self.file log.info('restore BEGIN: ' + str(self.sxpr())) + eserver.inject('xend.restore', [ 'begin', self.sxpr()]) + xfrd.request(['xfr.restore', self.file ]) def xfr_restore_ok(self, xfrd, val): @@ -419,8 +429,17 @@ class XendRestoreInfo(XfrdInfo): self.state = 'ok' if not self.deferred.called: self.deferred.callback(dominfo) - + def connectionLost(self, reason=None): + XfrdInfo.connectionLost(self, reason) + if self.state =='ok': + log.info('Restore OK: ' + self.file) + else: + self.state = 'error' + self.error("restore failed") + log.info('Restore ERROR: ' + str(self.sxpr())) + eserver.inject('xend.restore', [ self.state, self.sxpr()]) + class XendMigrate: """External api for interaction with xfrd for migrate and save. Singleton. @@ -445,7 +464,6 @@ class XendMigrate: self.db.saveall("", self.session_db) def sync_session(self, xid): - print 'sync_session>', type(xid), xid, self.session_db[xid] self.db.save(xid, self.session_db[xid]) def close(self): @@ -458,7 +476,6 @@ class XendMigrate: self.sync_session(xid) def _delete_session(self, xid): - print '***_delete_session>', xid if xid in self.session: del self.session[xid] if xid in self.session_db: @@ -482,16 +499,23 @@ class XendMigrate: @param info: session @return: deferred """ - def cbremove(val): - print '***cbremove>', val + dfr = defer.Deferred() + def cbok(val): self._delete_session(info.xid) + if not dfr.called: + dfr.callback(val) return val + def cberr(err): + self._delete_session(info.xid) + if not dfr.called: + dfr.errback(err) + return err self._add_session(info) - info.deferred.addCallback(cbremove) - info.deferred.addErrback(cbremove) + info.deferred.addCallback(cbok) + info.deferred.addErrback(cberr) xcf = XfrdClientFactory(info) reactor.connectTCP('localhost', XFRD_PORT, xcf) - return info.deferred + return dfr def migrate_begin(self, dominfo, host, port=XFRD_PORT, live=0, resource=0): """Begin to migrate a domain to another host. diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index d73a39bff5..a4c06f6c8d 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -29,13 +29,8 @@ class SrvDomain(SrvDir): [['dom', 'int'], ['config', 'sxpr']]) deferred = fn(req.args, {'dom': self.dom.dom}) - deferred.addErrback(self._op_configure_err, req) return deferred - def _op_configure_err(self, err, req): - req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err)) - return str(err) - def op_unpause(self, op, req): val = self.xd.domain_unpause(self.dom.name) return val @@ -68,16 +63,11 @@ class SrvDomain(SrvDir): ['file', 'str']]) deferred = fn(req.args, {'dom': self.dom.id}) deferred.addCallback(self._op_save_cb, req) - deferred.addErrback(self._op_save_err, req) return deferred def _op_save_cb(self, val, req): return 0 - def _op_save_err(self, err, req): - req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err)) - return str(err) - def op_migrate(self, op, req): fn = FormFn(self.xd.domain_migrate, [['dom', 'str'], @@ -85,9 +75,7 @@ class SrvDomain(SrvDir): ['live', 'int'], ['resource', 'int']]) deferred = fn(req.args, {'dom': self.dom.id}) - print 'op_migrate>', deferred deferred.addCallback(self._op_migrate_cb, req) - deferred.addErrback(self._op_migrate_err, req) return deferred def _op_migrate_cb(self, info, req): @@ -101,11 +89,6 @@ class SrvDomain(SrvDir): print '_op_migrate_cb> url=', url return url - def _op_migrate_err(self, err, req): - print '_op_migrate_err>', err, req - req.setResponseCode(http.BAD_REQUEST, "Error: "+ str(err)) - return str(err) - def op_pincpu(self, op, req): fn = FormFn(self.xd.domain_pincpu, [['dom', 'str'], From 7adbe03e19449bf5f9adbd341f08b091e1b6f717 Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sat, 12 Mar 2005 15:19:18 +0000 Subject: [PATCH 143/199] bitkeeper revision 1.1159.270.1 (423308766_Mxiqyj1XF-m4OxnLnExA) No longer require latex2html (bizarrely considered 'non-free' by Debian maintainers) to build docs. Instead we still build PS/PDF docs, but skip HTML docs. Signed-off-by: Keir Fraser --- docs/Makefile | 6 ++++-- docs/check_pkgs | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index e05a84fad4..8b968dc87e 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -25,7 +25,9 @@ ps: $(DOC_PS) pdf: $(DOC_PDF) -html: $(DOC_HTML) +html: + @if which $(LATEX2HTML) 1>/dev/null 2>/dev/null; then \ + $(MAKE) $(DOC_HTML); fi clean: rm -rf .word_count *.aux *.dvi *.bbl *.blg *.glo *.idx *~ @@ -37,7 +39,7 @@ install: all $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir) cp -dR ps $(DESTDIR)$(pkgdocdir) cp -dR pdf $(DESTDIR)$(pkgdocdir) - cp -dR html $(DESTDIR)$(pkgdocdir) + [ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir) pdf/%.pdf: ps/%.ps $(INSTALL_DIR) $(@D) diff --git a/docs/check_pkgs b/docs/check_pkgs index e705720458..25a624ef24 100644 --- a/docs/check_pkgs +++ b/docs/check_pkgs @@ -13,7 +13,6 @@ silent_which () } silent_which latex || exit 1 -silent_which latex2html || exit 1 silent_which dvips || exit 1 silent_which ps2pdf || exit 1 silent_which fig2dev || exit 1 From 61b59d9dd59957229d0938a7549b7ce8dcbda254 Mon Sep 17 00:00:00 2001 From: "doogie@brainfood.com[kaf24]" Date: Sat, 12 Mar 2005 15:28:18 +0000 Subject: [PATCH 144/199] bitkeeper revision 1.1159.270.2 (42330a929cE0pKehTkalVAgu8SLwKQ) [PATCH] non-xen-init-exit.patch Name: non-xen-init-exit.patch Description: exit if not running on a xen dom0 kernel. If /proc/xen/privcmd doesn't exist, then exit successfully. This allows for dual-boot setups, and installing xen before rebooting into a real xen kernel. Signed-off-by: Adam Heath --- BitKeeper/etc/logging_ok | 1 + tools/examples/init.d/xend | 4 ++++ tools/examples/init.d/xendomains | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index d54268186e..05d987fd88 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -16,6 +16,7 @@ cl349@freefall.cl.cam.ac.uk cl349@labyrinth.cl.cam.ac.uk cwc22@centipede.cl.cam.ac.uk djm@kirby.fc.hp.com +doogie@brainfood.com gm281@boulderdash.cl.cam.ac.uk gm281@tetrapod.cl.cam.ac.uk iap10@freefall.cl.cam.ac.uk diff --git a/tools/examples/init.d/xend b/tools/examples/init.d/xend index fc94c17dd2..058f6a821f 100755 --- a/tools/examples/init.d/xend +++ b/tools/examples/init.d/xend @@ -7,6 +7,10 @@ # chkconfig: 2345 98 01 # description: Starts and stops the Xen control daemon. +if ! [ -e /proc/xen/privcmd ]; then + exit 0 +fi + # Wait for Xend / Xfrd to be up function await_daemons_up { diff --git a/tools/examples/init.d/xendomains b/tools/examples/init.d/xendomains index c52c3cc0e9..3180f45aa2 100755 --- a/tools/examples/init.d/xendomains +++ b/tools/examples/init.d/xendomains @@ -15,6 +15,10 @@ # # +if ! [ -e /proc/xen/privcmd ]; then + exit 0 +fi + RETVAL=0 INITD=/etc/init.d From be7913c187dda75bed2e1d6a5fb829ea206c1c90 Mon Sep 17 00:00:00 2001 From: "doogie@brainfood.com[kaf24]" Date: Sat, 12 Mar 2005 15:29:44 +0000 Subject: [PATCH 145/199] bitkeeper revision 1.1159.270.3 (42330ae8efsd9SdlhNX6EpksrtV6oQ) [PATCH] add-build.patch Add build targets to all makefiles. Debian does builds as non-root, so it's better to do as much as possible before requiring root privs. Signed-off-by: Adam Heath --- Makefile | 5 +++++ docs/Makefile | 3 ++- tools/Makefile | 18 +++++++++--------- tools/examples/Makefile | 1 + tools/libxc/Makefile | 7 ++++--- tools/libxutil/Makefile | 5 +++-- tools/misc/Makefile | 5 +++-- tools/python/Makefile | 3 ++- tools/xentrace/Makefile | 5 +++-- tools/xfrd/Makefile | 3 ++- xen/Makefile | 7 ++++--- 11 files changed, 38 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index b7229fc9a7..cf860ad1fb 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,11 @@ all: dist # build and install everything into the standard system directories install: install-xen install-tools install-kernels install-docs +build: kernels + $(MAKE) -C xen build + $(MAKE) -C tools build + $(MAKE) -C docs build + # build and install everything into local dist directory dist: xen tools kernels docs $(INSTALL_DIR) $(DISTDIR)/check diff --git a/docs/Makefile b/docs/Makefile index 8b968dc87e..117e63ce4f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -18,7 +18,8 @@ DOC_HTML := $(patsubst src/%.tex,html/%/index.html,$(DOC_TEX)) GFX = $(patsubst %.fig, %.eps, $(wildcard figs/*.fig)) -all: ps pdf html +all: build +build: ps pdf html rm -f *.aux *.dvi *.bbl *.blg *.glo *.idx *.ilg *.log *.ind *.toc ps: $(DOC_PS) diff --git a/tools/Makefile b/tools/Makefile index 0140f8baae..c582a014d0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -20,13 +20,13 @@ install: $(MAKE) -C xfrd install $(MAKE) -C sv install -clean: - $(MAKE) -C check clean - $(MAKE) -C libxutil clean - $(MAKE) -C libxc clean - $(MAKE) -C misc clean - $(MAKE) -C examples clean - $(MAKE) -C xentrace clean - $(MAKE) -C python clean - $(MAKE) -C xfrd clean +clean build: + $(MAKE) -C check $@ + $(MAKE) -C libxutil $@ + $(MAKE) -C libxc $@ + $(MAKE) -C misc $@ + $(MAKE) -C examples $@ + $(MAKE) -C xentrace $@ + $(MAKE) -C python $@ + $(MAKE) -C xfrd $@ diff --git a/tools/examples/Makefile b/tools/examples/Makefile index 72c1f610eb..5957a422b9 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -21,6 +21,7 @@ XEN_SCRIPTS += block-file XEN_SCRIPTS += block-enbd all: +build: install: all install-initd install-configs install-scripts diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 01fd926cf4..a254f3f396 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -44,7 +44,8 @@ PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) LIB := libxc.a libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) -all: check-for-zlib mk-symlinks +all: build +build: check-for-zlib mk-symlinks $(MAKE) $(LIB) check-for-zlib: @@ -66,7 +67,7 @@ mk-symlinks: ( cd xen/linux >/dev/null ; \ ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . ) -install: all +install: build [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib @@ -78,7 +79,7 @@ install: all clean: rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen -rpm: all +rpm: build rm -rf staging mkdir staging mkdir staging/i386 diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile index a9be3e3977..95e8597b3e 100644 --- a/tools/libxutil/Makefile +++ b/tools/libxutil/Makefile @@ -40,7 +40,8 @@ LIB += libxutil.so.$(MAJOR) LIB += libxutil.so.$(MAJOR).$(MINOR) LIB += libxutil.a -all: check-for-zlib +all: build +build: check-for-zlib $(MAKE) $(LIB) libxutil.so: libxutil.so.$(MAJOR) @@ -63,7 +64,7 @@ check-for-zlib: false; \ fi -install: all +install: build [ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/lib diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 39bfc424e6..7bfe0fad6b 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -19,10 +19,11 @@ TARGETS = xenperf INSTALL_BIN = $(TARGETS) xencons INSTALL_SBIN = netfix xm xend xensv xenperf -all: $(TARGETS) +all: build +build: $(TARGETS) $(MAKE) -C miniterm -install: all +install: build [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin [ -d $(DESTDIR)/usr/sbin ] || $(INSTALL_DIR) $(DESTDIR)/usr/sbin $(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin diff --git a/tools/python/Makefile b/tools/python/Makefile index 7d152e12ae..3a42f6047f 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -2,7 +2,8 @@ XEN_ROOT = ../.. include $(XEN_ROOT)/tools/Rules.mk -all: +all: build +build: CFLAGS="$(CFLAGS)" python setup.py build install: all diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 5ed26cf795..3ee097ee31 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -21,9 +21,10 @@ SCRIPTS = xentrace_format MAN1 = $(wildcard *.1) MAN8 = $(wildcard *.8) -all: $(BIN) +all: build +build: $(BIN) -install: all +install: build [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin [ -d $(DESTDIR)/usr/man/man1 ] || \ $(INSTALL_DIR) $(DESTDIR)/usr/man/man1 diff --git a/tools/xfrd/Makefile b/tools/xfrd/Makefile index 4cdc810e95..fb6f2ae244 100644 --- a/tools/xfrd/Makefile +++ b/tools/xfrd/Makefile @@ -63,7 +63,8 @@ XFRD_LIBS += $(CURL_LIBS) #$(warning XFRD_LIBS = $(XFRD_LIBS)) -all: xfrd +all: build +build: xfrd xfrd: $(XFRD_PROG_OBJ) $(CC) -o $@ $^ $(XFRD_LIBS) diff --git a/xen/Makefile b/xen/Makefile index 04ce606de5..7593e017fa 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -16,7 +16,7 @@ export BASEDIR := $(CURDIR) include Rules.mk -default: $(TARGET).gz +default: build $(TARGET).gz: $(TARGET) gzip -f -9 < $< > $@.new mv $@.new $@ @@ -24,9 +24,10 @@ $(TARGET).gz: $(TARGET) debug: objdump -D -S $(TARGET)-syms > $(TARGET).s -dist: - $(MAKE) install +dist: install +build: $(TARGET).gz + install: $(TARGET).gz [ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot $(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot From 322cee6129e74bd9ff7595e92e17a77305abffcf Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Sat, 12 Mar 2005 15:42:39 +0000 Subject: [PATCH 146/199] bitkeeper revision 1.1159.270.4 (42330defA42oRGAfkwmQERgN45uyOg) Python packages can be installed to the Python installation's 'native' location, instead of generic /usr/lib/python, by specifying XEN_PYTHON_NATIVE_INSTALL in the environment or on the make command line. Signed-off-by: Keir Fraser --- tools/python/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/python/Makefile b/tools/python/Makefile index 3a42f6047f..a676cdf0e9 100644 --- a/tools/python/Makefile +++ b/tools/python/Makefile @@ -6,8 +6,13 @@ all: build build: CFLAGS="$(CFLAGS)" python setup.py build +ifndef XEN_PYTHON_NATIVE_INSTALL install: all CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" +else +install: all + CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" +endif clean: rm -rf build *.pyc *.pyo *.o *.a *~ From 84cc6d601f5bab8194ae3fb59edf44c785f543f6 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Sun, 13 Mar 2005 01:36:29 +0000 Subject: [PATCH 147/199] bitkeeper revision 1.1159.258.52 (4233991dQspKbtD0n-C6ReG4f2lHAQ) Add hypercall to allow domains to request that they be crashed. Signed-off-by: ian@xensource.com --- .../include/asm-xen/hypervisor.h | 16 ++++++++++++++++ xen/common/domain.c | 4 ++++ xen/include/public/io/domain_controller.h | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h index 2d5a88a56d..cccfae35ae 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h @@ -289,6 +289,22 @@ HYPERVISOR_suspend( return ret; } +static inline int +HYPERVISOR_crash( + void) +{ + int ret; + unsigned long ign1; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign1) + : "0" (__HYPERVISOR_sched_op), + "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + static inline long HYPERVISOR_set_timer_op( u64 timeout) diff --git a/xen/common/domain.c b/xen/common/domain.c index 47673b21ec..f04e8bdfc7 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -16,6 +16,7 @@ #include #include #include +#include /* Both these structures are protected by the domlist_lock. */ rwlock_t domlist_lock = RW_LOCK_UNLOCKED; @@ -168,6 +169,9 @@ void domain_shutdown(u8 reason) } } + if ( reason == SHUTDOWN_crash ) + domain_crash(); /* we will not return */ + current->shutdown_code = reason; set_bit(DF_SHUTDOWN, ¤t->flags); diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index 61ba2d3776..8415132d45 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -19,7 +19,7 @@ #define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ #define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ #define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ - +#define SHUTDOWN_crash 3 /* Tell controler we've crashed. */ /* * CONTROLLER MESSAGING INTERFACE. From 619ad08f6f503babbe1e0a225915647c50a3cec5 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sun, 13 Mar 2005 09:33:37 +0000 Subject: [PATCH 148/199] bitkeeper revision 1.1159.258.53 (423408f115Ns6FbhmO7JTOAWVZjwog) Small cleanup to shutdown codes. Signed-off-by: Keir Fraser --- xen/common/domain.c | 7 +++++-- xen/include/public/io/domain_controller.h | 11 ----------- xen/include/public/xen.h | 10 ++++++++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index f04e8bdfc7..fa07f2baf9 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -157,7 +157,7 @@ void domain_shutdown(u8 reason) extern void machine_restart(char *); extern void machine_halt(void); - if ( reason == 0 ) + if ( reason == SHUTDOWN_poweroff ) { printk("Domain 0 halted: halting machine.\n"); machine_halt(); @@ -170,7 +170,10 @@ void domain_shutdown(u8 reason) } if ( reason == SHUTDOWN_crash ) - domain_crash(); /* we will not return */ + { + domain_crash(); + BUG(); + } current->shutdown_code = reason; set_bit(DF_SHUTDOWN, ¤t->flags); diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index 8415132d45..c3494e34ca 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -10,17 +10,6 @@ #ifndef __XEN_PUBLIC_IO_DOMAIN_CONTROLLER_H__ #define __XEN_PUBLIC_IO_DOMAIN_CONTROLLER_H__ - -/* - * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be - * interpreted by control software to determine the appropriate action. These - * are only really advisories: the controller can actually do as it likes. - */ -#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ -#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ -#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ -#define SHUTDOWN_crash 3 /* Tell controler we've crashed. */ - /* * CONTROLLER MESSAGING INTERFACE. */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index ff13c0fb20..f226416a94 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -176,6 +176,16 @@ #define SCHEDOP_cmdmask 255 /* 8-bit command. */ #define SCHEDOP_reasonshift 8 /* 8-bit reason code. (SCHEDOP_shutdown) */ +/* + * Reason codes for SCHEDOP_shutdown. These may be interpreted by control + * software to determine the appropriate action. For the most part, Xen does + * not care about the shutdown code (SHUTDOWN_crash excepted). + */ +#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ +#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ +#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ +#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ + /* * Commands to HYPERVISOR_console_io(). */ From 979c0140ab60a3cb5253c4f2a1edc88383525552 Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Sun, 13 Mar 2005 14:55:05 +0000 Subject: [PATCH 149/199] bitkeeper revision 1.1159.258.54 (42345449eD0_m04QlYElhVoRN9Iyow) Bug fix in recent xend checking Signed-off-by: ian@xensource.com --- tools/python/xen/xend/server/console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py index 3e76c6ccef..efe85acccc 100755 --- a/tools/python/xen/xend/server/console.py +++ b/tools/python/xen/xend/server/console.py @@ -84,7 +84,7 @@ class ConsoleControllerFactory(controller.ControllerFactory): def createController(self, dom, console_port=None): if console_port is None: - console_port = CONSOLE_PORT_BASE + dom + console_port = xroot.get_console_port_base() + dom for c in self.getControllers(): if c.console_port == console_port: raise XendError('console port in use: ' + str(console_port)) From d434af3fab5785f5d64c8c84d53cce2ef7fe159b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 14 Mar 2005 22:28:40 +0000 Subject: [PATCH 150/199] bitkeeper revision 1.1159.258.55 (42361018TeYmwjC8C6haDMNI9sjHUw) Fix highmem patches to use PageHighMem instead of highmem_start_page. Signed-off-by: Keir Fraser --- .../arch/xen/i386/mm/highmem.c | 55 +++---------------- .../arch/xen/i386/mm/pgtable.c | 4 +- .../include/asm-xen/asm-i386/highmem.h | 1 - 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c index 7f771f81fd..1bf278733f 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/highmem.c @@ -25,7 +25,7 @@ void kunmap(struct page *page) * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ -void *kmap_atomic(struct page *page, enum km_type type) +static void *__kmap_atomic(struct page *page, enum km_type type, pgprot_t prot) { enum fixed_addresses idx; unsigned long vaddr; @@ -41,33 +41,21 @@ void *kmap_atomic(struct page *page, enum km_type type) if (!pte_none(*(kmap_pte-idx))) BUG(); #endif - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + set_pte(kmap_pte-idx, mk_pte(page, prot)); __flush_tlb_one(vaddr); return (void*) vaddr; } -/* Same as kmap_atomic but with PAGE_KERNEL_RO page protection */ +void *kmap_atomic(struct page *page, enum km_type type) +{ + return __kmap_atomic(page, type, kmap_prot); +} + +/* Same as kmap_atomic but with PAGE_KERNEL_RO page protection. */ void *kmap_atomic_pte(struct page *page, enum km_type type) { - enum fixed_addresses idx; - unsigned long vaddr; - - /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); - if (page < highmem_start_page) - return page_address(page); - - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); -#ifdef CONFIG_DEBUG_HIGHMEM - if (!pte_none(*(kmap_pte-idx))) - BUG(); -#endif - set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL_RO)); - __flush_tlb_one(vaddr); - - return (void*) vaddr; + return __kmap_atomic(page, type, PAGE_KERNEL_RO); } void kunmap_atomic(void *kvaddr, enum km_type type) @@ -97,31 +85,6 @@ void kunmap_atomic(void *kvaddr, enum km_type type) preempt_check_resched(); } -void kunmap_atomic_force(void *kvaddr, enum km_type type) -{ - unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; - enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - - if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - preempt_check_resched(); - return; - } - - if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) - BUG(); - - /* - * force other mappings to Oops if they'll try to access - * this pte without first remap it - */ - pte_clear(kmap_pte-idx); - __flush_tlb_one(vaddr); - - dec_preempt_count(); - preempt_check_resched(); -} - struct page *kmap_atomic_to_page(void *ptr) { unsigned long idx, vaddr = (unsigned long)ptr; diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c index 30e929ad51..6fe3f08632 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c @@ -232,7 +232,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); if (pte == NULL) return pte; - if (pte >= highmem_start_page) + if (PageHighMem(pte)) return pte; /* not a highmem page -- free page and grab one from the cache */ __free_page(pte); @@ -247,7 +247,7 @@ void pte_free(struct page *pte) { set_page_count(pte, 1); #ifdef CONFIG_HIGHPTE - if (pte < highmem_start_page) + if (!PageHighMem(pte)) #endif kmem_cache_free(pte_cache, phys_to_virt(page_to_pseudophys(pte))); diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h index 8273e2db97..e3e4a531d2 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h @@ -73,7 +73,6 @@ void kunmap(struct page *page); void *kmap_atomic(struct page *page, enum km_type type); void *kmap_atomic_pte(struct page *page, enum km_type type); void kunmap_atomic(void *kvaddr, enum km_type type); -void kunmap_atomic_force(void *kvaddr, enum km_type type); struct page *kmap_atomic_to_page(void *ptr); #define flush_cache_kmaps() do { } while (0) From 8d909771419ace2b3119e8620badaba6aa3b3380 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Tue, 15 Mar 2005 11:52:56 +0000 Subject: [PATCH 151/199] bitkeeper revision 1.1159.269.3 (4236cc98Jkx2LDbrsWrj59Z-UTR_jA) Change default config to bind to localhost only. Signed-off-by: Mike Wray --- tools/examples/xend-config.sxp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 8aa6ccaa7e..8d670c3d16 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -9,7 +9,7 @@ # Address xend should listen on for HTTP connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. -(xend-address '') +(xend-address 'localhost') # The port xend should start from when allocating a port # for a domain console. @@ -18,7 +18,7 @@ # Address xend should listen on for console connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. -(console-address '') +(console-address 'localhost') ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. From 421b18073ab17499d4ec5eb4a34f6862739a0740 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Tue, 15 Mar 2005 11:58:01 +0000 Subject: [PATCH 152/199] bitkeeper revision 1.1159.269.4 (4236cdc9eib4ejH25MkiyfkGp022dQ) Add channel function to close an event channel and call when devices are destroyed. Signed-off-by: Mike Wray --- tools/python/xen/xend/server/blkif.py | 2 ++ tools/python/xen/xend/server/channel.py | 26 ++++++++++++++++++++++++- tools/python/xen/xend/server/netif.py | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 8a1de09bfc..e90b45f74c 100755 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -181,6 +181,8 @@ class BlkifBackendInterface(controller.BackendInterface): self.close() d = defer.Deferred() d.addCallback(cb_destroy) + if self.evtchn: + channel.eventChannelClose(self.evtchn) self.send_be_disconnect(response=d) def send_be_disconnect(self, response=None): diff --git a/tools/python/xen/xend/server/channel.py b/tools/python/xen/xend/server/channel.py index 127f38f2c0..bdf7efd588 100755 --- a/tools/python/xen/xend/server/channel.py +++ b/tools/python/xen/xend/server/channel.py @@ -11,7 +11,31 @@ VIRQ_CONSOLE = 3 # (DOM0) bytes received on emergency console. VIRQ_DOM_EXC = 4 # (DOM0) Exceptional event for some domain. def eventChannel(dom1, dom2): - return xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2) + """Create an event channel between domains. + The returned dict contains dom1, dom2, port1 and port2 on success. + + @return dict (empty on error) + """ + evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2) + if evtchn: + evtchn['dom1'] = dom1 + evtchn['dom2'] = dom2 + return evtchn + +def eventChannelClose(evtchn): + """Close an event channel that was opened by eventChannel(). + """ + def evtchn_close(dom, port): + if (dom is None) or (port is None): return + try: + xc.evtchn_close(dom=dom, port=port) + except Exception, ex: + pass + + if not evtchn: return + evtchn_close(evtchn.get('dom1'), evtchn.get('port1')) + evtchn_close(evtchn.get('dom2'), evtchn.get('port2')) + class ChannelFactory: """Factory for creating channels. diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index d63c342435..753ae29972 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -288,6 +288,8 @@ class NetDev(controller.SplitDev): if change: self.reportStatus() log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif) + if self.evtchn: + channel.eventChannelClose(self.evtchn) self.vifctl('down') d = self.send_be_disconnect() d.addCallback(cb_destroy) From 96d4259a85a75f16f31840fe2b4635bb70bd603e Mon Sep 17 00:00:00 2001 From: "vh249@arcadians.cl.cam.ac.uk" Date: Tue, 15 Mar 2005 14:27:36 +0000 Subject: [PATCH 153/199] bitkeeper revision 1.1159.258.56 (4236f0d8NTb8nv3JBClhBcw3-6u3oQ) update code for having dynamic update of vbd for blkfront driver on 2.6 add some protection for kmalloc failure on 2.4 and 2.6 Signed-off-by: Vincent Hanquez --- BitKeeper/etc/logging_ok | 1 + .../arch/xen/drivers/blkif/frontend/vbd.c | 14 ++- .../drivers/xen/blkfront/blkfront.c | 7 ++ .../drivers/xen/blkfront/vbd.c | 87 +++++-------------- 4 files changed, 42 insertions(+), 67 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 05d987fd88..e671b4583f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -66,4 +66,5 @@ tlh20@labyrinth.cl.cam.ac.uk tw275@labyrinth.cl.cam.ac.uk tw275@striker.cl.cam.ac.uk vh249@airwolf.cl.cam.ac.uk +vh249@arcadians.cl.cam.ac.uk xenbk@gandalf.hpl.hp.com diff --git a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c index 74a43cdd4a..81a873e4e0 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c +++ b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c @@ -442,11 +442,11 @@ void xlvbd_update_vbds(void) old_nr = nr_vbds; new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); - if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) - { - kfree(new_info); + if (!new_info) return; - } + + if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) + goto out; /* * Final list maximum size is old list + new list. This occurs only when @@ -454,6 +454,8 @@ void xlvbd_update_vbds(void) * VBDs in the old list because the usage counts are busy. */ merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL); + if (!merged_info) + goto out; /* @i tracks old list; @j tracks new list; @k tracks merged list. */ i = j = k = 0; @@ -500,6 +502,7 @@ void xlvbd_update_vbds(void) nr_vbds = k; kfree(old_info); +out: kfree(new_info); } @@ -543,6 +546,9 @@ int xlvbd_init(void) } vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); + if (!vbd_info) + return -ENOMEM; + nr_vbds = xlvbd_get_vbd_info(vbd_info); if ( nr_vbds < 0 ) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c index e28db67411..c6035b7b4d 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -170,8 +170,15 @@ static inline void flush_requests(void) module_init(xlblk_init); #if ENABLE_VBD_UPDATE +static void update_vbds_task(void *unused) +{ + xlvbd_update_vbds(); +} + static void vbd_update(void) { + static DECLARE_WORK(update_tq, update_vbds_task, NULL); + schedule_work(&update_tq); } #endif /* ENABLE_VBD_UPDATE */ diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c index 8050e756ca..95f2bd4b3b 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c @@ -354,7 +354,6 @@ static int xlvbd_init_device(vdisk_t *xd) return err; } -#if 0 /* * xlvbd_remove_device - remove a device node if possible * @device: numeric device ID @@ -364,14 +363,16 @@ static int xlvbd_init_device(vdisk_t *xd) * This is OK for now but in future, should perhaps consider where this should * deallocate gendisks / unregister devices. */ -static int xlvbd_remove_device(int device) +static int xlvbd_remove_device(int dev16) { - int i, rc = 0, minor = MINOR(device); + int i, rc = 0, minor = MINOR(dev16); struct gendisk *gd; struct block_device *bd; - xen_block_t *disk = NULL; + struct xlbd_disk_info *di; + dev_t device = MKDEV(MAJOR_XEN(dev16), MINOR_XEN(dev16)); - if ( (bd = bdget(device)) == NULL ) + bd = bdget(device); + if (!bd) return -1; /* @@ -380,67 +381,25 @@ static int xlvbd_remove_device(int device) */ down(&bd->bd_sem); - if ( ((gd = get_gendisk(device)) == NULL) || - ((disk = xldev_to_xldisk(device)) == NULL) ) - BUG(); + gd = get_gendisk(device, &i); + BUG_ON(gd == NULL); + di = (struct xlbd_disk_info *) gd->private_data; + BUG_ON(di == NULL); - if ( disk->usage != 0 ) + if ( di->mi->usage != 0 ) { printk(KERN_ALERT "VBD removal failed - in use [dev=%x]\n", device); rc = -1; goto out; } - - if ( (minor & (gd->max_p-1)) != 0 ) - { - /* 1: The VBD is mapped to a partition rather than a whole unit. */ - invalidate_device(device, 1); - gd->part[minor].start_sect = 0; - gd->part[minor].nr_sects = 0; - gd->sizes[minor] = 0; - /* Clear the consists-of-virtual-partitions flag if possible. */ - gd->flags[minor >> gd->minor_shift] &= ~GENHD_FL_VIRT_PARTNS; - for ( i = 1; i < gd->max_p; i++ ) - if ( gd->sizes[(minor & ~(gd->max_p-1)) + i] != 0 ) - gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS; + BUG_ON(minor != gd->first_minor); + /* The VBD is mapped to an entire unit. */ + + invalidate_partition(gd, 0); + set_capacity(gd, 0); - /* - * If all virtual partitions are now gone, and a 'whole unit' VBD is - * present, then we can try to grok the unit's real partition table. - */ - if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) && - (gd->sizes[minor & ~(gd->max_p-1)] != 0) && - !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE) ) - { - register_disk(gd, - device&~(gd->max_p-1), - gd->max_p, - &xlvbd_block_fops, - gd->part[minor&~(gd->max_p-1)].nr_sects); - } - } - else - { - /* - * 2: The VBD is mapped to an entire 'unit'. Clear all partitions. - * NB. The partition entries are only cleared if there are no VBDs - * mapped to individual partitions on this unit. - */ - i = gd->max_p - 1; /* Default: clear subpartitions as well. */ - if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS ) - i = 0; /* 'Virtual' mode: only clear the 'whole unit' entry. */ - while ( i >= 0 ) - { - invalidate_device(device+i, 1); - gd->part[minor+i].start_sect = 0; - gd->part[minor+i].nr_sects = 0; - gd->sizes[minor+i] = 0; - i--; - } - } - - out: +out: up(&bd->bd_sem); bdput(bd); return rc; @@ -460,11 +419,11 @@ void xlvbd_update_vbds(void) old_nr = nr_vbds; new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); - if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) - { - kfree(new_info); + if (!new_info) return; - } + + if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) + goto out; /* * Final list maximum size is old list + new list. This occurs only when @@ -472,6 +431,8 @@ void xlvbd_update_vbds(void) * VBDs in the old list because the usage counts are busy. */ merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL); + if (!merged_info) + goto out; /* @i tracks old list; @j tracks new list; @k tracks merged list. */ i = j = k = 0; @@ -518,9 +479,9 @@ void xlvbd_update_vbds(void) nr_vbds = k; kfree(old_info); +out: kfree(new_info); } -#endif /* * Set up all the linux device goop for the virtual block devices From b336843e00376acccd75e81b47d4b2c5021c12fc Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 15 Mar 2005 18:15:48 +0000 Subject: [PATCH 154/199] bitkeeper revision 1.1159.258.57 (42372654d-IcZSg1-hScBU0TITRVfg) Define new io_remap_pfn_range() for mapping device space into user applications. Patch drivers to use this instead of remap_pfn_range() where appropriate. This patch should be pushed upstream to the kernel maintainers. Signed-off-by: Keir Fraser --- .rootkeys | 1 + .../include/asm-xen/asm-i386/pgtable.h | 5 +- patches/linux-2.6.11/iomap.patch | 120 ++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 patches/linux-2.6.11/iomap.patch diff --git a/.rootkeys b/.rootkeys index a495f8ea15..da85fa4826 100644 --- a/.rootkeys +++ b/.rootkeys @@ -294,6 +294,7 @@ 422e4430-gOD358H8nGGnNWes08Nng netbsd-2.0-xen-sparse/sys/miscfs/kernfs/kernfs_vnops.c 413cb3b53nyOv1OIeDSsCXhBFDXvJA netbsd-2.0-xen-sparse/sys/nfs/files.nfs 413aa1d0oNP8HXLvfPuMe6cSroUfSA patches/linux-2.6.11/agpgart.patch +42372652KCUP-IOH9RN19YQmGhs4aA patches/linux-2.6.11/iomap.patch 418abc69J3F638vPO9MYoDGeYilxoQ patches/linux-2.6.11/nettel.patch 3f776bd1Hy9rn69ntXBhPReUFw9IEA tools/Makefile 40e1b09db5mN69Ijj0X_Eol-S7dXiw tools/Rules.mk diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h index ddbb68e681..de594a8a6d 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -485,7 +485,10 @@ int __direct_remap_area_pages(struct mm_struct *mm, mmu_update_t *v); #define io_remap_page_range(vma,from,phys,size,prot) \ - direct_remap_area_pages(vma->vm_mm,from,phys,size,prot,DOMID_IO) +direct_remap_area_pages(vma->vm_mm,from,phys,size,prot,DOMID_IO) + +#define io_remap_pfn_range(vma,from,pfn,size,prot) \ +direct_remap_area_pages(vma->vm_mm,from,pfn<vm_ops = kerninfo.vm_ops; +- } else if (remap_pfn_range(vma, vma->vm_start, ++ } else if (io_remap_pfn_range(vma, vma->vm_start, + (kerninfo.aper_base + offset) >> PAGE_SHIFT, + size, vma->vm_page_prot)) { + goto out_again; +@@ -643,7 +643,7 @@ + DBG("controller vm_ops=%p", kerninfo.vm_ops); + if (kerninfo.vm_ops) { + vma->vm_ops = kerninfo.vm_ops; +- } else if (remap_pfn_range(vma, vma->vm_start, ++ } else if (io_remap_pfn_range(vma, vma->vm_start, + kerninfo.aper_base >> PAGE_SHIFT, + size, vma->vm_page_prot)) { + goto out_again; +diff -ur linux-2.6.11/drivers/char/drm/drm_vm.c linux-2.6.11-io/drivers/char/drm/drm_vm.c +--- linux-2.6.11/drivers/char/drm/drm_vm.c 2005-03-02 07:38:33.000000000 +0000 ++++ linux-2.6.11-io/drivers/char/drm/drm_vm.c 2005-03-15 17:43:26.000000000 +0000 +@@ -630,7 +630,7 @@ + vma->vm_end - vma->vm_start, + vma->vm_page_prot, 0)) + #else +- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, ++ if (io_remap_pfn_range(vma, vma->vm_start, + (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) +diff -ur linux-2.6.11/drivers/char/drm/i810_dma.c linux-2.6.11-io/drivers/char/drm/i810_dma.c +--- linux-2.6.11/drivers/char/drm/i810_dma.c 2005-03-02 07:37:55.000000000 +0000 ++++ linux-2.6.11-io/drivers/char/drm/i810_dma.c 2005-03-15 17:53:36.000000000 +0000 +@@ -139,7 +139,7 @@ + buf_priv->currently_mapped = I810_BUF_MAPPED; + unlock_kernel(); + +- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, ++ if (io_remap_pfn_range(vma, vma->vm_start, + VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) return -EAGAIN; +diff -ur linux-2.6.11/drivers/char/drm/i830_dma.c linux-2.6.11-io/drivers/char/drm/i830_dma.c +--- linux-2.6.11/drivers/char/drm/i830_dma.c 2005-03-02 07:37:48.000000000 +0000 ++++ linux-2.6.11-io/drivers/char/drm/i830_dma.c 2005-03-15 17:53:46.000000000 +0000 +@@ -157,7 +157,7 @@ + buf_priv->currently_mapped = I830_BUF_MAPPED; + unlock_kernel(); + +- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, ++ if (io_remap_pfn_range(vma, vma->vm_start, + VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) return -EAGAIN; +diff -ur linux-2.6.11/drivers/char/hpet.c linux-2.6.11-io/drivers/char/hpet.c +--- linux-2.6.11/drivers/char/hpet.c 2005-03-02 07:38:10.000000000 +0000 ++++ linux-2.6.11-io/drivers/char/hpet.c 2005-03-15 17:37:22.000000000 +0000 +@@ -76,6 +76,7 @@ + struct hpets { + struct hpets *hp_next; + struct hpet __iomem *hp_hpet; ++ unsigned long hp_hpet_phys; + struct time_interpolator *hp_interpolator; + unsigned long hp_period; + unsigned long hp_delta; +@@ -265,7 +266,7 @@ + return -EINVAL; + + devp = file->private_data; +- addr = (unsigned long)devp->hd_hpet; ++ addr = devp->hd_hpets->hp_hpet_phys; + + if (addr & (PAGE_SIZE - 1)) + return -ENOSYS; +@@ -274,7 +275,7 @@ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + addr = __pa(addr); + +- if (remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, ++ if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, + PAGE_SIZE, vma->vm_page_prot)) { + printk(KERN_ERR "remap_pfn_range failed in hpet.c\n"); + return -EAGAIN; +@@ -795,6 +796,7 @@ + + hpetp->hp_which = hpet_nhpet++; + hpetp->hp_hpet = hdp->hd_address; ++ hpetp->hp_hpet_phys = hdp->hd_phys_address; + + hpetp->hp_ntimer = hdp->hd_nirqs; + +diff -ur linux-2.6.11/drivers/sbus/char/flash.c linux-2.6.11-io/drivers/sbus/char/flash.c +--- linux-2.6.11/drivers/sbus/char/flash.c 2005-03-02 07:38:10.000000000 +0000 ++++ linux-2.6.11-io/drivers/sbus/char/flash.c 2005-03-15 17:20:22.000000000 +0000 +@@ -75,7 +75,7 @@ + pgprot_val(vma->vm_page_prot) |= _PAGE_E; + vma->vm_flags |= (VM_SHM | VM_LOCKED); + +- if (remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) ++ if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +diff -ur linux-2.6.11/include/linux/mm.h linux-2.6.11-io/include/linux/mm.h +--- linux-2.6.11/include/linux/mm.h 2005-03-02 07:37:47.000000000 +0000 ++++ linux-2.6.11-io/include/linux/mm.h 2005-03-15 17:03:46.000000000 +0000 +@@ -815,6 +815,10 @@ + extern int check_user_page_readable(struct mm_struct *mm, unsigned long address); + int remap_pfn_range(struct vm_area_struct *, unsigned long, + unsigned long, unsigned long, pgprot_t); ++/* Allow arch override for mapping of device and I/O (non-RAM) pages. */ ++#ifndef io_remap_pfn_range ++#define io_remap_pfn_range remap_pfn_range ++#endif + + #ifdef CONFIG_PROC_FS + void __vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); From d5e030e698c55a3f358ef09fde39657ded1ead53 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 16 Mar 2005 09:46:54 +0000 Subject: [PATCH 155/199] bitkeeper revision 1.1159.258.58 (4238008ex_KSQqR2a5fd8soijqba4g) If a Linux guest is allocated more memory than it can use (due to highmem constraints) it will now give that RAM back to Xen. Signed-off-by: Keir Fraser --- .../arch/xen/kernel/setup.c | 28 +++++++++++++++---- .../arch/xen/i386/kernel/setup.c | 25 ++++++++++++----- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c index 46507fbd93..50fc7c1b13 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c +++ b/linux-2.4.29-xen-sparse/arch/xen/kernel/setup.c @@ -377,15 +377,31 @@ void __init setup_arch(char **cmdline_p) paging_init(); - /* Make sure we have a large enough P->M table. */ - if ( max_pfn > xen_start_info.nr_pages ) + /* Make sure we have a correctly sized P->M table. */ + if ( max_pfn != xen_start_info.nr_pages ) { phys_to_machine_mapping = alloc_bootmem_low_pages( max_pfn * sizeof(unsigned long)); - memset(phys_to_machine_mapping, ~0, max_pfn * sizeof(unsigned long)); - memcpy(phys_to_machine_mapping, - (unsigned long *)xen_start_info.mfn_list, - xen_start_info.nr_pages * sizeof(unsigned long)); + if ( max_pfn > xen_start_info.nr_pages ) + { + memset(phys_to_machine_mapping, ~0, + max_pfn * sizeof(unsigned long)); + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info.mfn_list, + xen_start_info.nr_pages * sizeof(unsigned long)); + } + else + { + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info.mfn_list, + max_pfn * sizeof(unsigned long)); + if (HYPERVISOR_dom_mem_op( + MEMOP_decrease_reservation, + (unsigned long *)xen_start_info.mfn_list + max_pfn, + xen_start_info.nr_pages - max_pfn, 0) != + (xen_start_info.nr_pages - max_pfn)) + BUG(); + } free_bootmem(__pa(xen_start_info.mfn_list), PFN_PHYS(PFN_UP(xen_start_info.nr_pages * sizeof(unsigned long)))); diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c index 9b892b04ba..8551fad5a7 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1491,15 +1491,26 @@ void __init setup_arch(char **cmdline_p) #endif paging_init(); - /* Make sure we have a large enough P->M table. */ - if (max_pfn > xen_start_info.nr_pages) { + /* Make sure we have a correctly sized P->M table. */ + if (max_pfn != xen_start_info.nr_pages) { phys_to_machine_mapping = alloc_bootmem_low_pages( max_pfn * sizeof(unsigned long)); - memset(phys_to_machine_mapping, ~0, - max_pfn * sizeof(unsigned long)); - memcpy(phys_to_machine_mapping, - (unsigned long *)xen_start_info.mfn_list, - xen_start_info.nr_pages * sizeof(unsigned long)); + if (max_pfn > xen_start_info.nr_pages) { + memset(phys_to_machine_mapping, ~0, + max_pfn * sizeof(unsigned long)); + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info.mfn_list, + xen_start_info.nr_pages * sizeof(unsigned long)); + } else { + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info.mfn_list, + max_pfn * sizeof(unsigned long)); + if (HYPERVISOR_dom_mem_op( + MEMOP_decrease_reservation, + (unsigned long *)xen_start_info.mfn_list + max_pfn, + xen_start_info.nr_pages - max_pfn, 0) != + (xen_start_info.nr_pages - max_pfn)) BUG(); + } free_bootmem( __pa(xen_start_info.mfn_list), PFN_PHYS(PFN_UP(xen_start_info.nr_pages * From afedb1e48fe477fb8ae2e13387f5a467fd912884 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Wed, 16 Mar 2005 16:48:49 +0000 Subject: [PATCH 156/199] bitkeeper revision 1.1159.269.5 (42386371nvHctvk3SHgDUG4w3o9URw) Add support for specifying the interface name to be used by a netif backend driver instead of the default vifD.N. Signed-off-by: Mike Wray --- .../drivers/xen/netback/interface.c | 8 ++++-- tools/python/xen/lowlevel/xu/xu.c | 26 +++++++++++++++++++ tools/python/xen/xend/server/netif.py | 16 +++++++++--- tools/python/xen/xm/create.py | 10 +++++-- xen/include/public/io/domain_controller.h | 5 ++-- 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c index 9a3eea5932..f54dd0ad9c 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/interface.c @@ -119,9 +119,13 @@ void netif_create(netif_be_create_t *create) unsigned int handle = create->netif_handle; struct net_device *dev; netif_t **pnetif, *netif; - char name[IFNAMSIZ]; + char name[IFNAMSIZ] = {}; - snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); + if(create->vifname[0] == '\0'){ + snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); + } else { + snprintf(name, IFNAMSIZ - 1, "%s", create->vifname); + } dev = alloc_netdev(sizeof(netif_t), name, ether_setup); if ( dev == NULL ) { diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index 9a67693683..3f32cadc34 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -259,6 +259,7 @@ static PyTypeObject xu_notifier_type = { */ #define TYPE(_x,_y) (((_x)<<8)|(_y)) + #define P2C(_struct, _field, _ctype) \ do { \ PyObject *obj; \ @@ -279,6 +280,29 @@ static PyTypeObject xu_notifier_type = { } \ xum->msg.length = sizeof(_struct); \ } while ( 0 ) + +/** Set a char[] field in a struct from a Python string. + * Can't do this in P2C because of the typing. + */ +#define P2CSTRING(_struct, _field) \ + do { \ + PyObject *obj; \ + if ( (obj = PyDict_GetItemString(payload, #_field)) != NULL ) \ + { \ + if ( PyString_Check(obj) ) \ + { \ + _struct * _cobj = (_struct *)&xum->msg.msg[0]; \ + int _field_n = sizeof(_cobj->_field); \ + memset(_cobj->_field, 0, _field_n); \ + strncpy(_cobj->_field, \ + PyString_AsString(obj), \ + _field_n - 1); \ + dict_items_parsed++; \ + } \ + } \ + xum->msg.length = sizeof(_struct); \ + } while ( 0 ) + #define C2P(_struct, _field, _pytype, _ctype) \ do { \ PyObject *obj = Py ## _pytype ## _From ## _ctype \ @@ -456,6 +480,7 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) C2P(netif_be_create_t, domid, Int, Long); C2P(netif_be_create_t, netif_handle, Int, Long); C2P(netif_be_create_t, status, Int, Long); + C2P(netif_be_create_t, vifname, String, String); return dict; case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): C2P(netif_be_destroy_t, domid, Int, Long); @@ -623,6 +648,7 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args) P2C(netif_be_create_t, mac[3], u8); P2C(netif_be_create_t, mac[4], u8); P2C(netif_be_create_t, mac[5], u8); + P2CSTRING(netif_be_create_t, vifname); break; case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): P2C(netif_be_destroy_t, domid, u32); diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 753ae29972..5afb3df388 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -130,7 +130,13 @@ class NetDev(controller.SplitDev): self.bridge = None self.script = None self.ipaddr = [] + self.vifname = None + self.vifname = sxp.child_value(config, 'vifname') + if self.vifname is None: + self.vifname = "vif%d.%d" % (self.controller.dom, self.vif) + if len(self.vifname) > 15: + raise XendError('invalid vifname: too long: ' + self.vifname) mac = self._get_config_mac(config) if mac is None: raise XendError("invalid mac") @@ -189,7 +195,9 @@ class NetDev(controller.SplitDev): val = ['vif', ['idx', self.idx], ['vif', vif], - ['mac', mac]] + ['mac', mac], + ['vifname', self.vifname], + ] if self.bridge: val.append(['bridge', self.bridge]) if self.script: @@ -207,7 +215,7 @@ class NetDev(controller.SplitDev): def get_vifname(self): """Get the virtual interface device name. """ - return "vif%d.%d" % (self.controller.dom, self.vif) + return self.vifname def get_mac(self): """Get the MAC address as a string. @@ -267,7 +275,9 @@ class NetDev(controller.SplitDev): msg = packMsg('netif_be_create_t', { 'domid' : self.controller.dom, 'netif_handle' : self.vif, - 'mac' : self.mac }) + 'mac' : self.mac, + 'vifname' : self.vifname + }) self.getBackendInterface().writeRequest(msg, response=d) return d diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 03f815eddb..ae023e49f5 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -151,7 +151,7 @@ gopts.var('ipaddr', val="IPADDR", fn=append_value, default=[], use="Add an IP address to the domain.") -gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM", +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM,vifname=NAME", fn=append_value, default=[], use="""Add a network interface with the given MAC address and bridge. The vif is configured by calling the given configuration script. @@ -159,6 +159,8 @@ gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT,backend=DOM", If bridge is not specified the default bridge is used. If script is not specified the default script is used. If backend is not specified the default backend driver domain is used. + If vifname is not specified the backend virtual interface will have name vifD.N + where D is the domain id and N is the interface id. This option may be repeated to add more than one vif. Specifying vifs will increase the number of interfaces as needed.""") @@ -289,14 +291,18 @@ def configure_vifs(config_devs, vals): script = d.get('script') backend = d.get('backend') ip = d.get('ip') + vifname = d.get('vifname') else: mac = randomMAC() bridge = None script = None backend = None ip = None + vifname = None config_vif = ['vif'] config_vif.append(['mac', mac]) + if vifname: + config_vif.append(['vifname', vifname]) if bridge: config_vif.append(['bridge', bridge]) if script: @@ -383,7 +389,7 @@ def preprocess_vifs(opts, vals): (k, v) = b.strip().split('=', 1) k = k.strip() v = v.strip() - if k not in ['mac', 'bridge', 'script', 'backend', 'ip']: + if k not in ['mac', 'bridge', 'script', 'backend', 'ip', 'vifname']: opts.err('Invalid vif specifier: ' + vif) d[k] = v vifs.append(d) diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index 61ba2d3776..c706ab016e 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -477,9 +477,10 @@ typedef struct { u32 netif_handle; /* 4: Domain-specific interface handle. */ u8 mac[6]; /* 8 */ u16 __pad1; /* 14 */ + char vifname[16]; /* 16 */ /* OUT */ - u32 status; /* 16 */ -} PACKED netif_be_create_t; /* 20 bytes */ + u32 status; /* 32 */ +} PACKED netif_be_create_t; /* 36 bytes */ /* * CMSG_NETIF_BE_DESTROY: From 717339dbb2aafc7ac83ec7664019673930145528 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 17 Mar 2005 16:28:34 +0000 Subject: [PATCH 157/199] bitkeeper revision 1.1159.269.6 (4239b032OtoMBkr4L88BtgvDYgxbLg) Add support in 'xm create' for spawning a vncviewer. Signed-off-by: Mike Wray --- tools/python/xen/xm/create.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index ae023e49f5..5d45732dff 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -5,6 +5,7 @@ import random import string import sys +import socket from xen.xend import sxp from xen.xend import PrettyPrint @@ -81,6 +82,13 @@ gopts.opt('console_autoconnect', short='c', fn=set_true, default=0, use="Connect to the console after the domain is created.") +gopts.opt('vnc', val='DISPLAY', + fn=set_int, default=None, + use="""Spawn a vncviewer listening for a vnc server in the domain. + The address of the vncviewer is passed to the domain on the kernel command + line using 'VNC_SERVER=:'. The port used by vnc is 5500 + DISPLAY. + """) + gopts.var('name', val='NAME', fn=set_value, default=None, use="Domain name. Must be unique.") @@ -415,6 +423,27 @@ def preprocess_nfs(opts, vals): opts.err('Must set nfs root and nfs server') nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root vals.extra = nfs + ' ' + vals.extra + + +def get_host_addr(): + host = socket.gethostname() + addr = socket.gethostbyname(host) + return addr + +def spawn_vnc(display): + os.system("vncviewer -listen %d &" % display) + return 5500 + display + +def preprocess_vnc(opts, vals): + """If vnc was specified, spawn a vncviewer in listen mode + and pass its address to the domain on the kernel command line. + """ + if vals.vnc is None: return + vnc_host = get_host_addr() + vnc_port = spawn_vnc(vals.vnc) + if vnc_port > 0: + vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port) + vals.extra = vnc + ' ' + vals.extra def preprocess(opts, vals): if not vals.kernel: @@ -424,6 +453,7 @@ def preprocess(opts, vals): preprocess_vifs(opts, vals) preprocess_ip(opts, vals) preprocess_nfs(opts, vals) + preprocess_vnc(opts, vals) def make_domain(opts, config): """Create, build and start a domain. From 4e8d6c72d0e111405a3b865b76c9b334fb78576f Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 17 Mar 2005 16:29:49 +0000 Subject: [PATCH 158/199] bitkeeper revision 1.1159.269.7 (4239b07dqrgbq5nyeaRv54s7lw6AsA) Add sxpr function for installing a new type. Signed-off-by: Mike Wray --- tools/libxutil/sxpr.c | 24 ++++++++++++++++++++++++ tools/libxutil/sxpr.h | 1 + 2 files changed, 25 insertions(+) diff --git a/tools/libxutil/sxpr.c b/tools/libxutil/sxpr.c index 5a9364a317..02a5040b52 100644 --- a/tools/libxutil/sxpr.c +++ b/tools/libxutil/sxpr.c @@ -82,6 +82,30 @@ static SxprType types[1024] = { /** Number of entries in the types array. */ static int type_sup = sizeof(types)/sizeof(types[0]); +/** Define a type. + * The tydef must have a non-zero type code. + * It is an error if the type code is out of range or already defined. + * + * @param tydef type definition + * @return 0 on success, error code otherwise + */ +int def_sxpr_type(SxprType *tydef){ + int err = 0; + int ty = tydef->type; + if(ty < 0 || ty >= type_sup){ + err = -EINVAL; + goto exit; + } + if(types[ty].type){ + err = -EEXIST; + goto exit; + } + types[ty] = *tydef; + exit: + return err; + +} + /** Get the type definition for a given type code. * * @param ty type code diff --git a/tools/libxutil/sxpr.h b/tools/libxutil/sxpr.h index 8b01e84736..761b8b2da7 100644 --- a/tools/libxutil/sxpr.h +++ b/tools/libxutil/sxpr.h @@ -307,6 +307,7 @@ typedef struct SxprType { } SxprType; +extern int def_sxpr_type(SxprType *tydef); extern SxprType *get_sxpr_type(int ty); /** Free the pointer in an sxpr. From 9b82bd2d0ca05323db7b1897adbe520f5a154910 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 18 Mar 2005 09:05:06 +0000 Subject: [PATCH 159/199] bitkeeper revision 1.1159.258.59 (423a99c28LSWeyvb5zB2Je7BjDgLww) Fix install script to follow symlinks. Signed-off-by: Paul Larson Signed-off-by: Keir Fraser --- install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 491e5ab56f..a8ab96134c 100755 --- a/install.sh +++ b/install.sh @@ -32,9 +32,7 @@ do [ -e "$l" ] && ln -fs "$l" vmlinuz${v}-xenU done cd - -cp -fdR $src/* $dst -# hack to fixup the case that init.d is a symlink -cp -fdR $src/etc/init.d/* $dst/etc/init.d/ +cp -fdRL $src/* $dst echo "All done." echo "Checking to see whether prerequisite tools are installed..." From 81ec3e431241fc6d50046d27bdf029057621095b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 18 Mar 2005 09:18:26 +0000 Subject: [PATCH 160/199] bitkeeper revision 1.1159.258.60 (423a9ce2eJtKIkEGHQPPRXvkPvoHqQ) Check kmalloc return value in vbd code. Signed-off-by: Keir Fraser --- .../drivers/xen/blkfront/vbd.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c index 95f2bd4b3b..f9265e74ec 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c @@ -496,21 +496,16 @@ int xlvbd_init(void) { int i; - /* - * If compiled as a module, we don't support unloading yet. We - * therefore permanently increment the reference count to - * disallow it. - */ - /* MOD_INC_USE_COUNT; */ - memset(major_info, 0, sizeof(major_info)); - for (i = 0; i < sizeof(major_info) / sizeof(major_info[0]); i++) { + vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); + if (vbd_info == NULL) { + printk(KERN_ALERT "Failed to allocate memory for disk info.\n"); + nr_vbds = 0; + return 0; } - vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); nr_vbds = xlvbd_get_vbd_info(vbd_info); - if (nr_vbds < 0) { kfree(vbd_info); vbd_info = NULL; From 7b14405f61f000ad5d331a3dd480ee9d074762a9 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 18 Mar 2005 10:52:26 +0000 Subject: [PATCH 161/199] bitkeeper revision 1.1159.269.8 (423ab2eapL4QIhT8q2gPBPlVaSKmZw) Script and xdm config to connect vnc in a domain back to a viewer running in domain-0. Signed-off-by: Mike Wray --- .rootkeys | 2 ++ tools/examples/vnc/Xservers | 5 ++++ tools/examples/vnc/Xvnc-xen | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 tools/examples/vnc/Xservers create mode 100755 tools/examples/vnc/Xvnc-xen diff --git a/.rootkeys b/.rootkeys index f5baebe00f..e685054407 100644 --- a/.rootkeys +++ b/.rootkeys @@ -323,6 +323,8 @@ 40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge 41fc0c18AFAVXA1uGm1JFWHMeeznVw tools/examples/vif-nat 41e661e1ooiRKlOfwumG6wwzc0PdhQ tools/examples/vif-route +423ab2eaNCzxk3c-9yU1BwzxWvsDCQ tools/examples/vnc/Xservers +423ab2ea7ajZLdZOI-8Z-bpNdNhhAQ tools/examples/vnc/Xvnc-xen 40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp 41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1 40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2 diff --git a/tools/examples/vnc/Xservers b/tools/examples/vnc/Xservers new file mode 100644 index 0000000000..adc5748be6 --- /dev/null +++ b/tools/examples/vnc/Xservers @@ -0,0 +1,5 @@ +# Configuration lines to go in /etc/X11/xdm/Xservers to +# start Xvnc and connect back to a vncviewer in domain-0. +# See 'man xdm' under 'LOCAL SERVER SPECIFICATION' for format details. + +:1 Xvnc local /usr/X11R6/bin/Xvnc-xen :1 \ No newline at end of file diff --git a/tools/examples/vnc/Xvnc-xen b/tools/examples/vnc/Xvnc-xen new file mode 100755 index 0000000000..15058e622d --- /dev/null +++ b/tools/examples/vnc/Xvnc-xen @@ -0,0 +1,53 @@ +#!/bin/bash +#============================================================================ +# This script should be installed in /usr/X11R6/bin/Xvnc-xen. +#============================================================================ +# +# Start Xvnc and use vncconnect to connect back to a vncviewer listening in +# domain 0. The host and port to connect to are given by +# +# VNC_VIEWER=: +# +# in the kernel command line (/proc/cmdline). +# +# The '--vnc' option to 'xm create' will start a vncviewer and +# pass its address in VNC_VIEWER for this script to find. +# +# Usage: +# Xvnc-xen [args] +# +# Any arguments are passed to Xvnc. +# +#============================================================================ + +# Prefix for messages. +M="[$(basename $0)]" + +# Usage: vnc_addr +# Print : for the vncviewer given in +# the kernel command line. +vnc_addr () { + sed -n -e "s/.*VNC_VIEWER=\([^ ]*\).*/\1/p" /proc/cmdline +} + +# Usage: vnc_connect +# If a vncviewer address was given on the kernel command line, +# run vncconnect for it. +vnc_connect () { + local addr=$(vnc_addr) + + if [ -n "${addr}" ] ; then + echo "$M Connecting to ${addr}." + vncconnect ${addr} + else + echo "$M No VNC_VIEWER in kernel command line." + echo "$M Create the domain with 'xm create --vnc '." + return 1 + fi +} + +# Start the vnc server. +Xvnc "$@" >/dev/null 2>&1 & + +# Connect back to the viewer in domain-0. +vnc_connect From 3364477517768289e0cf215284ea93e269f65e74 Mon Sep 17 00:00:00 2001 From: "iap10@tetris.cl.cam.ac.uk" Date: Fri, 18 Mar 2005 13:02:40 +0000 Subject: [PATCH 162/199] bitkeeper revision 1.1159.271.1 (423ad1703X6TrdeKiTr87K5NCQAiGw) trivial comment fix Signed-off-by: ian.pratt@cl.cam.ac.uk --- linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c index 9b892b04ba..23570f6765 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1495,6 +1495,7 @@ void __init setup_arch(char **cmdline_p) if (max_pfn > xen_start_info.nr_pages) { phys_to_machine_mapping = alloc_bootmem_low_pages( max_pfn * sizeof(unsigned long)); + /* set to IVALID_P2M_ENTRY */ memset(phys_to_machine_mapping, ~0, max_pfn * sizeof(unsigned long)); memcpy(phys_to_machine_mapping, From 819309d880dd461d6a9a07605be04b9fb83a8e23 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 19 Mar 2005 20:30:54 +0000 Subject: [PATCH 163/199] bitkeeper revision 1.1159.273.1 (423c8bfeCXSFg6Xv58QRFeh4HYLpOQ) Add MMC and Infiniband devices to XenLinux driver configuration options. Signed-off-by: Keir Fraser --- linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers | 2 ++ .../arch/xen/configs/xen0_defconfig | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers b/linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers index 93db5f9df6..8158f26fd0 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers +++ b/linux-2.6.11-xen-sparse/arch/xen/Kconfig.drivers @@ -44,6 +44,8 @@ source "drivers/media/Kconfig" source "drivers/video/Kconfig" source "sound/Kconfig" source "drivers/usb/Kconfig" +source "drivers/mmc/Kconfig" +source "drivers/infiniband/Kconfig" endif if !XEN_PHYSDEV_ACCESS diff --git a/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig index 2cd0df6262..cdfb09fecf 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig +++ b/linux-2.6.11-xen-sparse/arch/xen/configs/xen0_defconfig @@ -887,6 +887,16 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # CONFIG_USB_GADGET is not set +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + # # File systems # From 9c42b63dd5cdf5ce916b1d741e312cd65e0e157d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 19 Mar 2005 20:36:50 +0000 Subject: [PATCH 164/199] bitkeeper revision 1.1159.273.2 (423c8d62e3tPnc05kdzopOE3xfcNiA) Allow domain0 to see PCI bridges. It should be able to deal with seeing PCI buses twice (once as a 'root bridge' from Xen; once by scanning behind a PCI-PCI bridge itself), and this gets rid of problems where the bridge needs to be seen by XenLinux for drivers to work (e.g., Mellanox Infiniband chipsets). Signed-off-by: Keir Fraser --- xen/common/physdev.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/xen/common/physdev.c b/xen/common/physdev.c index 516479c0b8..ff79c72b28 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -733,22 +733,6 @@ void physdev_init_dom0(struct domain *p) continue; } - /* Skip bridges and other peculiarities for now. - * - * Note that this can prevent the guest from detecting devices - * with fn>0 on slots where the fn=0 device is a bridge. We - * can identify such slots by looking at the multifunction bit - * (top bit of hdr_type, masked out in dev->hdr_type). - * - * In Linux2.4 we find all devices because the detection code - * scans all functions if the read of the fn=0 device's header - * type fails. - * - * In Linux2.6 we set pcibios_scan_all_fns(). - */ - if ( (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) && - (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) ) - continue; pdev = xmalloc(sizeof(phys_dev_t)); pdev->dev = dev; pdev->flags = ACC_WRITE; From 646fdfea886ddda6fbe80503605812e2af54bfc8 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 20 Mar 2005 09:40:05 +0000 Subject: [PATCH 165/199] bitkeeper revision 1.1159.273.3 (423d44f5mg2mqgtSGUZfZFYsYmHuMA) Primary floppy controller is at port 0x3f0, not 0x340. Signed-off-by: Keir Fraser --- linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h index aaa4747b58..ff838f21fb 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h @@ -186,7 +186,7 @@ static int xen_floppy_init(void) { use_virtual_dma = 1; can_use_virtual_dma = 1; - return 0x340; + return 0x3f0; } /* From d73b5730fbb7f3d0fd7fcd9a9b6e36d71d33ade0 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Mon, 21 Mar 2005 07:58:08 +0000 Subject: [PATCH 166/199] bitkeeper revision 1.1159.272.3 (423e7e90uxPqdRoA4EvOUikif-yhXA) Check-in of the sparse tree for FreeBSD 5.3 (version 050317) This currently supports running as a domU. - to create freebsd-5.3-xenU run fbsdxensetup from anywhere in the tree - once created go to freebsd-5.3-xenU on a FreeBSD 5.3 machine, run xenfbsd_kernel_build - you'll find kernel and kernel.debug under i386-xen/compile/XENCONF See http://www.fsmware.com/xenofreebsd/5.3/xenbsdsetup.txt Thanks to NetApp for their contributions in support of the FreeBSD port to Xen . Signed-off-by: Kip Macy ${.TARGET}" \ + no-obj no-implicit-rule before-depend \ + clean "linux_assym.h" +# +svr4_genassym.o optional compat_svr4 \ + dependency "$S/i386/svr4/svr4_genassym.c" \ + compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ + no-obj no-implicit-rule \ + clean "svr4_genassym.o" +# +svr4_assym.h optional compat_svr4 \ + dependency "$S/kern/genassym.sh svr4_genassym.o" \ + compile-with "sh $S/kern/genassym.sh svr4_genassym.o > ${.TARGET}" \ + no-obj no-implicit-rule before-depend \ + clean "svr4_assym.h" +# +font.h optional sc_dflt_font \ + compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ + no-obj no-implicit-rule before-depend \ + clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" +# +atkbdmap.h optional atkbd_dflt_keymap \ + compile-with "/usr/sbin/kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ + no-obj no-implicit-rule before-depend \ + clean "atkbdmap.h" +# +ukbdmap.h optional ukbd_dflt_keymap \ + compile-with "/usr/sbin/kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ + no-obj no-implicit-rule before-depend \ + clean "ukbdmap.h" +# +msysosak.o optional fla \ + dependency "$S/contrib/dev/fla/i386/msysosak.o.uu" \ + compile-with "uudecode < $S/contrib/dev/fla/i386/msysosak.o.uu" \ + no-implicit-rule +# +trlld.o optional oltr \ + dependency "$S/contrib/dev/oltr/i386-elf.trlld.o.uu" \ + compile-with "uudecode < $S/contrib/dev/oltr/i386-elf.trlld.o.uu" \ + no-implicit-rule +# +hal.o optional ath_hal \ + dependency "$S/contrib/dev/ath/freebsd/i386-elf.hal.o.uu" \ + compile-with "uudecode < $S/contrib/dev/ath/freebsd/i386-elf.hal.o.uu" \ + no-implicit-rule +# +# +compat/linux/linux_file.c optional compat_linux +compat/linux/linux_getcwd.c optional compat_linux +compat/linux/linux_ioctl.c optional compat_linux +compat/linux/linux_ipc.c optional compat_linux +compat/linux/linux_mib.c optional compat_linux +compat/linux/linux_misc.c optional compat_linux +compat/linux/linux_signal.c optional compat_linux +compat/linux/linux_socket.c optional compat_linux +compat/linux/linux_stats.c optional compat_linux +compat/linux/linux_sysctl.c optional compat_linux +compat/linux/linux_uid16.c optional compat_linux +compat/linux/linux_util.c optional compat_linux +compat/pecoff/imgact_pecoff.c optional pecoff_support +compat/svr4/imgact_svr4.c optional compat_svr4 +compat/svr4/svr4_fcntl.c optional compat_svr4 +compat/svr4/svr4_filio.c optional compat_svr4 +compat/svr4/svr4_ioctl.c optional compat_svr4 +compat/svr4/svr4_ipc.c optional compat_svr4 +compat/svr4/svr4_misc.c optional compat_svr4 +compat/svr4/svr4_resource.c optional compat_svr4 +compat/svr4/svr4_signal.c optional compat_svr4 +compat/svr4/svr4_socket.c optional compat_svr4 +compat/svr4/svr4_sockio.c optional compat_svr4 +compat/svr4/svr4_stat.c optional compat_svr4 +compat/svr4/svr4_stream.c optional compat_svr4 +compat/svr4/svr4_syscallnames.c optional compat_svr4 +compat/svr4/svr4_sysent.c optional compat_svr4 +compat/svr4/svr4_sysvec.c optional compat_svr4 +compat/svr4/svr4_termios.c optional compat_svr4 +compat/svr4/svr4_ttold.c optional compat_svr4 +contrib/dev/fla/fla.c optional fla +contrib/dev/oltr/if_oltr.c optional oltr +contrib/dev/oltr/trlldbm.c optional oltr +contrib/dev/oltr/trlldhm.c optional oltr +contrib/dev/oltr/trlldmac.c optional oltr +bf_enc.o optional ipsec ipsec_esp \ + dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ + compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ + no-implicit-rule +crypto/des/arch/i386/des_enc.S optional ipsec ipsec_esp +crypto/des/des_ecb.c optional netsmbcrypto +crypto/des/arch/i386/des_enc.S optional netsmbcrypto +crypto/des/des_setkey.c optional netsmbcrypto +bf_enc.o optional crypto \ + dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ + compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ + no-implicit-rule +crypto/des/arch/i386/des_enc.S optional crypto +crypto/des/des_ecb.c optional crypto +crypto/des/des_setkey.c optional crypto +dev/ar/if_ar.c optional ar +dev/ar/if_ar_pci.c optional ar pci +dev/cx/csigma.c optional cx +dev/cx/cxddk.c optional cx +dev/cx/if_cx.c optional cx +dev/dgb/dgb.c count dgb +dev/fb/fb.c optional fb +dev/fb/fb.c optional vga +dev/fb/splash.c optional splash +dev/fb/vga.c optional vga +dev/kbd/atkbd.c optional atkbd +dev/kbd/atkbdc.c optional atkbdc +dev/kbd/kbd.c optional atkbd +dev/kbd/kbd.c optional kbd +dev/kbd/kbd.c optional sc +dev/kbd/kbd.c optional ukbd +dev/kbd/kbd.c optional vt +dev/mem/memutil.c standard +dev/random/nehemiah.c standard +dev/ppc/ppc.c optional ppc +dev/ppc/ppc_puc.c optional ppc puc pci +dev/sio/sio.c optional sio +dev/sio/sio_isa.c optional sio isa +dev/syscons/schistory.c optional sc +dev/syscons/scmouse.c optional sc +dev/syscons/scterm.c optional sc +dev/syscons/scterm-dumb.c optional sc +dev/syscons/scterm-sc.c optional sc +dev/syscons/scvesactl.c optional sc vga vesa +dev/syscons/scvgarndr.c optional sc vga +dev/syscons/scvidctl.c optional sc +dev/syscons/scvtb.c optional sc +dev/syscons/syscons.c optional sc +dev/syscons/sysmouse.c optional sc +dev/uart/uart_cpu_i386.c optional uart +geom/geom_bsd.c standard +geom/geom_bsd_enc.c standard +geom/geom_mbr.c standard +geom/geom_mbr_enc.c standard +i386/acpica/OsdEnvironment.c optional acpi +i386/acpica/acpi_machdep.c optional acpi +i386/acpica/acpi_wakeup.c optional acpi +acpi_wakecode.h optional acpi \ + dependency "$S/i386/acpica/acpi_wakecode.S" \ + compile-with "${MAKE} -f $S/i386/acpica/Makefile MAKESRCPATH=$S/i386/acpica" \ + no-obj no-implicit-rule before-depend \ + clean "acpi_wakecode.h acpi_wakecode.o acpi_wakecode.bin" +# +i386/acpica/madt.c optional acpi apic +i386/bios/mca_machdep.c optional mca +i386/bios/smapi.c optional smapi +i386/bios/smapi_bios.S optional smapi +i386/bios/smbios.c optional smbios +i386/bios/vpd.c optional vpd +i386/i386/apic_vector.s optional apic +i386/i386/atomic.c standard \ + compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}" +i386/i386/autoconf.c standard +i386/i386/busdma_machdep.c standard +i386-xen/i386-xen/critical.c standard +i386/i386/db_disasm.c optional ddb +i386-xen/i386-xen/db_interface.c optional ddb +i386/i386/db_trace.c optional ddb +i386/i386/i386-gdbstub.c optional ddb +i386/i386/dump_machdep.c standard +i386/i386/elf_machdep.c standard +i386-xen/i386-xen/exception.s standard +i386-xen/i386-xen/i686_mem.c standard +i386/i386/identcpu.c standard +i386/i386/in_cksum.c optional inet +i386-xen/i386-xen/initcpu.c standard +i386-xen/i386-xen/intr_machdep.c standard +i386-xen/i386-xen/io_apic.c optional apic +i386/i386/legacy.c standard +i386-xen/i386-xen/locore.s standard no-obj +i386-xen/i386-xen/machdep.c standard +i386/i386/mem.c standard +i386-xen/i386-xen/mp_clock.c optional smp +i386-xen/i386-xen/mp_machdep.c optional smp +i386/i386/mpboot.s optional smp +i386-xen/i386-xen/mptable.c optional apic +i386-xen/i386-xen/local_apic.c optional apic +i386/i386/mptable_pci.c optional apic pci +i386/i386/nexus.c standard +i386/i386/uio_machdep.c standard +i386/i386/perfmon.c optional perfmon +i386/i386/perfmon.c optional perfmon profiling-routine +i386-xen/i386-xen/pmap.c standard +i386-xen/i386-xen/support.s standard +i386-xen/i386-xen/swtch.s standard +i386-xen/i386-xen/sys_machdep.c standard +i386-xen/i386-xen/trap.c standard +i386/i386/tsc.c standard +i386-xen/i386-xen/vm_machdep.c standard +i386-xen/i386-xen/clock.c standard + +# xen specific arch-dep files +i386-xen/i386-xen/hypervisor.c standard +i386-xen/i386-xen/xen_machdep.c standard +i386-xen/i386-xen/xen_bus.c standard +i386-xen/i386-xen/evtchn.c standard +i386-xen/i386-xen/ctrl_if.c standard + + +i386/isa/asc.c count asc +i386/isa/ctx.c optional ctx +i386/isa/cy.c count cy +i386/isa/elink.c optional ep +i386/isa/elink.c optional ie +i386/isa/gpib.c optional gp +i386/isa/gsc.c count gsc +i386/isa/istallion.c optional stli nowerror +i386/isa/loran.c optional loran +i386/isa/mse.c optional mse +i386/isa/nmi.c standard + +# drivers +i386-xen/xen/misc/npx.c optional npx +i386-xen/xen/misc/evtchn_dev.c standard +i386-xen/xen/char/console.c standard +i386-xen/xen/netfront/xn_netfront.c standard +i386-xen/xen/blkfront/xb_blkfront.c standard + + + +i386/isa/pcf.c optional pcf +i386/isa/pcvt/pcvt_drv.c optional vt +i386/isa/pcvt/pcvt_ext.c optional vt +i386/isa/pcvt/pcvt_kbd.c optional vt +i386/isa/pcvt/pcvt_out.c optional vt +i386/isa/pcvt/pcvt_sup.c optional vt +i386/isa/pcvt/pcvt_vtf.c optional vt +i386/isa/pmtimer.c optional pmtimer +i386/isa/prof_machdep.c optional profiling-routine +i386/isa/spic.c optional spic +i386/isa/spigot.c count spigot +i386/isa/spkr.c optional speaker +i386/isa/stallion.c optional stl nowerror +i386/isa/vesa.c optional vga vesa +i386/isa/wt.c count wt +i386/linux/imgact_linux.c optional compat_linux +i386/linux/linux_dummy.c optional compat_linux +i386/linux/linux_locore.s optional compat_linux \ + dependency "linux_assym.h" +i386/linux/linux_machdep.c optional compat_linux +i386/linux/linux_ptrace.c optional compat_linux +i386/linux/linux_sysent.c optional compat_linux +i386/linux/linux_sysvec.c optional compat_linux +i386/pci/pci_cfgreg.c optional pci +i386/pci/pci_bus.c optional pci +i386/svr4/svr4_locore.s optional compat_svr4 \ + dependency "svr4_assym.h" \ + warning "COMPAT_SVR4 is broken and should be avoided" +i386/svr4/svr4_machdep.c optional compat_svr4 +isa/atkbd_isa.c optional atkbd +isa/atkbdc_isa.c optional atkbdc +isa/fd.c optional fdc +isa/psm.c optional psm +isa/syscons_isa.c optional sc +isa/vga_isa.c optional vga +kern/imgact_aout.c optional compat_aout +kern/imgact_gzip.c optional gzip +libkern/divdi3.c standard +libkern/moddi3.c standard +libkern/qdivrem.c standard +libkern/ucmpdi2.c standard +libkern/udivdi3.c standard +libkern/umoddi3.c standard +libkern/flsl.c standard +libkern/ffsl.c standard + +pci/cy_pci.c optional cy pci +pci/agp_intel.c optional agp +pci/agp_via.c optional agp +pci/agp_sis.c optional agp +pci/agp_ali.c optional agp +pci/agp_amd.c optional agp +pci/agp_i810.c optional agp +pci/agp_nvidia.c optional agp + diff --git a/freebsd-5.3-xen-sparse/conf/ldscript.i386-xen b/freebsd-5.3-xen-sparse/conf/ldscript.i386-xen new file mode 100644 index 0000000000..65cbc852da --- /dev/null +++ b/freebsd-5.3-xen-sparse/conf/ldscript.i386-xen @@ -0,0 +1,134 @@ +/* $FreeBSD: src/sys/conf/ldscript.i386,v 1.9 2003/12/03 07:40:03 phk Exp $ */ +OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd") +OUTPUT_ARCH(i386) +ENTRY(btext) +SEARCH_DIR(/usr/lib); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = kernbase + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.text : + { *(.rel.text) *(.rel.gnu.linkonce.t*) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rel.data : + { *(.rel.data) *(.rel.gnu.linkonce.d*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rel.rodata : + { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x9090 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0x9090 + _etext = .; + PROVIDE (etext = .); + .fini : { *(.fini) } =0x9090 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(0x1000) + (. & (0x1000 - 1)) ; + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + . = ALIGN(32 / 8); + _start_ctors = .; + PROVIDE (start_ctors = .); + .ctors : + { + *(.ctors) + } + _stop_ctors = .; + PROVIDE (stop_ctors = .); + .dtors : + { + *(.dtors) + } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(32 / 8); + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} diff --git a/freebsd-5.3-xen-sparse/conf/options.i386-xen b/freebsd-5.3-xen-sparse/conf/options.i386-xen new file mode 100644 index 0000000000..6bbc509087 --- /dev/null +++ b/freebsd-5.3-xen-sparse/conf/options.i386-xen @@ -0,0 +1,162 @@ +# $FreeBSD: src/sys/conf/options.i386,v 1.204 2003/12/03 23:06:30 imp Exp $ +# Options specific to the i386 platform kernels + +AUTO_EOI_1 opt_auto_eoi.h +AUTO_EOI_2 opt_auto_eoi.h +BROKEN_KEYBOARD_RESET opt_reset.h +COMPAT_OLDISA +I586_PMC_GUPROF opt_i586_guprof.h +MAXMEM +MPTABLE_FORCE_HTT +NO_MIXED_MODE +PERFMON +DISABLE_PSE opt_pmap.h +DISABLE_PG_G opt_pmap.h +PMAP_SHPGPERPROC opt_pmap.h +PPC_PROBE_CHIPSET opt_ppc.h +PPC_DEBUG opt_ppc.h +POWERFAIL_NMI opt_trap.h +MP_WATCHDOG opt_mp_watchdog.h + + + +# Options for emulators. These should only be used at config time, so +# they are handled like options for static filesystems +# (see src/sys/conf/options), except for broken debugging options. +COMPAT_AOUT opt_dontuse.h +IBCS2 opt_dontuse.h +COMPAT_LINUX opt_dontuse.h +COMPAT_SVR4 opt_dontuse.h +DEBUG_SVR4 opt_svr4.h +PECOFF_SUPPORT opt_dontuse.h +PECOFF_DEBUG opt_pecoff.h + +# Change KVM size. Changes things all over the kernel. +KVA_PAGES opt_global.h +XEN opt_global.h +XENDEV opt_xen.h +NOXENDEBUG opt_xen.h +# Physical address extensions and support for >4G ram. As above. +PAE opt_global.h + +CLK_CALIBRATION_LOOP opt_clock.h +CLK_USE_I8254_CALIBRATION opt_clock.h +CLK_USE_TSC_CALIBRATION opt_clock.h +TIMER_FREQ opt_clock.h + +CPU_ATHLON_SSE_HACK opt_cpu.h +CPU_BLUELIGHTNING_3X opt_cpu.h +CPU_BLUELIGHTNING_FPU_OP_CACHE opt_cpu.h +CPU_BTB_EN opt_cpu.h +CPU_CYRIX_NO_LOCK opt_cpu.h +CPU_DIRECT_MAPPED_CACHE opt_cpu.h +CPU_DISABLE_5X86_LSSER opt_cpu.h +CPU_DISABLE_CMPXCHG opt_global.h # XXX global, unlike other CPU_* +CPU_DISABLE_SSE opt_cpu.h +CPU_ELAN opt_cpu.h +CPU_ELAN_XTAL opt_cpu.h +CPU_ELAN_PPS opt_cpu.h +CPU_ENABLE_SSE opt_cpu.h +CPU_FASTER_5X86_FPU opt_cpu.h +CPU_GEODE opt_cpu.h +CPU_I486_ON_386 opt_cpu.h +CPU_IORT opt_cpu.h +CPU_L2_LATENCY opt_cpu.h +CPU_LOOP_EN opt_cpu.h +CPU_PPRO2CELERON opt_cpu.h +CPU_RSTK_EN opt_cpu.h +CPU_SOEKRIS opt_cpu.h +CPU_SUSP_HLT opt_cpu.h +CPU_UPGRADE_HW_CACHE opt_cpu.h +CPU_WT_ALLOC opt_cpu.h +CYRIX_CACHE_REALLY_WORKS opt_cpu.h +CYRIX_CACHE_WORKS opt_cpu.h +NO_F00F_HACK opt_cpu.h +NO_MEMORY_HOLE opt_cpu.h + +# The CPU type affects the endian conversion functions all over the kernel. +I386_CPU opt_global.h +I486_CPU opt_global.h +I586_CPU opt_global.h +I686_CPU opt_global.h + +VGA_ALT_SEQACCESS opt_vga.h +VGA_DEBUG opt_vga.h +VGA_NO_FONT_LOADING opt_vga.h +VGA_NO_MODE_CHANGE opt_vga.h +VGA_SLOW_IOACCESS opt_vga.h +VGA_WIDTH90 opt_vga.h + +VESA +VESA_DEBUG opt_vesa.h + +PSM_HOOKRESUME opt_psm.h +PSM_RESETAFTERSUSPEND opt_psm.h +PSM_DEBUG opt_psm.h + +ATKBD_DFLT_KEYMAP opt_atkbd.h + +# pcvt(4) has a bunch of options +FAT_CURSOR opt_pcvt.h +XSERVER opt_pcvt.h +PCVT_24LINESDEF opt_pcvt.h +PCVT_CTRL_ALT_DEL opt_pcvt.h +PCVT_META_ESC opt_pcvt.h +PCVT_NSCREENS opt_pcvt.h +PCVT_PRETTYSCRNS opt_pcvt.h +PCVT_SCANSET opt_pcvt.h +PCVT_SCREENSAVER opt_pcvt.h +PCVT_USEKBDSEC opt_pcvt.h +PCVT_VT220KEYB opt_pcvt.h +PCVT_GREENSAVER opt_pcvt.h + +# Video spigot +SPIGOT_UNSECURE opt_spigot.h + +# Enables NETGRAPH support for Cronyx adapters +NETGRAPH_CRONYX opt_ng_cronyx.h + +# ------------------------------- +# isdn4bsd: passive ISA cards +# ------------------------------- +TEL_S0_8 opt_i4b.h +TEL_S0_16 opt_i4b.h +TEL_S0_16_3 opt_i4b.h +AVM_A1 opt_i4b.h +USR_STI opt_i4b.h +ITKIX1 opt_i4b.h +ELSA_PCC16 opt_i4b.h +# ------------------------------- +# isdn4bsd: passive ISA PnP cards +# ------------------------------- +CRTX_S0_P opt_i4b.h +DRN_NGO opt_i4b.h +TEL_S0_16_3_P opt_i4b.h +SEDLBAUER opt_i4b.h +DYNALINK opt_i4b.h +ASUSCOM_IPAC opt_i4b.h +ELSA_QS1ISA opt_i4b.h +SIEMENS_ISURF2 opt_i4b.h +EICON_DIVA opt_i4b.h +COMPAQ_M610 opt_i4b.h +# ------------------------------- +# isdn4bsd: passive PCI cards +# ------------------------------- +ELSA_QS1PCI opt_i4b.h +# ------------------------------- +# isdn4bsd: misc options +# ------------------------------- +# temporary workaround for SMP machines +I4B_SMP_WORKAROUND opt_i4b.h +# enable VJ compression code for ipr i/f +IPR_VJ opt_i4b.h +IPR_LOG opt_i4b.h + +# Device options +DEV_ACPI opt_acpi.h +DEV_APIC opt_apic.h +DEV_NPX opt_npx.h + +# ------------------------------- +# EOF +# ------------------------------- diff --git a/freebsd-5.3-xen-sparse/fbsdxensetup b/freebsd-5.3-xen-sparse/fbsdxensetup new file mode 100644 index 0000000000..3d024c370e --- /dev/null +++ b/freebsd-5.3-xen-sparse/fbsdxensetup @@ -0,0 +1,39 @@ +#!/bin/csh -f + +setenv XENROOT `bk root` +rm -rf $XENROOT/fbsdtmp $XENROOT/freebsd-5.3-xenU +mkdir -p $XENROOT/fbsdtmp +cd $XENROOT/fbsdtmp +echo "step 1" +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.aa +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ab +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ac +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ad +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ae +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.af +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ag +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ah +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ai +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.aj +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.ak +wget ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.3-RELEASE/src/ssys.al +mkdir -p foo +cat ssys.?? | tar --unlink -xpzf - -C foo/ +mkdir -p $XENROOT/freebsd-5.3-xenU +mv foo/sys/* $XENROOT/freebsd-5.3-xenU +cd $XENROOT +rm -rf $XENROOT/fbsdtmp +echo "step 2" +mkdir -p $XENROOT/freebsd-5.3-xenU/i386-xen/include +cd $XENROOT/freebsd-5.3-xenU/i386-xen/include/ +foreach file (../../i386/include/*) + ln -s $file +end +echo "step 3" +cd $XENROOT/freebsd-5.3-xen-sparse +echo "step 4" +./mkbuildtree ../freebsd-5.3-xenU +echo "step 5" +cd $XENROOT/freebsd-5.3-xenU/i386-xen/include +ln -s $XENROOT/xen/include/public xen-public +echo "done" diff --git a/freebsd-5.3-xen-sparse/i386-xen/Makefile b/freebsd-5.3-xen-sparse/i386-xen/Makefile new file mode 100644 index 0000000000..f33c7a5af6 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/Makefile @@ -0,0 +1,40 @@ +# $FreeBSD: src/sys/i386/Makefile,v 1.11 2002/06/21 06:18:02 mckusick Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/11/93 + +# Makefile for i386 links, tags file + +# SYS is normally set in Make.tags.inc +# SYS=/sys +SYS=/nsys + +TAGDIR= i386 + +.include "../kern/Make.tags.inc" + +all: + @echo "make links or tags only" + +# Directories in which to place i386 tags links +DI386= apm i386 ibcs2 include isa linux + +links:: + -for i in ${COMMDIR1}; do \ + (cd $$i && { rm -f tags; ln -s ../${TAGDIR}/tags tags; }) done + -for i in ${COMMDIR2}; do \ + (cd $$i && { rm -f tags; ln -s ../../${TAGDIR}/tags tags; }) done + -for i in ${DI386}; do \ + (cd $$i && { rm -f tags; ln -s ../tags tags; }) done + +SI386= ${SYS}/i386/apm/*.[ch] \ + ${SYS}/i386/i386/*.[ch] ${SYS}/i386/ibcs2/*.[ch] \ + ${SYS}/i386/include/*.[ch] ${SYS}/i386/isa/*.[ch] \ + ${SYS}/i386/linux/*.[ch] +AI386= ${SYS}/i386/i386/*.s + +tags:: + -ctags -wdt ${COMM} ${SI386} + egrep "^ENTRY(.*)|^ALTENTRY(.*)" ${AI386} | \ + sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \ + >> tags + sort -o tags tags + chmod 444 tags diff --git a/freebsd-5.3-xen-sparse/i386-xen/compile/.cvsignore b/freebsd-5.3-xen-sparse/i386-xen/compile/.cvsignore new file mode 100644 index 0000000000..232298edb1 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/compile/.cvsignore @@ -0,0 +1 @@ +[A-Za-z0-9]* diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC b/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC new file mode 100644 index 0000000000..6a70639bda --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC @@ -0,0 +1,273 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/i386 +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD: src/sys/i386/conf/GENERIC,v 1.394.2.3 2004/01/26 19:42:11 nectar Exp $ + +machine i386 +cpu I486_CPU +cpu I586_CPU +cpu I686_CPU +ident GENERIC + +#To statically compile in device wiring instead of /boot/device.hints +#hints "GENERIC.hints" #Default places to look for devices. + +#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +options MD_ROOT #MD is a potential root device +options NFSCLIENT #Network Filesystem Client +options NFSSERVER #Network Filesystem Server +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options MSDOSFS #MSDOS Filesystem +options CD9660 #ISO 9660 Filesystem +options PROCFS #Process filesystem (requires PSEUDOFS) +options PSEUDOFS #Pseudo-filesystem framework +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options COMPAT_FREEBSD4 #Compatible with FreeBSD4 +options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI +options KTRACE #ktrace(1) support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options AHC_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~128k to driver. +options AHD_REG_PRETTY_PRINT # Print register bitfields in debug + # output. Adds ~215k to driver. +options PFIL_HOOKS # pfil(9) framework + +# Debugging for use in -current +#options DDB #Enable the kernel debugger +#options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +# To make an SMP kernel, the next two are needed +options SMP # Symmetric MultiProcessor Kernel +device apic # I/O APIC + +device isa +device eisa +device pci + +# Floppy drives +device fdc + +# ATA and ATAPI devices +device ata +device atadisk # ATA disk drives +device ataraid # ATA RAID drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID #Static device numbering + +# SCSI Controllers +device ahb # EISA AHA1742 family +device ahc # AHA2940 and onboard AIC7xxx devices +device ahd # AHA39320/29320 and onboard AIC79xx devices +device amd # AMD 53C974 (Tekram DC-390(T)) +device isp # Qlogic family +device mpt # LSI-Logic MPT-Fusion +#device ncr # NCR/Symbios Logic +device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') +device trm # Tekram DC395U/UW/F DC315U adapters + +device adv # Advansys SCSI adapters +device adw # Advansys wide SCSI adapters +device aha # Adaptec 154x SCSI adapters +device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60. +device bt # Buslogic/Mylex MultiMaster SCSI adapters + +device ncv # NCR 53C500 +device nsp # Workbit Ninja SCSI-3 +device stg # TMC 18C30/18C50 + +# SCSI peripherals +device scbus # SCSI bus (required for SCSI) +device ch # SCSI media changers +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) +device ses # SCSI Environmental Services (and SAF-TE) + +# RAID controllers interfaced to the SCSI subsystem +device amr # AMI MegaRAID +device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID +device ciss # Compaq Smart RAID 5* +device dpt # DPT Smartcache III, IV - See NOTES for options +device iir # Intel Integrated RAID +device ips # IBM (Adaptec) ServeRAID +device mly # Mylex AcceleRAID/eXtremeRAID + +# RAID controllers +device aac # Adaptec FSA RAID +device aacp # SCSI passthrough for aac (requires CAM) +device ida # Compaq Smart RAID +device mlx # Mylex DAC960 family +device pst # Promise Supertrak SX6000 +device twe # 3ware ATA RAID + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse + +device vga # VGA video card driver + +device splash # Splash screen and screen saver support + +# syscons is the default console driver, resembling an SCO console +device sc + +# Enable this for the pcvt (VT220 compatible) console driver +#device vt +#options XSERVER # support for X server on a vt console +#options FAT_CURSOR # start with block cursor + +device agp # support several AGP chipsets + +# Floating point support - do not disable. +device npx + +# Power management support (see NOTES for more options) +#device apm +# Add suspend/resume support for the i8254. +device pmtimer + +# PCCARD (PCMCIA) support +# Pcmcia and cardbus bridge support +device cbb # cardbus (yenta) bridge +#device pcic # ExCA ISA and PCI bridges +device pccard # PC Card (16-bit) bus +device cardbus # CardBus (32-bit) bus + +# Serial (COM) ports +device sio # 8250, 16[45]50 based serial ports + +# Parallel port +device ppc +device ppbus # Parallel port bus (required) +device lpt # Printer +device plip # TCP/IP over parallel +device ppi # Parallel port interface device +#device vpo # Requires scbus and da + +# If you've got a "dumb" serial or parallel PCI card that is +# supported by the puc(4) glue driver, uncomment the following +# line to enable it (connects to the sio and/or ppc drivers): +#device puc + +# PCI Ethernet NICs. +device de # DEC/Intel DC21x4x (``Tulip'') +device em # Intel PRO/1000 adapter Gigabit Ethernet Card +device txp # 3Com 3cR990 (``Typhoon'') +device vx # 3Com 3c590, 3c595 (``Vortex'') + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support +device bfe # Broadcom BCM440x 10/100 ethernet +device bge # Broadcom BCM570xx Gigabit Ethernet +device dc # DEC/Intel 21143 and various workalikes +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device pcn # AMD Am79C97x PCI 10/100 (precedence over 'lnc') +device re # RealTek 8139C+/8169/8169S/8110S +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device sk # SysKonnect SK-984x and SK-982x gigabit ethernet +device ste # Sundance ST201 (D-Link DFE-550TX) +device ti # Alteon Networks Tigon I/II gigabit ethernet +device tl # Texas Instruments ThunderLAN +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') + +# ISA Ethernet NICs. pccard nics included. +device cs # Crystal Semiconductor CS89x0 NIC +# 'device ed' requires 'device miibus' +device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards +device ex # Intel EtherExpress Pro/10 and Pro/10+ +device ep # Etherlink III based cards +device fe # Fujitsu MB8696x based cards +device ie # EtherExpress 8/16, 3C507, StarLAN 10 etc. +device lnc # NE2100, NE32-VL Lance Ethernet cards +device sn # SMC's 9000 series of ethernet chips +device xe # Xircom pccard ethernet + +# ISA devices that use the old ISA shims +#device le + +# Wireless NIC cards +device wlan # 802.11 support +device an # Aironet 4500/4800 802.11 wireless NICs. +device awi # BayStack 660 and others +device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. +#device wl # Older non 802.11 Wavelan wireless NIC. + +# Pseudo devices - the number indicates how many units to allocate. +device random # Entropy device +device loop # Network loopback +device ether # Ethernet support +device sl # Kernel SLIP +device ppp # Kernel PPP +device tun # Packet tunnel. +device pty # Pseudo-ttys (telnet etc) +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +device bpf # Berkeley packet filter + +# USB support +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +device ugen # Generic +device uhid # "Human Interface Devices" +device ukbd # Keyboard +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ums # Mouse +device urio # Diamond Rio 500 MP3 player +device uscanner # Scanners +# USB Ethernet, requires mii +device aue # ADMtek USB ethernet +device axe # ASIX Electronics USB ethernet +device cue # CATC USB ethernet +device kue # Kawasaki LSI USB ethernet + +# FireWire support +device firewire # FireWire bus code +device sbp # SCSI over FireWire (Requires scbus and da) +device fwe # Ethernet over FireWire (non-standard!) diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC.hints b/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC.hints new file mode 100644 index 0000000000..c02274871b --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/GENERIC.hints @@ -0,0 +1,93 @@ +# $FreeBSD: src/sys/i386/conf/GENERIC.hints,v 1.11 2002/12/05 22:49:47 jhb Exp $ +hint.fdc.0.at="isa" +hint.fdc.0.port="0x3F0" +hint.fdc.0.irq="6" +hint.fdc.0.drq="2" +hint.fd.0.at="fdc0" +hint.fd.0.drive="0" +hint.fd.1.at="fdc0" +hint.fd.1.drive="1" +hint.ata.0.at="isa" +hint.ata.0.port="0x1F0" +hint.ata.0.irq="14" +hint.ata.1.at="isa" +hint.ata.1.port="0x170" +hint.ata.1.irq="15" +hint.adv.0.at="isa" +hint.adv.0.disabled="1" +hint.bt.0.at="isa" +hint.bt.0.disabled="1" +hint.aha.0.at="isa" +hint.aha.0.disabled="1" +hint.aic.0.at="isa" +hint.aic.0.disabled="1" +hint.atkbdc.0.at="isa" +hint.atkbdc.0.port="0x060" +hint.atkbd.0.at="atkbdc" +hint.atkbd.0.irq="1" +hint.atkbd.0.flags="0x1" +hint.psm.0.at="atkbdc" +hint.psm.0.irq="12" +hint.vga.0.at="isa" +hint.sc.0.at="isa" +hint.sc.0.flags="0x100" +hint.vt.0.at="isa" +hint.vt.0.disabled="1" +hint.apm.0.disabled="1" +hint.apm.0.flags="0x20" +hint.pcic.0.at="isa" +# hint.pcic.0.irq="10" # Default to polling +hint.pcic.0.port="0x3e0" +hint.pcic.0.maddr="0xd0000" +hint.pcic.1.at="isa" +hint.pcic.1.irq="11" +hint.pcic.1.port="0x3e2" +hint.pcic.1.maddr="0xd4000" +hint.pcic.1.disabled="1" +hint.sio.0.at="isa" +hint.sio.0.port="0x3F8" +hint.sio.0.flags="0x10" +hint.sio.0.irq="4" +hint.sio.1.at="isa" +hint.sio.1.port="0x2F8" +hint.sio.1.irq="3" +hint.sio.2.at="isa" +hint.sio.2.disabled="1" +hint.sio.2.port="0x3E8" +hint.sio.2.irq="5" +hint.sio.3.at="isa" +hint.sio.3.disabled="1" +hint.sio.3.port="0x2E8" +hint.sio.3.irq="9" +hint.ppc.0.at="isa" +hint.ppc.0.irq="7" +hint.ed.0.at="isa" +hint.ed.0.disabled="1" +hint.ed.0.port="0x280" +hint.ed.0.irq="10" +hint.ed.0.maddr="0xd8000" +hint.cs.0.at="isa" +hint.cs.0.disabled="1" +hint.cs.0.port="0x300" +hint.sn.0.at="isa" +hint.sn.0.disabled="1" +hint.sn.0.port="0x300" +hint.sn.0.irq="10" +hint.ie.0.at="isa" +hint.ie.0.disabled="1" +hint.ie.0.port="0x300" +hint.ie.0.irq="10" +hint.ie.0.maddr="0xd0000" +hint.fe.0.at="isa" +hint.fe.0.disabled="1" +hint.fe.0.port="0x300" +hint.le.0.at="isa" +hint.le.0.disabled="1" +hint.le.0.port="0x300" +hint.le.0.irq="5" +hint.le.0.maddr="0xd0000" +hint.lnc.0.at="isa" +hint.lnc.0.disabled="1" +hint.lnc.0.port="0x280" +hint.lnc.0.irq="10" +hint.lnc.0.drq="0" diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/Makefile b/freebsd-5.3-xen-sparse/i386-xen/conf/Makefile new file mode 100644 index 0000000000..0284f84e82 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/Makefile @@ -0,0 +1,3 @@ +# $FreeBSD: src/sys/i386/conf/Makefile,v 1.9 2003/02/26 23:36:58 ru Exp $ + +.include "${.CURDIR}/../../conf/makeLINT.mk" diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/NOTES b/freebsd-5.3-xen-sparse/i386-xen/conf/NOTES new file mode 100644 index 0000000000..b01c607dfa --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/NOTES @@ -0,0 +1,1115 @@ +# +# NOTES -- Lines that can be cut/pasted into kernel and hints configs. +# +# This file contains machine dependent kernel configuration notes. For +# machine independent notes, look in /sys/conf/NOTES. +# +# $FreeBSD: src/sys/i386/conf/NOTES,v 1.1108 2003/12/04 19:57:56 phk Exp $ +# + +# +# This directive is mandatory; it defines the architecture to be +# configured for; in this case, the 386 family based IBM-PC and +# compatibles. +# +machine i386 + +# +# We want LINT to cover profiling as well +profile 2 + + +##################################################################### +# SMP OPTIONS: +# +# The apic device enables the use of the I/O APIC for interrupt delivery. +# The apic device can be used in both UP and SMP kernels, but is required +# for SMP kernels. Thus, the apic device is not strictly an SMP option, +# but it is a prerequisite for SMP. +# +# Notes: +# +# Be sure to disable 'cpu I386_CPU' for SMP kernels. +# +# By default, mixed mode is used to route IRQ0 from the AT timer via +# the 8259A master PIC through the ExtINT pin on the first I/O APIC. +# This can be disabled via the NO_MIXED_MODE option. In that case, +# IRQ0 will be routed via an intpin on the first I/O APIC. Not all +# motherboards hook IRQ0 up to the first I/O APIC even though their +# MP table or MADT may claim to do so. That is why mixed mode is +# enabled by default. +# +# HTT CPUs should only be used if they are enabled in the BIOS. For +# the ACPI case, ACPI only correctly tells us about any HTT CPUs if +# they are enabled. However, most HTT systems do not list HTT CPUs +# in the MP Table if they are enabled, thus we guess at the HTT CPUs +# for the MP Table case. However, we shouldn't try to guess and use +# these CPUs if HTTT is disabled. Thus, HTT guessing is only enabled +# for the MP Table if the user explicitly asks for it via the +# MPTABLE_FORCE_HTT option. Do NOT use this option if you have HTT +# disabled in your BIOS. +# + +# Mandatory: +device apic # I/O apic + +# Optional: +options MPTABLE_FORCE_HTT # Enable HTT CPUs with the MP Table +options NO_MIXED_MODE # Disable use of mixed mode + + +##################################################################### +# CPU OPTIONS + +# +# You must specify at least one CPU (the one you intend to run on); +# deleting the specification for CPUs you don't need to use may make +# parts of the system run faster. +# I386_CPU is mutually exclusive with the other CPU types. +# +#cpu I386_CPU +cpu I486_CPU +cpu I586_CPU # aka Pentium(tm) +cpu I686_CPU # aka Pentium Pro(tm) + +# +# Options for CPU features. +# +# CPU_ATHLON_SSE_HACK tries to enable SSE instructions when the BIOS has +# forgotten to enable them. +# +# CPU_BLUELIGHTNING_FPU_OP_CACHE enables FPU operand cache on IBM +# BlueLightning CPU. It works only with Cyrix FPU, and this option +# should not be used with Intel FPU. +# +# CPU_BLUELIGHTNING_3X enables triple-clock mode on IBM Blue Lightning +# CPU if CPU supports it. The default is double-clock mode on +# BlueLightning CPU box. +# +# CPU_BTB_EN enables branch target buffer on Cyrix 5x86 (NOTE 1). +# +# CPU_DIRECT_MAPPED_CACHE sets L1 cache of Cyrix 486DLC CPU in direct +# mapped mode. Default is 2-way set associative mode. +# +# CPU_CYRIX_NO_LOCK enables weak locking for the entire address space +# of Cyrix 6x86 and 6x86MX CPUs by setting the NO_LOCK bit of CCR1. +# Otherwise, the NO_LOCK bit of CCR1 is cleared. (NOTE 3) +# +# CPU_DISABLE_5X86_LSSER disables load store serialize (i.e. enables +# reorder). This option should not be used if you use memory mapped +# I/O device(s). +# +# CPU_ELAN enables support for AMDs ElanSC520 CPU. +# CPU_ELAN_XTAL sets the clock crystal frequency in Hz +# CPU_ELAN_PPS enables precision timestamp code. +# +# CPU_SOEKRIS enables support www.soekris.com hardware. +# +# CPU_ENABLE_SSE enables SSE/MMX2 instructions support. This is default +# on I686_CPU and above. +# CPU_DISABLE_SSE explicitly prevent I686_CPU from turning on SSE. +# +# CPU_FASTER_5X86_FPU enables faster FPU exception handler. +# +# CPU_I486_ON_386 enables CPU cache on i486 based CPU upgrade products +# for i386 machines. +# +# CPU_IORT defines I/O clock delay time (NOTE 1). Default values of +# I/O clock delay time on Cyrix 5x86 and 6x86 are 0 and 7,respectively +# (no clock delay). +# +# CPU_L2_LATENCY specifed the L2 cache latency value. This option is used +# only when CPU_PPRO2CELERON is defined and Mendocino Celeron is detected. +# The default value is 5. +# +# CPU_LOOP_EN prevents flushing the prefetch buffer if the destination +# of a jump is already present in the prefetch buffer on Cyrix 5x86(NOTE +# 1). +# +# CPU_PPRO2CELERON enables L2 cache of Mendocino Celeron CPUs. This option +# is useful when you use Socket 8 to Socket 370 converter, because most Pentium +# Pro BIOSs do not enable L2 cache of Mendocino Celeron CPUs. +# +# CPU_RSTK_EN enables return stack on Cyrix 5x86 (NOTE 1). +# +# CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU +# enters suspend mode following execution of HALT instruction. +# +# CPU_UPGRADE_HW_CACHE eliminates unneeded cache flush instruction(s). +# +# CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD +# K5/K6/K6-2 cpus. +# +# CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache +# flush at hold state. +# +# CYRIX_CACHE_REALLY_WORKS enables (1) CPU cache on Cyrix 486 CPUs +# without cache flush at hold state, and (2) write-back CPU cache on +# Cyrix 6x86 whose revision < 2.7 (NOTE 2). +# +# NO_F00F_HACK disables the hack that prevents Pentiums (and ONLY +# Pentiums) from locking up when a LOCK CMPXCHG8B instruction is +# executed. This option is only needed if I586_CPU is also defined, +# and should be included for any non-Pentium CPU that defines it. +# +# NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors +# which indicates that the 15-16MB range is *definitely* not being +# occupied by an ISA memory hole. +# +# CPU_DISABLE_CMPXCHG disables the CMPXCHG instruction on > i386 IA32 +# machines. VmWare seems to emulate this instruction poorly, causing +# the guest OS to run very slowly. Enabling this with a SMP kernel +# will cause the kernel to be unusable. +# +# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT, +# CPU_LOOP_EN and CPU_RSTK_EN should not be used because of CPU bugs. +# These options may crash your system. +# +# NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled +# in write-through mode when revision < 2.7. If revision of Cyrix +# 6x86 >= 2.7, CPU cache is always enabled in write-back mode. +# +# NOTE 3: This option may cause failures for software that requires +# locked cycles in order to operate correctly. +# +options CPU_ATHLON_SSE_HACK +options CPU_BLUELIGHTNING_FPU_OP_CACHE +options CPU_BLUELIGHTNING_3X +options CPU_BTB_EN +options CPU_DIRECT_MAPPED_CACHE +options CPU_DISABLE_5X86_LSSER +options CPU_ELAN +options CPU_SOEKRIS +options CPU_ELAN_XTAL=32768000 +options CPU_ELAN_PPS +options CPU_ENABLE_SSE +#options CPU_DISABLE_SSE +options CPU_FASTER_5X86_FPU +options CPU_I486_ON_386 +options CPU_IORT +options CPU_L2_LATENCY=5 +options CPU_LOOP_EN +options CPU_PPRO2CELERON +options CPU_RSTK_EN +options CPU_SUSP_HLT +options CPU_UPGRADE_HW_CACHE +options CPU_WT_ALLOC +options CYRIX_CACHE_WORKS +options CYRIX_CACHE_REALLY_WORKS +#options NO_F00F_HACK +options CPU_DISABLE_CMPXCHG + +# Debug options +options NPX_DEBUG # enable npx debugging (FPU/math emu) + #new math emulator + +# +# PERFMON causes the driver for Pentium/Pentium Pro performance counters +# to be compiled. See perfmon(4) for more information. +# +options PERFMON + + +##################################################################### +# NETWORKING OPTIONS + +# +# DEVICE_POLLING adds support for mixed interrupt-polling handling +# of network device drivers, which has significant benefits in terms +# of robustness to overloads and responsivity, as well as permitting +# accurate scheduling of the CPU time between kernel network processing +# and other activities. The drawback is a moderate (up to 1/HZ seconds) +# potential increase in response times. +# It is strongly recommended to use HZ=1000 or 2000 with DEVICE_POLLING +# to achieve smoother behaviour. +# Additionally, you can enable/disable polling at runtime with the +# sysctl variable kern.polling.enable (defaults off), and select +# the CPU fraction reserved to userland with the sysctl variable +# kern.polling.user_frac (default 50, range 0..100). +# +# Only the "dc" "fxp" and "sis" devices support this mode of operation at +# the time of this writing. + +options DEVICE_POLLING + + +##################################################################### +# CLOCK OPTIONS + +# The following options are used for debugging clock behavior only, and +# should not be used for production systems. +# +# CLK_CALIBRATION_LOOP will run the clock calibration loop at startup +# until the user presses a key. + +options CLK_CALIBRATION_LOOP + +# The following two options measure the frequency of the corresponding +# clock relative to the RTC (onboard mc146818a). + +options CLK_USE_I8254_CALIBRATION +options CLK_USE_TSC_CALIBRATION + + +##################################################################### +# MISCELLANEOUS DEVICES AND OPTIONS + +device speaker #Play IBM BASIC-style noises out your speaker +hint.speaker.0.at="isa" +hint.speaker.0.port="0x61" +device gzip #Exec gzipped a.out's. REQUIRES COMPAT_AOUT! +device apm_saver # Requires APM + + +##################################################################### +# HARDWARE BUS CONFIGURATION + +# +# ISA bus +# +device isa + +# +# Options for `isa': +# +# AUTO_EOI_1 enables the `automatic EOI' feature for the master 8259A +# interrupt controller. This saves about 0.7-1.25 usec for each interrupt. +# This option breaks suspend/resume on some portables. +# +# AUTO_EOI_2 enables the `automatic EOI' feature for the slave 8259A +# interrupt controller. This saves about 0.7-1.25 usec for each interrupt. +# Automatic EOI is documented not to work for for the slave with the +# original i8259A, but it works for some clones and some integrated +# versions. +# +# MAXMEM specifies the amount of RAM on the machine; if this is not +# specified, FreeBSD will first read the amount of memory from the CMOS +# RAM, so the amount of memory will initially be limited to 64MB or 16MB +# depending on the BIOS. If the BIOS reports 64MB, a memory probe will +# then attempt to detect the installed amount of RAM. If this probe +# fails to detect >64MB RAM you will have to use the MAXMEM option. +# The amount is in kilobytes, so for a machine with 128MB of RAM, it would +# be 131072 (128 * 1024). +# +# BROKEN_KEYBOARD_RESET disables the use of the keyboard controller to +# reset the CPU for reboot. This is needed on some systems with broken +# keyboard controllers. + +options COMPAT_OLDISA #Use ISA shims and glue for old drivers +options AUTO_EOI_1 +#options AUTO_EOI_2 + +options MAXMEM=(128*1024) +#options BROKEN_KEYBOARD_RESET + +# +# EISA bus +# +# The EISA bus device is `eisa'. It provides auto-detection and +# configuration support for all devices on the EISA bus. + +device eisa + +# By default, only 10 EISA slots are probed, since the slot numbers +# above clash with the configuration address space of the PCI subsystem, +# and the EISA probe is not very smart about this. This is sufficient +# for most machines, but in particular the HP NetServer LC series comes +# with an onboard AIC7770 dual-channel SCSI controller on EISA slot #11, +# thus you need to bump this figure to 12 for them. +options EISA_SLOTS=12 + +# +# MCA bus: +# +# The MCA bus device is `mca'. It provides auto-detection and +# configuration support for all devices on the MCA bus. +# No hints are required for MCA. + +device mca + +# +# PCI bus & PCI options: +# +device pci + +# +# AGP GART support +device agp + + +##################################################################### +# HARDWARE DEVICE CONFIGURATION + +# +# Mandatory devices: +# + +# To include support for VGA VESA video modes +options VESA + +# Turn on extra debugging checks and output for VESA support. +options VESA_DEBUG + +# The pcvt console driver (vt220 compatible). +device vt +hint.vt.0.at="isa" +options XSERVER # support for running an X server on vt +options FAT_CURSOR # start with block cursor +# This PCVT option is for keyboards such as those used on really old ThinkPads +options PCVT_SCANSET=2 +# Other PCVT options are documented in pcvt(4). +options PCVT_24LINESDEF +options PCVT_CTRL_ALT_DEL +options PCVT_META_ESC +options PCVT_NSCREENS=9 +options PCVT_PRETTYSCRNS +options PCVT_SCREENSAVER +options PCVT_USEKBDSEC +options PCVT_VT220KEYB +options PCVT_GREENSAVER + +# +# The Numeric Processing eXtension driver. In addition to this, you +# may configure a math emulator (see above). If your machine has a +# hardware FPU and the kernel configuration includes the npx device +# *and* a math emulator compiled into the kernel, the hardware FPU +# will be used, unless it is found to be broken or unless "flags" to +# npx0 includes "0x08", which requests preference for the emulator. +device npx +hint.npx.0.flags="0x0" +hint.npx.0.irq="13" + +# +# `flags' for npx0: +# 0x01 don't use the npx registers to optimize bcopy. +# 0x02 don't use the npx registers to optimize bzero. +# 0x04 don't use the npx registers to optimize copyin or copyout. +# 0x08 use emulator even if hardware FPU is available. +# The npx registers are normally used to optimize copying and zeroing when +# all of the following conditions are satisfied: +# I586_CPU is an option +# the cpu is an i586 (perhaps not a Pentium) +# the probe for npx0 succeeds +# INT 16 exception handling works. +# Then copying and zeroing using the npx registers is normally 30-100% faster. +# The flags can be used to control cases where it doesn't work or is slower. +# Setting them at boot time using userconfig works right (the optimizations +# are not used until later in the bootstrap when npx0 is attached). +# Flag 0x08 automatically disables the i586 optimized routines. +# + +# +# Optional devices: +# + +# 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create +# the /dev/3dfx0 device to work with glide implementations. This should get +# linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as +# the tdfx DRI module from XFree86 and is completely unrelated. +# +# To enable Linuxulator support, one must also include COMPAT_LINUX in the +# config as well, or you will not have the dependencies. The other option +# is to load both as modules. + +device tdfx # Enable 3Dfx Voodoo support +options TDFX_LINUX # Enable Linuxulator support + +# +# ACPI support using the Intel ACPI Component Architecture reference +# implementation. +# +# ACPI_DEBUG enables the use of the debug.acpi.level and debug.acpi.layer +# kernel environment variables to select initial debugging levels for the +# Intel ACPICA code. (Note that the Intel code must also have USE_DEBUGGER +# defined when it is built). +# +# ACPI_MAX_THREADS sets the number of task threads started. +# +# ACPI_NO_SEMAPHORES makes the AcpiOs*Semaphore routines a no-op. +# +# ACPICA_PEDANTIC enables strict checking of AML. Our default is to +# relax these checks to allow code generated by the Microsoft compiler +# to still execute. +# +# Note that building ACPI into the kernel is deprecated; the module is +# normally loaded automatically by the loader. +# +device acpi +options ACPI_DEBUG +options ACPI_MAX_THREADS=1 +#!options ACPI_NO_SEMAPHORES +#!options ACPICA_PEDANTIC + +# DRM options: +# mgadrm: AGP Matrox G200, G400, G450, G550 +# r128drm: ATI Rage 128 +# radeondrm: ATI Radeon up to 9000/9100 +# sisdrm: SiS 300/305,540,630 +# tdfxdrm: 3dfx Voodoo 3/4/5 and Banshee +# DRM_DEBUG: include debug printfs, very slow +# +# mga requires AGP in the kernel, and it is recommended +# for AGP r128 and radeon cards. + +device mgadrm +device "r128drm" +device radeondrm +device sisdrm +device tdfxdrm + +options DRM_DEBUG + +# M-systems DiskOnchip products see src/sys/contrib/dev/fla/README +device fla +hint.fla.0.at="isa" + +# +# mse: Logitech and ATI InPort bus mouse ports + +device mse +hint.mse.0.at="isa" +hint.mse.0.port="0x23c" +hint.mse.0.irq="5" + +# +# Network interfaces: +# + +# ar: Arnet SYNC/570i hdlc sync 2/4 port V.35/X.21 serial driver +# (requires sppp) +# ath: Atheros a/b/g WiFi adapters (requires ath_hal and wlan) +# cx: Cronyx/Sigma multiport sync/async (with Cisco or PPP framing) +# ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503 +# HP PC Lan+, various PC Card devices (refer to etc/defauls/pccard.conf) +# (requires miibus) +# el: 3Com 3C501 (slow!) +# ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210; +# Intel EtherExpress +# le: Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100, +# DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422) +# lnc: Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL, AMD Am7990 and +# Am79C960) +# oltr: Olicom ISA token-ring adapters OC-3115, OC-3117, OC-3118 and OC-3133 +# (no hints needed). +# Olicom PCI token-ring adapters OC-3136, OC-3137, OC-3139, OC-3140, +# OC-3141, OC-3540, OC-3250 +# rdp: RealTek RTL 8002-based pocket ethernet adapters +# sbni: Granch SBNI12-xx ISA and PCI adapters +# sr: RISCom/N2 hdlc sync 1/2 port V.35/X.21 serial driver (requires sppp) +# wl: Lucent Wavelan (ISA card only). + +# Order for ISA/EISA devices is important here + +device ar +hint.ar.0.at="isa" +hint.ar.0.port="0x300" +hint.ar.0.irq="10" +hint.ar.0.maddr="0xd0000" +device cx +hint.cx.0.at="isa" +hint.cx.0.port="0x240" +hint.cx.0.irq="15" +hint.cx.0.drq="7" +device ed +#options ED_NO_MIIBUS # Disable ed miibus support +hint.ed.0.at="isa" +hint.ed.0.port="0x280" +hint.ed.0.irq="5" +hint.ed.0.maddr="0xd8000" +device el 1 +hint.el.0.at="isa" +hint.el.0.port="0x300" +hint.el.0.irq="9" +device ie # Hints only required for Starlan +hint.ie.2.at="isa" +hint.ie.2.port="0x300" +hint.ie.2.irq="5" +hint.ie.2.maddr="0xd0000" +device le 1 +hint.le.0.at="isa" +hint.le.0.port="0x300" +hint.le.0.irq="5" +hint.le.0.maddr="0xd0000" +device lnc +hint.lnc.0.at="isa" +hint.lnc.0.port="0x280" +hint.lnc.0.irq="10" +hint.lnc.0.drq="0" +device rdp 1 +hint.rdp.0.at="isa" +hint.rdp.0.port="0x378" +hint.rdp.0.irq="7" +hint.rdp.0.flags="2" +device sbni +hint.sbni.0.at="isa" +hint.sbni.0.port="0x210" +hint.sbni.0.irq="0xefdead" +hint.sbni.0.flags="0" +device sr +hint.sr.0.at="isa" +hint.sr.0.port="0x300" +hint.sr.0.irq="5" +hint.sr.0.maddr="0xd0000" +device oltr +hint.oltr.0.at="isa" +device wl +hint.wl.0.at="isa" +hint.wl.0.port="0x300" +options WLCACHE # enables the signal-strength cache +options WLDEBUG # enables verbose debugging output + +device ath +device ath_hal # Atheros HAL (includes binary component) +#device wlan # 802.11 layer + +# +# ATA raid adapters +# +device pst + +# +# SCSI host adapters: +# +# ncv: NCR 53C500 based SCSI host adapters. +# nsp: Workbit Ninja SCSI-3 based PC Card SCSI host adapters. +# stg: TMC 18C30, 18C50 based SCSI host adapters. + +device ncv +device nsp +device stg +hint.stg.0.at="isa" +hint.stg.0.port="0x140" +hint.stg.0.port="11" + +# +# Adaptec FSA RAID controllers, including integrated DELL controllers, +# the Dell PERC 2/QC and the HP NetRAID-4M +device aac +device aacp # SCSI Passthrough interface (optional, CAM required) + +# +# IBM (now Adaptec) ServeRAID controllers +device ips + +# +# SafeNet crypto driver: can be moved to the MI NOTES as soon as +# it's tested on a big-endian machine +# +device safe # SafeNet 1141 +options SAFE_DEBUG # enable debugging support: hw.safe.debug +options SAFE_RNDTEST # enable rndtest support + +##################################################################### + +# +# Miscellaneous hardware: +# +# wt: Wangtek and Archive QIC-02/QIC-36 tape drives +# ctx: Cortex-I frame grabber +# apm: Laptop Advanced Power Management (experimental) +# pmtimer: Timer device driver for power management events (APM or ACPI) +# spigot: The Creative Labs Video Spigot video-acquisition board +# dgb: Digiboard PC/Xi and PC/Xe series driver (ALPHA QUALITY!) +# digi: Digiboard driver +# gp: National Instruments AT-GPIB and AT-GPIB/TNT board, PCMCIA-GPIB +# asc: GI1904-based hand scanners, e.g. the Trust Amiscan Grey +# gsc: Genius GS-4500 hand scanner. +# spic: Sony Programmable I/O controller (VAIO notebooks) +# stl: Stallion EasyIO and EasyConnection 8/32 (cd1400 based) +# stli: Stallion EasyConnection 8/64, ONboard, Brumby (intelligent) + +# Notes on APM +# The flags takes the following meaning for apm0: +# 0x0020 Statclock is broken. +# If apm is omitted, some systems require sysctl kern.timecounter.method=1 +# for correct timekeeping. + +# Notes on the spigot: +# The video spigot is at 0xad6. This port address can not be changed. +# The irq values may only be 10, 11, or 15 +# I/O memory is an 8kb region. Possible values are: +# 0a0000, 0a2000, ..., 0fffff, f00000, f02000, ..., ffffff +# The start address must be on an even boundary. +# Add the following option if you want to allow non-root users to be able +# to access the spigot. This option is not secure because it allows users +# direct access to the I/O page. +# options SPIGOT_UNSECURE + +# Notes on the Specialix SI/XIO driver: +# The host card is memory, not IO mapped. +# The Rev 1 host cards use a 64K chunk, on a 32K boundary. +# The Rev 2 host cards use a 32K chunk, on a 32K boundary. +# The cards can use an IRQ of 11, 12 or 15. + +# Notes on the Sony Programmable I/O controller +# This is a temporary driver that should someday be replaced by something +# that hooks into the ACPI layer. The device is hooked to the PIIX4's +# General Device 10 decoder, which means you have to fiddle with PCI +# registers to map it in, even though it is otherwise treated here as +# an ISA device. At the moment, the driver polls, although the device +# is capable of generating interrupts. It largely undocumented. +# The port location in the hint is where you WANT the device to be +# mapped. 0x10a0 seems to be traditional. At the moment the jogdial +# is the only thing truly supported, but aparently a fair percentage +# of the Vaio extra features are controlled by this device. + +# Notes on the Stallion stl and stli drivers: +# See src/i386/isa/README.stl for complete instructions. +# This is version 0.0.5alpha, unsupported by Stallion. +# The stl driver has a secondary IO port hard coded at 0x280. You need +# to change src/i386/isa/stallion.c if you reconfigure this on the boards. +# The "flags" and "msize" settings on the stli driver depend on the board: +# EasyConnection 8/64 ISA: flags 23 msize 0x1000 +# EasyConnection 8/64 EISA: flags 24 msize 0x10000 +# EasyConnection 8/64 MCA: flags 25 msize 0x1000 +# ONboard ISA: flags 4 msize 0x10000 +# ONboard EISA: flags 7 msize 0x10000 +# ONboard MCA: flags 3 msize 0x10000 +# Brumby: flags 2 msize 0x4000 +# Stallion: flags 1 msize 0x10000 + +# Notes on the Digiboard PC/Xi and PC/Xe series driver +# +# The NDGBPORTS option specifies the number of ports controlled by the +# dgb(4) driver. The default value is 16 ports per device. +# +# The following flag values have special meanings in dgb: +# 0x01 - alternate layout of pins +# 0x02 - use the windowed PC/Xe in 64K mode + +device wt 1 +hint.wt.0.at="isa" +hint.wt.0.port="0x300" +hint.wt.0.irq="5" +hint.wt.0.drq="1" +device ctx +hint.ctx.0.at="isa" +hint.ctx.0.port="0x230" +hint.ctx.0.maddr="0xd0000" +device spigot 1 +hint.spigot.0.at="isa" +hint.spigot.0.port="0xad6" +hint.spigot.0.irq="15" +hint.spigot.0.maddr="0xee000" +device apm +hint.apm.0.flags="0x20" +device pmtimer # Adjust system timer at wakeup time +device gp +hint.gp.0.at="isa" +hint.gp.0.port="0x2c0" +device gsc 1 +hint.gsc.0.at="isa" +hint.gsc.0.port="0x270" +hint.gsc.0.drq="3" +device dgb 1 +options NDGBPORTS=17 +hint.dgb.0.at="isa" +hint.dgb.0.port="0x220" +hint.dgb.0.maddr="0xfc000" +device digi +hint.digi.0.at="isa" +hint.digi.0.port="0x104" +hint.digi.0.maddr="0xd0000" +# BIOS & FEP/OS components of device digi. +device digi_CX +device digi_CX_PCI +device digi_EPCX +device digi_EPCX_PCI +device digi_Xe +device digi_Xem +device digi_Xr +device asc 1 +hint.asc.0.at="isa" +hint.asc.0.port="0x3EB" +hint.asc.0.drq="3" +hint.asc.0.irq="10" +device spic +hint.spic.0.at="isa" +hint.spic.0.port="0x10a0" +device stl +hint.stl.0.at="isa" +hint.stl.0.port="0x2a0" +hint.stl.0.irq="10" +device stli +hint.stli.0.at="isa" +hint.stli.0.port="0x2a0" +hint.stli.0.maddr="0xcc000" +hint.stli.0.flags="23" +hint.stli.0.msize="0x1000" +# You are unlikely to have the hardware for loran +device loran +hint.loran.0.at="isa" +hint.loran.0.irq="5" +# HOT1 Xilinx 6200 card (http://www.vcc.com/) +device xrpu + +# +# Laptop/Notebook options: +# +# See also: +# apm under `Miscellaneous hardware' +# above. + +# For older notebooks that signal a powerfail condition (external +# power supply dropped, or battery state low) by issuing an NMI: + +options POWERFAIL_NMI # make it beep instead of panicing + +# +# I2C Bus +# +# Philips i2c bus support is provided by the `iicbus' device. +# +# Supported interfaces: +# pcf Philips PCF8584 ISA-bus controller +# +device pcf +hint.pcf.0.at="isa" +hint.pcf.0.port="0x320" +hint.pcf.0.irq="5" + +#--------------------------------------------------------------------------- +# ISDN4BSD +# +# See /usr/share/examples/isdn/ROADMAP for an introduction to isdn4bsd. +# +# i4b passive ISDN cards support contains the following hardware drivers: +# +# isic - Siemens/Infineon ISDN ISAC/HSCX/IPAC chipset driver +# iwic - Winbond W6692 PCI bus ISDN S/T interface controller +# ifpi - AVM Fritz!Card PCI driver +# ifpi2 - AVM Fritz!Card PCI version 2 driver +# ihfc - Cologne Chip HFC ISA/ISA-PnP chipset driver +# ifpnp - AVM Fritz!Card PnP driver +# itjc - Siemens ISAC / TJNet Tiger300/320 chipset +# +# i4b active ISDN cards support contains the following hardware drivers: +# +# iavc - AVM B1 PCI, AVM B1 ISA, AVM T1 +# +# Note that the ``options'' (if given) and ``device'' lines must BOTH +# be uncommented to enable support for a given card ! +# +# In addition to a hardware driver (and probably an option) the mandatory +# ISDN protocol stack devices and the mandatory support device must be +# enabled as well as one or more devices from the optional devices section. +# +#--------------------------------------------------------------------------- +# isic driver (Siemens/Infineon chipsets) +# +device isic +# +# ISA bus non-PnP Cards: +# ---------------------- +# +# Teles S0/8 or Niccy 1008 +options TEL_S0_8 +hint.isic.0.at="isa" +hint.isic.0.maddr="0xd0000" +hint.isic.0.irq="5" +hint.isic.0.flags="1" +# +# Teles S0/16 or Creatix ISDN-S0 or Niccy 1016 +options TEL_S0_16 +hint.isic.0.at="isa" +hint.isic.0.port="0xd80" +hint.isic.0.maddr="0xd0000" +hint.isic.0.irq="5" +hint.isic.0.flags="2" +# +# Teles S0/16.3 +options TEL_S0_16_3 +hint.isic.0.at="isa" +hint.isic.0.port="0xd80" +hint.isic.0.irq="5" +hint.isic.0.flags="3" +# +# AVM A1 or AVM Fritz!Card +options AVM_A1 +hint.isic.0.at="isa" +hint.isic.0.port="0x340" +hint.isic.0.irq="5" +hint.isic.0.flags="4" +# +# USRobotics Sportster ISDN TA intern +options USR_STI +hint.isic.0.at="isa" +hint.isic.0.port="0x268" +hint.isic.0.irq="5" +hint.isic.0.flags="7" +# +# ITK ix1 Micro ( < V.3, non-PnP version ) +options ITKIX1 +hint.isic.0.at="isa" +hint.isic.0.port="0x398" +hint.isic.0.irq="10" +hint.isic.0.flags="18" +# +# ELSA PCC-16 +options ELSA_PCC16 +hint.isic.0.at="isa" +hint.isic.0.port="0x360" +hint.isic.0.irq="10" +hint.isic.0.flags="20" +# +# ISA bus PnP Cards: +# ------------------ +# +# Teles S0/16.3 PnP +options TEL_S0_16_3_P +# +# Creatix ISDN-S0 P&P +options CRTX_S0_P +# +# Dr. Neuhaus Niccy Go@ +options DRN_NGO +# +# Sedlbauer Win Speed +options SEDLBAUER +# +# Dynalink IS64PH +options DYNALINK +# +# ELSA QuickStep 1000pro ISA +options ELSA_QS1ISA +# +# Siemens I-Surf 2.0 +options SIEMENS_ISURF2 +# +# Asuscom ISDNlink 128K ISA +options ASUSCOM_IPAC +# +# Eicon Diehl DIVA 2.0 and 2.02 +options EICON_DIVA +# +# Compaq Microcom 610 ISDN card (Compaq series PSB2222I) +options COMPAQ_M610 +# +# PCI bus Cards: +# -------------- +# +# Cyclades Cyclom-Y PCI serial driver +device cy 1 +options CY_PCI_FASTINTR # Use with cy_pci unless irq is shared +hint.cy.0.at="isa" +hint.cy.0.irq="10" +hint.cy.0.maddr="0xd4000" +hint.cy.0.msize="0x2000" +# +#--------------------------------------------------------------------------- +# ELSA MicroLink ISDN/PCI (same as ELSA QuickStep 1000pro PCI) +options ELSA_QS1PCI +# +# +#--------------------------------------------------------------------------- +# ifpnp driver for AVM Fritz!Card PnP +# +# AVM Fritz!Card PnP +device ifpnp +# +#--------------------------------------------------------------------------- +# ihfc driver for Cologne Chip ISA chipsets (experimental!) +# +# Teles 16.3c ISA PnP +# AcerISDN P10 ISA PnP +# TELEINT ISDN SPEED No.1 +device ihfc +# +#--------------------------------------------------------------------------- +# ifpi driver for AVM Fritz!Card PCI +# +# AVM Fritz!Card PCI +device ifpi +# +#--------------------------------------------------------------------------- +# ifpi2 driver for AVM Fritz!Card PCI version 2 +# +# AVM Fritz!Card PCI version 2 +device "ifpi2" +# +#--------------------------------------------------------------------------- +# iwic driver for Winbond W6692 chipset +# +# ASUSCOM P-IN100-ST-D (and other Winbond W6692 based cards) +device iwic +# +#--------------------------------------------------------------------------- +# itjc driver for Simens ISAC / TJNet Tiger300/320 chipset +# +# Traverse Technologies NETjet-S +# Teles PCI-TJ +device itjc +# +#--------------------------------------------------------------------------- +# iavc driver (AVM active cards, needs i4bcapi driver!) +# +device iavc +# +# AVM B1 ISA bus (PnP mode not supported!) +# ---------------------------------------- +hint.iavc.0.at="isa" +hint.iavc.0.port="0x150" +hint.iavc.0.irq="5" +# +#--------------------------------------------------------------------------- +# ISDN Protocol Stack - mandatory for all hardware drivers +# +# Q.921 / layer 2 - i4b passive cards D channel handling +device "i4bq921" +# +# Q.931 / layer 3 - i4b passive cards D channel handling +device "i4bq931" +# +# layer 4 - i4b common passive and active card handling +device "i4b" +# +#--------------------------------------------------------------------------- +# ISDN devices - mandatory for all hardware drivers +# +# userland driver to do ISDN tracing (for passive cards only) +device "i4btrc" 4 +# +# userland driver to control the whole thing +device "i4bctl" +# +#--------------------------------------------------------------------------- +# ISDN devices - optional +# +# userland driver for access to raw B channel +device "i4brbch" 4 +# +# userland driver for telephony +device "i4btel" 2 +# +# network driver for IP over raw HDLC ISDN +device "i4bipr" 4 +# enable VJ header compression detection for ipr i/f +options IPR_VJ +# enable logging of the first n IP packets to isdnd (n=32 here) +options IPR_LOG=32 +# +# network driver for sync PPP over ISDN; requires an equivalent +# number of sppp device to be configured +device "i4bisppp" 4 +# +# B-channel interface to the netgraph subsystem +device "i4bing" 2 +# +# CAPI driver needed for active ISDN cards (see iavc driver above) +device "i4bcapi" +# +#--------------------------------------------------------------------------- + +# +# Set the number of PV entries per process. Increasing this can +# stop panics related to heavy use of shared memory. However, that can +# (combined with large amounts of physical memory) cause panics at +# boot time due the kernel running out of VM space. +# +# If you're tweaking this, you might also want to increase the sysctls +# "vm.v_free_min", "vm.v_free_reserved", and "vm.v_free_target". +# +# The value below is the one more than the default. +# +options PMAP_SHPGPERPROC=201 + +# +# Change the size of the kernel virtual address space. Due to +# constraints in loader(8) on i386, this must be a multiple of 4. +# 256 = 1 GB of kernel address space. Increasing this also causes +# a reduction of the address space in user processes. 512 splits +# the 4GB cpu address space in half (2GB user, 2GB kernel). +# +options KVA_PAGES=260 + + +##################################################################### +# ABI Emulation + +# Enable iBCS2 runtime support for SCO and ISC binaries +options IBCS2 + +# Emulate spx device for client side of SVR3 local X interface +options SPX_HACK + +# Enable Linux ABI emulation +options COMPAT_LINUX + +# Enable i386 a.out binary support +options COMPAT_AOUT + +# Enable the linux-like proc filesystem support (requires COMPAT_LINUX +# and PSEUDOFS) +options LINPROCFS + +# +# SysVR4 ABI emulation +# +# The svr4 ABI emulator can be statically compiled into the kernel or loaded as +# a KLD module. +# The STREAMS network emulation code can also be compiled statically or as a +# module. If loaded as a module, it must be loaded before the svr4 module +# (the /usr/sbin/svr4 script does this for you). If compiling statically, +# the `streams' device must be configured into any kernel which also +# specifies COMPAT_SVR4. It is possible to have a statically-configured +# STREAMS device and a dynamically loadable svr4 emulator; the /usr/sbin/svr4 +# script understands that it doesn't need to load the `streams' module under +# those circumstances. +# Caveat: At this time, `options KTRACE' is required for the svr4 emulator +# (whether static or dynamic). +# +options COMPAT_SVR4 # build emulator statically +options DEBUG_SVR4 # enable verbose debugging +device streams # STREAMS network driver (required for svr4). + + +##################################################################### +# VM OPTIONS + +# Disable the 4 MByte page PSE CPU feature. The PSE feature allows the +# kernel to use a 4 MByte pages to map the kernel instead of 4k pages. +# This saves on the amount of memory needed for page tables needed to +# map the kernel. You should only disable this feature as a temporary +# workaround if you are having problems with it enabled. +# +#options DISABLE_PSE + +# Disable the global pages PGE CPU feature. The PGE feature allows pages +# to be marked with the PG_G bit. TLB entries for these pages are not +# flushed from the cache when %cr3 is reloaded. This can make context +# switches less expensive. You should only disable this feature as a +# temporary workaround if you are having problems with it enabled. +# +#options DISABLE_PG_G + +# KSTACK_PAGES is the number of memory pages to assign to the kernel +# stack of each thread. + +options KSTACK_PAGES=3 + +##################################################################### + +# More undocumented options for linting. +# Note that documenting these are not considered an affront. + +options FB_INSTALL_CDEV # install a CDEV entry in /dev + +# PECOFF module (Win32 Execution Format) +options PECOFF_SUPPORT +options PECOFF_DEBUG + +options ENABLE_ALART +options I4B_SMP_WORKAROUND +options I586_PMC_GUPROF=0x70000 +options KBDIO_DEBUG=2 +options KBD_MAXRETRY=4 +options KBD_MAXWAIT=6 +options KBD_RESETDELAY=201 + +options PSM_DEBUG=1 + +options TIMER_FREQ=((14318182+6)/12) + +options VM_KMEM_SIZE +options VM_KMEM_SIZE_MAX +options VM_KMEM_SIZE_SCALE diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/OLDCARD b/freebsd-5.3-xen-sparse/i386-xen/conf/OLDCARD new file mode 100644 index 0000000000..2d13fbe2b5 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/OLDCARD @@ -0,0 +1,17 @@ +# +# OLDCARD -- Generic kernel configuration file for FreeBSD/i386 +# using the OLDCARD pccard system. +# +# $FreeBSD: src/sys/i386/conf/OLDCARD,v 1.18 2003/02/15 02:39:13 ru Exp $ + +include GENERIC + +ident OLDCARD + +# PCCARD (PCMCIA) support +nodevice cbb # cardbus (yenta) bridge +#nodevice pcic # ExCA ISA and PCI bridges +nodevice pccard # PC Card (16-bit) bus +nodevice cardbus # CardBus (32-bit) bus +device card 1 # pccard bus +device pcic # PCMCIA bridge diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/PAE b/freebsd-5.3-xen-sparse/i386-xen/conf/PAE new file mode 100644 index 0000000000..98d4f2c252 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/PAE @@ -0,0 +1,99 @@ +# +# PAE -- Generic kernel configuration file for FreeBSD/i386 PAE +# +# $FreeBSD: src/sys/i386/conf/PAE,v 1.8 2003/11/03 22:49:19 jhb Exp $ + +include GENERIC + +ident PAE-GENERIC + +# To make a PAE kernel, the next option is needed +options PAE # Physical Address Extensions Kernel + +# Compile acpi in statically since the module isn't built properly. Most +# machines which support large amounts of memory require acpi. +device acpi + +# Don't build modules with this kernel config, since they are not built with +# the correct options headers. +makeoptions NO_MODULES=yes + +# What follows is a list of drivers that are normally in GENERIC, but either +# don't work or are untested with PAE. Be very careful before enabling any +# of these drivers. Drivers which use DMA and don't handle 64 bit physical +# address properly may cause data corruption when used in a machine with more +# than 4 gigabytes of memory. + +nodevice ahb +nodevice amd +nodevice isp +nodevice sym +nodevice trm + +nodevice adv +nodevice adw +nodevice aha +nodevice aic +nodevice bt + +nodevice ncv +nodevice nsp +nodevice stg + +nodevice asr +nodevice dpt +nodevice iir +nodevice mly + +nodevice amr +nodevice ida +nodevice mlx +nodevice pst + +nodevice agp + +nodevice de +nodevice txp +nodevice vx + +nodevice dc +nodevice pcn +nodevice rl +nodevice sf +nodevice sis +nodevice ste +nodevice tl +nodevice tx +nodevice vr +nodevice wb + +nodevice cs +nodevice ed +nodevice ex +nodevice ep +nodevice fe +nodevice ie +nodevice lnc +nodevice sn +nodevice xe + +nodevice wlan +nodevice an +nodevice awi +nodevice wi + +nodevice uhci +nodevice ohci +nodevice usb +nodevice ugen +nodevice uhid +nodevice ukbd +nodevice ulpt +nodevice umass +nodevice ums +nodevice urio +nodevice uscanner +nodevice aue +nodevice axe +nodevice cue +nodevice kue diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/XENCONF b/freebsd-5.3-xen-sparse/i386-xen/conf/XENCONF new file mode 100644 index 0000000000..4214b1c59b --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/XENCONF @@ -0,0 +1,137 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/i386 +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD: src/sys/i386/conf/GENERIC,v 1.394.2.3 2004/01/26 19:42:11 nectar Exp $ + +machine i386-xen +cpu I686_CPU +ident XEN + +#To statically compile in device wiring instead of /boot/device.hints +#hints "GENERIC.hints" #Default places to look for devices. + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories +options MD_ROOT #MD is a potential root device +options NFSCLIENT #Network Filesystem Client +options NFSSERVER #Network Filesystem Server +# options NFS_ROOT #NFS usable as /, requires NFSCLIENT +#options MSDOSFS #MSDOS Filesystem +#options CD9660 #ISO 9660 Filesystem +options PROCFS #Process filesystem (requires PSEUDOFS) +options PSEUDOFS #Pseudo-filesystem framework +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options COMPAT_FREEBSD4 #Compatible with FreeBSD4 +options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI +options KTRACE #ktrace(1) support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options CPU_DISABLE_SSE # don't turn on SSE framework with Xen +#options PFIL_HOOKS # pfil(9) framework + +# Debugging for use in -current +options KDB #Enable the kernel debugger +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed + +# To make an SMP kernel, the next two are needed +#options SMP # Symmetric MultiProcessor Kernel +#device apic # I/O APIC + +# SCSI peripherals +device scbus # SCSI bus (required for SCSI) +#device ch # SCSI media changers +device da # Direct Access (disks) +#device sa # Sequential Access (tape etc) +#device cd # CD +device pass # Passthrough device (direct SCSI access) +#device ses # SCSI Environmental Services (and SAF-TE) + +# atkbdc0 controls both the keyboard and the PS/2 mouse +#device atkbdc # AT keyboard controller +#device atkbd # AT keyboard +#device psm # PS/2 mouse + +# device vga # VGA video card driver + +#device splash # Splash screen and screen saver support + +# syscons is the default console driver, resembling an SCO console +#device sc + +# Enable this for the pcvt (VT220 compatible) console driver +#device vt +#options XSERVER # support for X server on a vt console +#options FAT_CURSOR # start with block cursor + +#device agp # support several AGP chipsets + +# Floating point support - do not disable. +device npx + +# Serial (COM) ports +#device sio # 8250, 16[45]50 based serial ports + +# Parallel port +#device ppc +#device ppbus # Parallel port bus (required) +#device lpt # Printer +#device plip # TCP/IP over parallel +#device ppi # Parallel port interface device +#device vpo # Requires scbus and da + +# If you've got a "dumb" serial or parallel PCI card that is +# supported by the puc(4) glue driver, uncomment the following +# line to enable it (connects to the sio and/or ppc drivers): +#device puc + + +# Pseudo devices - the number indicates how many units to allocate. +device random # Entropy device +device loop # Network loopback +device ether # Ethernet support +device tun # Packet tunnel. +device pty # Pseudo-ttys (telnet etc) +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device faith # IPv6-to-IPv4 relaying (translation) + +# The `bpf' device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +device bpf # Berkeley packet filter + +#options BOOTP +options XEN +options MCLSHIFT=12 # this has to be enabled for Xen as we can only have one cluster per page +options MSIZE=256 +options DIAGNOSTIC +options MAXMEM=(256*1024) +options NOXENDEBUG=1 # Turn off Debugging printfs + diff --git a/freebsd-5.3-xen-sparse/i386-xen/conf/gethints.awk b/freebsd-5.3-xen-sparse/i386-xen/conf/gethints.awk new file mode 100644 index 0000000000..e8cc6b67de --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/conf/gethints.awk @@ -0,0 +1,116 @@ +#! /usr/bin/awk -f +# +# This is a transition aid. It extracts old-style configuration information +# from a config file and writes an equivalent device.hints file to stdout. +# You can use that with loader(8) or statically compile it in with the +# 'hints' directive. See how GENERIC and GENERIC.hints fit together for +# a static example. You should use loader(8) if at all possible. +# +# $FreeBSD: src/sys/i386/conf/gethints.awk,v 1.2 2002/07/26 03:52:30 peter Exp $ + +# skip commented lines, empty lines and not "device" lines +/^[ \t]*#/ || /^[ \t]*$/ || !/[ \t]*device/ { next; } + +# input format : +# device at [?] [key [val]]... +# possible keys are : +# disable, port #, irq #, drq #, drive #, iomem #, iosiz #, +# flags #, bus #, target #, unit #. +# output format : +# hint...= +# mapped keys are : +# iomem -> maddr, iosiz -> msize. +{ + gsub ("#.*", ""); # delete comments + gsub ("\"", ""); # and double-quotes + nameunit = $2; # + at = $3; # at + controler = $4; # [?] + rest = 5; # optional keys begin at indice 5 + if (at != "at" || controler == "") + next; # skip devices w/o controlers + name = nameunit; + sub ("[0-9]*$", "", name); # get the name + unit = nameunit; + sub ("^" name, "", unit); # and the unit + sub ("\?$", "", controler); + printf "hint.%s.%s.at=\"%s\"\n", name, unit, controler; + # for each keys, if any ? + for (key = $rest; rest <= NF; key = $(++rest)) { + # skip auto-detect keys (the one w/ a ?) + if (key == "port?" || key == "drq?" || key == "irq?" || \ + key == "iomem?" || key == "iosiz?") + continue; + # disable has no value, so, give it one + if (key == "disable") { + printf "hint.%s.%s.disabled=\"1\"\n", name, unit; + continue; + } + # recognized keys + if (key == "port" || key == "irq" || key == "drq" || \ + key == "drive" || key == "iomem" || key == "iosiz" || \ + key == "flags" || key == "bus" || key == "target" || \ + key == "unit") { + val = $(++rest); + if (val == "?") # has above + continue; + if (key == "port") { + # map port macros to static values + sub ("IO_AHA0", "0x330", val); + sub ("IO_AHA1", "0x334", val); + sub ("IO_ASC1", "0x3EB", val); + sub ("IO_ASC2", "0x22B", val); + sub ("IO_ASC3", "0x26B", val); + sub ("IO_ASC4", "0x2AB", val); + sub ("IO_ASC5", "0x2EB", val); + sub ("IO_ASC6", "0x32B", val); + sub ("IO_ASC7", "0x36B", val); + sub ("IO_ASC8", "0x3AB", val); + sub ("IO_BT0", "0x330", val); + sub ("IO_BT1", "0x334", val); + sub ("IO_CGA", "0x3D0", val); + sub ("IO_COM1", "0x3F8", val); + sub ("IO_COM2", "0x2F8", val); + sub ("IO_COM3", "0x3E8", val); + sub ("IO_COM4", "0x2E8", val); + sub ("IO_DMA1", "0x000", val); + sub ("IO_DMA2", "0x0C0", val); + sub ("IO_DMAPG", "0x080", val); + sub ("IO_FD1", "0x3F0", val); + sub ("IO_FD2", "0x370", val); + sub ("IO_GAME", "0x201", val); + sub ("IO_GSC1", "0x270", val); + sub ("IO_GSC2", "0x2E0", val); + sub ("IO_GSC3", "0x370", val); + sub ("IO_GSC4", "0x3E0", val); + sub ("IO_ICU1", "0x020", val); + sub ("IO_ICU2", "0x0A0", val); + sub ("IO_KBD", "0x060", val); + sub ("IO_LPT1", "0x378", val); + sub ("IO_LPT2", "0x278", val); + sub ("IO_LPT3", "0x3BC", val); + sub ("IO_MDA", "0x3B0", val); + sub ("IO_NMI", "0x070", val); + sub ("IO_NPX", "0x0F0", val); + sub ("IO_PMP1", "0x026", val); + sub ("IO_PMP2", "0x178", val); + sub ("IO_PPI", "0x061", val); + sub ("IO_RTC", "0x070", val); + sub ("IO_TIMER1", "0x040", val); + sub ("IO_TIMER2", "0x048", val); + sub ("IO_UHA0", "0x330", val); + sub ("IO_VGA", "0x3C0", val); + sub ("IO_WD1", "0x1F0", val); + sub ("IO_WD2", "0x170", val); + } else { + # map key names + sub ("iomem", "maddr", key); + sub ("iosiz", "msize", key); + } + printf "hint.%s.%s.%s=\"%s\"\n", name, unit, key, val; + continue; + } + printf ("unrecognized config token '%s:%s' on line %s\n", + rest, key, NR); # > "/dev/stderr"; + } +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/clock.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/clock.c new file mode 100644 index 0000000000..393e091986 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/clock.c @@ -0,0 +1,511 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)clock.c 7.2 (Berkeley) 5/12/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/isa/clock.c,v 1.207 2003/11/13 10:02:12 phk Exp $"); + +/* #define DELAYDEBUG */ +/* + * Routines to handle clock hardware. + */ + +/* + * inittodr, settodr and support routines written + * by Christoph Robitschko + * + * reintroduced and updated by Chris Stenton 8/10/94 + */ + +#include "opt_clock.h" +#include "opt_isa.h" +#include "opt_mca.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#if defined(SMP) +#include +#endif +#include + +#include +#include +#include +#include + +/* XEN specific defines */ +#include + +/* + * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we + * can use a simple formula for leap years. + */ +#define LEAPYEAR(y) (((u_int)(y) % 4 == 0) ? 1 : 0) +#define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31) + +int adjkerntz; /* local offset from GMT in seconds */ +int clkintr_pending; +int disable_rtc_set = 1; /* disable resettodr() if != 0 */ +int pscnt = 1; +int psdiv = 1; +int statclock_disable; +#ifndef TIMER_FREQ +#define TIMER_FREQ 1193182 +#endif +u_int timer_freq = TIMER_FREQ; + +static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31}; + +/* Values for timerX_state: */ +#define RELEASED 0 +#define RELEASE_PENDING 1 +#define ACQUIRED 2 +#define ACQUIRE_PENDING 3 + +/* Cached *multiplier* to convert TSC counts to microseconds. + * (see the equation below). + * Equal to 2^32 * (1 / (clocks per usec) ). + * Initialized in time_init. + */ +static unsigned long fast_gettimeoffset_quotient; + +/* These are peridically updated in shared_info, and then copied here. */ +static uint32_t shadow_tsc_stamp; +static uint64_t shadow_system_time; +static uint32_t shadow_time_version; +static struct timeval shadow_tv; + +static uint64_t processed_system_time;/* System time (ns) at last processing. */ + +#define NS_PER_TICK (1000000000ULL/hz) + +/* convert from cycles(64bits) => nanoseconds (64bits) + * basic equation: + * ns = cycles / (freq / ns_per_sec) + * ns = cycles * (ns_per_sec / freq) + * ns = cycles * (10^9 / (cpu_mhz * 10^6)) + * ns = cycles * (10^3 / cpu_mhz) + * + * Then we use scaling math (suggested by george@mvista.com) to get: + * ns = cycles * (10^3 * SC / cpu_mhz) / SC + * ns = cycles * cyc2ns_scale / SC + * + * And since SC is a constant power of two, we can convert the div + * into a shift. + * -johnstul@us.ibm.com "math is hard, lets go shopping!" + */ +static unsigned long cyc2ns_scale; +#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ + +static inline void set_cyc2ns_scale(unsigned long cpu_mhz) +{ + cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz; +} + +static inline unsigned long long cycles_2_ns(unsigned long long cyc) +{ + return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; +} + +/* + * Reads a consistent set of time-base values from Xen, into a shadow data + * area. Must be called with the xtime_lock held for writing. + */ +static void __get_time_values_from_xen(void) +{ + shared_info_t *s = HYPERVISOR_shared_info; + + do { + shadow_time_version = s->time_version2; + rmb(); + shadow_tv.tv_sec = s->wc_sec; + shadow_tv.tv_usec = s->wc_usec; + shadow_tsc_stamp = (uint32_t)s->tsc_timestamp; + shadow_system_time = s->system_time; + rmb(); + } + while (shadow_time_version != s->time_version1); +} + +#define TIME_VALUES_UP_TO_DATE \ + (shadow_time_version == HYPERVISOR_shared_info->time_version2) + +static void (*timer_func)(struct clockframe *frame) = hardclock; + +static unsigned xen_get_offset(void); +static unsigned xen_get_timecount(struct timecounter *tc); + +static struct timecounter xen_timecounter = { + xen_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + 0, /* frequency */ + "ixen", /* name */ + 0 /* quality */ +}; + + +static void +clkintr(struct clockframe *frame) +{ + int64_t delta; + long ticks = 0; + + + do { + __get_time_values_from_xen(); + delta = (int64_t)(shadow_system_time + + xen_get_offset() * 1000 - + processed_system_time); + } while (!TIME_VALUES_UP_TO_DATE); + + if (unlikely(delta < 0)) { + printk("Timer ISR: Time went backwards: %lld\n", delta); + return; + } + + /* Process elapsed ticks since last call. */ + while ( delta >= NS_PER_TICK ) + { + ticks++; + delta -= NS_PER_TICK; + processed_system_time += NS_PER_TICK; + } + + if (ticks > 0) { + if (frame) + timer_func(frame); +#ifdef SMP + if (timer_func == hardclock && frame) + forward_hardclock(); +#endif + } +} + +#include "opt_ddb.h" +static uint32_t +getit(void) +{ + __get_time_values_from_xen(); + return shadow_tsc_stamp; +} + +/* + * Wait "n" microseconds. + * Relies on timer 1 counting down from (timer_freq / hz) + * Note: timer had better have been programmed before this is first used! + */ +void +DELAY(int n) +{ + int delta, ticks_left; + uint32_t tick, prev_tick; +#ifdef DELAYDEBUG + int getit_calls = 1; + int n1; + static int state = 0; + + if (state == 0) { + state = 1; + for (n1 = 1; n1 <= 10000000; n1 *= 10) + DELAY(n1); + state = 2; + } + if (state == 1) + printf("DELAY(%d)...", n); +#endif + /* + * Read the counter first, so that the rest of the setup overhead is + * counted. Guess the initial overhead is 20 usec (on most systems it + * takes about 1.5 usec for each of the i/o's in getit(). The loop + * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The + * multiplications and divisions to scale the count take a while). + * + * However, if ddb is active then use a fake counter since reading + * the i8254 counter involves acquiring a lock. ddb must not go + * locking for many reasons, but it calls here for at least atkbd + * input. + */ + prev_tick = getit(); + + n -= 0; /* XXX actually guess no initial overhead */ + /* + * Calculate (n * (timer_freq / 1e6)) without using floating point + * and without any avoidable overflows. + */ + if (n <= 0) + ticks_left = 0; + else if (n < 256) + /* + * Use fixed point to avoid a slow division by 1000000. + * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest. + * 2^15 is the first power of 2 that gives exact results + * for n between 0 and 256. + */ + ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15; + else + /* + * Don't bother using fixed point, although gcc-2.7.2 + * generates particularly poor code for the long long + * division, since even the slow way will complete long + * before the delay is up (unless we're interrupted). + */ + ticks_left = ((u_int)n * (long long)timer_freq + 999999) + / 1000000; + + while (ticks_left > 0) { + tick = getit(); +#ifdef DELAYDEBUG + ++getit_calls; +#endif + delta = tick - prev_tick; + prev_tick = tick; + if (delta < 0) { + /* + * Guard against timer0_max_count being wrong. + * This shouldn't happen in normal operation, + * but it may happen if set_timer_freq() is + * traced. + */ + /* delta += timer0_max_count; ??? */ + if (delta < 0) + delta = 0; + } + ticks_left -= delta; + } +#ifdef DELAYDEBUG + if (state == 1) + printf(" %d calls to getit() at %d usec each\n", + getit_calls, (n + 5) / getit_calls); +#endif +} + + +int +sysbeep(int pitch, int period) +{ + return (0); +} + +/* + * Restore all the timers non-atomically (XXX: should be atomically). + * + * This function is called from pmtimer_resume() to restore all the timers. + * This should not be necessary, but there are broken laptops that do not + * restore all the timers on resume. + */ +void +timer_restore(void) +{ + /* Get timebases for new environment. */ + __get_time_values_from_xen(); + + /* Reset our own concept of passage of system time. */ + processed_system_time = shadow_system_time; +} + +void +startrtclock() +{ + unsigned long long alarm; + uint64_t __cpu_khz; + uint32_t cpu_khz; + + __cpu_khz = HYPERVISOR_shared_info->cpu_freq; + __cpu_khz /= 1000; + cpu_khz = (uint32_t)__cpu_khz; + printk("Xen reported: %lu.%03lu MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); + + /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz = + (2^32 * 1 / (clocks/us)) */ + { + unsigned long eax=0, edx=1000; + __asm__("divl %2" + :"=a" (fast_gettimeoffset_quotient), "=d" (edx) + :"r" (cpu_khz), + "0" (eax), "1" (edx)); + } + + set_cyc2ns_scale(cpu_khz/1000); + timer_freq = tsc_freq = xen_timecounter.tc_frequency = cpu_khz * 1000; + tc_init(&xen_timecounter); + + + rdtscll(alarm); +} + +/* + * Initialize the time of day register, based on the time base which is, e.g. + * from a filesystem. + */ +void +inittodr(time_t base) +{ + int s, y; + struct timespec ts; + + s = splclock(); + if (base) { + ts.tv_sec = base; + ts.tv_nsec = 0; + tc_setclock(&ts); + } + + y = time_second - shadow_tv.tv_sec; + if (y <= -2 || y >= 2) { + /* badly off, adjust it */ + ts.tv_sec = shadow_tv.tv_sec; + ts.tv_nsec = shadow_tv.tv_usec * 1000; + tc_setclock(&ts); + } + splx(s); +} + +/* + * Write system time back to RTC. Not supported for guest domains. + */ +void +resettodr() +{ +} + + +/* + * Start clocks running. + */ +void +cpu_initclocks() +{ + int diag; + int time_irq = bind_virq_to_irq(VIRQ_TIMER); + + if ((diag = intr_add_handler("clk", time_irq, + (driver_intr_t *)clkintr, NULL, + INTR_TYPE_CLK | INTR_FAST, NULL))) { + panic("failed to register clock interrupt: %d\n", diag); + } + + /* should fast clock be enabled ? */ + + /* initialize xen values */ + __get_time_values_from_xen(); + processed_system_time = shadow_system_time; +} + +void +cpu_startprofclock(void) +{ + + printf("cpu_startprofclock: profiling clock is not supported\n"); +} + +void +cpu_stopprofclock(void) +{ + + printf("cpu_stopprofclock: profiling clock is not supported\n"); +} + +static uint32_t +xen_get_timecount(struct timecounter *tc) +{ + __get_time_values_from_xen(); + return shadow_tsc_stamp; +} + +/* + * Track behavior of cur_timer->get_offset() functionality in timer_tsc.c + */ +#undef rdtsc +#define rdtsc(low,high) \ + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) + +static uint32_t +xen_get_offset(void) +{ + register unsigned long eax, edx; + + /* Read the Time Stamp Counter */ + + rdtsc(eax,edx); + + /* .. relative to previous jiffy (32 bits is enough) */ + eax -= shadow_tsc_stamp; + + /* + * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient + * = (tsc_low delta) * (usecs_per_clock) + * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) + * + * Using a mull instead of a divl saves up to 31 clock cycles + * in the critical path. + */ + + __asm__("mull %2" + :"=a" (eax), "=d" (edx) + :"rm" (fast_gettimeoffset_quotient), + "0" (eax)); + + /* our adjusted time offset in microseconds */ + return edx; +} + +void +idle_block(void) +{ + if (HYPERVISOR_set_timer_op(processed_system_time + NS_PER_TICK) == 0) + HYPERVISOR_block(); +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/critical.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/critical.c new file mode 100644 index 0000000000..ce388fa048 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/critical.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2002 Matthew Dillon. All Rights Reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/critical.c,v 1.12 2003/11/03 21:06:54 jhb Exp $"); + +#include +#include +#include +#include +#include + +/* + * cpu_critical_fork_exit() - cleanup after fork + * + * Enable interrupts in the saved copy of eflags. + */ +void +cpu_critical_fork_exit(void) +{ + curthread->td_md.md_savecrit = 0; +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/ctrl_if.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/ctrl_if.c new file mode 100644 index 0000000000..8e8ce9fde7 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/ctrl_if.c @@ -0,0 +1,476 @@ +/****************************************************************************** + * ctrl_if.c + * + * Management functions for special interface to the domain controller. + * + * Copyright (c) 2004, K A Fraser + * Copyright (c) 2004, K M Macy + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* + * Only used by initial domain which must create its own control-interface + * event channel. This value is picked up by the user-space domain controller + * via an ioctl. + */ +int initdom_ctrlif_domcontroller_port = -1; + +static int ctrl_if_evtchn; +static int ctrl_if_irq; +static struct mtx ctrl_if_lock; +static int * ctrl_if_wchan = &ctrl_if_evtchn; + + +static CONTROL_RING_IDX ctrl_if_tx_resp_cons; +static CONTROL_RING_IDX ctrl_if_rx_req_cons; + +/* Incoming message requests. */ + /* Primary message type -> message handler. */ +static ctrl_msg_handler_t ctrl_if_rxmsg_handler[256]; + /* Primary message type -> callback in process context? */ +static unsigned long ctrl_if_rxmsg_blocking_context[256/sizeof(unsigned long)]; + /* Queue up messages to be handled in process context. */ +static ctrl_msg_t ctrl_if_rxmsg_deferred[CONTROL_RING_SIZE]; +static CONTROL_RING_IDX ctrl_if_rxmsg_deferred_prod; +static CONTROL_RING_IDX ctrl_if_rxmsg_deferred_cons; + +/* Incoming message responses: message identifier -> message handler/id. */ +static struct { + ctrl_msg_handler_t fn; + unsigned long id; +} ctrl_if_txmsg_id_mapping[CONTROL_RING_SIZE]; + +/* + * FreeBSD task queues don't allow you to requeue an already executing task. + * Since ctrl_if_interrupt clears the TX_FULL condition and schedules any + * waiting tasks, which themselves may need to schedule a new task + * (due to new a TX_FULL condition), we ping-pong between these A/B task queues. + * The interrupt runs anything on the current queue and moves the index so that + * future schedulings occur on the next queue. We should never get into a + * situation where there is a task scheduleded on both the A & B queues. + */ +TASKQUEUE_DECLARE(ctrl_if_txA); +TASKQUEUE_DEFINE(ctrl_if_txA, NULL, NULL, {}); +TASKQUEUE_DECLARE(ctrl_if_txB); +TASKQUEUE_DEFINE(ctrl_if_txB, NULL, NULL, {}); +struct taskqueue **taskqueue_ctrl_if_tx[2] = { &taskqueue_ctrl_if_txA, + &taskqueue_ctrl_if_txB }; +int ctrl_if_idx; + +static struct task ctrl_if_rx_tasklet; +static struct task ctrl_if_tx_tasklet; + /* Passed to schedule_task(). */ +static struct task ctrl_if_rxmsg_deferred_task; + + + +#define get_ctrl_if() ((control_if_t *)((char *)HYPERVISOR_shared_info + 2048)) +#define TX_FULL(_c) \ + (((_c)->tx_req_prod - ctrl_if_tx_resp_cons) == CONTROL_RING_SIZE) + +static void +ctrl_if_notify_controller(void) +{ + notify_via_evtchn(ctrl_if_evtchn); +} + +static void +ctrl_if_rxmsg_default_handler(ctrl_msg_t *msg, unsigned long id) +{ + msg->length = 0; + ctrl_if_send_response(msg); +} + +static void +__ctrl_if_tx_tasklet(void *context __unused, int pending __unused) +{ + control_if_t *ctrl_if = get_ctrl_if(); + ctrl_msg_t *msg; + int was_full = TX_FULL(ctrl_if); + + while ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ) + { + msg = &ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if_tx_resp_cons)]; + + /* Execute the callback handler, if one was specified. */ + if ( msg->id != 0xFF ) + { + (*ctrl_if_txmsg_id_mapping[msg->id].fn)( + msg, ctrl_if_txmsg_id_mapping[msg->id].id); + smp_mb(); /* Execute, /then/ free. */ + ctrl_if_txmsg_id_mapping[msg->id].fn = NULL; + } + + /* + * Step over the message in the ring /after/ finishing reading it. As + * soon as the index is updated then the message may get blown away. + */ + smp_mb(); + ctrl_if_tx_resp_cons++; + } + + if ( was_full && !TX_FULL(ctrl_if) ) + { + wakeup(ctrl_if_wchan); + + /* bump idx so future enqueues will occur on the next taskq + * process any currently pending tasks + */ + ctrl_if_idx++; + taskqueue_run(*taskqueue_ctrl_if_tx[(ctrl_if_idx-1) & 1]); + } +} + +static void +__ctrl_if_rxmsg_deferred_task(void *context __unused, int pending __unused) +{ + ctrl_msg_t *msg; + + while ( ctrl_if_rxmsg_deferred_cons != ctrl_if_rxmsg_deferred_prod ) + { + msg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX( + ctrl_if_rxmsg_deferred_cons++)]; + (*ctrl_if_rxmsg_handler[msg->type])(msg, 0); + } +} + +static void +__ctrl_if_rx_tasklet(void *context __unused, int pending __unused) +{ + control_if_t *ctrl_if = get_ctrl_if(); + ctrl_msg_t msg, *pmsg; + + while ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) + { + pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)]; + memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg)); + if ( msg.length != 0 ) + memcpy(msg.msg, pmsg->msg, msg.length); + if ( test_bit(msg.type, &ctrl_if_rxmsg_blocking_context) ) + { + pmsg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX( + ctrl_if_rxmsg_deferred_prod++)]; + memcpy(pmsg, &msg, offsetof(ctrl_msg_t, msg) + msg.length); + taskqueue_enqueue(taskqueue_thread, &ctrl_if_rxmsg_deferred_task); + } + else + { + (*ctrl_if_rxmsg_handler[msg.type])(&msg, 0); + } + } +} + +static void +ctrl_if_interrupt(void *ctrl_sc) +/* (int irq, void *dev_id, struct pt_regs *regs) */ +{ + control_if_t *ctrl_if = get_ctrl_if(); + + if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod ) + taskqueue_enqueue(taskqueue_swi, &ctrl_if_tx_tasklet); + + + if ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod ) + taskqueue_enqueue(taskqueue_swi, &ctrl_if_rx_tasklet); +} + +int +ctrl_if_send_message_noblock( + ctrl_msg_t *msg, + ctrl_msg_handler_t hnd, + unsigned long id) +{ + control_if_t *ctrl_if = get_ctrl_if(); + unsigned long flags; + int i; + + mtx_lock_irqsave(&ctrl_if_lock, flags); + + if ( TX_FULL(ctrl_if) ) + { + mtx_unlock_irqrestore(&ctrl_if_lock, flags); + return EAGAIN; + } + + msg->id = 0xFF; + if ( hnd != NULL ) + { + for ( i = 0; ctrl_if_txmsg_id_mapping[i].fn != NULL; i++ ) + continue; + ctrl_if_txmsg_id_mapping[i].fn = hnd; + ctrl_if_txmsg_id_mapping[i].id = id; + msg->id = i; + } + + memcpy(&ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if->tx_req_prod)], + msg, sizeof(*msg)); + wmb(); /* Write the message before letting the controller peek at it. */ + ctrl_if->tx_req_prod++; + + mtx_unlock_irqrestore(&ctrl_if_lock, flags); + + ctrl_if_notify_controller(); + + return 0; +} + +int +ctrl_if_send_message_block( + ctrl_msg_t *msg, + ctrl_msg_handler_t hnd, + unsigned long id, + long wait_state) +{ + int rc, sst = 0; + + /* Fast path. */ + if ( (rc = ctrl_if_send_message_noblock(msg, hnd, id)) != EAGAIN ) + return rc; + + + for ( ; ; ) + { + + if ( (rc = ctrl_if_send_message_noblock(msg, hnd, id)) != EAGAIN ) + break; + + if ( sst != 0) + return EINTR; + + sst = tsleep(ctrl_if_wchan, PWAIT|PCATCH, "ctlrwt", 10); + } + + return rc; +} + +int +ctrl_if_enqueue_space_callback(struct task *task) +{ + control_if_t *ctrl_if = get_ctrl_if(); + + /* Fast path. */ + if ( !TX_FULL(ctrl_if) ) + return 0; + + (void)taskqueue_enqueue(*taskqueue_ctrl_if_tx[(ctrl_if_idx & 1)], task); + + /* + * We may race execution of the task queue, so return re-checked status. If + * the task is not executed despite the ring being non-full then we will + * certainly return 'not full'. + */ + smp_mb(); + return TX_FULL(ctrl_if); +} + +void +ctrl_if_send_response(ctrl_msg_t *msg) +{ + control_if_t *ctrl_if = get_ctrl_if(); + unsigned long flags; + ctrl_msg_t *dmsg; + + /* + * NB. The response may the original request message, modified in-place. + * In this situation we may have src==dst, so no copying is required. + */ + mtx_lock_irqsave(&ctrl_if_lock, flags); + dmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if->rx_resp_prod)]; + if ( dmsg != msg ) + memcpy(dmsg, msg, sizeof(*msg)); + wmb(); /* Write the message before letting the controller peek at it. */ + ctrl_if->rx_resp_prod++; + mtx_unlock_irqrestore(&ctrl_if_lock, flags); + + ctrl_if_notify_controller(); +} + +int +ctrl_if_register_receiver( + uint8_t type, + ctrl_msg_handler_t hnd, + unsigned int flags) +{ + unsigned long _flags; + int inuse; + + mtx_lock_irqsave(&ctrl_if_lock, _flags); + + inuse = (ctrl_if_rxmsg_handler[type] != ctrl_if_rxmsg_default_handler); + + if ( inuse ) + { + printk("Receiver %p already established for control " + "messages of type %d.\n", ctrl_if_rxmsg_handler[type], type); + } + else + { + ctrl_if_rxmsg_handler[type] = hnd; + clear_bit(type, &ctrl_if_rxmsg_blocking_context); + if ( flags == CALLBACK_IN_BLOCKING_CONTEXT ) + { + set_bit(type, &ctrl_if_rxmsg_blocking_context); + } + } + + mtx_unlock_irqrestore(&ctrl_if_lock, _flags); + + return !inuse; +} + +void +ctrl_if_unregister_receiver(uint8_t type, ctrl_msg_handler_t hnd) +{ + unsigned long flags; + + mtx_lock_irqsave(&ctrl_if_lock, flags); + + if ( ctrl_if_rxmsg_handler[type] != hnd ) + printk("Receiver %p is not registered for control " + "messages of type %d.\n", hnd, type); + else + ctrl_if_rxmsg_handler[type] = ctrl_if_rxmsg_default_handler; + + mtx_unlock_irqrestore(&ctrl_if_lock, flags); + + /* Ensure that @hnd will not be executed after this function returns. */ + /* XXX need rx_tasklet_lock -- can cheat for now?*/ +#ifdef notyet + tasklet_unlock_wait(&ctrl_if_rx_tasklet); +#endif +} + +void +ctrl_if_suspend(void) +{ + /* I'm not sure what the equivalent is - we aren't going to support suspend + * yet anyway + */ +#ifdef notyet + free_irq(ctrl_if_irq, NULL); +#endif + unbind_evtchn_from_irq(ctrl_if_evtchn); +} + +/** Reset the control interface progress pointers. + * Marks the queues empty if 'clear' non-zero. + */ +static void +ctrl_if_reset(int clear) +{ + control_if_t *ctrl_if = get_ctrl_if(); + + if (clear) { + *ctrl_if = (control_if_t){}; + } + + ctrl_if_tx_resp_cons = ctrl_if->tx_resp_prod; + ctrl_if_rx_req_cons = ctrl_if->rx_resp_prod; +} + + +void +ctrl_if_resume(void) +{ + if ( xen_start_info->flags & SIF_INITDOMAIN ) + { + /* + * The initial domain must create its own domain-controller link. + * The controller is probably not running at this point, but will + * pick up its end of the event channel from + */ + evtchn_op_t op; + op.cmd = EVTCHNOP_bind_interdomain; + op.u.bind_interdomain.dom1 = DOMID_SELF; + op.u.bind_interdomain.dom2 = DOMID_SELF; + op.u.bind_interdomain.port1 = 0; + op.u.bind_interdomain.port2 = 0; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + panic("event_channel_op failed\n"); + xen_start_info->domain_controller_evtchn = op.u.bind_interdomain.port1; + initdom_ctrlif_domcontroller_port = op.u.bind_interdomain.port2; + } + + ctrl_if_reset(0); + + ctrl_if_evtchn = xen_start_info->domain_controller_evtchn; + ctrl_if_irq = bind_evtchn_to_irq(ctrl_if_evtchn); + + /* + * I have not taken the time to determine what the interrupt thread priorities + * correspond to - this interface is used for network and disk, network would + * seem higher priority, hence I'm using it + */ + + intr_add_handler("ctrl-if", ctrl_if_irq, (driver_intr_t*)ctrl_if_interrupt, + NULL, INTR_TYPE_NET | INTR_MPSAFE, NULL); +} + +static void +ctrl_if_init(void *dummy __unused) +{ + int i; + + for ( i = 0; i < 256; i++ ) + ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler; + + mtx_init(&ctrl_if_lock, "ctrlif", NULL, MTX_SPIN | MTX_NOWITNESS); + + TASK_INIT(&ctrl_if_tx_tasklet, 0, __ctrl_if_tx_tasklet, NULL); + + TASK_INIT(&ctrl_if_rx_tasklet, 0, __ctrl_if_rx_tasklet, NULL); + + TASK_INIT(&ctrl_if_rxmsg_deferred_task, 0, __ctrl_if_rxmsg_deferred_task, NULL); + + ctrl_if_reset(1); + ctrl_if_resume(); +} + +/* + * !! The following are DANGEROUS FUNCTIONS !! + * Use with care [for example, see xencons_force_flush()]. + */ + +int +ctrl_if_transmitter_empty(void) +{ + return (get_ctrl_if()->tx_req_prod == ctrl_if_tx_resp_cons); +} + +void +ctrl_if_discard_responses(void) +{ + ctrl_if_tx_resp_cons = get_ctrl_if()->tx_resp_prod; +} + +SYSINIT(ctrl_if_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, ctrl_if_init, NULL); diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/db_interface.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/db_interface.c new file mode 100644 index 0000000000..57aa4e2ef4 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/db_interface.c @@ -0,0 +1,209 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/db_interface.c,v 1.77 2003/11/08 03:01:26 alc Exp $"); + +/* + * Interface to new debugger. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef SMP +#include /** CPUSTOP_ON_DDBBREAK */ +#endif + +#include +#include + +#include + +#include +#include + + +static jmp_buf *db_nofault = 0; +extern jmp_buf db_jmpbuf; + +extern void gdb_handle_exception(db_regs_t *, int, int); + +int db_active; +db_regs_t ddb_regs; + +static __inline u_short +rss(void) +{ + u_short ss; +#ifdef __GNUC__ + __asm __volatile("mov %%ss,%0" : "=r" (ss)); +#else + ss = 0; /* XXXX Fix for other compilers. */ +#endif + return ss; +} + +/* + * kdb_trap - field a TRACE or BPT trap + */ +int +kdb_trap(int type, int code, struct i386_saved_state *regs) +{ + volatile int ddb_mode = !(boothowto & RB_GDB); + + disable_intr(); + + if (ddb_mode) { + /* we can't do much as a guest domain except print a + * backtrace and die gracefuly. The reason is that we + * can't get character input to make this work. + */ + db_active = 1; + db_print_backtrace(); + db_printf("************ Domain shutting down ************\n"); + HYPERVISOR_shutdown(); + } else { + Debugger("kdb_trap"); + } + return (1); +} + +/* + * Read bytes from kernel address space for debugger. + */ +void +db_read_bytes(vm_offset_t addr, size_t size, char *data) +{ + char *src; + + db_nofault = &db_jmpbuf; + + src = (char *)addr; + while (size-- > 0) + *data++ = *src++; + + db_nofault = 0; +} + +/* + * Write bytes to kernel address space for debugger. + */ +void +db_write_bytes(vm_offset_t addr, size_t size, char *data) +{ + char *dst; + + pt_entry_t *ptep0 = NULL; + pt_entry_t oldmap0 = 0; + vm_offset_t addr1; + pt_entry_t *ptep1 = NULL; + pt_entry_t oldmap1 = 0; + + db_nofault = &db_jmpbuf; + + if (addr > trunc_page((vm_offset_t)btext) - size && + addr < round_page((vm_offset_t)etext)) { + + ptep0 = pmap_pte(kernel_pmap, addr); + oldmap0 = *ptep0; + *ptep0 |= PG_RW; + + /* Map another page if the data crosses a page boundary. */ + if ((*ptep0 & PG_PS) == 0) { + addr1 = trunc_page(addr + size - 1); + if (trunc_page(addr) != addr1) { + ptep1 = pmap_pte(kernel_pmap, addr1); + oldmap1 = *ptep1; + *ptep1 |= PG_RW; + } + } else { + addr1 = trunc_4mpage(addr + size - 1); + if (trunc_4mpage(addr) != addr1) { + ptep1 = pmap_pte(kernel_pmap, addr1); + oldmap1 = *ptep1; + *ptep1 |= PG_RW; + } + } + + invltlb(); + } + + dst = (char *)addr; + + while (size-- > 0) + *dst++ = *data++; + + db_nofault = 0; + + if (ptep0) { + *ptep0 = oldmap0; + + if (ptep1) + *ptep1 = oldmap1; + + invltlb(); + } +} + +/* + * XXX + * Move this to machdep.c and allow it to be called if any debugger is + * installed. + */ +void +Debugger(const char *msg) +{ + static volatile u_int in_Debugger; + + /* + * XXX + * Do nothing if the console is in graphics mode. This is + * OK if the call is for the debugger hotkey but not if the call + * is a weak form of panicing. + */ + if (cons_unavail && !(boothowto & RB_GDB)) + return; + + if (atomic_cmpset_acq_int(&in_Debugger, 0, 1)) { + db_printf("Debugger(\"%s\")\n", msg); + breakpoint(); + atomic_store_rel_int(&in_Debugger, 0); + } +} + +void +db_show_mdpcpu(struct pcpu *pc) +{ + + db_printf("APIC ID = %d\n", pc->pc_apic_id); + db_printf("currentldt = 0x%x\n", pc->pc_currentldt); +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/evtchn.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/evtchn.c new file mode 100644 index 0000000000..635a3bfe4e --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/evtchn.c @@ -0,0 +1,580 @@ +/****************************************************************************** + * evtchn.c + * + * Communication via Xen event channels. + * + * Copyright (c) 2002-2004, K A Fraser + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +static struct mtx irq_mapping_update_lock; + +#define TODO printf("%s: not implemented!\n", __func__) + +/* IRQ <-> event-channel mappings. */ +static int evtchn_to_irq[NR_EVENT_CHANNELS]; +static int irq_to_evtchn[NR_IRQS]; + +/* IRQ <-> VIRQ mapping. */ +static int virq_to_irq[NR_VIRQS]; + +/* Reference counts for bindings to IRQs. */ +static int irq_bindcount[NR_IRQS]; + +#define VALID_EVTCHN(_chn) ((_chn) != -1) + +/* + * Force a proper event-channel callback from Xen after clearing the + * callback mask. We do this in a very simple manner, by making a call + * down into Xen. The pending flag will be checked by Xen on return. + */ +void force_evtchn_callback(void) +{ + (void)HYPERVISOR_xen_version(0); +} + +void +evtchn_do_upcall(struct intrframe *frame) +{ + unsigned long l1, l2; + unsigned int l1i, l2i, port; + int irq, owned; + unsigned long flags; + shared_info_t *s = HYPERVISOR_shared_info; + + local_irq_save(flags); + + while ( s->vcpu_data[0].evtchn_upcall_pending ) + { + s->vcpu_data[0].evtchn_upcall_pending = 0; + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + l1 = xen_xchg(&s->evtchn_pending_sel, 0); + while ( (l1i = ffs(l1)) != 0 ) + { + l1i--; + l1 &= ~(1 << l1i); + + l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; + while ( (l2i = ffs(l2)) != 0 ) + { + l2i--; + l2 &= ~(1 << l2i); + + port = (l1i << 5) + l2i; + if ((owned = mtx_owned(&sched_lock)) != 0) + mtx_unlock_spin_flags(&sched_lock, MTX_QUIET); + if ( (irq = evtchn_to_irq[port]) != -1 ) { + struct intsrc *isrc = intr_lookup_source(irq); + intr_execute_handlers(isrc, frame); + + } else { + evtchn_device_upcall(port); + } + if (owned) + mtx_lock_spin_flags(&sched_lock, MTX_QUIET); + } + } + } + + local_irq_restore(flags); + +} + + +static int +find_unbound_irq(void) +{ + int irq; + + for ( irq = 0; irq < NR_IRQS; irq++ ) + if ( irq_bindcount[irq] == 0 ) + break; + + if ( irq == NR_IRQS ) + panic("No available IRQ to bind to: increase NR_IRQS!\n"); + + return irq; +} + +int +bind_virq_to_irq(int virq) +{ + evtchn_op_t op; + int evtchn, irq; + + mtx_lock(&irq_mapping_update_lock); + + if ( (irq = virq_to_irq[virq]) == -1 ) + { + op.cmd = EVTCHNOP_bind_virq; + op.u.bind_virq.virq = virq; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + panic("Failed to bind virtual IRQ %d\n", virq); + evtchn = op.u.bind_virq.port; + + irq = find_unbound_irq(); + evtchn_to_irq[evtchn] = irq; + irq_to_evtchn[irq] = evtchn; + + virq_to_irq[virq] = irq; + } + + irq_bindcount[irq]++; + + mtx_unlock(&irq_mapping_update_lock); + + return irq; +} + +void +unbind_virq_from_irq(int virq) +{ + evtchn_op_t op; + int irq = virq_to_irq[virq]; + int evtchn = irq_to_evtchn[irq]; + + mtx_lock(&irq_mapping_update_lock); + + if ( --irq_bindcount[irq] == 0 ) + { + op.cmd = EVTCHNOP_close; + op.u.close.dom = DOMID_SELF; + op.u.close.port = evtchn; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + panic("Failed to unbind virtual IRQ %d\n", virq); + + evtchn_to_irq[evtchn] = -1; + irq_to_evtchn[irq] = -1; + virq_to_irq[virq] = -1; + } + + mtx_unlock(&irq_mapping_update_lock); +} + +int +bind_evtchn_to_irq(int evtchn) +{ + int irq; + + mtx_lock(&irq_mapping_update_lock); + + if ( (irq = evtchn_to_irq[evtchn]) == -1 ) + { + irq = find_unbound_irq(); + evtchn_to_irq[evtchn] = irq; + irq_to_evtchn[irq] = evtchn; + } + + irq_bindcount[irq]++; + + mtx_unlock(&irq_mapping_update_lock); + + return irq; +} + +void +unbind_evtchn_from_irq(int evtchn) +{ + int irq = evtchn_to_irq[evtchn]; + + mtx_lock(&irq_mapping_update_lock); + + if ( --irq_bindcount[irq] == 0 ) + { + evtchn_to_irq[evtchn] = -1; + irq_to_evtchn[irq] = -1; + } + + mtx_unlock(&irq_mapping_update_lock); +} + + +/* + * Interface to generic handling in intr_machdep.c + */ + + +/*------------ interrupt handling --------------------------------------*/ +#define TODO printf("%s: not implemented!\n", __func__) + + struct mtx xenpic_lock; + +struct xenpic_intsrc { + struct intsrc xp_intsrc; + uint8_t xp_vector; + boolean_t xp_masked; +}; + +struct xenpic { + struct pic xp_pic; /* this MUST be first */ + uint16_t xp_numintr; + struct xenpic_intsrc xp_pins[0]; +}; + +static void xenpic_enable_dynirq_source(struct intsrc *isrc); +static void xenpic_disable_dynirq_source(struct intsrc *isrc, int); +static void xenpic_eoi_source(struct intsrc *isrc); +static void xenpic_enable_dynirq_intr(struct intsrc *isrc); +static int xenpic_vector(struct intsrc *isrc); +static int xenpic_source_pending(struct intsrc *isrc); +static void xenpic_suspend(struct intsrc *isrc); +static void xenpic_resume(struct intsrc *isrc); + + +struct pic xenpic_template = { + xenpic_enable_dynirq_source, + xenpic_disable_dynirq_source, + xenpic_eoi_source, + xenpic_enable_dynirq_intr, + xenpic_vector, + xenpic_source_pending, + xenpic_suspend, + xenpic_resume +}; + + +void +xenpic_enable_dynirq_source(struct intsrc *isrc) +{ + unsigned int irq; + struct xenpic_intsrc *xp; + + xp = (struct xenpic_intsrc *)isrc; + + if (xp->xp_masked) { + irq = xenpic_vector(isrc); + unmask_evtchn(irq_to_evtchn[irq]); + xp->xp_masked = FALSE; + } +} + +static void +xenpic_disable_dynirq_source(struct intsrc *isrc, int foo) +{ + unsigned int irq; + struct xenpic_intsrc *xp; + + xp = (struct xenpic_intsrc *)isrc; + + if (!xp->xp_masked) { + irq = xenpic_vector(isrc); + mask_evtchn(irq_to_evtchn[irq]); + xp->xp_masked = TRUE; + } + +} + +static void +xenpic_enable_dynirq_intr(struct intsrc *isrc) +{ + unsigned int irq; + + irq = xenpic_vector(isrc); + unmask_evtchn(irq_to_evtchn[irq]); +} + +static void +xenpic_eoi_source(struct intsrc *isrc) +{ + unsigned int irq = xenpic_vector(isrc); + clear_evtchn(irq_to_evtchn[irq]); +} + +static int +xenpic_vector(struct intsrc *isrc) +{ + struct xenpic_intsrc *pin = (struct xenpic_intsrc *)isrc; + return (pin->xp_vector); +} + +static int +xenpic_source_pending(struct intsrc *isrc) +{ + TODO; + return 0; +} + +static void +xenpic_suspend(struct intsrc *isrc) +{ + TODO; +} + +static void +xenpic_resume(struct intsrc *isrc) +{ + TODO; +} + +#ifdef CONFIG_PHYSDEV +/* required for support of physical devices */ +static inline void +pirq_unmask_notify(int pirq) +{ + physdev_op_t op; + if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) ) + { + op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY; + (void)HYPERVISOR_physdev_op(&op); + } +} + +static inline void +pirq_query_unmask(int pirq) +{ + physdev_op_t op; + op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY; + op.u.irq_status_query.irq = pirq; + (void)HYPERVISOR_physdev_op(&op); + clear_bit(pirq, &pirq_needs_unmask_notify[0]); + if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY ) + set_bit(pirq, &pirq_needs_unmask_notify[0]); +} + +/* + * On startup, if there is no action associated with the IRQ then we are + * probing. In this case we should not share with others as it will confuse us. + */ +#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL) + +static unsigned int startup_pirq(unsigned int irq) +{ + evtchn_op_t op; + int evtchn; + + op.cmd = EVTCHNOP_bind_pirq; + op.u.bind_pirq.pirq = irq; + /* NB. We are happy to share unless we are probing. */ + op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + { + if ( !probing_irq(irq) ) /* Some failures are expected when probing. */ + printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq); + return 0; + } + evtchn = op.u.bind_pirq.port; + + pirq_query_unmask(irq_to_pirq(irq)); + + evtchn_to_irq[evtchn] = irq; + irq_to_evtchn[irq] = evtchn; + + unmask_evtchn(evtchn); + pirq_unmask_notify(irq_to_pirq(irq)); + + return 0; +} + +static void shutdown_pirq(unsigned int irq) +{ + evtchn_op_t op; + int evtchn = irq_to_evtchn[irq]; + + if ( !VALID_EVTCHN(evtchn) ) + return; + + mask_evtchn(evtchn); + + op.cmd = EVTCHNOP_close; + op.u.close.dom = DOMID_SELF; + op.u.close.port = evtchn; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + panic("Failed to unbind physical IRQ %d\n", irq); + + evtchn_to_irq[evtchn] = -1; + irq_to_evtchn[irq] = -1; +} + +static void enable_pirq(unsigned int irq) +{ + int evtchn = irq_to_evtchn[irq]; + if ( !VALID_EVTCHN(evtchn) ) + return; + unmask_evtchn(evtchn); + pirq_unmask_notify(irq_to_pirq(irq)); +} + +static void disable_pirq(unsigned int irq) +{ + int evtchn = irq_to_evtchn[irq]; + if ( !VALID_EVTCHN(evtchn) ) + return; + mask_evtchn(evtchn); +} + +static void ack_pirq(unsigned int irq) +{ + int evtchn = irq_to_evtchn[irq]; + if ( !VALID_EVTCHN(evtchn) ) + return; + mask_evtchn(evtchn); + clear_evtchn(evtchn); +} + +static void end_pirq(unsigned int irq) +{ + int evtchn = irq_to_evtchn[irq]; + if ( !VALID_EVTCHN(evtchn) ) + return; + if ( !(irq_desc[irq].status & IRQ_DISABLED) ) + { + unmask_evtchn(evtchn); + pirq_unmask_notify(irq_to_pirq(irq)); + } +} + +static struct hw_interrupt_type pirq_type = { + "Phys-irq", + startup_pirq, + shutdown_pirq, + enable_pirq, + disable_pirq, + ack_pirq, + end_pirq, + NULL +}; +#endif + + +static void +misdirect_interrupt(void *sc) +{ +} + +void irq_suspend(void) +{ + int virq, irq, evtchn; + + /* Unbind VIRQs from event channels. */ + for ( virq = 0; virq < NR_VIRQS; virq++ ) + { + if ( (irq = virq_to_irq[virq]) == -1 ) + continue; + evtchn = irq_to_evtchn[irq]; + + /* Mark the event channel as unused in our table. */ + evtchn_to_irq[evtchn] = -1; + irq_to_evtchn[irq] = -1; + } + + /* + * We should now be unbound from all event channels. Stale bindings to + * PIRQs and/or inter-domain event channels will cause us to barf here. + */ + for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ ) + if ( evtchn_to_irq[evtchn] != -1 ) + panic("Suspend attempted while bound to evtchn %d.\n", evtchn); +} + + +void irq_resume(void) +{ + evtchn_op_t op; + int virq, irq, evtchn; + + for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ ) + mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */ + + for ( virq = 0; virq < NR_VIRQS; virq++ ) + { + if ( (irq = virq_to_irq[virq]) == -1 ) + continue; + + /* Get a new binding from Xen. */ + op.cmd = EVTCHNOP_bind_virq; + op.u.bind_virq.virq = virq; + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + panic("Failed to bind virtual IRQ %d\n", virq); + evtchn = op.u.bind_virq.port; + + /* Record the new mapping. */ + evtchn_to_irq[evtchn] = irq; + irq_to_evtchn[irq] = evtchn; + + /* Ready for use. */ + unmask_evtchn(evtchn); + } +} + +static void +evtchn_init(void *dummy __unused) +{ + int i; + struct xenpic *xp; + struct xenpic_intsrc *pin; + + /* + * xenpic_lock: in order to allow an interrupt to occur in a critical + * section, to set pcpu->ipending (etc...) properly, we + * must be able to get the icu lock, so it can't be + * under witness. + */ + mtx_init(&irq_mapping_update_lock, "xp", NULL, MTX_DEF); + + /* No VIRQ -> IRQ mappings. */ + for ( i = 0; i < NR_VIRQS; i++ ) + virq_to_irq[i] = -1; + + /* No event-channel -> IRQ mappings. */ + for ( i = 0; i < NR_EVENT_CHANNELS; i++ ) + { + evtchn_to_irq[i] = -1; + mask_evtchn(i); /* No event channels are 'live' right now. */ + } + + /* No IRQ -> event-channel mappings. */ + for ( i = 0; i < NR_IRQS; i++ ) + irq_to_evtchn[i] = -1; + + xp = malloc(sizeof(struct xenpic) + NR_DYNIRQS*sizeof(struct xenpic_intsrc), M_DEVBUF, M_WAITOK); + xp->xp_pic = xenpic_template; + xp->xp_numintr = NR_DYNIRQS; + bzero(xp->xp_pins, sizeof(struct xenpic_intsrc) * NR_DYNIRQS); + + for ( i = 0, pin = xp->xp_pins; i < NR_DYNIRQS; i++, pin++ ) + { + /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ + irq_bindcount[dynirq_to_irq(i)] = 0; + + pin->xp_intsrc.is_pic = (struct pic *)xp; + pin->xp_vector = i; + intr_register_source(&pin->xp_intsrc); + } + /* We don't currently have any support for physical devices in XenoFreeBSD + * so leaving this out for the moment for the sake of expediency. + */ +#ifdef notyet + for ( i = 0; i < NR_PIRQS; i++ ) + { + /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */ + irq_bindcount[pirq_to_irq(i)] = 1; + + irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED; + irq_desc[pirq_to_irq(i)].action = 0; + irq_desc[pirq_to_irq(i)].depth = 1; + irq_desc[pirq_to_irq(i)].handler = &pirq_type; + } + +#endif + (void) intr_add_handler("xb_mis", bind_virq_to_irq(VIRQ_MISDIRECT), + (driver_intr_t *)misdirect_interrupt, + NULL, INTR_TYPE_MISC, NULL); +} + +SYSINIT(evtchn_init, SI_SUB_INTR, SI_ORDER_ANY, evtchn_init, NULL); diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/exception.s b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/exception.s new file mode 100644 index 0000000000..4adb61a350 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/exception.s @@ -0,0 +1,428 @@ +/*- + * Copyright (c) 1989, 1990 William F. Jolitz. + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/i386/exception.s,v 1.106 2003/11/03 22:08:52 jhb Exp $ + */ + +#include "opt_npx.h" + +#include +#include +#include + +#include "assym.s" + +#define SEL_RPL_MASK 0x0002 +/* Offsets into shared_info_t. */ +#define evtchn_upcall_pending /* 0 */ +#define evtchn_upcall_mask 1 +#define XEN_BLOCK_EVENTS(reg) movb $1,evtchn_upcall_mask(reg) +#define XEN_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg) +#define XEN_TEST_PENDING(reg) testb $0x1,evtchn_upcall_pending(reg) + + +#define POPA \ + popl %edi; \ + popl %esi; \ + popl %ebp; \ + popl %ebx; \ + popl %ebx; \ + popl %edx; \ + popl %ecx; \ + popl %eax; + + .text + +/*****************************************************************************/ +/* Trap handling */ +/*****************************************************************************/ +/* + * Trap and fault vector routines. + * + * Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on + * the stack that mostly looks like an interrupt, but does not disable + * interrupts. A few of the traps we are use are interrupt gates, + * SDT_SYS386IGT, which are nearly the same thing except interrupts are + * disabled on entry. + * + * The cpu will push a certain amount of state onto the kernel stack for + * the current process. The amount of state depends on the type of trap + * and whether the trap crossed rings or not. See i386/include/frame.h. + * At the very least the current EFLAGS (status register, which includes + * the interrupt disable state prior to the trap), the code segment register, + * and the return instruction pointer are pushed by the cpu. The cpu + * will also push an 'error' code for certain traps. We push a dummy + * error code for those traps where the cpu doesn't in order to maintain + * a consistent frame. We also push a contrived 'trap number'. + * + * The cpu does not push the general registers, we must do that, and we + * must restore them prior to calling 'iret'. The cpu adjusts the %cs and + * %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we + * must load them with appropriate values for supervisor mode operation. + */ + +MCOUNT_LABEL(user) +MCOUNT_LABEL(btrap) + +IDTVEC(div) + pushl $0; pushl $0; TRAP(T_DIVIDE) +IDTVEC(dbg) + pushl $0; pushl $0; TRAP(T_TRCTRAP) +IDTVEC(nmi) + pushl $0; pushl $0; TRAP(T_NMI) +IDTVEC(bpt) + pushl $0; pushl $0; TRAP(T_BPTFLT) +IDTVEC(ofl) + pushl $0; pushl $0; TRAP(T_OFLOW) +IDTVEC(bnd) + pushl $0; pushl $0; TRAP(T_BOUND) +IDTVEC(ill) + pushl $0; pushl $0; TRAP(T_PRIVINFLT) +IDTVEC(dna) + pushl $0; pushl $0; TRAP(T_DNA) +IDTVEC(fpusegm) + pushl $0; pushl $0; TRAP(T_FPOPFLT) +IDTVEC(tss) + pushl $0; TRAP(T_TSSFLT) +IDTVEC(missing) + pushl $0; TRAP(T_SEGNPFLT) +IDTVEC(stk) + pushl $0; TRAP(T_STKFLT) +IDTVEC(prot) + pushl $0; TRAP(T_PROTFLT) +IDTVEC(page) + TRAP(T_PAGEFLT) +IDTVEC(mchk) + pushl $0; pushl $0; TRAP(T_MCHK) +IDTVEC(rsvd) + pushl $0; pushl $0; TRAP(T_RESERVED) +IDTVEC(fpu) + pushl $0; pushl $0; TRAP(T_ARITHTRAP) +IDTVEC(align) + pushl $0; TRAP(T_ALIGNFLT) + +IDTVEC(xmm) + pushl $0; pushl $0; TRAP(T_XMMFLT) + +IDTVEC(hypervisor_callback) + pushl $T_HYPCALLBACK; pushl %eax; TRAP(T_HYPCALLBACK) + +hypervisor_callback_pending: + movl $T_HYPCALLBACK,TF_TRAPNO(%esp) + movl $T_HYPCALLBACK,TF_ERR(%esp) + jmp 11f + + /* + * alltraps entry point. Interrupts are enabled if this was a trap + * gate (TGT), else disabled if this was an interrupt gate (IGT). + * Note that int0x80_syscall is a trap gate. Only page faults + * use an interrupt gate. + */ + + SUPERALIGN_TEXT + .globl alltraps + .type alltraps,@function +alltraps: + cld + pushal + pushl %ds + pushl %es + pushl %fs +alltraps_with_regs_pushed: + movl $KDSEL,%eax + movl %eax,%ds + movl %eax,%es + movl $KPSEL,%eax + movl %eax,%fs + FAKE_MCOUNT(TF_EIP(%esp)) +calltrap: + movl TF_EIP(%esp),%eax + cmpl $scrit,%eax + jb 11f + cmpl $ecrit,%eax + jb critical_region_fixup +11: call trap + + /* + * Return via doreti to handle ASTs. + */ + MEXITCOUNT + jmp doreti + +/* + * SYSCALL CALL GATE (old entry point for a.out binaries) + * + * The intersegment call has been set up to specify one dummy parameter. + * + * This leaves a place to put eflags so that the call frame can be + * converted to a trap frame. Note that the eflags is (semi-)bogusly + * pushed into (what will be) tf_err and then copied later into the + * final spot. It has to be done this way because esp can't be just + * temporarily altered for the pushfl - an interrupt might come in + * and clobber the saved cs/eip. + */ + SUPERALIGN_TEXT +IDTVEC(lcall_syscall) + pushfl /* save eflags */ + popl 8(%esp) /* shuffle into tf_eflags */ + pushl $7 /* sizeof "lcall 7,0" */ + subl $4,%esp /* skip over tf_trapno */ + pushal + pushl %ds + pushl %es + pushl %fs + movl $KDSEL,%eax /* switch to kernel segments */ + movl %eax,%ds + movl %eax,%es + movl $KPSEL,%eax + movl %eax,%fs + FAKE_MCOUNT(TF_EIP(%esp)) + call syscall + MEXITCOUNT + jmp doreti + +/* + * Call gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80) + * + * Even though the name says 'int0x80', this is actually a TGT (trap gate) + * rather then an IGT (interrupt gate). Thus interrupts are enabled on + * entry just as they are for a normal syscall. + */ + SUPERALIGN_TEXT +IDTVEC(int0x80_syscall) + pushl $2 /* sizeof "int 0x80" */ + pushl $0xCAFE + pushl $0xDEAD + pushal + pushl %ds + pushl %es + pushl %fs + movl $KDSEL,%eax /* switch to kernel segments */ + movl %eax,%ds + movl %eax,%es + movl $KPSEL,%eax + movl %eax,%fs + FAKE_MCOUNT(TF_EIP(%esp)) + call syscall + MEXITCOUNT + jmp doreti + +ENTRY(fork_trampoline) + pushl %esp /* trapframe pointer */ + pushl %ebx /* arg1 */ + pushl %esi /* function */ + call fork_exit + addl $12,%esp + /* cut from syscall */ + + /* + * Return via doreti to handle ASTs. + */ + MEXITCOUNT + jmp doreti + + +/* +# A note on the "critical region" in our callback handler. +# We want to avoid stacking callback handlers due to events occurring +# during handling of the last event. To do this, we keep events disabled +# until weve done all processing. HOWEVER, we must enable events before +# popping the stack frame (cant be done atomically) and so it would still +# be possible to get enough handler activations to overflow the stack. +# Although unlikely, bugs of that kind are hard to track down, so wed +# like to avoid the possibility. +# So, on entry to the handler we detect whether we interrupted an +# existing activation in its critical region -- if so, we pop the current +# activation and restart the handler using the previous one. +*/ + + +/* + * void doreti(struct trapframe) + * + * Handle return from interrupts, traps and syscalls. + */ + .text + SUPERALIGN_TEXT + .globl doreti + .type doreti,@function +doreti: + FAKE_MCOUNT(bintr) /* init "from" bintr -> doreti */ +doreti_next: + testb $SEL_RPL_MASK,TF_CS(%esp) /* are we returning to user mode? */ + jz doreti_exit /* #can't handle ASTs now if not */ + +doreti_ast: + /* + * Check for ASTs atomically with returning. Disabling CPU + * interrupts provides sufficient locking even in the SMP case, + * since we will be informed of any new ASTs by an IPI. + */ + + movl HYPERVISOR_shared_info,%esi + XEN_BLOCK_EVENTS(%esi) + movl PCPU(CURTHREAD),%eax + testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%eax) + je doreti_exit + XEN_UNBLOCK_EVENTS(%esi) + pushl %esp /* pass a pointer to the trapframe */ + call ast + add $4,%esp + jmp doreti_ast + +doreti_exit: + /* + * doreti_exit: pop registers, iret. + * + * The segment register pop is a special case, since it may + * fault if (for example) a sigreturn specifies bad segment + * registers. The fault is handled in trap.c. + */ + + movl HYPERVISOR_shared_info,%esi + XEN_UNBLOCK_EVENTS(%esi) # reenable event callbacks (sti) + + .globl scrit +scrit: + XEN_TEST_PENDING(%esi) + jnz hypervisor_callback_pending /* More to go */ + MEXITCOUNT + + .globl doreti_popl_fs +doreti_popl_fs: + popl %fs + .globl doreti_popl_es +doreti_popl_es: + popl %es + .globl doreti_popl_ds +doreti_popl_ds: + popl %ds + POPA + addl $12,%esp + .globl doreti_iret +doreti_iret: + iret + .globl ecrit +ecrit: + + /* + * doreti_iret_fault and friends. Alternative return code for + * the case where we get a fault in the doreti_exit code + * above. trap() (i386/i386/trap.c) catches this specific + * case, sends the process a signal and continues in the + * corresponding place in the code below. + */ + ALIGN_TEXT + .globl doreti_iret_fault +doreti_iret_fault: + subl $12,%esp + pushal + pushl %ds + .globl doreti_popl_ds_fault +doreti_popl_ds_fault: + pushl %es + .globl doreti_popl_es_fault +doreti_popl_es_fault: + pushl %fs + .globl doreti_popl_fs_fault +doreti_popl_fs_fault: + movl $0,TF_ERR(%esp) /* XXX should be the error code */ + movl $T_PROTFLT,TF_TRAPNO(%esp) + jmp alltraps_with_regs_pushed + + + + +/* +# [How we do the fixup]. We want to merge the current stack frame with the +# just-interrupted frame. How we do this depends on where in the critical +# region the interrupted handler was executing, and so how many saved +# registers are in each frame. We do this quickly using the lookup table +# 'critical_fixup_table'. For each byte offset in the critical region, it +# provides the number of bytes which have already been popped from the +# interrupted stack frame. +*/ + +.globl critical_region_fixup +critical_region_fixup: + addl $critical_fixup_table-scrit,%eax + movzbl (%eax),%eax # %eax contains num bytes popped + movl %esp,%esi + add %eax,%esi # %esi points at end of src region + movl %esp,%edi + add $0x44,%edi # %edi points at end of dst region + movl %eax,%ecx + shr $2,%ecx # convert bytes to words + je 16f # skip loop if nothing to copy +15: subl $4,%esi # pre-decrementing copy loop + subl $4,%edi + movl (%esi),%eax + movl %eax,(%edi) + loop 15b +16: movl %edi,%esp # final %edi is top of merged stack + jmp hypervisor_callback_pending + + +critical_fixup_table: +.byte 0x0,0x0,0x0 #testb $0x1,(%esi) +.byte 0x0,0x0,0x0,0x0,0x0,0x0 #jne ea +.byte 0x0,0x0 #pop %fs +.byte 0x04 #pop %es +.byte 0x08 #pop %ds +.byte 0x0c #pop %edi +.byte 0x10 #pop %esi +.byte 0x14 #pop %ebp +.byte 0x18 #pop %ebx +.byte 0x1c #pop %ebx +.byte 0x20 #pop %edx +.byte 0x24 #pop %ecx +.byte 0x28 #pop %eax +.byte 0x2c,0x2c,0x2c #add $0xc,%esp +.byte 0x38 #iret + + +/* # Hypervisor uses this for application faults while it executes.*/ +ENTRY(failsafe_callback) + pushal + call xen_failsafe_handler +/*# call install_safe_pf_handler */ + movl 32(%esp),%ebx +1: movl %ebx,%ds + movl 36(%esp),%ebx +2: movl %ebx,%es + movl 40(%esp),%ebx +3: movl %ebx,%fs + movl 44(%esp),%ebx +4: movl %ebx,%gs +/*# call install_normal_pf_handler */ + popal + addl $16,%esp + iret + + diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/genassym.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/genassym.c new file mode 100644 index 0000000000..1e9df732c7 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/genassym.c @@ -0,0 +1,234 @@ +/*- + * Copyright (c) 1982, 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/genassym.c,v 1.146 2003/11/12 18:14:34 jhb Exp $"); + +#include "opt_apic.h" +#include "opt_compat.h" +#include "opt_kstack_pages.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DEV_APIC +#include +#endif +#include +#include +#include + +ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); +ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); +ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); +ASSYM(P_SFLAG, offsetof(struct proc, p_sflag)); +ASSYM(P_UAREA, offsetof(struct proc, p_uarea)); + +ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); +ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); +ASSYM(TD_PROC, offsetof(struct thread, td_proc)); +ASSYM(TD_MD, offsetof(struct thread, td_md)); + +ASSYM(P_MD, offsetof(struct proc, p_md)); +ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt)); + +ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); +ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); + +ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap)); +ASSYM(V_SYSCALL, offsetof(struct vmmeter, v_syscall)); +ASSYM(V_INTR, offsetof(struct vmmeter, v_intr)); +/* ASSYM(UPAGES, UPAGES);*/ +ASSYM(UAREA_PAGES, UAREA_PAGES); +ASSYM(KSTACK_PAGES, KSTACK_PAGES); +ASSYM(PAGE_SIZE, PAGE_SIZE); +ASSYM(NPTEPG, NPTEPG); +ASSYM(NPDEPG, NPDEPG); +ASSYM(NPDEPTD, NPDEPTD); +ASSYM(NPGPTD, NPGPTD); +ASSYM(PDESIZE, sizeof(pd_entry_t)); +ASSYM(PTESIZE, sizeof(pt_entry_t)); +ASSYM(PDESHIFT, PDESHIFT); +ASSYM(PTESHIFT, PTESHIFT); +ASSYM(PAGE_SHIFT, PAGE_SHIFT); +ASSYM(PAGE_MASK, PAGE_MASK); +ASSYM(PDRSHIFT, PDRSHIFT); +ASSYM(PDRMASK, PDRMASK); +ASSYM(USRSTACK, USRSTACK); +ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); +ASSYM(KERNBASE, KERNBASE); +ASSYM(KERNLOAD, KERNLOAD); +ASSYM(MCLBYTES, MCLBYTES); +ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3)); +ASSYM(PCB_EDI, offsetof(struct pcb, pcb_edi)); +ASSYM(PCB_ESI, offsetof(struct pcb, pcb_esi)); +ASSYM(PCB_EBP, offsetof(struct pcb, pcb_ebp)); +ASSYM(PCB_ESP, offsetof(struct pcb, pcb_esp)); +ASSYM(PCB_EBX, offsetof(struct pcb, pcb_ebx)); +ASSYM(PCB_EIP, offsetof(struct pcb, pcb_eip)); +ASSYM(TSS_ESP0, offsetof(struct i386tss, tss_esp0)); + +ASSYM(PCB_GS, offsetof(struct pcb, pcb_gs)); +ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0)); +ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1)); +ASSYM(PCB_DR2, offsetof(struct pcb, pcb_dr2)); +ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3)); +ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); +ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); +ASSYM(PCB_PSL, offsetof(struct pcb, pcb_psl)); +ASSYM(PCB_DBREGS, PCB_DBREGS); +ASSYM(PCB_EXT, offsetof(struct pcb, pcb_ext)); + +ASSYM(PCB_SPARE, offsetof(struct pcb, __pcb_spare)); +ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); +ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save)); +ASSYM(PCB_SAVEFPU_SIZE, sizeof(union savefpu)); +ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); +ASSYM(PCB_SWITCHOUT, offsetof(struct pcb, pcb_switchout)); + +ASSYM(PCB_SIZE, sizeof(struct pcb)); + +ASSYM(TF_TRAPNO, offsetof(struct trapframe, tf_trapno)); +ASSYM(TF_ERR, offsetof(struct trapframe, tf_err)); +ASSYM(TF_CS, offsetof(struct trapframe, tf_cs)); +ASSYM(TF_EFLAGS, offsetof(struct trapframe, tf_eflags)); +ASSYM(TF_EIP, offsetof(struct trapframe, tf_eip)); +ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler)); +#ifdef COMPAT_43 +ASSYM(SIGF_SC, offsetof(struct osigframe, sf_siginfo.si_sc)); +#endif +ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); +#ifdef COMPAT_FREEBSD4 +ASSYM(SIGF_UC4, offsetof(struct sigframe4, sf_uc)); +#endif +#ifdef COMPAT_43 +ASSYM(SC_PS, offsetof(struct osigcontext, sc_ps)); +ASSYM(SC_FS, offsetof(struct osigcontext, sc_fs)); +ASSYM(SC_GS, offsetof(struct osigcontext, sc_gs)); +ASSYM(SC_TRAPNO, offsetof(struct osigcontext, sc_trapno)); +#endif +#ifdef COMPAT_FREEBSD4 +ASSYM(UC4_EFLAGS, offsetof(struct ucontext4, uc_mcontext.mc_eflags)); +ASSYM(UC4_GS, offsetof(struct ucontext4, uc_mcontext.mc_gs)); +#endif +ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_eflags)); +ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs)); +ASSYM(ENOENT, ENOENT); +ASSYM(EFAULT, EFAULT); +ASSYM(ENAMETOOLONG, ENAMETOOLONG); +ASSYM(MAXCOMLEN, MAXCOMLEN); +ASSYM(MAXPATHLEN, MAXPATHLEN); +ASSYM(BOOTINFO_SIZE, sizeof(struct bootinfo)); +ASSYM(BI_VERSION, offsetof(struct bootinfo, bi_version)); +ASSYM(BI_KERNELNAME, offsetof(struct bootinfo, bi_kernelname)); +ASSYM(BI_NFS_DISKLESS, offsetof(struct bootinfo, bi_nfs_diskless)); +ASSYM(BI_ENDCOMMON, offsetof(struct bootinfo, bi_endcommon)); +ASSYM(NFSDISKLESS_SIZE, sizeof(struct nfs_diskless)); +ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size)); +ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab)); +ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab)); +ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend)); +ASSYM(PC_SIZEOF, sizeof(struct pcpu)); +ASSYM(PC_PRVSPACE, offsetof(struct pcpu, pc_prvspace)); +ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); +ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread)); +ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread)); +ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb)); +ASSYM(PC_COMMON_TSS, offsetof(struct pcpu, pc_common_tss)); +ASSYM(PC_COMMON_TSSD, offsetof(struct pcpu, pc_common_tssd)); +ASSYM(PC_TSS_GDT, offsetof(struct pcpu, pc_tss_gdt)); +ASSYM(PC_CURRENTLDT, offsetof(struct pcpu, pc_currentldt)); +ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid)); +ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap)); +ASSYM(PC_TRAP_NESTING, offsetof(struct pcpu, pc_trap_nesting)); + +ASSYM(PC_CR3, offsetof(struct pcpu, pc_pdir)); + +#ifdef DEV_APIC +ASSYM(LA_VER, offsetof(struct LAPIC, version)); +ASSYM(LA_TPR, offsetof(struct LAPIC, tpr)); +ASSYM(LA_EOI, offsetof(struct LAPIC, eoi)); +ASSYM(LA_SVR, offsetof(struct LAPIC, svr)); +ASSYM(LA_ICR_LO, offsetof(struct LAPIC, icr_lo)); +ASSYM(LA_ICR_HI, offsetof(struct LAPIC, icr_hi)); +ASSYM(LA_ISR, offsetof(struct LAPIC, isr0)); +#endif + +ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL)); +ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL)); +ASSYM(KPSEL, GSEL(GPRIV_SEL, SEL_KPL)); + +ASSYM(BC32SEL, GSEL(GBIOSCODE32_SEL, SEL_KPL)); +ASSYM(GPROC0_SEL, GPROC0_SEL); + +ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); +ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); + +#ifdef PC98 +#include + +ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base)); +ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat)); +#endif + +ASSYM(HYPERVISOR_STACK_SWITCH, __HYPERVISOR_stack_switch); diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/hypervisor.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/hypervisor.c new file mode 100644 index 0000000000..df9568c7d1 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/hypervisor.c @@ -0,0 +1,107 @@ +/****************************************************************************** + * hypervisor.c + * + * Communication to/from hypervisor. + * + * Copyright (c) 2002-2003, K A Fraser + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (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 WARRANTIEAS 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 + +/* XXX need to verify what the caller save registers are on x86 KMM */ +#define CALLER_SAVE __asm__("pushal; ") +#define CALLER_RESTORE __asm__("popal;") + + +/* ni == non-inline - these are only intended for use from assembler + * no reason to have them in a header - + * + */ +void ni_queue_multicall0(unsigned long op); +void ni_queue_multicall1(unsigned long op, unsigned long arg1); +void ni_queue_multicall2(unsigned long op, unsigned long arg1, + unsigned long arg2); +void ni_queue_multicall3(unsigned long op, unsigned long arg1, + unsigned long arg2, unsigned long arg3); +void ni_queue_multicall4(unsigned long op, unsigned long arg1, + unsigned long arg2, unsigned long arg4, + unsigned long arg5); + +void ni_execute_multicall_list(void); + +multicall_entry_t multicall_list[MAX_MULTICALL_ENTS]; +int nr_multicall_ents = 0; + + +void +ni_queue_multicall0(unsigned long op) +{ + CALLER_SAVE; + queue_multicall0(op); + CALLER_RESTORE; +} + +void +ni_queue_multicall1(unsigned long op, unsigned long arg1) +{ + CALLER_SAVE; + queue_multicall1(op, arg1); + CALLER_RESTORE; +} + +void +ni_queue_multicall2(unsigned long op, unsigned long arg1, + unsigned long arg2) +{ + CALLER_SAVE; + queue_multicall2(op, arg1, arg2); + CALLER_RESTORE; +} + +void +ni_queue_multicall3(unsigned long op, unsigned long arg1, + unsigned long arg2, unsigned long arg3) +{ + CALLER_SAVE; + queue_multicall3(op, arg1, arg2, arg3); + CALLER_RESTORE; +} + +void +ni_queue_multicall4(unsigned long op, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4) +{ + CALLER_SAVE; + queue_multicall4(op, arg1, arg2, arg3, arg4); + CALLER_RESTORE; +} + +void +ni_execute_multicall_list(void) +{ + CALLER_SAVE; + execute_multicall_list(); + CALLER_RESTORE; +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/i686_mem.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/i686_mem.c new file mode 100644 index 0000000000..fe21232f7a --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/i686_mem.c @@ -0,0 +1,626 @@ +/*- + * Copyright (c) 1999 Michael Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/i686_mem.c,v 1.23 2003/10/21 18:28:34 silby Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * i686 memory range operations + * + * This code will probably be impenetrable without reference to the + * Intel Pentium Pro documentation. + */ + +static char *mem_owner_bios = "BIOS"; + +#define MR686_FIXMTRR (1<<0) + +#define mrwithin(mr, a) \ + (((a) >= (mr)->mr_base) && ((a) < ((mr)->mr_base + (mr)->mr_len))) +#define mroverlap(mra, mrb) \ + (mrwithin(mra, mrb->mr_base) || mrwithin(mrb, mra->mr_base)) + +#define mrvalid(base, len) \ + ((!(base & ((1 << 12) - 1))) && /* base is multiple of 4k */ \ + ((len) >= (1 << 12)) && /* length is >= 4k */ \ + powerof2((len)) && /* ... and power of two */ \ + !((base) & ((len) - 1))) /* range is not discontiuous */ + +#define mrcopyflags(curr, new) (((curr) & ~MDF_ATTRMASK) | ((new) & MDF_ATTRMASK)) + +static int mtrrs_disabled; +TUNABLE_INT("machdep.disable_mtrrs", &mtrrs_disabled); +SYSCTL_INT(_machdep, OID_AUTO, disable_mtrrs, CTLFLAG_RDTUN, + &mtrrs_disabled, 0, "Disable i686 MTRRs."); + +static void i686_mrinit(struct mem_range_softc *sc); +static int i686_mrset(struct mem_range_softc *sc, + struct mem_range_desc *mrd, + int *arg); +static void i686_mrAPinit(struct mem_range_softc *sc); + +static struct mem_range_ops i686_mrops = { + i686_mrinit, + i686_mrset, + i686_mrAPinit +}; + +/* XXX for AP startup hook */ +static u_int64_t mtrrcap, mtrrdef; + +static struct mem_range_desc *mem_range_match(struct mem_range_softc *sc, + struct mem_range_desc *mrd); +static void i686_mrfetch(struct mem_range_softc *sc); +static int i686_mtrrtype(int flags); +#if 0 +static int i686_mrt2mtrr(int flags, int oldval); +#endif +static int i686_mtrrconflict(int flag1, int flag2); +static void i686_mrstore(struct mem_range_softc *sc); +static void i686_mrstoreone(void *arg); +static struct mem_range_desc *i686_mtrrfixsearch(struct mem_range_softc *sc, + u_int64_t addr); +static int i686_mrsetlow(struct mem_range_softc *sc, + struct mem_range_desc *mrd, + int *arg); +static int i686_mrsetvariable(struct mem_range_softc *sc, + struct mem_range_desc *mrd, + int *arg); + +/* i686 MTRR type to memory range type conversion */ +static int i686_mtrrtomrt[] = { + MDF_UNCACHEABLE, + MDF_WRITECOMBINE, + MDF_UNKNOWN, + MDF_UNKNOWN, + MDF_WRITETHROUGH, + MDF_WRITEPROTECT, + MDF_WRITEBACK +}; + +#define MTRRTOMRTLEN (sizeof(i686_mtrrtomrt) / sizeof(i686_mtrrtomrt[0])) + +static int +i686_mtrr2mrt(int val) { + if (val < 0 || val >= MTRRTOMRTLEN) + return MDF_UNKNOWN; + return i686_mtrrtomrt[val]; +} + +/* + * i686 MTRR conflicts. Writeback and uncachable may overlap. + */ +static int +i686_mtrrconflict(int flag1, int flag2) { + flag1 &= MDF_ATTRMASK; + flag2 &= MDF_ATTRMASK; + if (flag1 == flag2 || + (flag1 == MDF_WRITEBACK && flag2 == MDF_UNCACHEABLE) || + (flag2 == MDF_WRITEBACK && flag1 == MDF_UNCACHEABLE)) + return 0; + return 1; +} + +/* + * Look for an exactly-matching range. + */ +static struct mem_range_desc * +mem_range_match(struct mem_range_softc *sc, struct mem_range_desc *mrd) +{ + struct mem_range_desc *cand; + int i; + + for (i = 0, cand = sc->mr_desc; i < sc->mr_ndesc; i++, cand++) + if ((cand->mr_base == mrd->mr_base) && + (cand->mr_len == mrd->mr_len)) + return(cand); + return(NULL); +} + +/* + * Fetch the current mtrr settings from the current CPU (assumed to all + * be in sync in the SMP case). Note that if we are here, we assume + * that MTRRs are enabled, and we may or may not have fixed MTRRs. + */ +static void +i686_mrfetch(struct mem_range_softc *sc) +{ + struct mem_range_desc *mrd; + u_int64_t msrv; + int i, j, msr; + + mrd = sc->mr_desc; + + /* Get fixed-range MTRRs */ + if (sc->mr_cap & MR686_FIXMTRR) { + msr = MSR_MTRR64kBase; + for (i = 0; i < (MTRR_N64K / 8); i++, msr++) { + msrv = rdmsr(msr); + for (j = 0; j < 8; j++, mrd++) { + mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | + i686_mtrr2mrt(msrv & 0xff) | + MDF_ACTIVE; + if (mrd->mr_owner[0] == 0) + strcpy(mrd->mr_owner, mem_owner_bios); + msrv = msrv >> 8; + } + } + msr = MSR_MTRR16kBase; + for (i = 0; i < (MTRR_N16K / 8); i++, msr++) { + msrv = rdmsr(msr); + for (j = 0; j < 8; j++, mrd++) { + mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | + i686_mtrr2mrt(msrv & 0xff) | + MDF_ACTIVE; + if (mrd->mr_owner[0] == 0) + strcpy(mrd->mr_owner, mem_owner_bios); + msrv = msrv >> 8; + } + } + msr = MSR_MTRR4kBase; + for (i = 0; i < (MTRR_N4K / 8); i++, msr++) { + msrv = rdmsr(msr); + for (j = 0; j < 8; j++, mrd++) { + mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | + i686_mtrr2mrt(msrv & 0xff) | + MDF_ACTIVE; + if (mrd->mr_owner[0] == 0) + strcpy(mrd->mr_owner, mem_owner_bios); + msrv = msrv >> 8; + } + } + } + + /* Get remainder which must be variable MTRRs */ + msr = MSR_MTRRVarBase; + for (; (mrd - sc->mr_desc) < sc->mr_ndesc; msr += 2, mrd++) { + msrv = rdmsr(msr); + mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | + i686_mtrr2mrt(msrv & 0xff); + mrd->mr_base = msrv & 0x0000000ffffff000LL; + msrv = rdmsr(msr + 1); + mrd->mr_flags = (msrv & 0x800) ? + (mrd->mr_flags | MDF_ACTIVE) : + (mrd->mr_flags & ~MDF_ACTIVE); + /* Compute the range from the mask. Ick. */ + mrd->mr_len = (~(msrv & 0x0000000ffffff000LL) & 0x0000000fffffffffLL) + 1; + if (!mrvalid(mrd->mr_base, mrd->mr_len)) + mrd->mr_flags |= MDF_BOGUS; + /* If unclaimed and active, must be the BIOS */ + if ((mrd->mr_flags & MDF_ACTIVE) && (mrd->mr_owner[0] == 0)) + strcpy(mrd->mr_owner, mem_owner_bios); + } +} + +/* + * Return the MTRR memory type matching a region's flags + */ +static int +i686_mtrrtype(int flags) +{ + int i; + + flags &= MDF_ATTRMASK; + + for (i = 0; i < MTRRTOMRTLEN; i++) { + if (i686_mtrrtomrt[i] == MDF_UNKNOWN) + continue; + if (flags == i686_mtrrtomrt[i]) + return(i); + } + return(-1); +} +#if 0 +static int +i686_mrt2mtrr(int flags, int oldval) +{ + int val; + + if ((val = i686_mtrrtype(flags)) == -1) + return oldval & 0xff; + return val & 0xff; +} +#endif +/* + * Update running CPU(s) MTRRs to match the ranges in the descriptor + * list. + * + * XXX Must be called with interrupts enabled. + */ +static void +i686_mrstore(struct mem_range_softc *sc) +{ +#ifdef SMP + /* + * We should use ipi_all_but_self() to call other CPUs into a + * locking gate, then call a target function to do this work. + * The "proper" solution involves a generalised locking gate + * implementation, not ready yet. + */ + smp_rendezvous(NULL, i686_mrstoreone, NULL, (void *)sc); +#else + disable_intr(); /* disable interrupts */ + i686_mrstoreone((void *)sc); + enable_intr(); +#endif +} + +/* + * Update the current CPU's MTRRs with those represented in the + * descriptor list. Note that we do this wholesale rather than + * just stuffing one entry; this is simpler (but slower, of course). + */ +static void +i686_mrstoreone(void *arg) +{ +#if 0 + struct mem_range_softc *sc = (struct mem_range_softc *)arg; + struct mem_range_desc *mrd; + u_int64_t omsrv, msrv; + int i, j, msr; + u_int cr4save; + + mrd = sc->mr_desc; + + cr4save = rcr4(); /* save cr4 */ + if (cr4save & CR4_PGE) + load_cr4(cr4save & ~CR4_PGE); + load_cr0((rcr0() & ~CR0_NW) | CR0_CD); /* disable caches (CD = 1, NW = 0) */ + wbinvd(); /* flush caches, TLBs */ + wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) & ~0x800); /* disable MTRRs (E = 0) */ + + /* Set fixed-range MTRRs */ + if (sc->mr_cap & MR686_FIXMTRR) { + msr = MSR_MTRR64kBase; + for (i = 0; i < (MTRR_N64K / 8); i++, msr++) { + msrv = 0; + omsrv = rdmsr(msr); + for (j = 7; j >= 0; j--) { + msrv = msrv << 8; + msrv |= i686_mrt2mtrr((mrd + j)->mr_flags, omsrv >> (j*8)); + } + wrmsr(msr, msrv); + mrd += 8; + } + msr = MSR_MTRR16kBase; + for (i = 0; i < (MTRR_N16K / 8); i++, msr++) { + msrv = 0; + omsrv = rdmsr(msr); + for (j = 7; j >= 0; j--) { + msrv = msrv << 8; + msrv |= i686_mrt2mtrr((mrd + j)->mr_flags, omsrv >> (j*8)); + } + wrmsr(msr, msrv); + mrd += 8; + } + msr = MSR_MTRR4kBase; + for (i = 0; i < (MTRR_N4K / 8); i++, msr++) { + msrv = 0; + omsrv = rdmsr(msr); + for (j = 7; j >= 0; j--) { + msrv = msrv << 8; + msrv |= i686_mrt2mtrr((mrd + j)->mr_flags, omsrv >> (j*8)); + } + wrmsr(msr, msrv); + mrd += 8; + } + } + + /* Set remainder which must be variable MTRRs */ + msr = MSR_MTRRVarBase; + for (; (mrd - sc->mr_desc) < sc->mr_ndesc; msr += 2, mrd++) { + /* base/type register */ + omsrv = rdmsr(msr); + if (mrd->mr_flags & MDF_ACTIVE) { + msrv = mrd->mr_base & 0x0000000ffffff000LL; + msrv |= i686_mrt2mtrr(mrd->mr_flags, omsrv); + } else { + msrv = 0; + } + wrmsr(msr, msrv); + + /* mask/active register */ + if (mrd->mr_flags & MDF_ACTIVE) { + msrv = 0x800 | (~(mrd->mr_len - 1) & 0x0000000ffffff000LL); + } else { + msrv = 0; + } + wrmsr(msr + 1, msrv); + } + wbinvd(); /* flush caches, TLBs */ + wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) | 0x800); /* restore MTRR state */ + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* enable caches CD = 0 and NW = 0 */ + load_cr4(cr4save); /* restore cr4 */ +#endif +} + +/* + * Hunt for the fixed MTRR referencing (addr) + */ +static struct mem_range_desc * +i686_mtrrfixsearch(struct mem_range_softc *sc, u_int64_t addr) +{ + struct mem_range_desc *mrd; + int i; + + for (i = 0, mrd = sc->mr_desc; i < (MTRR_N64K + MTRR_N16K + MTRR_N4K); i++, mrd++) + if ((addr >= mrd->mr_base) && (addr < (mrd->mr_base + mrd->mr_len))) + return(mrd); + return(NULL); +} + +/* + * Try to satisfy the given range request by manipulating the fixed MTRRs that + * cover low memory. + * + * Note that we try to be generous here; we'll bloat the range out to the + * next higher/lower boundary to avoid the consumer having to know too much + * about the mechanisms here. + * + * XXX note that this will have to be updated when we start supporting "busy" ranges. + */ +static int +i686_mrsetlow(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg) +{ + struct mem_range_desc *first_md, *last_md, *curr_md; + + /* range check */ + if (((first_md = i686_mtrrfixsearch(sc, mrd->mr_base)) == NULL) || + ((last_md = i686_mtrrfixsearch(sc, mrd->mr_base + mrd->mr_len - 1)) == NULL)) + return(EINVAL); + + /* check we aren't doing something risky */ + if (!(mrd->mr_flags & MDF_FORCE)) + for (curr_md = first_md; curr_md <= last_md; curr_md++) { + if ((curr_md->mr_flags & MDF_ATTRMASK) == MDF_UNKNOWN) + return (EACCES); + } + + /* set flags, clear set-by-firmware flag */ + for (curr_md = first_md; curr_md <= last_md; curr_md++) { + curr_md->mr_flags = mrcopyflags(curr_md->mr_flags & ~MDF_FIRMWARE, mrd->mr_flags); + bcopy(mrd->mr_owner, curr_md->mr_owner, sizeof(mrd->mr_owner)); + } + + return(0); +} + + +/* + * Modify/add a variable MTRR to satisfy the request. + * + * XXX needs to be updated to properly support "busy" ranges. + */ +static int +i686_mrsetvariable(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg) +{ + struct mem_range_desc *curr_md, *free_md; + int i; + + /* + * Scan the currently active variable descriptors, look for + * one we exactly match (straight takeover) and for possible + * accidental overlaps. + * Keep track of the first empty variable descriptor in case we + * can't perform a takeover. + */ + i = (sc->mr_cap & MR686_FIXMTRR) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0; + curr_md = sc->mr_desc + i; + free_md = NULL; + for (; i < sc->mr_ndesc; i++, curr_md++) { + if (curr_md->mr_flags & MDF_ACTIVE) { + /* exact match? */ + if ((curr_md->mr_base == mrd->mr_base) && + (curr_md->mr_len == mrd->mr_len)) { + /* whoops, owned by someone */ + if (curr_md->mr_flags & MDF_BUSY) + return(EBUSY); + /* check we aren't doing something risky */ + if (!(mrd->mr_flags & MDF_FORCE) && + ((curr_md->mr_flags & MDF_ATTRMASK) == MDF_UNKNOWN)) + return (EACCES); + /* Ok, just hijack this entry */ + free_md = curr_md; + break; + } + /* non-exact overlap ? */ + if (mroverlap(curr_md, mrd)) { + /* between conflicting region types? */ + if (i686_mtrrconflict(curr_md->mr_flags, mrd->mr_flags)) + return(EINVAL); + } + } else if (free_md == NULL) { + free_md = curr_md; + } + } + /* got somewhere to put it? */ + if (free_md == NULL) + return(ENOSPC); + + /* Set up new descriptor */ + free_md->mr_base = mrd->mr_base; + free_md->mr_len = mrd->mr_len; + free_md->mr_flags = mrcopyflags(MDF_ACTIVE, mrd->mr_flags); + bcopy(mrd->mr_owner, free_md->mr_owner, sizeof(mrd->mr_owner)); + return(0); +} + +/* + * Handle requests to set memory range attributes by manipulating MTRRs. + * + */ +static int +i686_mrset(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg) +{ + struct mem_range_desc *targ; + int error = 0; + + switch(*arg) { + case MEMRANGE_SET_UPDATE: + /* make sure that what's being asked for is even possible at all */ + if (!mrvalid(mrd->mr_base, mrd->mr_len) || + i686_mtrrtype(mrd->mr_flags) == -1) + return(EINVAL); + +#define FIXTOP ((MTRR_N64K * 0x10000) + (MTRR_N16K * 0x4000) + (MTRR_N4K * 0x1000)) + + /* are the "low memory" conditions applicable? */ + if ((sc->mr_cap & MR686_FIXMTRR) && + ((mrd->mr_base + mrd->mr_len) <= FIXTOP)) { + if ((error = i686_mrsetlow(sc, mrd, arg)) != 0) + return(error); + } else { + /* it's time to play with variable MTRRs */ + if ((error = i686_mrsetvariable(sc, mrd, arg)) != 0) + return(error); + } + break; + + case MEMRANGE_SET_REMOVE: + if ((targ = mem_range_match(sc, mrd)) == NULL) + return(ENOENT); + if (targ->mr_flags & MDF_FIXACTIVE) + return(EPERM); + if (targ->mr_flags & MDF_BUSY) + return(EBUSY); + targ->mr_flags &= ~MDF_ACTIVE; + targ->mr_owner[0] = 0; + break; + + default: + return(EOPNOTSUPP); + } + + /* update the hardware */ + i686_mrstore(sc); + i686_mrfetch(sc); /* refetch to see where we're at */ + return(0); +} + +/* + * Work out how many ranges we support, initialise storage for them, + * fetch the initial settings. + */ +static void +i686_mrinit(struct mem_range_softc *sc) +{ + struct mem_range_desc *mrd; + int nmdesc = 0; + int i; + + /* XXX */ + return; + + mtrrcap = rdmsr(MSR_MTRRcap); + mtrrdef = rdmsr(MSR_MTRRdefType); + + /* For now, bail out if MTRRs are not enabled */ + if (!(mtrrdef & 0x800)) { + if (bootverbose) + printf("CPU supports MTRRs but not enabled\n"); + return; + } + nmdesc = mtrrcap & 0xff; + printf("Pentium Pro MTRR support enabled\n"); + + /* If fixed MTRRs supported and enabled */ + if ((mtrrcap & 0x100) && (mtrrdef & 0x400)) { + sc->mr_cap = MR686_FIXMTRR; + nmdesc += MTRR_N64K + MTRR_N16K + MTRR_N4K; + } + + sc->mr_desc = + (struct mem_range_desc *)malloc(nmdesc * sizeof(struct mem_range_desc), + M_MEMDESC, M_WAITOK | M_ZERO); + sc->mr_ndesc = nmdesc; + + mrd = sc->mr_desc; + + /* Populate the fixed MTRR entries' base/length */ + if (sc->mr_cap & MR686_FIXMTRR) { + for (i = 0; i < MTRR_N64K; i++, mrd++) { + mrd->mr_base = i * 0x10000; + mrd->mr_len = 0x10000; + mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; + } + for (i = 0; i < MTRR_N16K; i++, mrd++) { + mrd->mr_base = i * 0x4000 + 0x80000; + mrd->mr_len = 0x4000; + mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; + } + for (i = 0; i < MTRR_N4K; i++, mrd++) { + mrd->mr_base = i * 0x1000 + 0xc0000; + mrd->mr_len = 0x1000; + mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; + } + } + + /* + * Get current settings, anything set now is considered to have + * been set by the firmware. (XXX has something already played here?) + */ + i686_mrfetch(sc); + mrd = sc->mr_desc; + for (i = 0; i < sc->mr_ndesc; i++, mrd++) { + if (mrd->mr_flags & MDF_ACTIVE) + mrd->mr_flags |= MDF_FIRMWARE; + } +} + +/* + * Initialise MTRRs on an AP after the BSP has run the init code. + */ +static void +i686_mrAPinit(struct mem_range_softc *sc) +{ + i686_mrstoreone((void *)sc); /* set MTRRs to match BSP */ + wrmsr(MSR_MTRRdefType, mtrrdef); /* set MTRR behaviour to match BSP */ +} + +static void +i686_mem_drvinit(void *unused) +{ + /* Try for i686 MTRRs */ + if (!mtrrs_disabled && (cpu_feature & CPUID_MTRR) && + ((cpu_id & 0xf00) == 0x600 || (cpu_id & 0xf00) == 0xf00) && + ((strcmp(cpu_vendor, "GenuineIntel") == 0) || + (strcmp(cpu_vendor, "AuthenticAMD") == 0))) { + mem_range_softc.mr_op = &i686_mrops; + } +} + +SYSINIT(i686memdev,SI_SUB_DRIVERS,SI_ORDER_FIRST,i686_mem_drvinit,NULL) diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/initcpu.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/initcpu.c new file mode 100644 index 0000000000..0852fb98aa --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/initcpu.c @@ -0,0 +1,889 @@ +/*- + * Copyright (c) KATO Takenori, 1997, 1998. + * + * All rights reserved. Unpublished rights reserved under the copyright + * laws of Japan. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/initcpu.c,v 1.49 2003/11/10 15:48:30 jhb Exp $"); + +#include "opt_cpu.h" + +#include +#include +#include +#include + +#include +#include +#include + +#if !defined(CPU_ENABLE_SSE) && defined(I686_CPU) +#define CPU_ENABLE_SSE +#endif +#if defined(CPU_DISABLE_SSE) +#undef CPU_ENABLE_SSE +#endif + +void initializecpu(void); +#if defined(I586_CPU) && defined(CPU_WT_ALLOC) +void enable_K5_wt_alloc(void); +void enable_K6_wt_alloc(void); +void enable_K6_2_wt_alloc(void); +#endif + +#ifdef I486_CPU +static void init_5x86(void); +static void init_bluelightning(void); +static void init_486dlc(void); +static void init_cy486dx(void); +#ifdef CPU_I486_ON_386 +static void init_i486_on_386(void); +#endif +static void init_6x86(void); +#endif /* I486_CPU */ + +#ifdef I686_CPU +static void init_6x86MX(void); +static void init_ppro(void); +static void init_mendocino(void); +#endif + +static int hw_instruction_sse; +SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD, + &hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU"); + +/* Must *NOT* be BSS or locore will bzero these after setting them */ +int cpu = 0; /* Are we 386, 386sx, 486, etc? */ +u_int cpu_feature = 0; /* Feature flags */ +u_int cpu_high = 0; /* Highest arg to CPUID */ +u_int cpu_id = 0; /* Stepping ID */ +u_int cpu_procinfo = 0; /* HyperThreading Info / Brand Index / CLFUSH */ +char cpu_vendor[20] = ""; /* CPU Origin code */ + +#ifdef CPU_ENABLE_SSE +u_int cpu_fxsr; /* SSE enabled */ +#endif + +#ifdef I486_CPU +/* + * IBM Blue Lightning + */ +static void +init_bluelightning(void) +{ +#if 0 + u_long eflags; + +#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) + need_post_dma_flush = 1; +#endif + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() | CR0_CD | CR0_NW); + invd(); + +#ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE + wrmsr(0x1000, 0x9c92LL); /* FP operand can be cacheable on Cyrix FPU */ +#else + wrmsr(0x1000, 0x1c92LL); /* Intel FPU */ +#endif + /* Enables 13MB and 0-640KB cache. */ + wrmsr(0x1001, (0xd0LL << 32) | 0x3ff); +#ifdef CPU_BLUELIGHTNING_3X + wrmsr(0x1002, 0x04000000LL); /* Enables triple-clock mode. */ +#else + wrmsr(0x1002, 0x03000000LL); /* Enables double-clock mode. */ +#endif + + /* Enable caching in CR0. */ + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ + invd(); + write_eflags(eflags); +#endif +} + +/* + * Cyrix 486SLC/DLC/SR/DR series + */ +static void +init_486dlc(void) +{ + u_long eflags; + u_char ccr0; + + eflags = read_eflags(); + disable_intr(); + invd(); + + ccr0 = read_cyrix_reg(CCR0); +#ifndef CYRIX_CACHE_WORKS + ccr0 |= CCR0_NC1 | CCR0_BARB; + write_cyrix_reg(CCR0, ccr0); + invd(); +#else + ccr0 &= ~CCR0_NC0; +#ifndef CYRIX_CACHE_REALLY_WORKS + ccr0 |= CCR0_NC1 | CCR0_BARB; +#else + ccr0 |= CCR0_NC1; +#endif +#ifdef CPU_DIRECT_MAPPED_CACHE + ccr0 |= CCR0_CO; /* Direct mapped mode. */ +#endif + write_cyrix_reg(CCR0, ccr0); + + /* Clear non-cacheable region. */ + write_cyrix_reg(NCR1+2, NCR_SIZE_0K); + write_cyrix_reg(NCR2+2, NCR_SIZE_0K); + write_cyrix_reg(NCR3+2, NCR_SIZE_0K); + write_cyrix_reg(NCR4+2, NCR_SIZE_0K); + + write_cyrix_reg(0, 0); /* dummy write */ + + /* Enable caching in CR0. */ + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ + invd(); +#endif /* !CYRIX_CACHE_WORKS */ + write_eflags(eflags); +} + + +/* + * Cyrix 486S/DX series + */ +static void +init_cy486dx(void) +{ + u_long eflags; + u_char ccr2; + + eflags = read_eflags(); + disable_intr(); + invd(); + + ccr2 = read_cyrix_reg(CCR2); +#ifdef CPU_SUSP_HLT + ccr2 |= CCR2_SUSP_HLT; +#endif + +#ifdef PC98 + /* Enables WB cache interface pin and Lock NW bit in CR0. */ + ccr2 |= CCR2_WB | CCR2_LOCK_NW; + /* Unlock NW bit in CR0. */ + write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW); + load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ +#endif + + write_cyrix_reg(CCR2, ccr2); + write_eflags(eflags); +} + + +/* + * Cyrix 5x86 + */ +static void +init_5x86(void) +{ + u_long eflags; + u_char ccr2, ccr3, ccr4, pcr0; + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() | CR0_CD | CR0_NW); + wbinvd(); + + (void)read_cyrix_reg(CCR3); /* dummy */ + + /* Initialize CCR2. */ + ccr2 = read_cyrix_reg(CCR2); + ccr2 |= CCR2_WB; +#ifdef CPU_SUSP_HLT + ccr2 |= CCR2_SUSP_HLT; +#else + ccr2 &= ~CCR2_SUSP_HLT; +#endif + ccr2 |= CCR2_WT1; + write_cyrix_reg(CCR2, ccr2); + + /* Initialize CCR4. */ + ccr3 = read_cyrix_reg(CCR3); + write_cyrix_reg(CCR3, CCR3_MAPEN0); + + ccr4 = read_cyrix_reg(CCR4); + ccr4 |= CCR4_DTE; + ccr4 |= CCR4_MEM; +#ifdef CPU_FASTER_5X86_FPU + ccr4 |= CCR4_FASTFPE; +#else + ccr4 &= ~CCR4_FASTFPE; +#endif + ccr4 &= ~CCR4_IOMASK; + /******************************************************************** + * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time + * should be 0 for errata fix. + ********************************************************************/ +#ifdef CPU_IORT + ccr4 |= CPU_IORT & CCR4_IOMASK; +#endif + write_cyrix_reg(CCR4, ccr4); + + /* Initialize PCR0. */ + /**************************************************************** + * WARNING: RSTK_EN and LOOP_EN could make your system unstable. + * BTB_EN might make your system unstable. + ****************************************************************/ + pcr0 = read_cyrix_reg(PCR0); +#ifdef CPU_RSTK_EN + pcr0 |= PCR0_RSTK; +#else + pcr0 &= ~PCR0_RSTK; +#endif +#ifdef CPU_BTB_EN + pcr0 |= PCR0_BTB; +#else + pcr0 &= ~PCR0_BTB; +#endif +#ifdef CPU_LOOP_EN + pcr0 |= PCR0_LOOP; +#else + pcr0 &= ~PCR0_LOOP; +#endif + + /**************************************************************** + * WARNING: if you use a memory mapped I/O device, don't use + * DISABLE_5X86_LSSER option, which may reorder memory mapped + * I/O access. + * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER. + ****************************************************************/ +#ifdef CPU_DISABLE_5X86_LSSER + pcr0 &= ~PCR0_LSSER; +#else + pcr0 |= PCR0_LSSER; +#endif + write_cyrix_reg(PCR0, pcr0); + + /* Restore CCR3. */ + write_cyrix_reg(CCR3, ccr3); + + (void)read_cyrix_reg(0x80); /* dummy */ + + /* Unlock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); + load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */ + /* Lock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); + + write_eflags(eflags); +} + +#ifdef CPU_I486_ON_386 +/* + * There are i486 based upgrade products for i386 machines. + * In this case, BIOS doesn't enables CPU cache. + */ +static void +init_i486_on_386(void) +{ + u_long eflags; + +#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) + need_post_dma_flush = 1; +#endif + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0, NW = 0 */ + + write_eflags(eflags); +} +#endif + +/* + * Cyrix 6x86 + * + * XXX - What should I do here? Please let me know. + */ +static void +init_6x86(void) +{ + u_long eflags; + u_char ccr3, ccr4; + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() | CR0_CD | CR0_NW); + wbinvd(); + + /* Initialize CCR0. */ + write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); + + /* Initialize CCR1. */ +#ifdef CPU_CYRIX_NO_LOCK + write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); +#else + write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); +#endif + + /* Initialize CCR2. */ +#ifdef CPU_SUSP_HLT + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); +#else + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); +#endif + + ccr3 = read_cyrix_reg(CCR3); + write_cyrix_reg(CCR3, CCR3_MAPEN0); + + /* Initialize CCR4. */ + ccr4 = read_cyrix_reg(CCR4); + ccr4 |= CCR4_DTE; + ccr4 &= ~CCR4_IOMASK; +#ifdef CPU_IORT + write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); +#else + write_cyrix_reg(CCR4, ccr4 | 7); +#endif + + /* Initialize CCR5. */ +#ifdef CPU_WT_ALLOC + write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); +#endif + + /* Restore CCR3. */ + write_cyrix_reg(CCR3, ccr3); + + /* Unlock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); + + /* + * Earlier revision of the 6x86 CPU could crash the system if + * L1 cache is in write-back mode. + */ + if ((cyrix_did & 0xff00) > 0x1600) + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ + else { + /* Revision 2.6 and lower. */ +#ifdef CYRIX_CACHE_REALLY_WORKS + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ +#else + load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0 and NW = 1 */ +#endif + } + + /* Lock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); + + write_eflags(eflags); +} +#endif /* I486_CPU */ + +#ifdef I686_CPU +/* + * Cyrix 6x86MX (code-named M2) + * + * XXX - What should I do here? Please let me know. + */ +static void +init_6x86MX(void) +{ +#if 0 + u_long eflags; + u_char ccr3, ccr4; + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() | CR0_CD | CR0_NW); + wbinvd(); + + /* Initialize CCR0. */ + write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1); + + /* Initialize CCR1. */ +#ifdef CPU_CYRIX_NO_LOCK + write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK); +#else + write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK); +#endif + + /* Initialize CCR2. */ +#ifdef CPU_SUSP_HLT + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT); +#else + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT); +#endif + + ccr3 = read_cyrix_reg(CCR3); + write_cyrix_reg(CCR3, CCR3_MAPEN0); + + /* Initialize CCR4. */ + ccr4 = read_cyrix_reg(CCR4); + ccr4 &= ~CCR4_IOMASK; +#ifdef CPU_IORT + write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK)); +#else + write_cyrix_reg(CCR4, ccr4 | 7); +#endif + + /* Initialize CCR5. */ +#ifdef CPU_WT_ALLOC + write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC); +#endif + + /* Restore CCR3. */ + write_cyrix_reg(CCR3, ccr3); + + /* Unlock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW); + + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */ + + /* Lock NW bit in CR0. */ + write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW); + + write_eflags(eflags); +#endif +} + +static void +init_ppro(void) +{ + u_int64_t apicbase; + + /* + * Local APIC should be disabled if it is not going to be used. + */ + apicbase = rdmsr(MSR_APICBASE); + apicbase &= ~APICBASE_ENABLED; + wrmsr(MSR_APICBASE, apicbase); +} + +/* + * Initialize BBL_CR_CTL3 (Control register 3: used to configure the + * L2 cache). + */ +static void +init_mendocino(void) +{ +#ifdef CPU_PPRO2CELERON + u_long eflags; + u_int64_t bbl_cr_ctl3; + + eflags = read_eflags(); + disable_intr(); + + load_cr0(rcr0() | CR0_CD | CR0_NW); + wbinvd(); + + bbl_cr_ctl3 = rdmsr(MSR_BBL_CR_CTL3); + + /* If the L2 cache is configured, do nothing. */ + if (!(bbl_cr_ctl3 & 1)) { + bbl_cr_ctl3 = 0x134052bLL; + + /* Set L2 Cache Latency (Default: 5). */ +#ifdef CPU_CELERON_L2_LATENCY +#if CPU_L2_LATENCY > 15 +#error invalid CPU_L2_LATENCY. +#endif + bbl_cr_ctl3 |= CPU_L2_LATENCY << 1; +#else + bbl_cr_ctl3 |= 5 << 1; +#endif + wrmsr(MSR_BBL_CR_CTL3, bbl_cr_ctl3); + } + + load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); + write_eflags(eflags); +#endif /* CPU_PPRO2CELERON */ +} + +#endif /* I686_CPU */ + +/* + * Initialize CR4 (Control register 4) to enable SSE instructions. + */ +void +enable_sse(void) +{ +#ifdef XEN + return; +#endif +#if defined(CPU_ENABLE_SSE) + if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) { + load_cr4(rcr4() | CR4_FXSR | CR4_XMM); + cpu_fxsr = hw_instruction_sse = 1; + } +#endif +} + +void +initializecpu(void) +{ + + switch (cpu) { +#ifdef I486_CPU + case CPU_BLUE: + init_bluelightning(); + break; + case CPU_486DLC: + init_486dlc(); + break; + case CPU_CY486DX: + init_cy486dx(); + break; + case CPU_M1SC: + init_5x86(); + break; +#ifdef CPU_I486_ON_386 + case CPU_486: + init_i486_on_386(); + break; +#endif + case CPU_M1: + init_6x86(); + break; +#endif /* I486_CPU */ +#ifdef I686_CPU + case CPU_M2: + init_6x86MX(); + break; + case CPU_686: + if (strcmp(cpu_vendor, "GenuineIntel") == 0) { + switch (cpu_id & 0xff0) { + case 0x610: + init_ppro(); + break; + case 0x660: + init_mendocino(); + break; + } + } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { +#if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK) + /* + * Sometimes the BIOS doesn't enable SSE instructions. + * According to AMD document 20734, the mobile + * Duron, the (mobile) Athlon 4 and the Athlon MP + * support SSE. These correspond to cpu_id 0x66X + * or 0x67X. + */ + if ((cpu_feature & CPUID_XMM) == 0 && + ((cpu_id & ~0xf) == 0x660 || + (cpu_id & ~0xf) == 0x670 || + (cpu_id & ~0xf) == 0x680)) { + u_int regs[4]; + wrmsr(0xC0010015, rdmsr(0xC0010015) & ~0x08000); + do_cpuid(1, regs); + cpu_feature = regs[3]; + } +#endif + } + break; +#endif + default: + break; + } + enable_sse(); + +#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) + /* + * OS should flush L1 cache by itself because no PC-98 supports + * non-Intel CPUs. Use wbinvd instruction before DMA transfer + * when need_pre_dma_flush = 1, use invd instruction after DMA + * transfer when need_post_dma_flush = 1. If your CPU upgrade + * product supports hardware cache control, you can add the + * CPU_UPGRADE_HW_CACHE option in your kernel configuration file. + * This option eliminates unneeded cache flush instruction(s). + */ + if (strcmp(cpu_vendor, "CyrixInstead") == 0) { + switch (cpu) { +#ifdef I486_CPU + case CPU_486DLC: + need_post_dma_flush = 1; + break; + case CPU_M1SC: + need_pre_dma_flush = 1; + break; + case CPU_CY486DX: + need_pre_dma_flush = 1; +#ifdef CPU_I486_ON_386 + need_post_dma_flush = 1; +#endif + break; +#endif + default: + break; + } + } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + switch (cpu_id & 0xFF0) { + case 0x470: /* Enhanced Am486DX2 WB */ + case 0x490: /* Enhanced Am486DX4 WB */ + case 0x4F0: /* Am5x86 WB */ + need_pre_dma_flush = 1; + break; + } + } else if (strcmp(cpu_vendor, "IBM") == 0) { + need_post_dma_flush = 1; + } else { +#ifdef CPU_I486_ON_386 + need_pre_dma_flush = 1; +#endif + } +#endif /* PC98 && !CPU_UPGRADE_HW_CACHE */ +} + +#if defined(I586_CPU) && defined(CPU_WT_ALLOC) +/* + * Enable write allocate feature of AMD processors. + * Following two functions require the Maxmem variable being set. + */ +void +enable_K5_wt_alloc(void) +{ + u_int64_t msr; + register_t savecrit; + + /* + * Write allocate is supported only on models 1, 2, and 3, with + * a stepping of 4 or greater. + */ + if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) { + savecrit = intr_disable(); + msr = rdmsr(0x83); /* HWCR */ + wrmsr(0x83, msr & !(0x10)); + + /* + * We have to tell the chip where the top of memory is, + * since video cards could have frame bufferes there, + * memory-mapped I/O could be there, etc. + */ + if(Maxmem > 0) + msr = Maxmem / 16; + else + msr = 0; + msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE; +#ifdef PC98 + if (!(inb(0x43b) & 4)) { + wrmsr(0x86, 0x0ff00f0); + msr |= AMD_WT_ALLOC_PRE; + } +#else + /* + * There is no way to know wheter 15-16M hole exists or not. + * Therefore, we disable write allocate for this range. + */ + wrmsr(0x86, 0x0ff00f0); + msr |= AMD_WT_ALLOC_PRE; +#endif + wrmsr(0x85, msr); + + msr=rdmsr(0x83); + wrmsr(0x83, msr|0x10); /* enable write allocate */ + intr_restore(savecrit); + } +} + +void +enable_K6_wt_alloc(void) +{ + quad_t size; + u_int64_t whcr; + u_long eflags; + + eflags = read_eflags(); + disable_intr(); + wbinvd(); + +#ifdef CPU_DISABLE_CACHE + /* + * Certain K6-2 box becomes unstable when write allocation is + * enabled. + */ + /* + * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), + * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. + * All other bits in TR12 have no effect on the processer's operation. + * The I/O Trap Restart function (bit 9 of TR12) is always enabled + * on the AMD-K6. + */ + wrmsr(0x0000000e, (u_int64_t)0x0008); +#endif + /* Don't assume that memory size is aligned with 4M. */ + if (Maxmem > 0) + size = ((Maxmem >> 8) + 3) >> 2; + else + size = 0; + + /* Limit is 508M bytes. */ + if (size > 0x7f) + size = 0x7f; + whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1); + +#if defined(PC98) || defined(NO_MEMORY_HOLE) + if (whcr & (0x7fLL << 1)) { +#ifdef PC98 + /* + * If bit 2 of port 0x43b is 0, disable wrte allocate for the + * 15-16M range. + */ + if (!(inb(0x43b) & 4)) + whcr &= ~0x0001LL; + else +#endif + whcr |= 0x0001LL; + } +#else + /* + * There is no way to know wheter 15-16M hole exists or not. + * Therefore, we disable write allocate for this range. + */ + whcr &= ~0x0001LL; +#endif + wrmsr(0x0c0000082, whcr); + + write_eflags(eflags); +} + +void +enable_K6_2_wt_alloc(void) +{ + quad_t size; + u_int64_t whcr; + u_long eflags; + + eflags = read_eflags(); + disable_intr(); + wbinvd(); + +#ifdef CPU_DISABLE_CACHE + /* + * Certain K6-2 box becomes unstable when write allocation is + * enabled. + */ + /* + * The AMD-K6 processer provides the 64-bit Test Register 12(TR12), + * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported. + * All other bits in TR12 have no effect on the processer's operation. + * The I/O Trap Restart function (bit 9 of TR12) is always enabled + * on the AMD-K6. + */ + wrmsr(0x0000000e, (u_int64_t)0x0008); +#endif + /* Don't assume that memory size is aligned with 4M. */ + if (Maxmem > 0) + size = ((Maxmem >> 8) + 3) >> 2; + else + size = 0; + + /* Limit is 4092M bytes. */ + if (size > 0x3fff) + size = 0x3ff; + whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22); + +#if defined(PC98) || defined(NO_MEMORY_HOLE) + if (whcr & (0x3ffLL << 22)) { +#ifdef PC98 + /* + * If bit 2 of port 0x43b is 0, disable wrte allocate for the + * 15-16M range. + */ + if (!(inb(0x43b) & 4)) + whcr &= ~(1LL << 16); + else +#endif + whcr |= 1LL << 16; + } +#else + /* + * There is no way to know wheter 15-16M hole exists or not. + * Therefore, we disable write allocate for this range. + */ + whcr &= ~(1LL << 16); +#endif + wrmsr(0x0c0000082, whcr); + + write_eflags(eflags); +} +#endif /* I585_CPU && CPU_WT_ALLOC */ + +#include "opt_ddb.h" +#ifdef DDB +#include +#if 0 +DB_SHOW_COMMAND(cyrixreg, cyrixreg) +{ + u_long eflags; + u_int cr0; + u_char ccr1, ccr2, ccr3; + u_char ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0; + + cr0 = rcr0(); + if (strcmp(cpu_vendor,"CyrixInstead") == 0) { + eflags = read_eflags(); + disable_intr(); + + + if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) { + ccr0 = read_cyrix_reg(CCR0); + } + ccr1 = read_cyrix_reg(CCR1); + ccr2 = read_cyrix_reg(CCR2); + ccr3 = read_cyrix_reg(CCR3); + if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { + write_cyrix_reg(CCR3, CCR3_MAPEN0); + ccr4 = read_cyrix_reg(CCR4); + if ((cpu == CPU_M1) || (cpu == CPU_M2)) + ccr5 = read_cyrix_reg(CCR5); + else + pcr0 = read_cyrix_reg(PCR0); + write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */ + } + write_eflags(eflags); + + if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) + printf("CCR0=%x, ", (u_int)ccr0); + + printf("CCR1=%x, CCR2=%x, CCR3=%x", + (u_int)ccr1, (u_int)ccr2, (u_int)ccr3); + if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { + printf(", CCR4=%x, ", (u_int)ccr4); + if (cpu == CPU_M1SC) + printf("PCR0=%x\n", pcr0); + else + printf("CCR5=%x\n", ccr5); + } + } + printf("CR0=%x\n", cr0); +} +#endif +#endif /* DDB */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/intr_machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/intr_machdep.c new file mode 100644 index 0000000000..6ab354a00c --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/intr_machdep.c @@ -0,0 +1,326 @@ +/*- + * Copyright (c) 2003 John Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/i386/intr_machdep.c,v 1.4 2003/11/17 06:10:14 peter Exp $ + */ + +/* + * Machine dependent interrupt code for i386. For the i386, we have to + * deal with different PICs. Thus, we use the passed in vector to lookup + * an interrupt source associated with that vector. The interrupt source + * describes which PIC the source belongs to and includes methods to handle + * that source. + */ + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DDB +#include +#endif + +#define MAX_STRAY_LOG 5 + +typedef void (*mask_fn)(uintptr_t vector); + +static int intrcnt_index; +static struct intsrc *interrupt_sources[NUM_IO_INTS]; +static struct mtx intr_table_lock; + +static void intr_init(void *__dummy); +static void intrcnt_setname(const char *name, int index); +static void intrcnt_updatename(struct intsrc *is); +static void intrcnt_register(struct intsrc *is); + +/* + * Register a new interrupt source with the global interrupt system. + * The global interrupts need to be disabled when this function is + * called. + */ +int +intr_register_source(struct intsrc *isrc) +{ + int error, vector; + + vector = isrc->is_pic->pic_vector(isrc); + if (interrupt_sources[vector] != NULL) + return (EEXIST); + error = ithread_create(&isrc->is_ithread, (uintptr_t)isrc, 0, + (mask_fn)isrc->is_pic->pic_disable_source, + (mask_fn)isrc->is_pic->pic_enable_source, "irq%d:", vector); + if (error) + return (error); + mtx_lock_spin(&intr_table_lock); + if (interrupt_sources[vector] != NULL) { + mtx_unlock_spin(&intr_table_lock); + ithread_destroy(isrc->is_ithread); + return (EEXIST); + } + intrcnt_register(isrc); + interrupt_sources[vector] = isrc; + mtx_unlock_spin(&intr_table_lock); + return (0); +} + +struct intsrc * +intr_lookup_source(int vector) +{ + + return (interrupt_sources[vector]); +} + +int +intr_add_handler(const char *name, int vector, driver_intr_t handler, + void *arg, enum intr_type flags, void **cookiep) +{ + struct intsrc *isrc; + int error; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + + error = ithread_add_handler(isrc->is_ithread, name, handler, arg, + ithread_priority(flags), flags, cookiep); + if (error == 0) { + intrcnt_updatename(isrc); + isrc->is_pic->pic_enable_intr(isrc); + isrc->is_pic->pic_enable_source(isrc); + } + return (error); +} + +int +intr_remove_handler(void *cookie) +{ + int error; + + error = ithread_remove_handler(cookie); +#ifdef XXX + if (error == 0) + intrcnt_updatename(/* XXX */); +#endif + return (error); +} + +int +intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol) +{ + struct intsrc *isrc; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + return (isrc->is_pic->pic_config_intr(isrc, trig, pol)); +} + +void +intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe) +{ + struct thread *td; + struct ithd *it; + struct intrhand *ih; + int error, vector; + + td = curthread; + td->td_intr_nesting_level++; + + /* + * We count software interrupts when we process them. The + * code here follows previous practice, but there's an + * argument for counting hardware interrupts when they're + * processed too. + */ + atomic_add_long(isrc->is_count, 1); + atomic_add_int(&cnt.v_intr, 1); + + it = isrc->is_ithread; + if (it == NULL) + ih = NULL; + else + ih = TAILQ_FIRST(&it->it_handlers); + + /* + * XXX: We assume that IRQ 0 is only used for the ISA timer + * device (clk). + */ + vector = isrc->is_pic->pic_vector(isrc); + if (vector == 0) + clkintr_pending = 1; + + + if (ih != NULL && ih->ih_flags & IH_FAST) { + /* + * Execute fast interrupt handlers directly. + * To support clock handlers, if a handler registers + * with a NULL argument, then we pass it a pointer to + * a trapframe as its argument. + */ + critical_enter(); + TAILQ_FOREACH(ih, &it->it_handlers, ih_next) { + MPASS(ih->ih_flags & IH_FAST); + CTR3(KTR_INTR, "%s: executing handler %p(%p)", + __func__, ih->ih_handler, + ih->ih_argument == NULL ? iframe : + ih->ih_argument); + if (ih->ih_argument == NULL) + ih->ih_handler(iframe); + else + ih->ih_handler(ih->ih_argument); + } + isrc->is_pic->pic_eoi_source(isrc); + error = 0; + /* XXX */ + td->td_pflags &= ~TDP_OWEPREEMPT; + critical_exit(); + } else { + /* + * For stray and threaded interrupts, we mask and EOI the + * source. + */ + isrc->is_pic->pic_disable_source(isrc, PIC_EOI); + if (ih == NULL) + error = EINVAL; + else + error = ithread_schedule(it); + isrc->is_pic->pic_eoi_source(isrc); + } + + if (error == EINVAL) { + atomic_add_long(isrc->is_straycount, 1); + if (*isrc->is_straycount < MAX_STRAY_LOG) + log(LOG_ERR, "stray irq%d\n", vector); + else if (*isrc->is_straycount == MAX_STRAY_LOG) + log(LOG_CRIT, + "too many stray irq %d's: not logging anymore\n", + vector); + } + td->td_intr_nesting_level--; + +} + +void +intr_resume(void) +{ + struct intsrc **isrc; + int i; + + mtx_lock_spin(&intr_table_lock); + for (i = 0, isrc = interrupt_sources; i < NUM_IO_INTS; i++, isrc++) + if (*isrc != NULL && (*isrc)->is_pic->pic_resume != NULL) + (*isrc)->is_pic->pic_resume(*isrc); + mtx_unlock_spin(&intr_table_lock); +} + +void +intr_suspend(void) +{ + struct intsrc **isrc; + int i; + + mtx_lock_spin(&intr_table_lock); + for (i = 0, isrc = interrupt_sources; i < NUM_IO_INTS; i++, isrc++) + if (*isrc != NULL && (*isrc)->is_pic->pic_suspend != NULL) + (*isrc)->is_pic->pic_suspend(*isrc); + mtx_unlock_spin(&intr_table_lock); +} + +static void +intrcnt_setname(const char *name, int index) +{ + + snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s", + MAXCOMLEN, name); +} + +static void +intrcnt_updatename(struct intsrc *is) +{ + + intrcnt_setname(is->is_ithread->it_td->td_proc->p_comm, is->is_index); +} + +static void +intrcnt_register(struct intsrc *is) +{ + char straystr[MAXCOMLEN + 1]; + + /* mtx_assert(&intr_table_lock, MA_OWNED); */ + KASSERT(is->is_ithread != NULL, ("%s: isrc with no ithread", __func__)); + is->is_index = intrcnt_index; + intrcnt_index += 2; + snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", + is->is_pic->pic_vector(is)); + intrcnt_updatename(is); + is->is_count = &intrcnt[is->is_index]; + intrcnt_setname(straystr, is->is_index + 1); + is->is_straycount = &intrcnt[is->is_index + 1]; +} + +static void +intr_init(void *dummy __unused) +{ + + intrcnt_setname("???", 0); + intrcnt_index = 1; + mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); +} +SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL) + +#ifdef DDB +/* + * Dump data about interrupt handlers + */ +DB_SHOW_COMMAND(irqs, db_show_irqs) +{ + struct intsrc **isrc; + int i, quit, verbose; + + quit = 0; + if (strcmp(modif, "v") == 0) + verbose = 1; + else + verbose = 0; + isrc = interrupt_sources; + db_setup_paging(db_simple_pager, &quit, DB_LINES_PER_PAGE); + for (i = 0; i < NUM_IO_INTS && !quit; i++, isrc++) + if (*isrc != NULL) + db_dump_ithread((*isrc)->is_ithread, verbose); +} +#endif diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/io_apic.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/io_apic.c new file mode 100644 index 0000000000..9892a998b2 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/io_apic.c @@ -0,0 +1,850 @@ +/*- + * Copyright (c) 2003 John Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/io_apic.c,v 1.14 2004/08/02 15:31:10 scottl Exp $"); + +#include "opt_isa.h" +#include "opt_no_mixed_mode.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define IOAPIC_ISA_INTS 16 +#define IOAPIC_MEM_REGION 32 +#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2) +#define IOAPIC_REDTBL_HI(i) (IOAPIC_REDTBL_LO(i) + 1) + +#define VECTOR_EXTINT 252 +#define VECTOR_NMI 253 +#define VECTOR_SMI 254 +#define VECTOR_DISABLED 255 + +#define DEST_NONE -1 +#define DEST_EXTINT -2 + +#define TODO printf("%s: not implemented!\n", __func__) + +MALLOC_DEFINE(M_IOAPIC, "I/O APIC", "I/O APIC structures"); + +/* + * New interrupt support code.. + * + * XXX: we really should have the interrupt cookie passed up from new-bus + * just be a int pin, and not map 1:1 to interrupt vector number but should + * use INTR_TYPE_FOO to set priority bands for device classes and do all the + * magic remapping of intpin to vector in here. For now we just cheat as on + * ia64 and map intpin X to vector NRSVIDT + X. Note that we assume that the + * first IO APIC has ISA interrupts on pins 1-15. Not sure how you are + * really supposed to figure out which IO APIC in a system with multiple IO + * APIC's actually has the ISA interrupts routed to it. As far as interrupt + * pin numbers, we use the ACPI System Interrupt number model where each + * IO APIC has a contiguous chunk of the System Interrupt address space. + */ + +/* + * Direct the ExtINT pin on the first I/O APIC to a logical cluster of + * CPUs rather than a physical destination of just the BSP. + * + * Note: This is disabled by default as test systems seem to croak with it + * enabled. +#define ENABLE_EXTINT_LOGICAL_DESTINATION + */ + +struct ioapic_intsrc { + struct intsrc io_intsrc; + u_int io_intpin:8; + u_int io_vector:8; + u_int io_activehi:1; + u_int io_edgetrigger:1; + u_int io_masked:1; + int io_dest:5; + int io_bus:4; +}; + +struct ioapic { + struct pic io_pic; + u_int io_id:8; /* logical ID */ + u_int io_apic_id:4; + u_int io_intbase:8; /* System Interrupt base */ + u_int io_numintr:8; + volatile ioapic_t *io_addr; /* XXX: should use bus_space */ + STAILQ_ENTRY(ioapic) io_next; + struct ioapic_intsrc io_pins[0]; +}; + +static u_int ioapic_read(volatile ioapic_t *apic, int reg); +static void ioapic_write(volatile ioapic_t *apic, int reg, u_int val); +static const char *ioapic_bus_string(int bus_type); +static void ioapic_print_vector(struct ioapic_intsrc *intpin); +static void ioapic_enable_source(struct intsrc *isrc); +static void ioapic_disable_source(struct intsrc *isrc, int eoi); +static void ioapic_eoi_source(struct intsrc *isrc); +static void ioapic_enable_intr(struct intsrc *isrc); +static int ioapic_vector(struct intsrc *isrc); +static int ioapic_source_pending(struct intsrc *isrc); +static int ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, + enum intr_polarity pol); +static void ioapic_suspend(struct intsrc *isrc); +static void ioapic_resume(struct intsrc *isrc); +static void ioapic_program_destination(struct ioapic_intsrc *intpin); +static void ioapic_program_intpin(struct ioapic_intsrc *intpin); +static void ioapic_setup_mixed_mode(struct ioapic_intsrc *intpin); + +static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list); +struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source, + ioapic_eoi_source, ioapic_enable_intr, + ioapic_vector, ioapic_source_pending, + ioapic_suspend, ioapic_resume, + ioapic_config_intr }; + +static int bsp_id, current_cluster, logical_clusters, next_ioapic_base; +static u_int mixed_mode_enabled, next_id, program_logical_dest; +#ifdef NO_MIXED_MODE +static int mixed_mode_active = 0; +#else +static int mixed_mode_active = 1; +#endif +TUNABLE_INT("hw.apic.mixed_mode", &mixed_mode_active); + +static __inline void +_ioapic_eoi_source(struct intsrc *isrc) +{ + lapic_eoi(); +} + +static u_int +ioapic_read(volatile ioapic_t *apic, int reg) +{ + + mtx_assert(&icu_lock, MA_OWNED); + apic->ioregsel = reg; + return (apic->iowin); +} + +static void +ioapic_write(volatile ioapic_t *apic, int reg, u_int val) +{ + + mtx_assert(&icu_lock, MA_OWNED); + apic->ioregsel = reg; + apic->iowin = val; +} + +static const char * +ioapic_bus_string(int bus_type) +{ + + switch (bus_type) { + case APIC_BUS_ISA: + return ("ISA"); + case APIC_BUS_EISA: + return ("EISA"); + case APIC_BUS_PCI: + return ("PCI"); + default: + return ("unknown"); + } +} + +static void +ioapic_print_vector(struct ioapic_intsrc *intpin) +{ + + switch (intpin->io_vector) { + case VECTOR_DISABLED: + printf("disabled"); + break; + case VECTOR_EXTINT: + printf("ExtINT"); + break; + case VECTOR_NMI: + printf("NMI"); + break; + case VECTOR_SMI: + printf("SMI"); + break; + default: + printf("%s IRQ %u", ioapic_bus_string(intpin->io_bus), + intpin->io_vector); + } +} + +static void +ioapic_enable_source(struct intsrc *isrc) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + struct ioapic *io = (struct ioapic *)isrc->is_pic; + uint32_t flags; + + mtx_lock_spin(&icu_lock); + if (intpin->io_masked) { + flags = ioapic_read(io->io_addr, + IOAPIC_REDTBL_LO(intpin->io_intpin)); + flags &= ~(IOART_INTMASK); + ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), + flags); + intpin->io_masked = 0; + } + mtx_unlock_spin(&icu_lock); +} + +static void +ioapic_disable_source(struct intsrc *isrc, int eoi) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + struct ioapic *io = (struct ioapic *)isrc->is_pic; + uint32_t flags; + + mtx_lock_spin(&icu_lock); + if (!intpin->io_masked && !intpin->io_edgetrigger) { + flags = ioapic_read(io->io_addr, + IOAPIC_REDTBL_LO(intpin->io_intpin)); + flags |= IOART_INTMSET; + ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), + flags); + intpin->io_masked = 1; + } + + if (eoi == PIC_EOI) + _ioapic_eoi_source(isrc); + + mtx_unlock_spin(&icu_lock); +} + +static void +ioapic_eoi_source(struct intsrc *isrc) +{ + + _ioapic_eoi_source(isrc); +} + +/* + * Completely program an intpin based on the data in its interrupt source + * structure. + */ +static void +ioapic_program_intpin(struct ioapic_intsrc *intpin) +{ + struct ioapic *io = (struct ioapic *)intpin->io_intsrc.is_pic; + uint32_t low, high, value; + + /* + * For pins routed via mixed mode or disabled, just ensure that + * they are masked. + */ + if (intpin->io_dest == DEST_EXTINT || + intpin->io_vector == VECTOR_DISABLED) { + low = ioapic_read(io->io_addr, + IOAPIC_REDTBL_LO(intpin->io_intpin)); + if ((low & IOART_INTMASK) == IOART_INTMCLR) + ioapic_write(io->io_addr, + IOAPIC_REDTBL_LO(intpin->io_intpin), + low | IOART_INTMSET); + return; + } + + /* Set the destination. */ + if (intpin->io_dest == DEST_NONE) { + low = IOART_DESTPHY; + high = bsp_id << APIC_ID_SHIFT; + } else { + low = IOART_DESTLOG; + high = (intpin->io_dest << APIC_ID_CLUSTER_SHIFT | + APIC_ID_CLUSTER_ID) << APIC_ID_SHIFT; + } + + /* Program the rest of the low word. */ + if (intpin->io_edgetrigger) + low |= IOART_TRGREDG; + else + low |= IOART_TRGRLVL; + if (intpin->io_activehi) + low |= IOART_INTAHI; + else + low |= IOART_INTALO; + if (intpin->io_masked) + low |= IOART_INTMSET; + switch (intpin->io_vector) { + case VECTOR_EXTINT: + KASSERT(intpin->io_edgetrigger, + ("EXTINT not edge triggered")); + low |= IOART_DELEXINT; + break; + case VECTOR_NMI: + KASSERT(intpin->io_edgetrigger, + ("NMI not edge triggered")); + low |= IOART_DELNMI; + break; + case VECTOR_SMI: + KASSERT(intpin->io_edgetrigger, + ("SMI not edge triggered")); + low |= IOART_DELSMI; + break; + default: + low |= IOART_DELLOPRI | apic_irq_to_idt(intpin->io_vector); + } + + /* Write the values to the APIC. */ + mtx_lock_spin(&icu_lock); + ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low); + value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin)); + value &= ~IOART_DEST; + value |= high; + ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value); + mtx_unlock_spin(&icu_lock); +} + +/* + * Program an individual intpin's logical destination. + */ +static void +ioapic_program_destination(struct ioapic_intsrc *intpin) +{ + struct ioapic *io = (struct ioapic *)intpin->io_intsrc.is_pic; + + KASSERT(intpin->io_dest != DEST_NONE, + ("intpin not assigned to a cluster")); + KASSERT(intpin->io_dest != DEST_EXTINT, + ("intpin routed via ExtINT")); + if (bootverbose) { + printf("ioapic%u: routing intpin %u (", io->io_id, + intpin->io_intpin); + ioapic_print_vector(intpin); + printf(") to cluster %u\n", intpin->io_dest); + } + ioapic_program_intpin(intpin); +} + +static void +ioapic_assign_cluster(struct ioapic_intsrc *intpin) +{ + + /* + * Assign this intpin to a logical APIC cluster in a + * round-robin fashion. We don't actually use the logical + * destination for this intpin until after all the CPU's + * have been started so that we don't end up with interrupts + * that don't go anywhere. Another alternative might be to + * start up the CPU's earlier so that they can handle interrupts + * sooner. + */ + intpin->io_dest = current_cluster; + current_cluster++; + if (current_cluster >= logical_clusters) + current_cluster = 0; + if (program_logical_dest) + ioapic_program_destination(intpin); +} + +static void +ioapic_enable_intr(struct intsrc *isrc) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + + KASSERT(intpin->io_dest != DEST_EXTINT, + ("ExtINT pin trying to use ioapic enable_intr method")); + if (intpin->io_dest == DEST_NONE) { + ioapic_assign_cluster(intpin); + lapic_enable_intr(intpin->io_vector); + } +} + +static int +ioapic_vector(struct intsrc *isrc) +{ + struct ioapic_intsrc *pin; + + pin = (struct ioapic_intsrc *)isrc; + return (pin->io_vector); +} + +static int +ioapic_source_pending(struct intsrc *isrc) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + + return (lapic_intr_pending(intpin->io_vector)); +} + +static int +ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, + enum intr_polarity pol) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + struct ioapic *io = (struct ioapic *)isrc->is_pic; + int changed; + + KASSERT(!(trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM), + ("%s: Conforming trigger or polarity\n", __func__)); + + /* + * EISA interrupts always use active high polarity, so don't allow + * them to be set to active low. + * + * XXX: Should we write to the ELCR if the trigger mode changes for + * an EISA IRQ? + */ + if (intpin->io_bus == APIC_BUS_EISA) + pol = INTR_POLARITY_HIGH; + changed = 0; + if (intpin->io_edgetrigger != (trig == INTR_TRIGGER_EDGE)) { + if (bootverbose) + printf("ioapic%u: Changing trigger for pin %u to %s\n", + io->io_id, intpin->io_intpin, + trig == INTR_TRIGGER_EDGE ? "edge" : "level"); + intpin->io_edgetrigger = (trig == INTR_TRIGGER_EDGE); + changed++; + } + if (intpin->io_activehi != (pol == INTR_POLARITY_HIGH)) { + if (bootverbose) + printf("ioapic%u: Changing polarity for pin %u to %s\n", + io->io_id, intpin->io_intpin, + pol == INTR_POLARITY_HIGH ? "high" : "low"); + intpin->io_activehi = (pol == INTR_POLARITY_HIGH); + changed++; + } + if (changed) + ioapic_program_intpin(intpin); + return (0); +} + +static void +ioapic_suspend(struct intsrc *isrc) +{ + + TODO; +} + +static void +ioapic_resume(struct intsrc *isrc) +{ + + ioapic_program_intpin((struct ioapic_intsrc *)isrc); +} + +/* + * APIC enumerators call this function to indicate that the 8259A AT PICs + * are available and that mixed mode can be used. + */ +void +ioapic_enable_mixed_mode(void) +{ + + mixed_mode_enabled = 1; +} + +/* + * Allocate and return a logical cluster ID. Note that the first time + * this is called, it returns cluster 0. ioapic_enable_intr() treats + * the two cases of logical_clusters == 0 and logical_clusters == 1 the + * same: one cluster of ID 0 exists. The logical_clusters == 0 case is + * for UP kernels, which should never call this function. + */ +int +ioapic_next_logical_cluster(void) +{ + + if (logical_clusters >= APIC_MAX_CLUSTER) + panic("WARNING: Local APIC cluster IDs exhausted!"); + return (logical_clusters++); +} + +/* + * Create a plain I/O APIC object. + */ +void * +ioapic_create(uintptr_t addr, int32_t apic_id, int intbase) +{ + struct ioapic *io; + struct ioapic_intsrc *intpin; + volatile ioapic_t *apic; + u_int numintr, i; + uint32_t value; + + apic = (ioapic_t *)pmap_mapdev(addr, IOAPIC_MEM_REGION); + mtx_lock_spin(&icu_lock); + numintr = ((ioapic_read(apic, IOAPIC_VER) & IOART_VER_MAXREDIR) >> + MAXREDIRSHIFT) + 1; + mtx_unlock_spin(&icu_lock); + io = malloc(sizeof(struct ioapic) + + numintr * sizeof(struct ioapic_intsrc), M_IOAPIC, M_WAITOK); + io->io_pic = ioapic_template; + mtx_lock_spin(&icu_lock); + io->io_id = next_id++; + io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT; + if (apic_id != -1 && io->io_apic_id != apic_id) { + ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT); + mtx_unlock_spin(&icu_lock); + io->io_apic_id = apic_id; + printf("ioapic%u: Changing APIC ID to %d\n", io->io_id, + apic_id); + } else + mtx_unlock_spin(&icu_lock); + if (intbase == -1) { + intbase = next_ioapic_base; + printf("ioapic%u: Assuming intbase of %d\n", io->io_id, + intbase); + } else if (intbase != next_ioapic_base) + printf("ioapic%u: WARNING: intbase %d != expected base %d\n", + io->io_id, intbase, next_ioapic_base); + io->io_intbase = intbase; + next_ioapic_base = intbase + numintr; + io->io_numintr = numintr; + io->io_addr = apic; + + /* + * Initialize pins. Start off with interrupts disabled. Default + * to active-hi and edge-triggered for ISA interrupts and active-lo + * and level-triggered for all others. + */ + bzero(io->io_pins, sizeof(struct ioapic_intsrc) * numintr); + mtx_lock_spin(&icu_lock); + for (i = 0, intpin = io->io_pins; i < numintr; i++, intpin++) { + intpin->io_intsrc.is_pic = (struct pic *)io; + intpin->io_intpin = i; + intpin->io_vector = intbase + i; + + /* + * Assume that pin 0 on the first I/O APIC is an ExtINT pin + * and that pins 1-15 are ISA interrupts. Assume that all + * other pins are PCI interrupts. + */ + if (intpin->io_vector == 0) + ioapic_set_extint(io, i); + else if (intpin->io_vector < IOAPIC_ISA_INTS) { + intpin->io_bus = APIC_BUS_ISA; + intpin->io_activehi = 1; + intpin->io_edgetrigger = 1; + intpin->io_masked = 1; + } else { + intpin->io_bus = APIC_BUS_PCI; + intpin->io_activehi = 0; + intpin->io_edgetrigger = 0; + intpin->io_masked = 1; + } + + /* + * Route interrupts to the BSP by default using physical + * addressing. Vectored interrupts get readdressed using + * logical IDs to CPU clusters when they are enabled. + */ + intpin->io_dest = DEST_NONE; + if (bootverbose && intpin->io_vector != VECTOR_DISABLED) { + printf("ioapic%u: intpin %d -> ", io->io_id, i); + ioapic_print_vector(intpin); + printf(" (%s, %s)\n", intpin->io_edgetrigger ? + "edge" : "level", intpin->io_activehi ? "high" : + "low"); + } + value = ioapic_read(apic, IOAPIC_REDTBL_LO(i)); + ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET); + } + mtx_unlock_spin(&icu_lock); + + return (io); +} + +int +ioapic_get_vector(void *cookie, u_int pin) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (-1); + return (io->io_pins[pin].io_vector); +} + +int +ioapic_disable_pin(void *cookie, u_int pin) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (EINVAL); + if (io->io_pins[pin].io_vector == VECTOR_DISABLED) + return (EINVAL); + io->io_pins[pin].io_vector = VECTOR_DISABLED; + if (bootverbose) + printf("ioapic%u: intpin %d disabled\n", io->io_id, pin); + return (0); +} + +int +ioapic_remap_vector(void *cookie, u_int pin, int vector) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr || vector < 0) + return (EINVAL); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_vector = vector; + if (bootverbose) + printf("ioapic%u: Routing IRQ %d -> intpin %d\n", io->io_id, + vector, pin); + return (0); +} + +int +ioapic_set_bus(void *cookie, u_int pin, int bus_type) +{ + struct ioapic *io; + + if (bus_type < 0 || bus_type > APIC_BUS_MAX) + return (EINVAL); + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (EINVAL); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_bus = bus_type; + if (bootverbose) + printf("ioapic%u: intpin %d bus %s\n", io->io_id, pin, + ioapic_bus_string(bus_type)); + return (0); +} + +int +ioapic_set_nmi(void *cookie, u_int pin) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (EINVAL); + if (io->io_pins[pin].io_vector == VECTOR_NMI) + return (0); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; + io->io_pins[pin].io_vector = VECTOR_NMI; + io->io_pins[pin].io_masked = 0; + io->io_pins[pin].io_edgetrigger = 1; + io->io_pins[pin].io_activehi = 1; + if (bootverbose) + printf("ioapic%u: Routing NMI -> intpin %d\n", + io->io_id, pin); + return (0); +} + +int +ioapic_set_smi(void *cookie, u_int pin) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (EINVAL); + if (io->io_pins[pin].io_vector == VECTOR_SMI) + return (0); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; + io->io_pins[pin].io_vector = VECTOR_SMI; + io->io_pins[pin].io_masked = 0; + io->io_pins[pin].io_edgetrigger = 1; + io->io_pins[pin].io_activehi = 1; + if (bootverbose) + printf("ioapic%u: Routing SMI -> intpin %d\n", + io->io_id, pin); + return (0); +} + +int +ioapic_set_extint(void *cookie, u_int pin) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr) + return (EINVAL); + if (io->io_pins[pin].io_vector == VECTOR_EXTINT) + return (0); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_bus = APIC_BUS_UNKNOWN; + io->io_pins[pin].io_vector = VECTOR_EXTINT; + + /* Enable this pin if mixed mode is available and active. */ + if (mixed_mode_enabled && mixed_mode_active) + io->io_pins[pin].io_masked = 0; + else + io->io_pins[pin].io_masked = 1; + io->io_pins[pin].io_edgetrigger = 1; + io->io_pins[pin].io_activehi = 1; + if (bootverbose) + printf("ioapic%u: Routing external 8259A's -> intpin %d\n", + io->io_id, pin); + return (0); +} + +int +ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr || pol == INTR_POLARITY_CONFORM) + return (EINVAL); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_activehi = (pol == INTR_POLARITY_HIGH); + if (bootverbose) + printf("ioapic%u: intpin %d polarity: %s\n", io->io_id, pin, + pol == INTR_POLARITY_HIGH ? "high" : "low"); + return (0); +} + +int +ioapic_set_triggermode(void *cookie, u_int pin, enum intr_trigger trigger) +{ + struct ioapic *io; + + io = (struct ioapic *)cookie; + if (pin >= io->io_numintr || trigger == INTR_TRIGGER_CONFORM) + return (EINVAL); + if (io->io_pins[pin].io_vector >= NUM_IO_INTS) + return (EINVAL); + io->io_pins[pin].io_edgetrigger = (trigger == INTR_TRIGGER_EDGE); + if (bootverbose) + printf("ioapic%u: intpin %d trigger: %s\n", io->io_id, pin, + trigger == INTR_TRIGGER_EDGE ? "edge" : "level"); + return (0); +} + +/* + * Register a complete I/O APIC object with the interrupt subsystem. + */ +void +ioapic_register(void *cookie) +{ + struct ioapic_intsrc *pin; + struct ioapic *io; + volatile ioapic_t *apic; + uint32_t flags; + int i; + + io = (struct ioapic *)cookie; + apic = io->io_addr; + mtx_lock_spin(&icu_lock); + flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION; + STAILQ_INSERT_TAIL(&ioapic_list, io, io_next); + mtx_unlock_spin(&icu_lock); + printf("ioapic%u irqs %u-%u on motherboard\n", + io->io_id, flags >> 4, flags & 0xf, io->io_intbase, + io->io_intbase + io->io_numintr - 1); + bsp_id = PCPU_GET(apic_id); + for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++) { + /* + * Finish initializing the pins by programming the vectors + * and delivery mode. + */ + if (pin->io_vector == VECTOR_DISABLED) + continue; + ioapic_program_intpin(pin); + if (pin->io_vector >= NUM_IO_INTS) + continue; + /* + * Route IRQ0 via the 8259A using mixed mode if mixed mode + * is available and turned on. + */ + if (pin->io_vector == 0 && mixed_mode_active && + mixed_mode_enabled) + ioapic_setup_mixed_mode(pin); + else + intr_register_source(&pin->io_intsrc); + } +} + +/* + * Program all the intpins to use logical destinations once the AP's + * have been launched. + */ +static void +ioapic_set_logical_destinations(void *arg __unused) +{ + struct ioapic *io; + int i; + + program_logical_dest = 1; + STAILQ_FOREACH(io, &ioapic_list, io_next) + for (i = 0; i < io->io_numintr; i++) + if (io->io_pins[i].io_dest != DEST_NONE && + io->io_pins[i].io_dest != DEST_EXTINT) + ioapic_program_destination(&io->io_pins[i]); +} +SYSINIT(ioapic_destinations, SI_SUB_SMP, SI_ORDER_SECOND, + ioapic_set_logical_destinations, NULL) + +/* + * Support for mixed-mode interrupt sources. These sources route an ISA + * IRQ through the 8259A's via the ExtINT on pin 0 of the I/O APIC that + * routes the ISA interrupts. We just ignore the intpins that use this + * mode and allow the atpic driver to register its interrupt source for + * that IRQ instead. + */ + +static void +ioapic_setup_mixed_mode(struct ioapic_intsrc *intpin) +{ + struct ioapic_intsrc *extint; + struct ioapic *io; + + /* + * Mark the associated I/O APIC intpin as being delivered via + * ExtINT and enable the ExtINT pin on the I/O APIC if needed. + */ + intpin->io_dest = DEST_EXTINT; + io = (struct ioapic *)intpin->io_intsrc.is_pic; + extint = &io->io_pins[0]; + if (extint->io_vector != VECTOR_EXTINT) + panic("Can't find ExtINT pin to route through!"); +#ifdef ENABLE_EXTINT_LOGICAL_DESTINATION + if (extint->io_dest == DEST_NONE) + ioapic_assign_cluster(extint); +#endif +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/local_apic.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/local_apic.c new file mode 100644 index 0000000000..8fb7f9f12e --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/local_apic.c @@ -0,0 +1,762 @@ +/*- + * Copyright (c) 2003 John Baldwin + * Copyright (c) 1996, by Steve Passe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the developer may NOT be used to endorse or promote products + * derived from this software without specific prior written permission. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Local APIC support on Pentium and later processors. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/local_apic.c,v 1.9 2004/07/14 18:12:15 jhb Exp $"); + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * We can handle up to 60 APICs via our logical cluster IDs, but currently + * the physical IDs on Intel processors up to the Pentium 4 are limited to + * 16. + */ +#define MAX_APICID 16 + +/* Sanity checks on IDT vectors. */ +CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS <= APIC_LOCAL_INTS); +CTASSERT(IPI_STOP < APIC_SPURIOUS_INT); + +/* + * Support for local APICs. Local APICs manage interrupts on each + * individual processor as opposed to I/O APICs which receive interrupts + * from I/O devices and then forward them on to the local APICs. + * + * Local APICs can also send interrupts to each other thus providing the + * mechanism for IPIs. + */ + +struct lvt { + u_int lvt_edgetrigger:1; + u_int lvt_activehi:1; + u_int lvt_masked:1; + u_int lvt_active:1; + u_int lvt_mode:16; + u_int lvt_vector:8; +}; + +struct lapic { + struct lvt la_lvts[LVT_MAX + 1]; + u_int la_id:8; + u_int la_cluster:4; + u_int la_cluster_id:2; + u_int la_present:1; +} static lapics[MAX_APICID]; + +/* XXX: should thermal be an NMI? */ + +/* Global defaults for local APIC LVT entries. */ +static struct lvt lvts[LVT_MAX + 1] = { + { 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */ + { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */ + { 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* Timer: needs a vector */ + { 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* Error: needs a vector */ + { 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* PMC */ + { 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* Thermal: needs a vector */ +}; + +static inthand_t *ioint_handlers[] = { + NULL, /* 0 - 31 */ + IDTVEC(apic_isr1), /* 32 - 63 */ + IDTVEC(apic_isr2), /* 64 - 95 */ + IDTVEC(apic_isr3), /* 96 - 127 */ + IDTVEC(apic_isr4), /* 128 - 159 */ + IDTVEC(apic_isr5), /* 160 - 191 */ + IDTVEC(apic_isr6), /* 192 - 223 */ + IDTVEC(apic_isr7), /* 224 - 255 */ +}; + +volatile lapic_t *lapic; + +static uint32_t +lvt_mode(struct lapic *la, u_int pin, uint32_t value) +{ + struct lvt *lvt; + + KASSERT(pin <= LVT_MAX, ("%s: pin %u out of range", __func__, pin)); + if (la->la_lvts[pin].lvt_active) + lvt = &la->la_lvts[pin]; + else + lvt = &lvts[pin]; + + value &= ~(APIC_LVT_M | APIC_LVT_TM | APIC_LVT_IIPP | APIC_LVT_DM | + APIC_LVT_VECTOR); + if (lvt->lvt_edgetrigger == 0) + value |= APIC_LVT_TM; + if (lvt->lvt_activehi == 0) + value |= APIC_LVT_IIPP_INTALO; + if (lvt->lvt_masked) + value |= APIC_LVT_M; + value |= lvt->lvt_mode; + switch (lvt->lvt_mode) { + case APIC_LVT_DM_NMI: + case APIC_LVT_DM_SMI: + case APIC_LVT_DM_INIT: + case APIC_LVT_DM_EXTINT: + if (!lvt->lvt_edgetrigger) { + printf("lapic%u: Forcing LINT%u to edge trigger\n", + la->la_id, pin); + value |= APIC_LVT_TM; + } + /* Use a vector of 0. */ + break; + case APIC_LVT_DM_FIXED: +#if 0 + value |= lvt->lvt_vector; +#else + panic("Fixed LINT pins not supported"); +#endif + break; + default: + panic("bad APIC LVT delivery mode: %#x\n", value); + } + return (value); +} + +/* + * Map the local APIC and setup necessary interrupt vectors. + */ +void +lapic_init(uintptr_t addr) +{ + u_int32_t value; + + /* Map the local APIC and setup the spurious interrupt handler. */ + KASSERT(trunc_page(addr) == addr, + ("local APIC not aligned on a page boundary")); + lapic = (lapic_t *)pmap_mapdev(addr, sizeof(lapic_t)); + setidt(APIC_SPURIOUS_INT, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + + /* Perform basic initialization of the BSP's local APIC. */ + value = lapic->svr; + value &= ~(APIC_SVR_VECTOR | APIC_SVR_FOCUS); + value |= (APIC_SVR_FEN | APIC_SVR_SWEN | APIC_SPURIOUS_INT); + lapic->svr = value; + + /* Set BSP's per-CPU local APIC ID. */ + PCPU_SET(apic_id, lapic_id()); + + /* XXX: timer/error/thermal interrupts */ +} + +/* + * Create a local APIC instance. + */ +void +lapic_create(u_int apic_id, int boot_cpu) +{ + int i; + + if (apic_id >= MAX_APICID) { + printf("APIC: Ignoring local APIC with ID %d\n", apic_id); + if (boot_cpu) + panic("Can't ignore BSP"); + return; + } + KASSERT(!lapics[apic_id].la_present, ("duplicate local APIC %u", + apic_id)); + + /* + * Assume no local LVT overrides and a cluster of 0 and + * intra-cluster ID of 0. + */ + lapics[apic_id].la_present = 1; + lapics[apic_id].la_id = apic_id; + for (i = 0; i < LVT_MAX; i++) { + lapics[apic_id].la_lvts[i] = lvts[i]; + lapics[apic_id].la_lvts[i].lvt_active = 0; + } + +#ifdef SMP + cpu_add(apic_id, boot_cpu); +#endif +} + +/* + * Dump contents of local APIC registers + */ +void +lapic_dump(const char* str) +{ + + printf("cpu%d %s:\n", PCPU_GET(cpuid), str); + printf(" ID: 0x%08x VER: 0x%08x LDR: 0x%08x DFR: 0x%08x\n", + lapic->id, lapic->version, lapic->ldr, lapic->dfr); + printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n", + lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr); +} + +void +lapic_enable_intr(u_int irq) +{ + u_int vector; + + vector = apic_irq_to_idt(irq); + KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry")); + KASSERT(ioint_handlers[vector / 32] != NULL, + ("No ISR handler for IRQ %u", irq)); + setidt(vector, ioint_handlers[vector / 32], SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); +} + +void +lapic_setup(void) +{ + struct lapic *la; + u_int32_t value, maxlvt; + register_t eflags; + + la = &lapics[lapic_id()]; + KASSERT(la->la_present, ("missing APIC structure")); + eflags = intr_disable(); + maxlvt = (lapic->version & APIC_VER_MAXLVT) >> MAXLVTSHIFT; + + /* Program LINT[01] LVT entries. */ + lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); + lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); + + /* XXX: more LVT entries */ + + /* Clear the TPR. */ + value = lapic->tpr; + value &= ~APIC_TPR_PRIO; + lapic->tpr = value; + + /* Use the cluster model for logical IDs. */ + value = lapic->dfr; + value &= ~APIC_DFR_MODEL_MASK; + value |= APIC_DFR_MODEL_CLUSTER; + lapic->dfr = value; + + /* Set this APIC's logical ID. */ + value = lapic->ldr; + value &= ~APIC_ID_MASK; + value |= (la->la_cluster << APIC_ID_CLUSTER_SHIFT | + 1 << la->la_cluster_id) << APIC_ID_SHIFT; + lapic->ldr = value; + + /* Setup spurious vector and enable the local APIC. */ + value = lapic->svr; + value &= ~(APIC_SVR_VECTOR | APIC_SVR_FOCUS); + value |= (APIC_SVR_FEN | APIC_SVR_SWEN | APIC_SPURIOUS_INT); + lapic->svr = value; + intr_restore(eflags); +} + +void +lapic_disable(void) +{ + uint32_t value; + + /* Software disable the local APIC. */ + value = lapic->svr; + value &= ~APIC_SVR_SWEN; + lapic->svr = value; +} + +int +lapic_id(void) +{ + + KASSERT(lapic != NULL, ("local APIC is not mapped")); + return (lapic->id >> APIC_ID_SHIFT); +} + +int +lapic_intr_pending(u_int vector) +{ + volatile u_int32_t *irr; + + /* + * The IRR registers are an array of 128-bit registers each of + * which only describes 32 interrupts in the low 32 bits.. Thus, + * we divide the vector by 32 to get the 128-bit index. We then + * multiply that index by 4 to get the equivalent index from + * treating the IRR as an array of 32-bit registers. Finally, we + * modulus the vector by 32 to determine the individual bit to + * test. + */ + irr = &lapic->irr0; + return (irr[(vector / 32) * 4] & 1 << (vector % 32)); +} + +void +lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id) +{ + struct lapic *la; + + KASSERT(lapics[apic_id].la_present, ("%s: APIC %u doesn't exist", + __func__, apic_id)); + KASSERT(cluster <= APIC_MAX_CLUSTER, ("%s: cluster %u too big", + __func__, cluster)); + KASSERT(cluster_id <= APIC_MAX_INTRACLUSTER_ID, + ("%s: intra cluster id %u too big", __func__, cluster_id)); + la = &lapics[apic_id]; + la->la_cluster = cluster; + la->la_cluster_id = cluster_id; +} + +int +lapic_set_lvt_mask(u_int apic_id, u_int pin, u_char masked) +{ + + if (pin > LVT_MAX) + return (EINVAL); + if (apic_id == APIC_ID_ALL) { + lvts[pin].lvt_masked = masked; + if (bootverbose) + printf("lapic:"); + } else { + KASSERT(lapics[apic_id].la_present, + ("%s: missing APIC %u", __func__, apic_id)); + lapics[apic_id].la_lvts[pin].lvt_masked = masked; + lapics[apic_id].la_lvts[pin].lvt_active = 1; + if (bootverbose) + printf("lapic%u:", apic_id); + } + if (bootverbose) + printf(" LINT%u %s\n", pin, masked ? "masked" : "unmasked"); + return (0); +} + +int +lapic_set_lvt_mode(u_int apic_id, u_int pin, u_int32_t mode) +{ + struct lvt *lvt; + + if (pin > LVT_MAX) + return (EINVAL); + if (apic_id == APIC_ID_ALL) { + lvt = &lvts[pin]; + if (bootverbose) + printf("lapic:"); + } else { + KASSERT(lapics[apic_id].la_present, + ("%s: missing APIC %u", __func__, apic_id)); + lvt = &lapics[apic_id].la_lvts[pin]; + lvt->lvt_active = 1; + if (bootverbose) + printf("lapic%u:", apic_id); + } + lvt->lvt_mode = mode; + switch (mode) { + case APIC_LVT_DM_NMI: + case APIC_LVT_DM_SMI: + case APIC_LVT_DM_INIT: + case APIC_LVT_DM_EXTINT: + lvt->lvt_edgetrigger = 1; + lvt->lvt_activehi = 1; + if (mode == APIC_LVT_DM_EXTINT) + lvt->lvt_masked = 1; + else + lvt->lvt_masked = 0; + break; + default: + panic("Unsupported delivery mode: 0x%x\n", mode); + } + if (bootverbose) { + printf(" Routing "); + switch (mode) { + case APIC_LVT_DM_NMI: + printf("NMI"); + break; + case APIC_LVT_DM_SMI: + printf("SMI"); + break; + case APIC_LVT_DM_INIT: + printf("INIT"); + break; + case APIC_LVT_DM_EXTINT: + printf("ExtINT"); + break; + } + printf(" -> LINT%u\n", pin); + } + return (0); +} + +int +lapic_set_lvt_polarity(u_int apic_id, u_int pin, enum intr_polarity pol) +{ + + if (pin > LVT_MAX || pol == INTR_POLARITY_CONFORM) + return (EINVAL); + if (apic_id == APIC_ID_ALL) { + lvts[pin].lvt_activehi = (pol == INTR_POLARITY_HIGH); + if (bootverbose) + printf("lapic:"); + } else { + KASSERT(lapics[apic_id].la_present, + ("%s: missing APIC %u", __func__, apic_id)); + lapics[apic_id].la_lvts[pin].lvt_active = 1; + lapics[apic_id].la_lvts[pin].lvt_activehi = + (pol == INTR_POLARITY_HIGH); + if (bootverbose) + printf("lapic%u:", apic_id); + } + if (bootverbose) + printf(" LINT%u polarity: active-%s\n", pin, + pol == INTR_POLARITY_HIGH ? "high" : "low"); + return (0); +} + +int +lapic_set_lvt_triggermode(u_int apic_id, u_int pin, enum intr_trigger trigger) +{ + + if (pin > LVT_MAX || trigger == INTR_TRIGGER_CONFORM) + return (EINVAL); + if (apic_id == APIC_ID_ALL) { + lvts[pin].lvt_edgetrigger = (trigger == INTR_TRIGGER_EDGE); + if (bootverbose) + printf("lapic:"); + } else { + KASSERT(lapics[apic_id].la_present, + ("%s: missing APIC %u", __func__, apic_id)); + lapics[apic_id].la_lvts[pin].lvt_edgetrigger = + (trigger == INTR_TRIGGER_EDGE); + lapics[apic_id].la_lvts[pin].lvt_active = 1; + if (bootverbose) + printf("lapic%u:", apic_id); + } + if (bootverbose) + printf(" LINT%u trigger: %s\n", pin, + trigger == INTR_TRIGGER_EDGE ? "edge" : "level"); + return (0); +} + +void +lapic_eoi(void) +{ + + lapic->eoi = 0; +} + +void +lapic_handle_intr(struct intrframe frame) +{ + struct intsrc *isrc; + + if (frame.if_vec == -1) + panic("Couldn't get vector from ISR!"); + isrc = intr_lookup_source(apic_idt_to_irq(frame.if_vec)); + intr_execute_handlers(isrc, &frame); +} + +/* Translate between IDT vectors and IRQ vectors. */ +u_int +apic_irq_to_idt(u_int irq) +{ + u_int vector; + + KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq)); + vector = irq + APIC_IO_INTS; + if (vector >= IDT_SYSCALL) + vector++; + return (vector); +} + +u_int +apic_idt_to_irq(u_int vector) +{ + + KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL && + vector <= APIC_IO_INTS + NUM_IO_INTS, + ("Vector %u does not map to an IRQ line", vector)); + if (vector > IDT_SYSCALL) + vector--; + return (vector - APIC_IO_INTS); +} + +/* + * APIC probing support code. This includes code to manage enumerators. + */ + +static SLIST_HEAD(, apic_enumerator) enumerators = + SLIST_HEAD_INITIALIZER(enumerators); +static struct apic_enumerator *best_enum; + +void +apic_register_enumerator(struct apic_enumerator *enumerator) +{ +#ifdef INVARIANTS + struct apic_enumerator *apic_enum; + + SLIST_FOREACH(apic_enum, &enumerators, apic_next) { + if (apic_enum == enumerator) + panic("%s: Duplicate register of %s", __func__, + enumerator->apic_name); + } +#endif + SLIST_INSERT_HEAD(&enumerators, enumerator, apic_next); +} + +/* + * Probe the APIC enumerators, enumerate CPUs, and initialize the + * local APIC. + */ +static void +apic_init(void *dummy __unused) +{ + struct apic_enumerator *enumerator; + uint64_t apic_base; + int retval, best; + + /* We only support built in local APICs. */ + if (!(cpu_feature & CPUID_APIC)) + return; + + /* Don't probe if APIC mode is disabled. */ + if (resource_disabled("apic", 0)) + return; + + /* First, probe all the enumerators to find the best match. */ + best_enum = NULL; + best = 0; + SLIST_FOREACH(enumerator, &enumerators, apic_next) { + retval = enumerator->apic_probe(); + if (retval > 0) + continue; + if (best_enum == NULL || best < retval) { + best_enum = enumerator; + best = retval; + } + } + if (best_enum == NULL) { + if (bootverbose) + printf("APIC: Could not find any APICs.\n"); + return; + } + + if (bootverbose) + printf("APIC: Using the %s enumerator.\n", + best_enum->apic_name); + + /* + * To work around an errata, we disable the local APIC on some + * CPUs during early startup. We need to turn the local APIC back + * on on such CPUs now. + */ + if (cpu == CPU_686 && strcmp(cpu_vendor, "GenuineIntel") == 0 && + (cpu_id & 0xff0) == 0x610) { + apic_base = rdmsr(MSR_APICBASE); + apic_base |= APICBASE_ENABLED; + wrmsr(MSR_APICBASE, apic_base); + } + + /* Second, probe the CPU's in the system. */ + retval = best_enum->apic_probe_cpus(); + if (retval != 0) + printf("%s: Failed to probe CPUs: returned %d\n", + best_enum->apic_name, retval); + + /* Third, initialize the local APIC. */ + retval = best_enum->apic_setup_local(); + if (retval != 0) + printf("%s: Failed to setup the local APIC: returned %d\n", + best_enum->apic_name, retval); +#ifdef SMP + /* Last, setup the cpu topology now that we have probed CPUs */ + mp_topology(); +#endif +} +SYSINIT(apic_init, SI_SUB_CPU, SI_ORDER_FIRST, apic_init, NULL) + +/* + * Setup the I/O APICs. + */ +static void +apic_setup_io(void *dummy __unused) +{ + int retval; + + if (best_enum == NULL) + return; + retval = best_enum->apic_setup_io(); + if (retval != 0) + printf("%s: Failed to setup I/O APICs: returned %d\n", + best_enum->apic_name, retval); + + /* + * Finish setting up the local APIC on the BSP once we know how to + * properly program the LINT pins. + */ + lapic_setup(); + if (bootverbose) + lapic_dump("BSP"); +} +SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_SECOND, apic_setup_io, NULL) + +#ifdef SMP +/* + * Inter Processor Interrupt functions. The lapic_ipi_*() functions are + * private the sys/i386 code. The public interface for the rest of the + * kernel is defined in mp_machdep.c. + */ + +int +lapic_ipi_wait(int delay) +{ + int x, incr; + + /* + * Wait delay loops for IPI to be sent. This is highly bogus + * since this is sensitive to CPU clock speed. If delay is + * -1, we wait forever. + */ + if (delay == -1) { + incr = 0; + delay = 1; + } else + incr = 1; + for (x = 0; x < delay; x += incr) { + if ((lapic->icr_lo & APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE) + return (1); + ia32_pause(); + } + return (0); +} + +void +lapic_ipi_raw(register_t icrlo, u_int dest) +{ + register_t value, eflags; + + /* XXX: Need more sanity checking of icrlo? */ + KASSERT(lapic != NULL, ("%s called too early", __func__)); + KASSERT((dest & ~(APIC_ID_MASK >> APIC_ID_SHIFT)) == 0, + ("%s: invalid dest field", __func__)); + KASSERT((icrlo & APIC_ICRLO_RESV_MASK) == 0, + ("%s: reserved bits set in ICR LO register", __func__)); + + /* Set destination in ICR HI register if it is being used. */ + eflags = intr_disable(); + if ((icrlo & APIC_DEST_MASK) == APIC_DEST_DESTFLD) { + value = lapic->icr_hi; + value &= ~APIC_ID_MASK; + value |= dest << APIC_ID_SHIFT; + lapic->icr_hi = value; + } + + /* Program the contents of the IPI and dispatch it. */ + value = lapic->icr_lo; + value &= APIC_ICRLO_RESV_MASK; + value |= icrlo; + lapic->icr_lo = value; + intr_restore(eflags); +} + +#define BEFORE_SPIN 1000000 +#ifdef DETECT_DEADLOCK +#define AFTER_SPIN 1000 +#endif + +void +lapic_ipi_vectored(u_int vector, int dest) +{ + register_t icrlo, destfield; + + KASSERT((vector & ~APIC_VECTOR_MASK) == 0, + ("%s: invalid vector %d", __func__, vector)); + + icrlo = vector | APIC_DELMODE_FIXED | APIC_DESTMODE_PHY | + APIC_LEVEL_DEASSERT | APIC_TRIGMOD_EDGE; + destfield = 0; + switch (dest) { + case APIC_IPI_DEST_SELF: + icrlo |= APIC_DEST_SELF; + break; + case APIC_IPI_DEST_ALL: + icrlo |= APIC_DEST_ALLISELF; + break; + case APIC_IPI_DEST_OTHERS: + icrlo |= APIC_DEST_ALLESELF; + break; + default: + KASSERT((dest & ~(APIC_ID_MASK >> APIC_ID_SHIFT)) == 0, + ("%s: invalid destination 0x%x", __func__, dest)); + destfield = dest; + } + + /* Wait for an earlier IPI to finish. */ + if (!lapic_ipi_wait(BEFORE_SPIN)) + panic("APIC: Previous IPI is stuck"); + + lapic_ipi_raw(icrlo, destfield); + +#ifdef DETECT_DEADLOCK + /* Wait for IPI to be delivered. */ + if (!lapic_ipi_wait(AFTER_SPIN)) { +#ifdef needsattention + /* + * XXX FIXME: + * + * The above function waits for the message to actually be + * delivered. It breaks out after an arbitrary timeout + * since the message should eventually be delivered (at + * least in theory) and that if it wasn't we would catch + * the failure with the check above when the next IPI is + * sent. + * + * We could skiip this wait entirely, EXCEPT it probably + * protects us from other routines that assume that the + * message was delivered and acted upon when this function + * returns. + */ + printf("APIC: IPI might be stuck\n"); +#else /* !needsattention */ + /* Wait until mesage is sent without a timeout. */ + while (lapic->icr_lo & APIC_DELSTAT_PEND) + ia32_pause(); +#endif /* needsattention */ + } +#endif /* DETECT_DEADLOCK */ +} +#endif /* SMP */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/locore.s b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/locore.s new file mode 100644 index 0000000000..5146169162 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/locore.s @@ -0,0 +1,949 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)locore.s 7.3 (Berkeley) 5/13/91 + * $FreeBSD: src/sys/i386/i386/locore.s,v 1.181 2003/11/03 21:53:37 jhb Exp $ + * + * originally from: locore.s, by William F. Jolitz + * + * Substantially rewritten by David Greenman, Rod Grimes, + * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp + * and many others. + */ + +#include "opt_bootp.h" +#include "opt_compat.h" +#include "opt_nfsroot.h" +#include "opt_pmap.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "assym.s" + +.section __xen_guest + .asciz "LOADER=generic,GUEST_VER=5.2.1,XEN_VER=2.0,BSD_SYMTAB" + + +/* + * XXX + * + * Note: This version greatly munged to avoid various assembler errors + * that may be fixed in newer versions of gas. Perhaps newer versions + * will have more pleasant appearance. + */ + +/* + * PTmap is recursive pagemap at top of virtual address space. + * Within PTmap, the page directory can be found (third indirection). + */ + .globl PTmap,PTD,PTDpde + .set PTmap,(PTDPTDI << PDRSHIFT) + .set PTD,PTmap + (PTDPTDI * PAGE_SIZE) + .set PTDpde,PTD + (PTDPTDI * PDESIZE) + +#ifdef SMP +/* + * Define layout of per-cpu address space. + * This is "constructed" in locore.s on the BSP and in mp_machdep.c + * for each AP. DO NOT REORDER THESE WITHOUT UPDATING THE REST! + */ + .globl SMP_prvspace + .set SMP_prvspace,(MPPTDI << PDRSHIFT) +#endif /* SMP */ + +/* + * Compiled KERNBASE location and the kernel load address + */ + .globl kernbase + .set kernbase,KERNBASE + .globl kernload + .set kernload,KERNLOAD + +/* + * Globals + */ + .data + ALIGN_DATA /* just to be sure */ + + .space 0x2000 /* space for tmpstk - temporary stack */ +tmpstk: + + .globl bootinfo +bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ + + .globl KERNend +KERNend: .long 0 /* phys addr end of kernel (just after bss) */ +physfree: .long 0 /* phys addr of next free page */ + +#ifdef SMP + .globl cpu0prvpage +cpu0pp: .long 0 /* phys addr cpu0 private pg */ +cpu0prvpage: .long 0 /* relocated version */ + + .globl SMPpt +SMPptpa: .long 0 /* phys addr SMP page table */ +SMPpt: .long 0 /* relocated version */ +#endif /* SMP */ + + .globl IdlePTD +IdlePTD: .long 0 /* phys addr of kernel PTD */ + + + .globl KPTphys +KPTphys: .long 0 /* phys addr of kernel page tables */ + + .globl proc0uarea, proc0kstack +proc0uarea: .long 0 /* address of proc 0 uarea space */ +proc0kstack: .long 0 /* address of proc 0 kstack space */ +p0upa: .long 0 /* phys addr of proc0's UAREA */ +p0kpa: .long 0 /* phys addr of proc0's STACK */ + +#ifdef PC98 + .globl pc98_system_parameter +pc98_system_parameter: + .space 0x240 +#endif + +/********************************************************************** + * + * Some handy macros + * + */ + +#define R(foo) ((foo)) + +#define ALLOCPAGES(foo) \ + movl R(physfree), %esi ; \ + movl $((foo)*PAGE_SIZE), %eax ; \ + addl %esi, %eax ; \ + movl %eax, R(physfree) ; \ + movl %esi, %edi ; \ + movl $((foo)*PAGE_SIZE),%ecx ; \ + xorl %eax,%eax ; \ + cld ; \ + rep ; \ + stosb + +/* + * fillkpt + * eax = page frame address + * ebx = index into page table + * ecx = how many pages to map + * base = base address of page dir/table + * prot = protection bits + */ +#define fillkpt(base, prot) \ + shll $PTESHIFT,%ebx ; \ + addl base,%ebx ; \ + orl $PG_V,%eax ; \ + orl prot,%eax ; \ +1: movl %eax,(%ebx) ; \ + addl $PAGE_SIZE,%eax ; /* increment physical address */ \ + addl $PTESIZE,%ebx ; /* next pte */ \ + loop 1b + +/* + * fillkptphys(prot) + * eax = physical address + * ecx = how many pages to map + * prot = protection bits + */ +#define fillkptphys(prot) \ + movl %eax, %ebx ; \ + shrl $PAGE_SHIFT, %ebx ; \ + fillkpt(R(KPTphys), prot) + + .text +/********************************************************************** + * + * This is where the bootblocks start us, set the ball rolling... + * + */ +NON_GPROF_ENTRY(btext) + pushl %esi + call initvalues + popl %esi + call identify_cpu + movl proc0kstack,%eax + leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp + xorl %ebp,%ebp /* mark end of frames */ + movl IdlePTD,%esi + movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax) + call init386 + call mi_startup + int $3 + + +#ifdef PC98 + /* save SYSTEM PARAMETER for resume (NS/T or other) */ + movl $0xa1400,%esi + movl $R(pc98_system_parameter),%edi + movl $0x0240,%ecx + cld + rep + movsb +#else /* IBM-PC */ +/* Tell the bios to warmboot next time */ + movw $0x1234,0x472 +#endif /* PC98 */ + +/* Set up a real frame in case the double return in newboot is executed. */ + pushl %ebp + movl %esp, %ebp + +/* Don't trust what the BIOS gives for eflags. */ + pushl $PSL_KERNEL + popfl + +/* + * Don't trust what the BIOS gives for %fs and %gs. Trust the bootstrap + * to set %cs, %ds, %es and %ss. + */ + mov %ds, %ax + mov %ax, %fs + mov %ax, %gs + +/* + * Clear the bss. Not all boot programs do it, and it is our job anyway. + * + * XXX we don't check that there is memory for our bss and page tables + * before using it. + * + * Note: we must be careful to not overwrite an active gdt or idt. They + * inactive from now until we switch to new ones, since we don't load any + * more segment registers or permit interrupts until after the switch. + */ + movl $R(end),%ecx + movl $R(edata),%edi + subl %edi,%ecx + xorl %eax,%eax + cld + rep + stosb + + call recover_bootinfo + +/* Get onto a stack that we can trust. */ +/* + * XXX this step is delayed in case recover_bootinfo needs to return via + * the old stack, but it need not be, since recover_bootinfo actually + * returns via the old frame. + */ + movl $R(tmpstk),%esp + +#ifdef PC98 + /* pc98_machine_type & M_EPSON_PC98 */ + testb $0x02,R(pc98_system_parameter)+220 + jz 3f + /* epson_machine_id <= 0x0b */ + cmpb $0x0b,R(pc98_system_parameter)+224 + ja 3f + + /* count up memory */ + movl $0x100000,%eax /* next, talley remaining memory */ + movl $0xFFF-0x100,%ecx +1: movl 0(%eax),%ebx /* save location to check */ + movl $0xa55a5aa5,0(%eax) /* write test pattern */ + cmpl $0xa55a5aa5,0(%eax) /* does not check yet for rollover */ + jne 2f + movl %ebx,0(%eax) /* restore memory */ + addl $PAGE_SIZE,%eax + loop 1b +2: subl $0x100000,%eax + shrl $17,%eax + movb %al,R(pc98_system_parameter)+1 +3: + + movw R(pc98_system_parameter+0x86),%ax + movw %ax,R(cpu_id) +#endif + + call identify_cpu + call create_pagetables + +/* + * If the CPU has support for VME, turn it on. + */ + testl $CPUID_VME, R(cpu_feature) + jz 1f + movl %cr4, %eax + orl $CR4_VME, %eax + movl %eax, %cr4 +1: + +/* Now enable paging */ + movl R(IdlePTD), %eax + movl %eax,%cr3 /* load ptd addr into mmu */ + movl %cr0,%eax /* get control word */ + orl $CR0_PE|CR0_PG,%eax /* enable paging */ + movl %eax,%cr0 /* and let's page NOW! */ + + pushl $begin /* jump to high virtualized address */ + ret + +/* now running relocated at KERNBASE where the system is linked to run */ +begin: + /* set up bootstrap stack */ + movl proc0kstack,%eax /* location of in-kernel stack */ + /* bootstrap stack end location */ + leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp + + xorl %ebp,%ebp /* mark end of frames */ + +#ifdef PAE + movl IdlePDPT,%esi +#else + movl IdlePTD,%esi +#endif + movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax) + + pushl physfree /* value of first for init386(first) */ + call init386 /* wire 386 chip for unix operation */ + + /* + * Clean up the stack in a way that db_numargs() understands, so + * that backtraces in ddb don't underrun the stack. Traps for + * inaccessible memory are more fatal than usual this early. + */ + addl $4,%esp + + call mi_startup /* autoconfiguration, mountroot etc */ + /* NOTREACHED */ + addl $0,%esp /* for db_numargs() again */ + +/* + * Signal trampoline, copied to top of user stack + */ +NON_GPROF_ENTRY(sigcode) + calll *SIGF_HANDLER(%esp) + leal SIGF_UC(%esp),%eax /* get ucontext */ + pushl %eax + testl $PSL_VM,UC_EFLAGS(%eax) + jne 1f + movl UC_GS(%eax),%gs /* restore %gs */ +1: + movl $SYS_sigreturn,%eax + pushl %eax /* junk to fake return addr. */ + int $0x80 /* enter kernel with args */ + /* on stack */ +1: + jmp 1b + +#ifdef COMPAT_FREEBSD4 + ALIGN_TEXT +freebsd4_sigcode: + calll *SIGF_HANDLER(%esp) + leal SIGF_UC4(%esp),%eax /* get ucontext */ + pushl %eax + testl $PSL_VM,UC4_EFLAGS(%eax) + jne 1f + movl UC4_GS(%eax),%gs /* restore %gs */ +1: + movl $344,%eax /* 4.x SYS_sigreturn */ + pushl %eax /* junk to fake return addr. */ + int $0x80 /* enter kernel with args */ + /* on stack */ +1: + jmp 1b +#endif + +#ifdef COMPAT_43 + ALIGN_TEXT +osigcode: + call *SIGF_HANDLER(%esp) /* call signal handler */ + lea SIGF_SC(%esp),%eax /* get sigcontext */ + pushl %eax + testl $PSL_VM,SC_PS(%eax) + jne 9f + movl SC_GS(%eax),%gs /* restore %gs */ +9: + movl $103,%eax /* 3.x SYS_sigreturn */ + pushl %eax /* junk to fake return addr. */ + int $0x80 /* enter kernel with args */ +0: jmp 0b +#endif /* COMPAT_43 */ + + ALIGN_TEXT +esigcode: + + .data + .globl szsigcode +szsigcode: + .long esigcode-sigcode +#ifdef COMPAT_FREEBSD4 + .globl szfreebsd4_sigcode +szfreebsd4_sigcode: + .long esigcode-freebsd4_sigcode +#endif +#ifdef COMPAT_43 + .globl szosigcode +szosigcode: + .long esigcode-osigcode +#endif + .text + +/********************************************************************** + * + * Recover the bootinfo passed to us from the boot program + * + */ +recover_bootinfo: + /* + * This code is called in different ways depending on what loaded + * and started the kernel. This is used to detect how we get the + * arguments from the other code and what we do with them. + * + * Old disk boot blocks: + * (*btext)(howto, bootdev, cyloffset, esym); + * [return address == 0, and can NOT be returned to] + * [cyloffset was not supported by the FreeBSD boot code + * and always passed in as 0] + * [esym is also known as total in the boot code, and + * was never properly supported by the FreeBSD boot code] + * + * Old diskless netboot code: + * (*btext)(0,0,0,0,&nfsdiskless,0,0,0); + * [return address != 0, and can NOT be returned to] + * If we are being booted by this code it will NOT work, + * so we are just going to halt if we find this case. + * + * New uniform boot code: + * (*btext)(howto, bootdev, 0, 0, 0, &bootinfo) + * [return address != 0, and can be returned to] + * + * There may seem to be a lot of wasted arguments in here, but + * that is so the newer boot code can still load very old kernels + * and old boot code can load new kernels. + */ + + /* + * The old style disk boot blocks fake a frame on the stack and + * did an lret to get here. The frame on the stack has a return + * address of 0. + */ + cmpl $0,4(%ebp) + je olddiskboot + + /* + * We have some form of return address, so this is either the + * old diskless netboot code, or the new uniform code. That can + * be detected by looking at the 5th argument, if it is 0 + * we are being booted by the new uniform boot code. + */ + cmpl $0,24(%ebp) + je newboot + + /* + * Seems we have been loaded by the old diskless boot code, we + * don't stand a chance of running as the diskless structure + * changed considerably between the two, so just halt. + */ + hlt + + /* + * We have been loaded by the new uniform boot code. + * Let's check the bootinfo version, and if we do not understand + * it we return to the loader with a status of 1 to indicate this error + */ +newboot: + movl 28(%ebp),%ebx /* &bootinfo.version */ + movl BI_VERSION(%ebx),%eax + cmpl $1,%eax /* We only understand version 1 */ + je 1f + movl $1,%eax /* Return status */ + leave + /* + * XXX this returns to our caller's caller (as is required) since + * we didn't set up a frame and our caller did. + */ + ret + +1: + /* + * If we have a kernelname copy it in + */ + movl BI_KERNELNAME(%ebx),%esi + cmpl $0,%esi + je 2f /* No kernelname */ + movl $MAXPATHLEN,%ecx /* Brute force!!! */ + movl $R(kernelname),%edi + cmpb $'/',(%esi) /* Make sure it starts with a slash */ + je 1f + movb $'/',(%edi) + incl %edi + decl %ecx +1: + cld + rep + movsb + +2: + /* + * Determine the size of the boot loader's copy of the bootinfo + * struct. This is impossible to do properly because old versions + * of the struct don't contain a size field and there are 2 old + * versions with the same version number. + */ + movl $BI_ENDCOMMON,%ecx /* prepare for sizeless version */ + testl $RB_BOOTINFO,8(%ebp) /* bi_size (and bootinfo) valid? */ + je got_bi_size /* no, sizeless version */ + movl BI_SIZE(%ebx),%ecx +got_bi_size: + + /* + * Copy the common part of the bootinfo struct + */ + movl %ebx,%esi + movl $R(bootinfo),%edi + cmpl $BOOTINFO_SIZE,%ecx + jbe got_common_bi_size + movl $BOOTINFO_SIZE,%ecx +got_common_bi_size: + cld + rep + movsb + +#ifdef NFS_ROOT +#ifndef BOOTP_NFSV3 + /* + * If we have a nfs_diskless structure copy it in + */ + movl BI_NFS_DISKLESS(%ebx),%esi + cmpl $0,%esi + je olddiskboot + movl $R(nfs_diskless),%edi + movl $NFSDISKLESS_SIZE,%ecx + cld + rep + movsb + movl $R(nfs_diskless_valid),%edi + movl $1,(%edi) +#endif +#endif + + /* + * The old style disk boot. + * (*btext)(howto, bootdev, cyloffset, esym); + * Note that the newer boot code just falls into here to pick + * up howto and bootdev, cyloffset and esym are no longer used + */ +olddiskboot: + movl 8(%ebp),%eax + movl %eax,R(boothowto) + movl 12(%ebp),%eax + movl %eax,R(bootdev) + + ret + + +/********************************************************************** + * + * Identify the CPU and initialize anything special about it + * + */ +identify_cpu: + + /* Try to toggle alignment check flag ; does not exist on 386. */ + pushfl + popl %eax + movl %eax,%ecx + orl $PSL_AC,%eax + pushl %eax + popfl + pushfl + popl %eax + xorl %ecx,%eax + andl $PSL_AC,%eax + pushl %ecx + popfl + + testl %eax,%eax + jnz try486 + + /* NexGen CPU does not have aligment check flag. */ + pushfl + movl $0x5555, %eax + xorl %edx, %edx + movl $2, %ecx + clc + divl %ecx + jz trynexgen + popfl + movl $CPU_386,R(cpu) + jmp 3f + +trynexgen: + popfl + movl $CPU_NX586,R(cpu) + movl $0x4778654e,R(cpu_vendor) # store vendor string + movl $0x72446e65,R(cpu_vendor+4) + movl $0x6e657669,R(cpu_vendor+8) + movl $0,R(cpu_vendor+12) + jmp 3f + +try486: /* Try to toggle identification flag ; does not exist on early 486s. */ + pushfl + popl %eax + movl %eax,%ecx + xorl $PSL_ID,%eax + pushl %eax + popfl + pushfl + popl %eax + xorl %ecx,%eax + andl $PSL_ID,%eax + pushl %ecx + popfl + + testl %eax,%eax + jnz trycpuid + movl $CPU_486,R(cpu) + + /* + * Check Cyrix CPU + * Cyrix CPUs do not change the undefined flags following + * execution of the divide instruction which divides 5 by 2. + * + * Note: CPUID is enabled on M2, so it passes another way. + */ + pushfl + movl $0x5555, %eax + xorl %edx, %edx + movl $2, %ecx + clc + divl %ecx + jnc trycyrix + popfl + jmp 3f /* You may use Intel CPU. */ + +trycyrix: + popfl + /* + * IBM Bluelighting CPU also doesn't change the undefined flags. + * Because IBM doesn't disclose the information for Bluelighting + * CPU, we couldn't distinguish it from Cyrix's (including IBM + * brand of Cyrix CPUs). + */ + movl $0x69727943,R(cpu_vendor) # store vendor string + movl $0x736e4978,R(cpu_vendor+4) + movl $0x64616574,R(cpu_vendor+8) + jmp 3f + +trycpuid: /* Use the `cpuid' instruction. */ + xorl %eax,%eax + cpuid # cpuid 0 + movl %eax,R(cpu_high) # highest capability + movl %ebx,R(cpu_vendor) # store vendor string + movl %edx,R(cpu_vendor+4) + movl %ecx,R(cpu_vendor+8) + movb $0,R(cpu_vendor+12) + + movl $1,%eax + cpuid # cpuid 1 + movl %eax,R(cpu_id) # store cpu_id + movl %ebx,R(cpu_procinfo) # store cpu_procinfo + movl %edx,R(cpu_feature) # store cpu_feature + rorl $8,%eax # extract family type + andl $15,%eax + cmpl $5,%eax + jae 1f + + /* less than Pentium ; must be 486 */ + movl $CPU_486,R(cpu) + jmp 3f +1: + /* a Pentium? */ + cmpl $5,%eax + jne 2f + movl $CPU_586,R(cpu) + jmp 3f +2: + /* Greater than Pentium...call it a Pentium Pro */ + movl $CPU_686,R(cpu) +3: + ret + +/********************************************************************** + * + * Create the first page directory and its page tables. + * + */ + +create_pagetables: + +/* Find end of kernel image (rounded up to a page boundary). */ + movl $R(_end),%esi + +/* Include symbols, if any. */ + movl R(bootinfo+BI_ESYMTAB),%edi + testl %edi,%edi + je over_symalloc + movl %edi,%esi + movl $KERNBASE,%edi + addl %edi,R(bootinfo+BI_SYMTAB) + addl %edi,R(bootinfo+BI_ESYMTAB) +over_symalloc: + +/* If we are told where the end of the kernel space is, believe it. */ + movl R(bootinfo+BI_KERNEND),%edi + testl %edi,%edi + je no_kernend + movl %edi,%esi +no_kernend: + + addl $PDRMASK,%esi /* Play conservative for now, and */ + andl $~PDRMASK,%esi /* ... wrap to next 4M. */ + movl %esi,R(KERNend) /* save end of kernel */ + movl %esi,R(physfree) /* next free page is at end of kernel */ + +/* Allocate Kernel Page Tables */ + ALLOCPAGES(NKPT) + movl %esi,R(KPTphys) + +/* Allocate Page Table Directory */ +#ifdef PAE + /* XXX only need 32 bytes (easier for now) */ + ALLOCPAGES(1) + movl %esi,R(IdlePDPT) +#endif + ALLOCPAGES(NPGPTD) + movl %esi,R(IdlePTD) + +/* Allocate UPAGES */ + ALLOCPAGES(UAREA_PAGES) + movl %esi,R(p0upa) + addl $KERNBASE, %esi + movl %esi, R(proc0uarea) + + ALLOCPAGES(KSTACK_PAGES) + movl %esi,R(p0kpa) + addl $KERNBASE, %esi + movl %esi, R(proc0kstack) +#if 0 + ALLOCPAGES(1) /* vm86/bios stack */ + movl %esi,R(vm86phystk) + + ALLOCPAGES(3) /* pgtable + ext + IOPAGES */ + movl %esi,R(vm86pa) + addl $KERNBASE, %esi + movl %esi, R(vm86paddr) +#endif +#ifdef SMP +/* Allocate cpu0's private data page */ + ALLOCPAGES(1) + movl %esi,R(cpu0pp) + addl $KERNBASE, %esi + movl %esi, R(cpu0prvpage) /* relocated to KVM space */ + +/* Allocate SMP page table page */ + ALLOCPAGES(1) + movl %esi,R(SMPptpa) + addl $KERNBASE, %esi + movl %esi, R(SMPpt) /* relocated to KVM space */ +#endif /* SMP */ + +/* Map page zero read-write so bios32 calls can use it */ + xorl %eax, %eax + movl $PG_RW,%edx + movl $1,%ecx + fillkptphys(%edx) + +/* Map read-only from page 1 to the beginning of the kernel text section */ + movl $PAGE_SIZE, %eax + xorl %edx,%edx + movl $R(btext),%ecx + addl $PAGE_MASK,%ecx + subl %eax,%ecx + shrl $PAGE_SHIFT,%ecx + fillkptphys(%edx) + +/* + * Enable PSE and PGE. + */ +#ifndef DISABLE_PSE + testl $CPUID_PSE, R(cpu_feature) + jz 1f + movl $PG_PS, R(pseflag) + movl %cr4, %eax + orl $CR4_PSE, %eax + movl %eax, %cr4 +1: +#endif +#ifndef DISABLE_PG_G + testl $CPUID_PGE, R(cpu_feature) + jz 2f + movl $PG_G, R(pgeflag) + movl %cr4, %eax + orl $CR4_PGE, %eax + movl %eax, %cr4 +2: +#endif + +/* + * Write page tables for the kernel starting at btext and + * until the end. Make sure to map read+write. We do this even + * if we've enabled PSE above, we'll just switch the corresponding kernel + * PDEs before we turn on paging. + * + * XXX: We waste some pages here in the PSE case! DON'T BLINDLY REMOVE + * THIS! SMP needs the page table to be there to map the kernel P==V. + */ + movl $R(btext),%eax + addl $PAGE_MASK, %eax + andl $~PAGE_MASK, %eax + movl $PG_RW,%edx + movl R(KERNend),%ecx + subl %eax,%ecx + shrl $PAGE_SHIFT,%ecx + fillkptphys(%edx) + +/* Map page directory. */ + movl R(IdlePTD), %eax + movl $NPGPTD, %ecx + fillkptphys($PG_RW) + +/* Map proc0's UPAGES in the physical way ... */ + movl R(p0upa), %eax + movl $(UAREA_PAGES), %ecx + fillkptphys($PG_RW) + +/* Map proc0's KSTACK in the physical way ... */ + movl R(p0kpa), %eax + movl $(KSTACK_PAGES), %ecx + fillkptphys($PG_RW) + +/* Map ISA hole */ + movl $ISA_HOLE_START, %eax + movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx + fillkptphys($PG_RW) +#if 0 +/* Map space for the vm86 region */ + movl R(vm86phystk), %eax + movl $4, %ecx + fillkptphys($PG_RW) + +/* Map page 0 into the vm86 page table */ + movl $0, %eax + movl $0, %ebx + movl $1, %ecx + fillkpt(R(vm86pa), $PG_RW|PG_U) + +/* ...likewise for the ISA hole */ + movl $ISA_HOLE_START, %eax + movl $ISA_HOLE_START>>PAGE_SHIFT, %ebx + movl $ISA_HOLE_LENGTH>>PAGE_SHIFT, %ecx + fillkpt(R(vm86pa), $PG_RW|PG_U) +#endif +#ifdef SMP +/* Map cpu0's private page into global kmem (4K @ cpu0prvpage) */ + movl R(cpu0pp), %eax + movl $1, %ecx + fillkptphys($PG_RW) + +/* Map SMP page table page into global kmem FWIW */ + movl R(SMPptpa), %eax + movl $1, %ecx + fillkptphys($PG_RW) + +/* Map the private page into the SMP page table */ + movl R(cpu0pp), %eax + movl $0, %ebx /* pte offset = 0 */ + movl $1, %ecx /* one private page coming right up */ + fillkpt(R(SMPptpa), $PG_RW) + +/* ... and put the page table table in the pde. */ + movl R(SMPptpa), %eax + movl $MPPTDI, %ebx + movl $1, %ecx + fillkpt(R(IdlePTD), $PG_RW) + +/* Fakeup VA for the local apic to allow early traps. */ + ALLOCPAGES(1) + movl %esi, %eax + movl $(NPTEPG-1), %ebx /* pte offset = NTEPG-1 */ + movl $1, %ecx /* one private pt coming right up */ + fillkpt(R(SMPptpa), $PG_RW) +#endif /* SMP */ + +/* install a pde for temporary double map of bottom of VA */ + movl R(KPTphys), %eax + xorl %ebx, %ebx + movl $NKPT, %ecx + fillkpt(R(IdlePTD), $PG_RW) + +/* + * For the non-PSE case, install PDEs for PTs covering the kernel. + * For the PSE case, do the same, but clobber the ones corresponding + * to the kernel (from btext to KERNend) with 4M ('PS') PDEs immediately + * after. + */ + movl R(KPTphys), %eax + movl $KPTDI, %ebx + movl $NKPT, %ecx + fillkpt(R(IdlePTD), $PG_RW) + cmpl $0,R(pseflag) + je done_pde + + movl R(KERNend), %ecx + movl $KERNLOAD, %eax + subl %eax, %ecx + shrl $PDRSHIFT, %ecx + movl $(KPTDI+(KERNLOAD/(1 << PDRSHIFT))), %ebx + shll $PDESHIFT, %ebx + addl R(IdlePTD), %ebx + orl $(PG_V|PG_RW|PG_PS), %eax +1: movl %eax, (%ebx) + addl $(1 << PDRSHIFT), %eax + addl $PDESIZE, %ebx + loop 1b + +done_pde: +/* install a pde recursively mapping page directory as a page table */ + movl R(IdlePTD), %eax + movl $PTDPTDI, %ebx + movl $NPGPTD,%ecx + fillkpt(R(IdlePTD), $PG_RW) + +#ifdef PAE + movl R(IdlePTD), %eax + xorl %ebx, %ebx + movl $NPGPTD, %ecx + fillkpt(R(IdlePDPT), $0x0) +#endif + + ret diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c new file mode 100644 index 0000000000..ea813b897c --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c @@ -0,0 +1,2396 @@ +/*- + * Copyright (c) 1992 Terrence R. Lambert. + * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/machdep.c,v 1.584 2003/12/03 21:12:09 jhb Exp $"); + +#include "opt_apic.h" +#include "opt_atalk.h" +#include "opt_compat.h" +#include "opt_cpu.h" +#include "opt_ddb.h" +#include "opt_inet.h" +#include "opt_ipx.h" +#include "opt_isa.h" +#include "opt_kstack_pages.h" +#include "opt_maxmem.h" +#include "opt_msgbuf.h" +#include "opt_npx.h" +#include "opt_perfmon.h" +#include "opt_xen.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef DDB +#ifndef KDB +#error KDB must be enabled in order for DDB to work! +#endif +#include +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* pcb.h included via sys/user.h */ +#include +#ifdef PERFMON +#include +#endif +#ifdef SMP +#include +#include +#endif + +#ifdef DEV_ISA +#include +#endif + +#include +#include +#include + + +/* XEN includes */ +#include +#include +#include +#include +#include +#include + +void Xhypervisor_callback(void); +void failsafe_callback(void); + +/***************/ + + +/* Sanity check for __curthread() */ +CTASSERT(offsetof(struct pcpu, pc_curthread) == 0); + +extern void init386(void); +extern void dblfault_handler(void); + +extern void printcpuinfo(void); /* XXX header file */ +extern void finishidentcpu(void); +extern void panicifcpuunsupported(void); +extern void initializecpu(void); +void initvalues(start_info_t *startinfo); + +#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) +#define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) + +#if !defined(CPU_ENABLE_SSE) && defined(I686_CPU) +#define CPU_ENABLE_SSE +#endif +#if defined(CPU_DISABLE_SSE) +#undef CPU_ENABLE_SSE +#endif + +static void cpu_startup(void *); +static void fpstate_drop(struct thread *td); +static void get_fpcontext(struct thread *td, mcontext_t *mcp); +static int set_fpcontext(struct thread *td, const mcontext_t *mcp); +#ifdef CPU_ENABLE_SSE +static void set_fpregs_xmm(struct save87 *, struct savexmm *); +static void fill_fpregs_xmm(struct savexmm *, struct save87 *); +#endif /* CPU_ENABLE_SSE */ +SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) + +#ifdef DDB +extern vm_offset_t ksym_start, ksym_end; +#endif + +int _udatasel, _ucodesel; +u_int basemem; + +start_info_t *xen_start_info; +unsigned long *xen_phys_machine; +int xendebug_flags; +int init_first = 0; +int cold = 1; + +#ifdef COMPAT_43 +static void osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code); +#endif +#ifdef COMPAT_FREEBSD4 +static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask, + u_long code); +#endif + +long Maxmem = 0; + +vm_paddr_t phys_avail[10]; + +/* must be 2 less so 0 0 can signal end of chunks */ +#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) + +struct kva_md_info kmi; + +static struct trapframe proc0_tf; +#ifndef SMP +static struct pcpu __pcpu; +#endif + +static void +map_range(void *physptr, unsigned long physptrindex, + unsigned long physindex, int count, unsigned int flags) { + int i; + unsigned long pte, ppa; + for (i = 0; i < count; i++) { + pte = ((unsigned long)physptr) + (physptrindex << 2) + (i << 2); + ppa = (PTOM(physindex + i) << PAGE_SHIFT) | flags | PG_V | PG_A; + xpq_queue_pt_update((pt_entry_t *)pte, ppa); + } + mcl_flush_queue(); +} + +struct mem_range_softc mem_range_softc; + +static void +cpu_startup(void *dummy) +{ + /* + * Good {morning,afternoon,evening,night}. + */ + /* XXX need to write clock driver */ + startrtclock(); + + printcpuinfo(); + panicifcpuunsupported(); +#ifdef PERFMON + perfmon_init(); +#endif + printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), + ptoa((uintmax_t)Maxmem) / 1048576); + /* + * Display any holes after the first chunk of extended memory. + */ + if (bootverbose) { + int indx; + + printf("Physical memory chunk(s):\n"); + for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { + vm_paddr_t size; + + size = phys_avail[indx + 1] - phys_avail[indx]; + printf( + "0x%016jx - 0x%016jx, %ju bytes (%ju pages)\n", + (uintmax_t)phys_avail[indx], + (uintmax_t)phys_avail[indx + 1] - 1, + (uintmax_t)size, (uintmax_t)size / PAGE_SIZE); + } + } + + vm_ksubmap_init(&kmi); + + printf("avail memory = %ju (%ju MB)\n", + ptoa((uintmax_t)cnt.v_free_count), + ptoa((uintmax_t)cnt.v_free_count) / 1048576); + + /* + * Set up buffers, so they can be used to read disk labels. + */ + bufinit(); + vm_pager_bufferinit(); + + cpu_setregs(); + +} + +/* + * Send an interrupt to process. + * + * Stack is set up to allow sigcode stored + * at top to call routine, followed by kcall + * to sigreturn routine below. After sigreturn + * resets the signal mask, the stack, and the + * frame pointer, it returns to the user + * specified pc, psl. + */ +#ifdef COMPAT_43 +static void +osendsig(catcher, sig, mask, code) + sig_t catcher; + int sig; + sigset_t *mask; + u_long code; +{ + struct osigframe sf, *fp; + struct proc *p; + struct thread *td; + struct sigacts *psp; + struct trapframe *regs; + int oonstack; + + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + psp = p->p_sigacts; + mtx_assert(&psp->ps_mtx, MA_OWNED); + regs = td->td_frame; + oonstack = sigonstack(regs->tf_esp); + + /* Allocate space for the signal handler context. */ + if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + fp = (struct osigframe *)(td->td_sigstk.ss_sp + + td->td_sigstk.ss_size - sizeof(struct osigframe)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + td->td_sigstk.ss_flags |= SS_ONSTACK; +#endif + } else + fp = (struct osigframe *)regs->tf_esp - 1; + + /* Translate the signal if appropriate. */ + if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + + /* Build the argument list for the signal handler. */ + sf.sf_signum = sig; + sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; + if (SIGISMEMBER(psp->ps_siginfo, sig)) { + /* Signal handler installed with SA_SIGINFO. */ + sf.sf_arg2 = (register_t)&fp->sf_siginfo; + sf.sf_siginfo.si_signo = sig; + sf.sf_siginfo.si_code = code; + sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher; + } else { + /* Old FreeBSD-style arguments. */ + sf.sf_arg2 = code; + sf.sf_addr = regs->tf_err; + sf.sf_ahu.sf_handler = catcher; + } + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(p); + + /* Save most if not all of trap frame. */ + sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax; + sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx; + sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx; + sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx; + sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi; + sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi; + sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs; + sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds; + sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss; + sf.sf_siginfo.si_sc.sc_es = regs->tf_es; + sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs; + sf.sf_siginfo.si_sc.sc_gs = rgs(); + sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp; + + /* Build the signal context to be used by osigreturn(). */ + sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; + SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); + sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp; + sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp; + sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip; + sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags; + sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno; + sf.sf_siginfo.si_sc.sc_err = regs->tf_err; + + /* + * Copy the sigframe out to the user's stack. + */ + if (copyout(&sf, fp, sizeof(*fp)) != 0) { +#ifdef DEBUG + printf("process %ld has trashed its stack\n", (long)p->p_pid); +#endif + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + regs->tf_esp = (int)fp; + regs->tf_eip = PS_STRINGS - szosigcode; + regs->tf_eflags &= ~PSL_T; + regs->tf_cs = _ucodesel; + regs->tf_ds = _udatasel; + regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; + load_gs(_udatasel); + regs->tf_ss = _udatasel; + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); +} +#endif /* COMPAT_43 */ + +#ifdef COMPAT_FREEBSD4 +static void +freebsd4_sendsig(catcher, sig, mask, code) + sig_t catcher; + int sig; + sigset_t *mask; + u_long code; +{ + struct sigframe4 sf, *sfp; + struct proc *p; + struct thread *td; + struct sigacts *psp; + struct trapframe *regs; + int oonstack; + + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + psp = p->p_sigacts; + mtx_assert(&psp->ps_mtx, MA_OWNED); + regs = td->td_frame; + oonstack = sigonstack(regs->tf_esp); + + /* Save user context. */ + bzero(&sf, sizeof(sf)); + sf.sf_uc.uc_sigmask = *mask; + sf.sf_uc.uc_stack = td->td_sigstk; + sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) + ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; + sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; + sf.sf_uc.uc_mcontext.mc_gs = rgs(); + bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); + + /* Allocate space for the signal handler context. */ + if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + sfp = (struct sigframe4 *)(td->td_sigstk.ss_sp + + td->td_sigstk.ss_size - sizeof(struct sigframe4)); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + td->td_sigstk.ss_flags |= SS_ONSTACK; +#endif + } else + sfp = (struct sigframe4 *)regs->tf_esp - 1; + + /* Translate the signal if appropriate. */ + if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + + /* Build the argument list for the signal handler. */ + sf.sf_signum = sig; + sf.sf_ucontext = (register_t)&sfp->sf_uc; + if (SIGISMEMBER(psp->ps_siginfo, sig)) { + /* Signal handler installed with SA_SIGINFO. */ + sf.sf_siginfo = (register_t)&sfp->sf_si; + sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; + + /* Fill in POSIX parts */ + sf.sf_si.si_signo = sig; + sf.sf_si.si_code = code; + sf.sf_si.si_addr = (void *)regs->tf_err; + } else { + /* Old FreeBSD-style arguments. */ + sf.sf_siginfo = code; + sf.sf_addr = regs->tf_err; + sf.sf_ahu.sf_handler = catcher; + } + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(p); + + /* + * Copy the sigframe out to the user's stack. + */ + if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { +#ifdef DEBUG + printf("process %ld has trashed its stack\n", (long)p->p_pid); +#endif + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + regs->tf_esp = (int)sfp; + regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode; + regs->tf_eflags &= ~PSL_T; + regs->tf_cs = _ucodesel; + regs->tf_ds = _udatasel; + regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; + regs->tf_ss = _udatasel; + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); +} +#endif /* COMPAT_FREEBSD4 */ + +void +sendsig(catcher, sig, mask, code) + sig_t catcher; + int sig; + sigset_t *mask; + u_long code; +{ + struct sigframe sf, *sfp; + struct proc *p; + struct thread *td; + struct sigacts *psp; + char *sp; + struct trapframe *regs; + int oonstack; + + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + psp = p->p_sigacts; + mtx_assert(&psp->ps_mtx, MA_OWNED); +#ifdef COMPAT_FREEBSD4 + if (SIGISMEMBER(psp->ps_freebsd4, sig)) { + freebsd4_sendsig(catcher, sig, mask, code); + return; + } +#endif +#ifdef COMPAT_43 + if (SIGISMEMBER(psp->ps_osigset, sig)) { + osendsig(catcher, sig, mask, code); + return; + } +#endif + regs = td->td_frame; + oonstack = sigonstack(regs->tf_esp); + + /* Save user context. */ + bzero(&sf, sizeof(sf)); + sf.sf_uc.uc_sigmask = *mask; + sf.sf_uc.uc_stack = td->td_sigstk; + sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) + ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; + sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; + sf.sf_uc.uc_mcontext.mc_gs = rgs(); + bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); + sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ + get_fpcontext(td, &sf.sf_uc.uc_mcontext); + fpstate_drop(td); + + /* Allocate space for the signal handler context. */ + if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + sp = td->td_sigstk.ss_sp + + td->td_sigstk.ss_size - sizeof(struct sigframe); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + td->td_sigstk.ss_flags |= SS_ONSTACK; +#endif + } else + sp = (char *)regs->tf_esp - sizeof(struct sigframe); + /* Align to 16 bytes. */ + sfp = (struct sigframe *)((unsigned int)sp & ~0xF); + + /* Translate the signal if appropriate. */ + if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) + sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; + + /* Build the argument list for the signal handler. */ + sf.sf_signum = sig; + sf.sf_ucontext = (register_t)&sfp->sf_uc; + if (SIGISMEMBER(psp->ps_siginfo, sig)) { + /* Signal handler installed with SA_SIGINFO. */ + sf.sf_siginfo = (register_t)&sfp->sf_si; + sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; + + /* Fill in POSIX parts */ + sf.sf_si.si_signo = sig; + sf.sf_si.si_code = code; + sf.sf_si.si_addr = (void *)regs->tf_err; + } else { + /* Old FreeBSD-style arguments. */ + sf.sf_siginfo = code; + sf.sf_addr = regs->tf_err; + sf.sf_ahu.sf_handler = catcher; + } + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(p); + /* + * Copy the sigframe out to the user's stack. + */ + if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { +#ifdef DEBUG + printf("process %ld has trashed its stack\n", (long)p->p_pid); +#endif + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + regs->tf_esp = (int)sfp; + regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); + regs->tf_eflags &= ~PSL_T; + regs->tf_cs = _ucodesel; + regs->tf_ds = _udatasel; + regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; + regs->tf_ss = _udatasel; + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); +} + +/* + * Build siginfo_t for SA thread + */ +void +cpu_thread_siginfo(int sig, u_long code, siginfo_t *si) +{ + struct proc *p; + struct thread *td; + + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + + bzero(si, sizeof(*si)); + si->si_signo = sig; + si->si_code = code; + si->si_addr = (void *)td->td_frame->tf_err; + /* XXXKSE fill other fields */ +} + +/* + * System call to cleanup state after a signal + * has been taken. Reset signal mask and + * stack state from context left by sendsig (above). + * Return to previous pc and psl as specified by + * context left by sendsig. Check carefully to + * make sure that the user has not modified the + * state to gain improper privileges. + * + * MPSAFE + */ +#ifdef COMPAT_43 +int +osigreturn(td, uap) + struct thread *td; + struct osigreturn_args /* { + struct osigcontext *sigcntxp; + } */ *uap; +{ + struct osigcontext sc; + struct trapframe *regs; + struct osigcontext *scp; + struct proc *p = td->td_proc; + int eflags, error; + + regs = td->td_frame; + error = copyin(uap->sigcntxp, &sc, sizeof(sc)); + if (error != 0) + return (error); + scp = ≻ + eflags = scp->sc_ps; + /* + * Don't allow users to change privileged or reserved flags. + */ + /* + * XXX do allow users to change the privileged flag PSL_RF. + * The cpu sets PSL_RF in tf_eflags for faults. Debuggers + * should sometimes set it there too. tf_eflags is kept in + * the signal context during signal handling and there is no + * other place to remember it, so the PSL_RF bit may be + * corrupted by the signal handler without us knowing. + * Corruption of the PSL_RF bit at worst causes one more or + * one less debugger trap, so allowing it is fairly harmless. + */ + if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { + return (EINVAL); + } + + /* + * Don't allow users to load a valid privileged %cs. Let the + * hardware check for invalid selectors, excess privilege in + * other selectors, invalid %eip's and invalid %esp's. + */ + if (!CS_SECURE(scp->sc_cs)) { + trapsignal(td, SIGBUS, T_PROTFLT); + return (EINVAL); + } + regs->tf_ds = scp->sc_ds; + regs->tf_es = scp->sc_es; + regs->tf_fs = scp->sc_fs; + + /* Restore remaining registers. */ + regs->tf_eax = scp->sc_eax; + regs->tf_ebx = scp->sc_ebx; + regs->tf_ecx = scp->sc_ecx; + regs->tf_edx = scp->sc_edx; + regs->tf_esi = scp->sc_esi; + regs->tf_edi = scp->sc_edi; + regs->tf_cs = scp->sc_cs; + regs->tf_ss = scp->sc_ss; + regs->tf_isp = scp->sc_isp; + regs->tf_ebp = scp->sc_fp; + regs->tf_esp = scp->sc_sp; + regs->tf_eip = scp->sc_pc; + regs->tf_eflags = eflags; + + PROC_LOCK(p); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (scp->sc_onstack & 1) + td->td_sigstk.ss_flags |= SS_ONSTACK; + else + td->td_sigstk.ss_flags &= ~SS_ONSTACK; +#endif + SIGSETOLD(td->td_sigmask, scp->sc_mask); + SIG_CANTMASK(td->td_sigmask); + signotify(td); + PROC_UNLOCK(p); + return (EJUSTRETURN); +} +#endif /* COMPAT_43 */ + +#ifdef COMPAT_FREEBSD4 +/* + * MPSAFE + */ +int +freebsd4_sigreturn(td, uap) + struct thread *td; + struct freebsd4_sigreturn_args /* { + const ucontext4 *sigcntxp; + } */ *uap; +{ + struct ucontext4 uc; + struct proc *p = td->td_proc; + struct trapframe *regs; + const struct ucontext4 *ucp; + int cs, eflags, error; + + error = copyin(uap->sigcntxp, &uc, sizeof(uc)); + if (error != 0) + return (error); + ucp = &uc; + regs = td->td_frame; + eflags = ucp->uc_mcontext.mc_eflags; + /* + * Don't allow users to change privileged or reserved flags. + */ + /* + * XXX do allow users to change the privileged flag PSL_RF. + * The cpu sets PSL_RF in tf_eflags for faults. Debuggers + * should sometimes set it there too. tf_eflags is kept in + * the signal context during signal handling and there is no + * other place to remember it, so the PSL_RF bit may be + * corrupted by the signal handler without us knowing. + * Corruption of the PSL_RF bit at worst causes one more or + * one less debugger trap, so allowing it is fairly harmless. + */ + if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { + printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags); + return (EINVAL); + } + + /* + * Don't allow users to load a valid privileged %cs. Let the + * hardware check for invalid selectors, excess privilege in + * other selectors, invalid %eip's and invalid %esp's. + */ + cs = ucp->uc_mcontext.mc_cs; + if (!CS_SECURE(cs)) { + printf("freebsd4_sigreturn: cs = 0x%x\n", cs); + trapsignal(td, SIGBUS, T_PROTFLT); + return (EINVAL); + } + + bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); + + PROC_LOCK(p); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (ucp->uc_mcontext.mc_onstack & 1) + td->td_sigstk.ss_flags |= SS_ONSTACK; + else + td->td_sigstk.ss_flags &= ~SS_ONSTACK; +#endif + + td->td_sigmask = ucp->uc_sigmask; + SIG_CANTMASK(td->td_sigmask); + signotify(td); + PROC_UNLOCK(p); + return (EJUSTRETURN); +} +#endif /* COMPAT_FREEBSD4 */ + +/* + * MPSAFE + */ +int +sigreturn(td, uap) + struct thread *td; + struct sigreturn_args /* { + const __ucontext *sigcntxp; + } */ *uap; +{ + ucontext_t uc; + struct proc *p = td->td_proc; + struct trapframe *regs; + const ucontext_t *ucp; + int cs, eflags, error, ret; + + error = copyin(uap->sigcntxp, &uc, sizeof(uc)); + if (error != 0) + return (error); + ucp = &uc; + regs = td->td_frame; + eflags = ucp->uc_mcontext.mc_eflags; + /* + * Don't allow users to change privileged or reserved flags. + */ + /* + * XXX do allow users to change the privileged flag PSL_RF. + * The cpu sets PSL_RF in tf_eflags for faults. Debuggers + * should sometimes set it there too. tf_eflags is kept in + * the signal context during signal handling and there is no + * other place to remember it, so the PSL_RF bit may be + * corrupted by the signal handler without us knowing. + * Corruption of the PSL_RF bit at worst causes one more or + * one less debugger trap, so allowing it is fairly harmless. + */ +#if 0 + if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { + __asm__("int $0x3"); + printf("sigreturn: eflags = 0x%x\n", eflags); + return (EINVAL); + } +#endif + /* + * Don't allow users to load a valid privileged %cs. Let the + * hardware check for invalid selectors, excess privilege in + * other selectors, invalid %eip's and invalid %esp's. + */ + cs = ucp->uc_mcontext.mc_cs; + if (!CS_SECURE(cs)) { + __asm__("int $0x3"); + printf("sigreturn: cs = 0x%x\n", cs); + trapsignal(td, SIGBUS, T_PROTFLT); + return (EINVAL); + } + + ret = set_fpcontext(td, &ucp->uc_mcontext); + if (ret != 0) + return (ret); + bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); + PROC_LOCK(p); +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) + if (ucp->uc_mcontext.mc_onstack & 1) + td->td_sigstk.ss_flags |= SS_ONSTACK; + else + td->td_sigstk.ss_flags &= ~SS_ONSTACK; +#endif + + td->td_sigmask = ucp->uc_sigmask; + SIG_CANTMASK(td->td_sigmask); + signotify(td); + PROC_UNLOCK(p); + return (EJUSTRETURN); +} + +/* + * Machine dependent boot() routine + * + * I haven't seen anything to put here yet + * Possibly some stuff might be grafted back here from boot() + */ +void +cpu_boot(int howto) +{ +} + +/* + * Shutdown the CPU as much as possible + */ +void +cpu_halt(void) +{ + HYPERVISOR_shutdown(); +} + +/* + * Hook to idle the CPU when possible. In the SMP case we default to + * off because a halted cpu will not currently pick up a new thread in the + * run queue until the next timer tick. If turned on this will result in + * approximately a 4.2% loss in real time performance in buildworld tests + * (but improves user and sys times oddly enough), and saves approximately + * 5% in power consumption on an idle machine (tests w/2xCPU 1.1GHz P3). + * + * XXX we need to have a cpu mask of idle cpus and generate an IPI or + * otherwise generate some sort of interrupt to wake up cpus sitting in HLT. + * Then we can have our cake and eat it too. + * + * XXX I'm turning it on for SMP as well by default for now. It seems to + * help lock contention somewhat, and this is critical for HTT. -Peter + */ +static int cpu_idle_hlt = 1; +SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, + &cpu_idle_hlt, 0, "Idle loop HLT enable"); + +static void +cpu_idle_default(void) +{ +#if 0 + /* + * we must absolutely guarentee that hlt is the + * absolute next instruction after sti or we + * introduce a timing window. + */ + __asm __volatile("sti; hlt"); +#endif + idle_block(); + enable_intr(); +} + +/* + * Note that we have to be careful here to avoid a race between checking + * sched_runnable() and actually halting. If we don't do this, we may waste + * the time between calling hlt and the next interrupt even though there + * is a runnable process. + */ +void +cpu_idle(void) +{ + +#ifdef SMP + if (mp_grab_cpu_hlt()) + return; +#endif + + if (cpu_idle_hlt) { + disable_intr(); + if (sched_runnable()) + enable_intr(); + else + (*cpu_idle_hook)(); + } +} + +/* Other subsystems (e.g., ACPI) can hook this later. */ +void (*cpu_idle_hook)(void) = cpu_idle_default; + +/* + * Clear registers on exec + */ +void +exec_setregs(td, entry, stack, ps_strings) + struct thread *td; + u_long entry; + u_long stack; + u_long ps_strings; +{ + struct trapframe *regs = td->td_frame; + struct pcb *pcb = td->td_pcb; + + /* Reset pc->pcb_gs and %gs before possibly invalidating it. */ + pcb->pcb_gs = _udatasel; + load_gs(_udatasel); + + if (td->td_proc->p_md.md_ldt) + user_ldt_free(td); + + bzero((char *)regs, sizeof(struct trapframe)); + regs->tf_eip = entry; + regs->tf_esp = stack; + regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T); + regs->tf_ss = _udatasel; + regs->tf_ds = _udatasel; + regs->tf_es = _udatasel; + regs->tf_fs = _udatasel; + regs->tf_cs = _ucodesel; + + /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ + regs->tf_ebx = ps_strings; + + /* + * Reset the hardware debug registers if they were in use. + * They won't have any meaning for the newly exec'd process. + */ + if (pcb->pcb_flags & PCB_DBREGS) { + pcb->pcb_dr0 = 0; + pcb->pcb_dr1 = 0; + pcb->pcb_dr2 = 0; + pcb->pcb_dr3 = 0; + pcb->pcb_dr6 = 0; + pcb->pcb_dr7 = 0; + if (pcb == PCPU_GET(curpcb)) { + /* + * Clear the debug registers on the running + * CPU, otherwise they will end up affecting + * the next process we switch to. + */ + reset_dbregs(); + } + pcb->pcb_flags &= ~PCB_DBREGS; + } + + /* + * Initialize the math emulator (if any) for the current process. + * Actually, just clear the bit that says that the emulator has + * been initialized. Initialization is delayed until the process + * traps to the emulator (if it is done at all) mainly because + * emulators don't provide an entry point for initialization. + */ + td->td_pcb->pcb_flags &= ~FP_SOFTFP; + + /* Initialize the npx (if any) for the current process. */ + /* + * XXX the above load_cr0() also initializes it and is a layering + * violation if NPX is configured. It drops the npx partially + * and this would be fatal if we were interrupted now, and decided + * to force the state to the pcb, and checked the invariant + * (CR0_TS clear) if and only if PCPU_GET(fpcurthread) != NULL). + * ALL of this can happen except the check. The check used to + * happen and be fatal later when we didn't complete the drop + * before returning to user mode. This should be fixed properly + * soon. + */ + fpstate_drop(td); + + /* + * XXX - Linux emulator + * Make sure sure edx is 0x0 on entry. Linux binaries depend + * on it. + */ + td->td_retval[1] = 0; +} + +void +cpu_setregs(void) +{ + /* nothing for Xen to do */ +} + +static int +sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) +{ + int error; + error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, + req); + if (!error && req->newptr) + resettodr(); + return (error); +} + +SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, + &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); + +SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, + CTLFLAG_RW, &disable_rtc_set, 0, ""); + +SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, + CTLFLAG_RD, &bootinfo, bootinfo, ""); + +u_long bootdev; /* not a dev_t - encoding is different */ +SYSCTL_ULONG(_machdep, OID_AUTO, guessed_bootdev, + CTLFLAG_RD, &bootdev, 0, "Maybe the Boot device (not in struct cdev *format)"); + +/* + * Initialize 386 and configure to run kernel + */ + +/* + * Initialize segments & interrupt table + */ + +int _default_ldt; +union descriptor *gdt; /* global descriptor table */ +static struct gate_descriptor idt0[NIDT]; +struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ +union descriptor *ldt; /* local descriptor table */ +struct region_descriptor r_idt; /* table descriptors */ + +int private_tss; /* flag indicating private tss */ + +#if defined(I586_CPU) && !defined(NO_F00F_HACK) +extern int has_f00f_bug; +#endif + +static struct i386tss dblfault_tss; +static char dblfault_stack[PAGE_SIZE]; + +extern struct user *proc0uarea; +extern vm_offset_t proc0kstack; + + +/* software prototypes -- in more palatable form */ +struct soft_segment_descriptor gdt_segs[] = { +/* GNULL_SEL 0 Null Descriptor */ +{ 0x0, /* segment base address */ + 0x0, /* length */ + 0, /* segment type */ + SEL_KPL, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GCODE_SEL 1 Code Descriptor for kernel */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + +/* GDATA_SEL 2 Data Descriptor for kernel */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + +/* GPRIV_SEL 3 SMP Per-Processor Private Data Descriptor */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + SEL_KPL, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +#if 0 +/* GPROC0_SEL 4 Proc 0 Tss Descriptor */ +{ + 0x0, /* segment base address */ + sizeof(struct i386tss)-1,/* length */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GLDT_SEL 5 LDT Descriptor */ +{ (int) ldt, /* segment base address */ + sizeof(ldt)-1, /* length - all address space */ + SDT_SYSLDT, /* segment type */ + SEL_UPL, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GUSERLDT_SEL 6 User LDT Descriptor per process */ +{ (int) ldt, /* segment base address */ + (512 * sizeof(union descriptor)-1), /* length */ + SDT_SYSLDT, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GTGATE_SEL 7 Null Descriptor - Placeholder */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GBIOSLOWMEM_SEL 8 BIOS access to realmode segment 0x40, must be #8 in GDT */ +{ 0x400, /* segment base address */ + 0xfffff, /* length */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GPANIC_SEL 9 Panic Tss Descriptor */ +{ (int) &dblfault_tss, /* segment base address */ + sizeof(struct i386tss)-1,/* length - all address space */ + SDT_SYS386TSS, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* unused - default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, +/* GBIOSCODE32_SEL 10 BIOS 32-bit interface (32bit Code) */ +{ 0, /* segment base address (overwritten) */ + 0xfffff, /* length */ + SDT_MEMERA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GBIOSCODE16_SEL 11 BIOS 32-bit interface (16bit Code) */ +{ 0, /* segment base address (overwritten) */ + 0xfffff, /* length */ + SDT_MEMERA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GBIOSDATA_SEL 12 BIOS 32-bit interface (Data) */ +{ 0, /* segment base address (overwritten) */ + 0xfffff, /* length */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GBIOSUTIL_SEL 13 BIOS 16-bit interface (Utility) */ +{ 0, /* segment base address (overwritten) */ + 0xfffff, /* length */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +/* GBIOSARGS_SEL 14 BIOS 16-bit interface (Arguments) */ +{ 0, /* segment base address (overwritten) */ + 0xfffff, /* length */ + SDT_MEMRWA, /* segment type */ + 0, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +#endif +}; + +static struct soft_segment_descriptor ldt_segs[] = { + /* Null Descriptor - overwritten by call gate */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + /* Null Descriptor - overwritten by call gate */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + /* Null Descriptor - overwritten by call gate */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + /* Code Descriptor for user */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMERA, /* segment type */ + SEL_UPL, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, + /* Null Descriptor - overwritten by call gate */ +{ 0x0, /* segment base address */ + 0x0, /* length - all address space */ + 0, /* segment type */ + 0, /* segment descriptor priority level */ + 0, /* segment descriptor present */ + 0, 0, + 0, /* default 32 vs 16 bit size */ + 0 /* limit granularity (byte/page units)*/ }, + /* Data Descriptor for user */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + SEL_UPL, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, 0, + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, +}; + +struct proc_ldt default_proc_ldt; + +void +setidt(idx, func, typ, dpl, selec) + int idx; + inthand_t *func; + int typ; + int dpl; + int selec; +{ + struct gate_descriptor *ip; + + ip = idt + idx; + ip->gd_looffset = (int)func; + ip->gd_selector = selec; + ip->gd_stkcpy = 0; + ip->gd_xx = 0; + ip->gd_type = typ; + ip->gd_dpl = dpl; + ip->gd_p = 1; + ip->gd_hioffset = ((int)func)>>16 ; +} + +#define IDTVEC(name) __CONCAT(X,name) + +extern inthand_t + IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), + IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), + IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), + IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), + IDTVEC(xmm), IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall); + +#ifdef DDB +/* + * Display the index and function name of any IDT entries that don't use + * the default 'rsvd' entry point. + */ +DB_SHOW_COMMAND(idt, db_show_idt) +{ + struct gate_descriptor *ip; + int idx, quit; + uintptr_t func; + + ip = idt; + db_setup_paging(db_simple_pager, &quit, DB_LINES_PER_PAGE); + for (idx = 0, quit = 0; idx < NIDT; idx++) { + func = (ip->gd_hioffset << 16 | ip->gd_looffset); + if (func != (uintptr_t)&IDTVEC(rsvd)) { + db_printf("%3d\t", idx); + db_printsym(func, DB_STGY_PROC); + db_printf("\n"); + } + ip++; + } +} +#endif + +void +sdtossd(sd, ssd) + struct segment_descriptor *sd; + struct soft_segment_descriptor *ssd; +{ + ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase; + ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit; + ssd->ssd_type = sd->sd_type; + ssd->ssd_dpl = sd->sd_dpl; + ssd->ssd_p = sd->sd_p; + ssd->ssd_def32 = sd->sd_def32; + ssd->ssd_gran = sd->sd_gran; +} + +#define PHYSMAP_SIZE (2 * 8) + +/* + * Populate the (physmap) array with base/bound pairs describing the + * available physical memory in the system, then test this memory and + * build the phys_avail array describing the actually-available memory. + * + * If we cannot accurately determine the physical memory map, then use + * value from the 0xE801 call, and failing that, the RTC. + * + * Total memory size may be set by the kernel environment variable + * hw.physmem or the compile-time define MAXMEM. + * + * XXX first should be vm_paddr_t. + */ +static void +getmemsize(void) +{ + int i; + printf("start_info %p\n", xen_start_info); + printf("start_info->nr_pages %ld\n", xen_start_info->nr_pages); + Maxmem = xen_start_info->nr_pages - init_first; + /* call pmap initialization to make new kernel address space */ + pmap_bootstrap((init_first)<< PAGE_SHIFT, 0); + for (i = 0; i < 10; i++) + phys_avail[i] = 0; +#ifdef MAXMEM + if (MAXMEM/4 < Maxmem) + Maxmem = MAXMEM/4; +#endif + physmem = Maxmem; + avail_end = ptoa(Maxmem) - round_page(MSGBUF_SIZE); + phys_avail[0] = init_first << PAGE_SHIFT; + phys_avail[1] = avail_end; +} + +extern pt_entry_t *KPTphys; +extern int kernbase; +pteinfo_t *pteinfo_list; +unsigned long *xen_machine_phys = ((unsigned long *)VADDR(1008, 0)); + +/* Linux infection */ +#define PAGE_OFFSET KERNBASE +#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +void +initvalues(start_info_t *startinfo) +{ + int i; + xen_start_info = startinfo; + xen_phys_machine = (unsigned long *)startinfo->mfn_list; + unsigned long tmpindex = ((__pa(xen_start_info->pt_base) >> PAGE_SHIFT) + xen_start_info->nr_pt_frames) + 3 /* number of pages allocated after the pts + 1*/; + xendebug_flags = 0xffffffff; + /* pre-zero unused mapped pages */ + bzero((char *)(KERNBASE + (tmpindex << PAGE_SHIFT)), (1024 - tmpindex)*PAGE_SIZE); + + KPTphys = (pt_entry_t *)xpmap_ptom(__pa(startinfo->pt_base + PAGE_SIZE)); + IdlePTD = (pd_entry_t *)xpmap_ptom(__pa(startinfo->pt_base)); + XENPRINTF("IdlePTD %p\n", IdlePTD); + XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%lx pt_base: 0x%lx " + "mod_start: 0x%lx mod_len: 0x%lx\n", + xen_start_info->nr_pages, xen_start_info->shared_info, + xen_start_info->flags, xen_start_info->pt_base, + xen_start_info->mod_start, xen_start_info->mod_len); + + /* Map proc0's UPAGES */ + proc0uarea = (struct user *)(KERNBASE + (tmpindex << PAGE_SHIFT)); + tmpindex += UAREA_PAGES; + + /* Map proc0's KSTACK */ + proc0kstack = KERNBASE + (tmpindex << PAGE_SHIFT); + tmpindex += KSTACK_PAGES; + + /* allocate page for gdt */ + gdt = (union descriptor *)(KERNBASE + (tmpindex << PAGE_SHIFT)); + tmpindex++; + + /* allocate page for ldt */ + ldt = (union descriptor *)(KERNBASE + (tmpindex << PAGE_SHIFT)); + tmpindex++; + +#ifdef PMAP_DEBUG + pteinfo_list = (pteinfo_t *)(KERNBASE + (tmpindex << PAGE_SHIFT)); + tmpindex += ((xen_start_info->nr_pages >> 10) + 1)*(1 + XPQ_CALL_DEPTH*XPQ_CALL_COUNT); + + if (tmpindex > 980) + __asm__("int3"); +#endif + /* unmap remaining pages from initial 4MB chunk */ + for (i = tmpindex; i%1024 != 0; i++) + PT_CLEAR(KERNBASE + (i << PAGE_SHIFT), TRUE); + + /* allocate remainder of NKPT pages */ + map_range(IdlePTD, KPTDI + 1, tmpindex, NKPT-1, PG_U | PG_M | PG_RW); + tmpindex += NKPT-1; + map_range(IdlePTD, PTDPTDI, __pa(xen_start_info->pt_base) >> PAGE_SHIFT, 1, 0); + + xpq_queue_pt_update(KPTphys + tmpindex, xen_start_info->shared_info | PG_A | PG_V | PG_RW); + HYPERVISOR_shared_info = (shared_info_t *)(KERNBASE + (tmpindex << PAGE_SHIFT)); + tmpindex++; + + mcl_flush_queue(); + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list = (unsigned long)xen_phys_machine; + HYPERVISOR_shared_info->arch.mfn_to_pfn_start = (unsigned long)xen_machine_phys; + + init_first = tmpindex; + +} + +void +init386(void) +{ + int gsel_tss, metadata_missing, off, x, error; + struct pcpu *pc; + trap_info_t trap_table[] = { + { 0, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(div)}, + { 1, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dbg)}, + { 3, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bpt)}, + { 4, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ofl)}, + /* This is UPL on Linux and KPL on BSD */ + { 5, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bnd)}, + { 6, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ill)}, + { 7, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dna)}, + /* + * { 8, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(XXX)}, + * no handler for double fault + */ + { 9, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(fpusegm)}, + {10, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(tss)}, + {11, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(missing)}, + {12, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(stk)}, + {13, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(prot)}, + {14, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(page)}, + {15, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(rsvd)}, + {16, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(fpu)}, + {17, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(align)}, + {18, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(mchk)}, + {19, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(xmm)}, + {0x80, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(int0x80_syscall)}, + { 0, 0, 0, 0 } + }; + proc0.p_uarea = proc0uarea; + thread0.td_kstack = proc0kstack; + thread0.td_pcb = (struct pcb *) + (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + + /* + * This may be done better later if it gets more high level + * components in it. If so just link td->td_proc here. + */ + proc_linkup(&proc0, &ksegrp0, &thread0); + + metadata_missing = 0; + if (xen_start_info->mod_start) + preload_metadata = (caddr_t)xen_start_info->mod_start; + else + metadata_missing = 1; + + /* XXX - temporary hack */ + preload_metadata = (caddr_t)0; + /* XXX */ + + if (envmode == 1) + kern_envp = static_env; + else if ((caddr_t)xen_start_info->cmd_line) + kern_envp = xen_setbootenv((caddr_t)xen_start_info->cmd_line); + + boothowto |= xen_boothowto(kern_envp); + + if (boothowto & RB_GDB_PAUSE) + __asm__("int $0x3;"); + + /* Init basic tunables, hz etc */ + init_param1(); + /* + * make gdt memory segments, the code segment goes up to end of the + * page with etext in it, the data segment goes to the end of + * the address space + */ +#if 0 + /* + * XEN occupies the upper 64MB of virtual address space + * At its base it manages an array mapping machine page frames + * to physical page frames - hence we need to be able to + * access 4GB - (64MB - 4MB + 64k) + */ + gdt_segs[GCODE_SEL].ssd_limit = atop(0 - ((1 << 26) - (1 << 22) + (1 << 16))); + gdt_segs[GDATA_SEL].ssd_limit = atop(0 - ((1 << 26) - (1 << 22) + (1 << 16))); +#endif +#ifdef SMP + pc = &SMP_prvspace[0].pcpu; + gdt_segs[GPRIV_SEL].ssd_limit = + atop(sizeof(struct privatespace) - 1); +#else + pc = &__pcpu; + gdt_segs[GPRIV_SEL].ssd_limit = + atop(sizeof(struct pcpu) - 1); +#endif + gdt_segs[GPRIV_SEL].ssd_base = (int) pc; + gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss; + for (x = 0; x < NGDT; x++) + ssdtosd(&gdt_segs[x], &gdt[x].sd); + /* re-map GDT read-only */ + { + unsigned long gdtindex = (((unsigned long)gdt - KERNBASE) >> PAGE_SHIFT); + unsigned long gdtphys = PTOM(gdtindex); + map_range(KPTphys, gdtindex, gdtindex, 1, 0); + mcl_flush_queue(); + if (HYPERVISOR_set_gdt(&gdtphys, LAST_RESERVED_GDT_ENTRY + 1)) { + panic("set_gdt failed\n"); + } + lgdt_finish(); + } + + if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) { + panic("set_trap_table failed - error %d\n", error); + } + if ((error = HYPERVISOR_set_fast_trap(0x80)) != 0) { + panic("set_fast_trap failed - error %d\n", error); + } + HYPERVISOR_set_callbacks(GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback, + GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback); + + + + pcpu_init(pc, 0, sizeof(struct pcpu)); + PCPU_SET(prvspace, pc); + PCPU_SET(curthread, &thread0); + PCPU_SET(curpcb, thread0.td_pcb); + PCPU_SET(trap_nesting, 0); + PCPU_SET(pdir, (unsigned long)IdlePTD); + /* + * Initialize mutexes. + * + */ + mutex_init(); + + /* make ldt memory segments */ + /* + * XXX - VM_MAXUSER_ADDRESS is an end address, not a max. And it + * should be spelled ...MAX_USER... + */ + ldt_segs[LUCODE_SEL].ssd_limit = atop(VM_MAXUSER_ADDRESS - 1); + ldt_segs[LUDATA_SEL].ssd_limit = atop(VM_MAXUSER_ADDRESS - 1); + for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) + ssdtosd(&ldt_segs[x], &ldt[x].sd); + default_proc_ldt.ldt_base = (caddr_t)ldt; + default_proc_ldt.ldt_len = 6; + _default_ldt = (int)&default_proc_ldt; + PCPU_SET(currentldt, _default_ldt); + { + unsigned long ldtindex = (((unsigned long)ldt - KERNBASE) >> PAGE_SHIFT); + map_range(KPTphys, ldtindex, ldtindex, 1, 0); + mcl_flush_queue(); + xen_set_ldt((unsigned long) ldt, (sizeof ldt_segs / sizeof ldt_segs[0])); + } + + /* + * Initialize the console before we print anything out. + */ + cninit(); + if (metadata_missing) + printf("WARNING: loader(8) metadata is missing!\n"); + +#ifdef DDB + ksym_start = bootinfo.bi_symtab; + ksym_end = bootinfo.bi_esymtab; +#endif + kdb_init(); +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter("Boot flags requested debugger"); +#endif + + finishidentcpu(); /* Final stage of CPU initialization */ + setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + initializecpu(); /* Initialize CPU registers */ + + /* make an initial tss so cpu can get interrupt stack on syscall! */ + /* Note: -16 is so we can grow the trapframe if we came from vm86 */ + PCPU_SET(common_tss.tss_esp0, thread0.td_kstack + + KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16); + PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + private_tss = 0; + PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd); + PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); + PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); + HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), PCPU_GET(common_tss.tss_esp0)); + + dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = + dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; + dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = + dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); + + dblfault_tss.tss_cr3 = (int)IdlePTD; + dblfault_tss.tss_eip = (int)dblfault_handler; + dblfault_tss.tss_eflags = PSL_KERNEL; + dblfault_tss.tss_ds = dblfault_tss.tss_es = + dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); + dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); + dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + + getmemsize(); + init_param2(physmem); + /* now running on new page tables, configured,and u/iom is accessible */ + /* Map the message buffer. */ + for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) + pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off); + PT_UPDATES_FLUSH(); + + /* safe to enable xen page queue locking */ + xpq_init(); + + msgbufinit(msgbufp, MSGBUF_SIZE); + /* XXX KMM I don't think we need call gates */ +#if 0 + printf("modify ldt\n"); + /* make a call gate to reenter kernel with */ + gdp = &ldt[LSYS5CALLS_SEL].gd; + + x = (int) &IDTVEC(lcall_syscall); + gdp->gd_looffset = x; + gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); + gdp->gd_stkcpy = 1; + gdp->gd_type = SDT_SYS386CGT; + gdp->gd_dpl = SEL_UPL; + gdp->gd_p = 1; + gdp->gd_hioffset = x >> 16; + + /* XXX does this work? */ + ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL]; + ldt[LSOL26CALLS_SEL] = ldt[LSYS5CALLS_SEL]; +#endif + /* transfer to user mode */ + + _ucodesel = LSEL(LUCODE_SEL, SEL_UPL); + _udatasel = LSEL(LUDATA_SEL, SEL_UPL); + + /* setup proc 0's pcb */ + thread0.td_pcb->pcb_flags = 0; /* XXXKSE */ + thread0.td_pcb->pcb_cr3 = (int)IdlePTD; + thread0.td_pcb->pcb_ext = 0; + thread0.td_frame = &proc0_tf; +} + +void +cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) +{ + + pcpu->pc_acpi_id = 0xffffffff; +} + +/* + * Construct a PCB from a trapframe. This is called from kdb_trap() where + * we want to start a backtrace from the function that caused us to enter + * the debugger. We have the context in the trapframe, but base the trace + * on the PCB. The PCB doesn't have to be perfect, as long as it contains + * enough for a backtrace. + */ +void +makectx(struct trapframe *tf, struct pcb *pcb) +{ + + pcb->pcb_edi = tf->tf_edi; + pcb->pcb_esi = tf->tf_esi; + pcb->pcb_ebp = tf->tf_ebp; + pcb->pcb_ebx = tf->tf_ebx; + pcb->pcb_eip = tf->tf_eip; + pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8; +} + +int +ptrace_set_pc(struct thread *td, u_long addr) +{ + + td->td_frame->tf_eip = addr; + return (0); +} + +int +ptrace_single_step(struct thread *td) +{ + td->td_frame->tf_eflags |= PSL_T; + return (0); +} + +int +ptrace_clear_single_step(struct thread *td) +{ + td->td_frame->tf_eflags &= ~PSL_T; + return (0); +} + +int +fill_regs(struct thread *td, struct reg *regs) +{ + struct pcb *pcb; + struct trapframe *tp; + + tp = td->td_frame; + regs->r_fs = tp->tf_fs; + regs->r_es = tp->tf_es; + regs->r_ds = tp->tf_ds; + regs->r_edi = tp->tf_edi; + regs->r_esi = tp->tf_esi; + regs->r_ebp = tp->tf_ebp; + regs->r_ebx = tp->tf_ebx; + regs->r_edx = tp->tf_edx; + regs->r_ecx = tp->tf_ecx; + regs->r_eax = tp->tf_eax; + regs->r_eip = tp->tf_eip; + regs->r_cs = tp->tf_cs; + regs->r_eflags = tp->tf_eflags; + regs->r_esp = tp->tf_esp; + regs->r_ss = tp->tf_ss; + pcb = td->td_pcb; + regs->r_gs = pcb->pcb_gs; + return (0); +} + +int +set_regs(struct thread *td, struct reg *regs) +{ + struct pcb *pcb; + struct trapframe *tp; + + tp = td->td_frame; + if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) || + !CS_SECURE(regs->r_cs)) + return (EINVAL); + tp->tf_fs = regs->r_fs; + tp->tf_es = regs->r_es; + tp->tf_ds = regs->r_ds; + tp->tf_edi = regs->r_edi; + tp->tf_esi = regs->r_esi; + tp->tf_ebp = regs->r_ebp; + tp->tf_ebx = regs->r_ebx; + tp->tf_edx = regs->r_edx; + tp->tf_ecx = regs->r_ecx; + tp->tf_eax = regs->r_eax; + tp->tf_eip = regs->r_eip; + tp->tf_cs = regs->r_cs; + tp->tf_eflags = regs->r_eflags; + tp->tf_esp = regs->r_esp; + tp->tf_ss = regs->r_ss; + pcb = td->td_pcb; + pcb->pcb_gs = regs->r_gs; + return (0); +} + +#ifdef CPU_ENABLE_SSE +static void +fill_fpregs_xmm(sv_xmm, sv_87) + struct savexmm *sv_xmm; + struct save87 *sv_87; +{ + register struct env87 *penv_87 = &sv_87->sv_env; + register struct envxmm *penv_xmm = &sv_xmm->sv_env; + int i; + + bzero(sv_87, sizeof(*sv_87)); + + /* FPU control/status */ + penv_87->en_cw = penv_xmm->en_cw; + penv_87->en_sw = penv_xmm->en_sw; + penv_87->en_tw = penv_xmm->en_tw; + penv_87->en_fip = penv_xmm->en_fip; + penv_87->en_fcs = penv_xmm->en_fcs; + penv_87->en_opcode = penv_xmm->en_opcode; + penv_87->en_foo = penv_xmm->en_foo; + penv_87->en_fos = penv_xmm->en_fos; + + /* FPU registers */ + for (i = 0; i < 8; ++i) + sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc; +} + +static void +set_fpregs_xmm(sv_87, sv_xmm) + struct save87 *sv_87; + struct savexmm *sv_xmm; +{ + register struct env87 *penv_87 = &sv_87->sv_env; + register struct envxmm *penv_xmm = &sv_xmm->sv_env; + int i; + + /* FPU control/status */ + penv_xmm->en_cw = penv_87->en_cw; + penv_xmm->en_sw = penv_87->en_sw; + penv_xmm->en_tw = penv_87->en_tw; + penv_xmm->en_fip = penv_87->en_fip; + penv_xmm->en_fcs = penv_87->en_fcs; + penv_xmm->en_opcode = penv_87->en_opcode; + penv_xmm->en_foo = penv_87->en_foo; + penv_xmm->en_fos = penv_87->en_fos; + + /* FPU registers */ + for (i = 0; i < 8; ++i) + sv_xmm->sv_fp[i].fp_acc = sv_87->sv_ac[i]; +} +#endif /* CPU_ENABLE_SSE */ + +int +fill_fpregs(struct thread *td, struct fpreg *fpregs) +{ +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) { + fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm, + (struct save87 *)fpregs); + return (0); + } +#endif /* CPU_ENABLE_SSE */ + bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs); + return (0); +} + +int +set_fpregs(struct thread *td, struct fpreg *fpregs) +{ +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) { + set_fpregs_xmm((struct save87 *)fpregs, + &td->td_pcb->pcb_save.sv_xmm); + return (0); + } +#endif /* CPU_ENABLE_SSE */ + bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs); + return (0); +} + +/* + * Get machine context. + */ +int +get_mcontext(struct thread *td, mcontext_t *mcp, int flags) +{ + struct trapframe *tp; + + tp = td->td_frame; + + PROC_LOCK(curthread->td_proc); + mcp->mc_onstack = sigonstack(tp->tf_esp); + PROC_UNLOCK(curthread->td_proc); + mcp->mc_gs = td->td_pcb->pcb_gs; + mcp->mc_fs = tp->tf_fs; + mcp->mc_es = tp->tf_es; + mcp->mc_ds = tp->tf_ds; + mcp->mc_edi = tp->tf_edi; + mcp->mc_esi = tp->tf_esi; + mcp->mc_ebp = tp->tf_ebp; + mcp->mc_isp = tp->tf_isp; + if (flags & GET_MC_CLEAR_RET) { + mcp->mc_eax = 0; + mcp->mc_edx = 0; + } else { + mcp->mc_eax = tp->tf_eax; + mcp->mc_edx = tp->tf_edx; + } + mcp->mc_ebx = tp->tf_ebx; + mcp->mc_ecx = tp->tf_ecx; + mcp->mc_eip = tp->tf_eip; + mcp->mc_cs = tp->tf_cs; + mcp->mc_eflags = tp->tf_eflags; + mcp->mc_esp = tp->tf_esp; + mcp->mc_ss = tp->tf_ss; + mcp->mc_len = sizeof(*mcp); + get_fpcontext(td, mcp); + return (0); +} + +/* + * Set machine context. + * + * However, we don't set any but the user modifiable flags, and we won't + * touch the cs selector. + */ +int +set_mcontext(struct thread *td, const mcontext_t *mcp) +{ + struct trapframe *tp; + int eflags, ret; + + tp = td->td_frame; + if (mcp->mc_len != sizeof(*mcp)) + return (EINVAL); + eflags = (mcp->mc_eflags & PSL_USERCHANGE) | + (tp->tf_eflags & ~PSL_USERCHANGE); + if ((ret = set_fpcontext(td, mcp)) == 0) { + tp->tf_fs = mcp->mc_fs; + tp->tf_es = mcp->mc_es; + tp->tf_ds = mcp->mc_ds; + tp->tf_edi = mcp->mc_edi; + tp->tf_esi = mcp->mc_esi; + tp->tf_ebp = mcp->mc_ebp; + tp->tf_ebx = mcp->mc_ebx; + tp->tf_edx = mcp->mc_edx; + tp->tf_ecx = mcp->mc_ecx; + tp->tf_eax = mcp->mc_eax; + tp->tf_eip = mcp->mc_eip; + tp->tf_eflags = eflags; + tp->tf_esp = mcp->mc_esp; + tp->tf_ss = mcp->mc_ss; + td->td_pcb->pcb_gs = mcp->mc_gs; + ret = 0; + } + return (ret); +} + +static void +get_fpcontext(struct thread *td, mcontext_t *mcp) +{ +#ifndef DEV_NPX + mcp->mc_fpformat = _MC_FPFMT_NODEV; + mcp->mc_ownedfp = _MC_FPOWNED_NONE; +#else + union savefpu *addr; + + /* + * XXX mc_fpstate might be misaligned, since its declaration is not + * unportabilized using __attribute__((aligned(16))) like the + * declaration of struct savemm, and anyway, alignment doesn't work + * for auto variables since we don't use gcc's pessimal stack + * alignment. Work around this by abusing the spare fields after + * mcp->mc_fpstate. + * + * XXX unpessimize most cases by only aligning when fxsave might be + * called, although this requires knowing too much about + * npxgetregs()'s internals. + */ + addr = (union savefpu *)&mcp->mc_fpstate; + if (td == PCPU_GET(fpcurthread) && +#ifdef CPU_ENABLE_SSE + cpu_fxsr && +#endif + ((uintptr_t)(void *)addr & 0xF)) { + do + addr = (void *)((char *)addr + 4); + while ((uintptr_t)(void *)addr & 0xF); + } + mcp->mc_ownedfp = npxgetregs(td, addr); + if (addr != (union savefpu *)&mcp->mc_fpstate) { + bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate)); + bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2)); + } + mcp->mc_fpformat = npxformat(); +#endif +} + +static int +set_fpcontext(struct thread *td, const mcontext_t *mcp) +{ + union savefpu *addr; + + if (mcp->mc_fpformat == _MC_FPFMT_NODEV) + return (0); + else if (mcp->mc_fpformat != _MC_FPFMT_387 && + mcp->mc_fpformat != _MC_FPFMT_XMM) + return (EINVAL); + else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) + /* We don't care what state is left in the FPU or PCB. */ + fpstate_drop(td); + else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || + mcp->mc_ownedfp == _MC_FPOWNED_PCB) { + /* XXX align as above. */ + addr = (union savefpu *)&mcp->mc_fpstate; + if (td == PCPU_GET(fpcurthread) && +#ifdef CPU_ENABLE_SSE + cpu_fxsr && +#endif + ((uintptr_t)(void *)addr & 0xF)) { + do + addr = (void *)((char *)addr + 4); + while ((uintptr_t)(void *)addr & 0xF); + bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate)); + } +#ifdef DEV_NPX + /* + * XXX we violate the dubious requirement that npxsetregs() + * be called with interrupts disabled. + */ + npxsetregs(td, addr); +#endif + /* + * Don't bother putting things back where they were in the + * misaligned case, since we know that the caller won't use + * them again. + */ + } else + return (EINVAL); + return (0); +} + +static void +fpstate_drop(struct thread *td) +{ + register_t s; + + s = intr_disable(); +#ifdef DEV_NPX + if (PCPU_GET(fpcurthread) == td) + npxdrop(); +#endif + /* + * XXX force a full drop of the npx. The above only drops it if we + * owned it. npxgetregs() has the same bug in the !cpu_fxsr case. + * + * XXX I don't much like npxgetregs()'s semantics of doing a full + * drop. Dropping only to the pcb matches fnsave's behaviour. + * We only need to drop to !PCB_INITDONE in sendsig(). But + * sendsig() is the only caller of npxgetregs()... perhaps we just + * have too many layers. + */ + curthread->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; + intr_restore(s); +} + +int +fill_dbregs(struct thread *td, struct dbreg *dbregs) +{ + struct pcb *pcb; + + if (td == NULL) { + dbregs->dr[0] = rdr0(); + dbregs->dr[1] = rdr1(); + dbregs->dr[2] = rdr2(); + dbregs->dr[3] = rdr3(); + dbregs->dr[4] = rdr4(); + dbregs->dr[5] = rdr5(); + dbregs->dr[6] = rdr6(); + dbregs->dr[7] = rdr7(); + } else { + pcb = td->td_pcb; + dbregs->dr[0] = pcb->pcb_dr0; + dbregs->dr[1] = pcb->pcb_dr1; + dbregs->dr[2] = pcb->pcb_dr2; + dbregs->dr[3] = pcb->pcb_dr3; + dbregs->dr[4] = 0; + dbregs->dr[5] = 0; + dbregs->dr[6] = pcb->pcb_dr6; + dbregs->dr[7] = pcb->pcb_dr7; + } + return (0); +} + +int +set_dbregs(struct thread *td, struct dbreg *dbregs) +{ + struct pcb *pcb; + int i; + u_int32_t mask1, mask2; + + if (td == NULL) { + load_dr0(dbregs->dr[0]); + load_dr1(dbregs->dr[1]); + load_dr2(dbregs->dr[2]); + load_dr3(dbregs->dr[3]); + load_dr4(dbregs->dr[4]); + load_dr5(dbregs->dr[5]); + load_dr6(dbregs->dr[6]); + load_dr7(dbregs->dr[7]); + } else { + /* + * Don't let an illegal value for dr7 get set. Specifically, + * check for undefined settings. Setting these bit patterns + * result in undefined behaviour and can lead to an unexpected + * TRCTRAP. + */ + for (i = 0, mask1 = 0x3<<16, mask2 = 0x2<<16; i < 8; + i++, mask1 <<= 2, mask2 <<= 2) + if ((dbregs->dr[7] & mask1) == mask2) + return (EINVAL); + + pcb = td->td_pcb; + + /* + * Don't let a process set a breakpoint that is not within the + * process's address space. If a process could do this, it + * could halt the system by setting a breakpoint in the kernel + * (if ddb was enabled). Thus, we need to check to make sure + * that no breakpoints are being enabled for addresses outside + * process's address space, unless, perhaps, we were called by + * uid 0. + * + * XXX - what about when the watched area of the user's + * address space is written into from within the kernel + * ... wouldn't that still cause a breakpoint to be generated + * from within kernel mode? + */ + + if (suser(td) != 0) { + if (dbregs->dr[7] & 0x3) { + /* dr0 is enabled */ + if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS) + return (EINVAL); + } + + if (dbregs->dr[7] & (0x3<<2)) { + /* dr1 is enabled */ + if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS) + return (EINVAL); + } + + if (dbregs->dr[7] & (0x3<<4)) { + /* dr2 is enabled */ + if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS) + return (EINVAL); + } + + if (dbregs->dr[7] & (0x3<<6)) { + /* dr3 is enabled */ + if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS) + return (EINVAL); + } + } + + pcb->pcb_dr0 = dbregs->dr[0]; + pcb->pcb_dr1 = dbregs->dr[1]; + pcb->pcb_dr2 = dbregs->dr[2]; + pcb->pcb_dr3 = dbregs->dr[3]; + pcb->pcb_dr6 = dbregs->dr[6]; + pcb->pcb_dr7 = dbregs->dr[7]; + + pcb->pcb_flags |= PCB_DBREGS; + } + + return (0); +} + +/* + * Return > 0 if a hardware breakpoint has been hit, and the + * breakpoint was in user space. Return 0, otherwise. + */ +int +user_dbreg_trap(void) +{ + u_int32_t dr7, dr6; /* debug registers dr6 and dr7 */ + u_int32_t bp; /* breakpoint bits extracted from dr6 */ + int nbp; /* number of breakpoints that triggered */ + caddr_t addr[4]; /* breakpoint addresses */ + int i; + + dr7 = rdr7(); + if ((dr7 & 0x000000ff) == 0) { + /* + * all GE and LE bits in the dr7 register are zero, + * thus the trap couldn't have been caused by the + * hardware debug registers + */ + return 0; + } + + nbp = 0; + dr6 = rdr6(); + bp = dr6 & 0x0000000f; + + if (!bp) { + /* + * None of the breakpoint bits are set meaning this + * trap was not caused by any of the debug registers + */ + return 0; + } + + /* + * at least one of the breakpoints were hit, check to see + * which ones and if any of them are user space addresses + */ + + if (bp & 0x01) { + addr[nbp++] = (caddr_t)rdr0(); + } + if (bp & 0x02) { + addr[nbp++] = (caddr_t)rdr1(); + } + if (bp & 0x04) { + addr[nbp++] = (caddr_t)rdr2(); + } + if (bp & 0x08) { + addr[nbp++] = (caddr_t)rdr3(); + } + + for (i=0; i + +/* + * Provide stub functions so that the MADT APIC enumerator in the acpi + * kernel module will link against a kernel without 'device apic'. + * + * XXX - This is a gross hack. + */ +void +apic_register_enumerator(struct apic_enumerator *enumerator) +{ +} + +void * +ioapic_create(uintptr_t addr, int32_t id, int intbase) +{ + return (NULL); +} + +int +ioapic_disable_pin(void *cookie, u_int pin) +{ + return (ENXIO); +} + +int +ioapic_get_vector(void *cookie, u_int pin) +{ + return (-1); +} + +void +ioapic_register(void *cookie) +{ +} + +int +ioapic_remap_vector(void *cookie, u_int pin, int vector) +{ + return (ENXIO); +} + +int +ioapic_set_extint(void *cookie, u_int pin) +{ + return (ENXIO); +} + +int +ioapic_set_nmi(void *cookie, u_int pin) +{ + return (ENXIO); +} + +int +ioapic_set_polarity(void *cookie, u_int pin,enum intr_polarity pol ) +{ + return (ENXIO); +} + +int +ioapic_set_triggermode(void *cookie, u_int pin, enum intr_trigger trigger ) +{ + return (ENXIO); +} + +void +lapic_create(u_int apic_id, int boot_cpu) +{ +} + +void +lapic_init(uintptr_t addr) +{ +} + +int +lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode) +{ + return (ENXIO); +} + +int +lapic_set_lvt_polarity(u_int apic_id, u_int lvt, enum intr_polarity pol) +{ + return (ENXIO); +} + +int +lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger) +{ + return (ENXIO); +} +#endif + +#ifdef KDB + +/* + * Provide inb() and outb() as functions. They are normally only + * available as macros calling inlined functions, thus cannot be + * called from the debugger. + * + * The actual code is stolen from , and de-inlined. + */ + +#undef inb +#undef outb + +/* silence compiler warnings */ +u_char inb(u_int); +void outb(u_int, u_char); + +u_char +inb(u_int port) +{ + u_char data; + /* + * We use %%dx and not %1 here because i/o is done at %dx and not at + * %edx, while gcc generates inferior code (movw instead of movl) + * if we tell it to load (u_short) port. + */ + __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); + return (data); +} + +void +outb(u_int port, u_char data) +{ + u_char al; + /* + * Use an unnecessary assignment to help gcc's register allocator. + * This make a large difference for gcc-1.40 and a tiny difference + * for gcc-2.6.0. For gcc-1.40, al had to be ``asm("ax")'' for + * best results. gcc-2.6.0 can't handle this. + */ + al = data; + __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port)); +} + +#endif /* KDB */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_clock.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_clock.c new file mode 100644 index 0000000000..af07002ebb --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_clock.c @@ -0,0 +1,150 @@ +/*- + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/mp_clock.c,v 1.19 2004/05/30 20:34:57 phk Exp $"); + +/*- + * Just when we thought life were beautiful, reality pops its grim face over + * the edge again: + * + * ] 20. ACPI Timer Errata + * ] + * ] Problem: The power management timer may return improper result when + * ] read. Although the timer value settles properly after incrementing, + * ] while incrementing there is a 3nS window every 69.8nS where the + * ] timer value is indeterminate (a 4.2% chance that the data will be + * ] incorrect when read). As a result, the ACPI free running count up + * ] timer specification is violated due to erroneous reads. Implication: + * ] System hangs due to the "inaccuracy" of the timer when used by + * ] software for time critical events and delays. + * ] + * ] Workaround: Read the register twice and compare. + * ] Status: This will not be fixed in the PIIX4 or PIIX4E. + * + * The counter is in other words not latched to the PCI bus clock when + * read. Notice the workaround isn't: We need to read until we have + * three monotonic samples and then use the middle one, otherwise we are + * not protected against the fact that the bits can be wrong in two + * directions. If we only cared about monosity two reads would be enough. + */ + +/* #include "opt_bus.h" */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static unsigned piix_get_timecount(struct timecounter *tc); + +static u_int32_t piix_timecounter_address; +static u_int piix_freq = 14318182/4; + +static struct timecounter piix_timecounter = { + piix_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + 0xffffff, /* counter_mask */ + 0, /* frequency */ + "PIIX" /* name */ +}; + + +static int +sysctl_machdep_piix_freq(SYSCTL_HANDLER_ARGS) +{ + int error; + u_int freq; + + if (piix_timecounter.tc_frequency == 0) + return (EOPNOTSUPP); + freq = piix_freq; + error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); + if (error == 0 && req->newptr != NULL) { + piix_freq = freq; + piix_timecounter.tc_frequency = piix_freq; + } + return (error); +} + +SYSCTL_PROC(_machdep, OID_AUTO, piix_freq, CTLTYPE_INT | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_piix_freq, "I", ""); + +static unsigned +piix_get_timecount(struct timecounter *tc) +{ + unsigned u1, u2, u3; + + u2 = inl(piix_timecounter_address); + u3 = inl(piix_timecounter_address); + do { + u1 = u2; + u2 = u3; + u3 = inl(piix_timecounter_address); + } while (u1 > u2 || u2 > u3); + return (u2); +} + +static int +piix_probe(device_t dev) +{ + u_int32_t d; + + if (devclass_get_device(devclass_find("acpi"), 0) != NULL) + return (ENXIO); + switch (pci_get_devid(dev)) { + case 0x71138086: + device_set_desc(dev, "PIIX Timecounter"); + break; + default: + return (ENXIO); + } + + d = pci_read_config(dev, PCIR_COMMAND, 2); + if (!(d & PCIM_CMD_PORTEN)) { + device_printf(dev, "PIIX I/O space not mapped\n"); + return (ENXIO); + } + return (0); +} + +static int +piix_attach(device_t dev) +{ + u_int32_t d; + + d = pci_read_config(dev, 0x40, 4); + piix_timecounter_address = (d & 0xffc0) + 8; + piix_timecounter.tc_frequency = piix_freq; + tc_init(&piix_timecounter); + return (0); +} + +static device_method_t piix_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, piix_probe), + DEVMETHOD(device_attach, piix_attach), + { 0, 0 } +}; + +static driver_t piix_driver = { + "piix", + piix_methods, + 1, +}; + +static devclass_t piix_devclass; + +DRIVER_MODULE(piix, pci, piix_driver, piix_devclass, 0, 0); diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_machdep.c new file mode 100644 index 0000000000..b975c9e491 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mp_machdep.c @@ -0,0 +1,1315 @@ +/*- + * Copyright (c) 1996, by Steve Passe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the developer may NOT be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/mp_machdep.c,v 1.235.2.3 2004/09/24 15:02:33 rik Exp $"); + +#include "opt_apic.h" +#include "opt_cpu.h" +#include "opt_kstack_pages.h" +#include "opt_mp_watchdog.h" + +#if !defined(lint) +#if !defined(SMP) +#error How did you get here? +#endif + +#if defined(I386_CPU) && !defined(COMPILING_LINT) +#error SMP not supported with I386_CPU +#endif +#if 0 +#ifndef DEV_APIC +#error The apic device is required for SMP, add "device apic" to your config file. +#endif +#endif +#if defined(CPU_DISABLE_CMPXCHG) && !defined(COMPILING_LINT) +#error SMP not supported with CPU_DISABLE_CMPXCHG +#endif +#endif /* not lint */ + +#include +#include +#include +#include /* cngetc() */ +#ifdef GPROF +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include /** COUNT_XINVLTLB_HITS */ +#include +#include + +#include + +#define WARMBOOT_TARGET 0 +#define WARMBOOT_OFF (KERNBASE + 0x0467) +#define WARMBOOT_SEG (KERNBASE + 0x0469) + +#define CMOS_REG (0x70) +#define CMOS_DATA (0x71) +#define BIOS_RESET (0x0f) +#define BIOS_WARM (0x0a) + +/* + * this code MUST be enabled here and in mpboot.s. + * it follows the very early stages of AP boot by placing values in CMOS ram. + * it NORMALLY will never be needed and thus the primitive method for enabling. + * +#define CHECK_POINTS + */ + +#if defined(CHECK_POINTS) && !defined(PC98) +#define CHECK_READ(A) (outb(CMOS_REG, (A)), inb(CMOS_DATA)) +#define CHECK_WRITE(A,D) (outb(CMOS_REG, (A)), outb(CMOS_DATA, (D))) + +#define CHECK_INIT(D); \ + CHECK_WRITE(0x34, (D)); \ + CHECK_WRITE(0x35, (D)); \ + CHECK_WRITE(0x36, (D)); \ + CHECK_WRITE(0x37, (D)); \ + CHECK_WRITE(0x38, (D)); \ + CHECK_WRITE(0x39, (D)); + +#define CHECK_PRINT(S); \ + printf("%s: %d, %d, %d, %d, %d, %d\n", \ + (S), \ + CHECK_READ(0x34), \ + CHECK_READ(0x35), \ + CHECK_READ(0x36), \ + CHECK_READ(0x37), \ + CHECK_READ(0x38), \ + CHECK_READ(0x39)); + +#else /* CHECK_POINTS */ + +#define CHECK_INIT(D) +#define CHECK_PRINT(S) +#define CHECK_WRITE(A, D) + +#endif /* CHECK_POINTS */ + +/* + * Values to send to the POST hardware. + */ +#define MP_BOOTADDRESS_POST 0x10 +#define MP_PROBE_POST 0x11 +#define MPTABLE_PASS1_POST 0x12 + +#define MP_START_POST 0x13 +#define MP_ENABLE_POST 0x14 +#define MPTABLE_PASS2_POST 0x15 + +#define START_ALL_APS_POST 0x16 +#define INSTALL_AP_TRAMP_POST 0x17 +#define START_AP_POST 0x18 + +#define MP_ANNOUNCE_POST 0x19 + +/* lock region used by kernel profiling */ +int mcount_lock; + +/** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */ +int current_postcode; + +int mp_naps; /* # of Applications processors */ +int boot_cpu_id = -1; /* designated BSP */ +extern int nkpt; + +/* + * CPU topology map datastructures for HTT. + */ +static struct cpu_group mp_groups[MAXCPU]; +static struct cpu_top mp_top; + +/* AP uses this during bootstrap. Do not staticize. */ +char *bootSTK; +static int bootAP; + +/* Hotwire a 0->4MB V==P mapping */ +extern pt_entry_t *KPTphys; + +/* SMP page table page */ +extern pt_entry_t *SMPpt; + +struct pcb stoppcbs[MAXCPU]; + +/* Variables needed for SMP tlb shootdown. */ +vm_offset_t smp_tlb_addr1; +vm_offset_t smp_tlb_addr2; +volatile int smp_tlb_wait; + +/* + * Local data and functions. + */ + +static u_int logical_cpus; + +/* used to hold the AP's until we are ready to release them */ +static struct mtx ap_boot_mtx; + +/* Set to 1 once we're ready to let the APs out of the pen. */ +static volatile int aps_ready = 0; + +/* + * Store data from cpu_add() until later in the boot when we actually setup + * the APs. + */ +struct cpu_info { + int cpu_present:1; + int cpu_bsp:1; +} static cpu_info[MAXCPU]; +static int cpu_apic_ids[MAXCPU]; + +static u_int boot_address; + +static void set_logical_apic_ids(void); +static int start_all_aps(void); +static void install_ap_tramp(void); +static int start_ap(int apic_id); +static void release_aps(void *dummy); + +static int hlt_logical_cpus; +static struct sysctl_ctx_list logical_cpu_clist; + +static void +mem_range_AP_init(void) +{ + if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP) + mem_range_softc.mr_op->initAP(&mem_range_softc); +} + +void +mp_topology(void) +{ + struct cpu_group *group; + int logical_cpus; + int apic_id; + int groups; + int cpu; + + /* Build the smp_topology map. */ + /* Nothing to do if there is no HTT support. */ + if ((cpu_feature & CPUID_HTT) == 0) + return; + logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16; + if (logical_cpus <= 1) + return; + group = &mp_groups[0]; + groups = 1; + for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) { + if (!cpu_info[apic_id].cpu_present) + continue; + /* + * If the current group has members and we're not a logical + * cpu, create a new group. + */ + if (group->cg_count != 0 && (apic_id % logical_cpus) == 0) { + group++; + groups++; + } + group->cg_count++; + group->cg_mask |= 1 << cpu; + cpu++; + } + + mp_top.ct_count = groups; + mp_top.ct_group = mp_groups; + smp_topology = &mp_top; +} + + +/* + * Calculate usable address in base memory for AP trampoline code. + */ +u_int +mp_bootaddress(u_int basemem) +{ + POSTCODE(MP_BOOTADDRESS_POST); + + boot_address = trunc_page(basemem); /* round down to 4k boundary */ + if ((basemem - boot_address) < bootMP_size) + boot_address -= PAGE_SIZE; /* not enough, lower by 4k */ + + return boot_address; +} + +void +cpu_add(u_int apic_id, char boot_cpu) +{ + + if (apic_id >= MAXCPU) { + printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n", + apic_id, MAXCPU - 1); + return; + } + KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice", + apic_id)); + cpu_info[apic_id].cpu_present = 1; + if (boot_cpu) { + KASSERT(boot_cpu_id == -1, + ("CPU %d claims to be BSP, but CPU %d already is", apic_id, + boot_cpu_id)); + boot_cpu_id = apic_id; + cpu_info[apic_id].cpu_bsp = 1; + } + mp_ncpus++; + if (bootverbose) + printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" : + "AP"); + +} + +void +cpu_mp_setmaxid(void) +{ + + mp_maxid = MAXCPU - 1; +} + +int +cpu_mp_probe(void) +{ + + /* + * Always record BSP in CPU map so that the mbuf init code works + * correctly. + */ + all_cpus = 1; + if (mp_ncpus == 0) { + /* + * No CPUs were found, so this must be a UP system. Setup + * the variables to represent a system with a single CPU + * with an id of 0. + */ + mp_ncpus = 1; + return (0); + } + + /* At least one CPU was found. */ + if (mp_ncpus == 1) { + /* + * One CPU was found, so this must be a UP system with + * an I/O APIC. + */ + return (0); + } + + /* At least two CPUs were found. */ + return (1); +} + +/* + * Initialize the IPI handlers and start up the AP's. + */ +void +cpu_mp_start(void) +{ + int i; + + POSTCODE(MP_START_POST); + + /* Initialize the logical ID to APIC ID table. */ + for (i = 0; i < MAXCPU; i++) + cpu_apic_ids[i] = -1; + + /* Install an inter-CPU IPI for TLB invalidation */ + setidt(IPI_INVLTLB, IDTVEC(invltlb), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(IPI_INVLPG, IDTVEC(invlpg), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + setidt(IPI_INVLRNG, IDTVEC(invlrng), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for forwarding hardclock() */ + setidt(IPI_HARDCLOCK, IDTVEC(hardclock), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for forwarding statclock() */ + setidt(IPI_STATCLOCK, IDTVEC(statclock), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for lazy pmap release */ + setidt(IPI_LAZYPMAP, IDTVEC(lazypmap), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for all-CPU rendezvous */ + setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for forcing an additional software trap */ + setidt(IPI_AST, IDTVEC(cpuast), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* Install an inter-CPU IPI for CPU stop/restart */ + setidt(IPI_STOP, IDTVEC(cpustop), + SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + + /* Set boot_cpu_id if needed. */ + if (boot_cpu_id == -1) { + boot_cpu_id = PCPU_GET(apic_id); + cpu_info[boot_cpu_id].cpu_bsp = 1; + } else + KASSERT(boot_cpu_id == PCPU_GET(apic_id), + ("BSP's APIC ID doesn't match boot_cpu_id")); + cpu_apic_ids[0] = boot_cpu_id; + + /* Start each Application Processor */ + start_all_aps(); + + /* Setup the initial logical CPUs info. */ + logical_cpus = logical_cpus_mask = 0; + if (cpu_feature & CPUID_HTT) + logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16; + + set_logical_apic_ids(); +} + + +/* + * Print various information about the SMP system hardware and setup. + */ +void +cpu_mp_announce(void) +{ + int i, x; + + POSTCODE(MP_ANNOUNCE_POST); + + /* List CPUs */ + printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id); + for (i = 1, x = 0; x < MAXCPU; x++) { + if (cpu_info[x].cpu_present && !cpu_info[x].cpu_bsp) { + KASSERT(i < mp_ncpus, + ("mp_ncpus and actual cpus are out of whack")); + printf(" cpu%d (AP): APIC ID: %2d\n", i++, x); + } + } +} + +/* + * AP CPU's call this to initialize themselves. + */ +void +init_secondary(void) +{ + int gsel_tss; + int x, myid; +#if 0 + u_int cr0; +#endif + /* bootAP is set in start_ap() to our ID. */ + myid = bootAP; + gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid]; + gdt_segs[GPROC0_SEL].ssd_base = + (int) &SMP_prvspace[myid].pcpu.pc_common_tss; + SMP_prvspace[myid].pcpu.pc_prvspace = + &SMP_prvspace[myid].pcpu; + + for (x = 0; x < NGDT; x++) { + ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); + } + +#if 0 + r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; + r_gdt.rd_base = (int) &gdt[myid * NGDT]; + lgdt(&r_gdt); /* does magic intra-segment return */ + + lidt(&r_idt); + lldt(_default_ldt); +#endif + PCPU_SET(currentldt, _default_ldt); + + gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); + gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; + PCPU_SET(common_tss.tss_esp0, 0); /* not used until after switch */ + PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); + PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); + PCPU_SET(tss_gdt, &gdt[myid * NGDT + GPROC0_SEL].sd); + PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); +#if 0 + ltr(gsel_tss); + + /* + * Set to a known state: + * Set by mpboot.s: CR0_PG, CR0_PE + * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM + */ + cr0 = rcr0(); + cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); + load_cr0(cr0); +#endif + CHECK_WRITE(0x38, 5); + + /* Disable local APIC just to be sure. */ + lapic_disable(); + + /* signal our startup to the BSP. */ + mp_naps++; + CHECK_WRITE(0x39, 6); + + /* Spin until the BSP releases the AP's. */ + while (!aps_ready) + ia32_pause(); + + /* BSP may have changed PTD while we were waiting */ + invltlb(); + pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1); + +#if defined(I586_CPU) && !defined(NO_F00F_HACK) + lidt(&r_idt); +#endif + + /* set up CPU registers and state */ + cpu_setregs(); + + /* set up FPU state on the AP */ + npxinit(__INITIAL_NPXCW__); + + /* set up SSE registers */ + enable_sse(); + + /* A quick check from sanity claus */ + if (PCPU_GET(apic_id) != lapic_id()) { + printf("SMP: cpuid = %d\n", PCPU_GET(cpuid)); + printf("SMP: actual apic_id = %d\n", lapic_id()); + printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id)); + printf("PTD[MPPTDI] = %#jx\n", (uintmax_t)PTD[MPPTDI]); + panic("cpuid mismatch! boom!!"); + } + + mtx_lock_spin(&ap_boot_mtx); + + /* Init local apic for irq's */ + lapic_setup(); + + /* Set memory range attributes for this CPU to match the BSP */ + mem_range_AP_init(); + + smp_cpus++; + + CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid)); + printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid)); + + /* Determine if we are a logical CPU. */ + if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0) + logical_cpus_mask |= PCPU_GET(cpumask); + + /* Build our map of 'other' CPUs. */ + PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask)); + + if (bootverbose) + lapic_dump("AP"); + + if (smp_cpus == mp_ncpus) { + /* enable IPI's, tlb shootdown, freezes etc */ + atomic_store_rel_int(&smp_started, 1); + smp_active = 1; /* historic */ + } + + mtx_unlock_spin(&ap_boot_mtx); + + /* wait until all the AP's are up */ + while (smp_started == 0) + ia32_pause(); + + /* ok, now grab sched_lock and enter the scheduler */ + mtx_lock_spin(&sched_lock); + + binuptime(PCPU_PTR(switchtime)); + PCPU_SET(switchticks, ticks); + + cpu_throw(NULL, choosethread()); /* doesn't return */ + + panic("scheduler returned us to %s", __func__); + /* NOTREACHED */ +} + +/******************************************************************* + * local functions and data + */ + +/* + * Set the APIC logical IDs. + * + * We want to cluster logical CPU's within the same APIC ID cluster. + * Since logical CPU's are aligned simply filling in the clusters in + * APIC ID order works fine. Note that this does not try to balance + * the number of CPU's in each cluster. (XXX?) + */ +static void +set_logical_apic_ids(void) +{ + u_int apic_id, cluster, cluster_id; + + /* Force us to allocate cluster 0 at the start. */ + cluster = -1; + cluster_id = APIC_MAX_INTRACLUSTER_ID; + for (apic_id = 0; apic_id < MAXCPU; apic_id++) { + if (!cpu_info[apic_id].cpu_present) + continue; + if (cluster_id == APIC_MAX_INTRACLUSTER_ID) { + cluster = ioapic_next_logical_cluster(); + cluster_id = 0; + } else + cluster_id++; + if (bootverbose) + printf("APIC ID: physical %u, logical %u:%u\n", + apic_id, cluster, cluster_id); + lapic_set_logical_id(apic_id, cluster, cluster_id); + } +} + +/* + * start each AP in our list + */ +static int +start_all_aps(void) +{ +#ifndef PC98 + u_char mpbiosreason; +#endif + u_long mpbioswarmvec; + struct pcpu *pc; + char *stack; + uintptr_t kptbase; + int i, pg, apic_id, cpu; + + POSTCODE(START_ALL_APS_POST); + + mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); + + /* install the AP 1st level boot code */ + install_ap_tramp(); + + /* save the current value of the warm-start vector */ + mpbioswarmvec = *((u_long *) WARMBOOT_OFF); +#ifndef PC98 + outb(CMOS_REG, BIOS_RESET); + mpbiosreason = inb(CMOS_DATA); +#endif + + /* set up temporary P==V mapping for AP boot */ + /* XXX this is a hack, we should boot the AP on its own stack/PTD */ + kptbase = (uintptr_t)(void *)KPTphys; + for (i = 0; i < NKPT; i++) + PTD[i] = (pd_entry_t)(PG_V | PG_RW | + ((kptbase + i * PAGE_SIZE) & PG_FRAME)); + invltlb(); + + /* start each AP */ + for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) { + if (!cpu_info[apic_id].cpu_present || + cpu_info[apic_id].cpu_bsp) + continue; + cpu++; + + /* save APIC ID for this logical ID */ + cpu_apic_ids[cpu] = apic_id; + + /* first page of AP's private space */ + pg = cpu * i386_btop(sizeof(struct privatespace)); + + /* allocate a new private data page */ + pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE); + + /* wire it into the private page table page */ + SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc)); + + /* allocate and set up an idle stack data page */ + stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */ + for (i = 0; i < KSTACK_PAGES; i++) + SMPpt[pg + 1 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + + /* prime data page for it to use */ + pcpu_init(pc, cpu, sizeof(struct pcpu)); + pc->pc_apic_id = apic_id; + + /* setup a vector to our boot code */ + *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; + *((volatile u_short *) WARMBOOT_SEG) = (boot_address >> 4); +#ifndef PC98 + outb(CMOS_REG, BIOS_RESET); + outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ +#endif + + bootSTK = &SMP_prvspace[cpu].idlekstack[KSTACK_PAGES * + PAGE_SIZE]; + bootAP = cpu; + + /* attempt to start the Application Processor */ + CHECK_INIT(99); /* setup checkpoints */ + if (!start_ap(apic_id)) { + printf("AP #%d (PHY# %d) failed!\n", cpu, apic_id); + CHECK_PRINT("trace"); /* show checkpoints */ + /* better panic as the AP may be running loose */ + printf("panic y/n? [y] "); + if (cngetc() != 'n') + panic("bye-bye"); + } + CHECK_PRINT("trace"); /* show checkpoints */ + + all_cpus |= (1 << cpu); /* record AP in CPU map */ + } + + /* build our map of 'other' CPUs */ + PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask)); + + /* restore the warmstart vector */ + *(u_long *) WARMBOOT_OFF = mpbioswarmvec; +#ifndef PC98 + outb(CMOS_REG, BIOS_RESET); + outb(CMOS_DATA, mpbiosreason); +#endif + + /* + * Set up the idle context for the BSP. Similar to above except + * that some was done by locore, some by pmap.c and some is implicit + * because the BSP is cpu#0 and the page is initially zero and also + * because we can refer to variables by name on the BSP.. + */ + + /* Allocate and setup BSP idle stack */ + stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); + for (i = 0; i < KSTACK_PAGES; i++) + SMPpt[1 + i] = (pt_entry_t) + (PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack)); + + for (i = 0; i < NKPT; i++) + PTD[i] = 0; + pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1); + + /* number of APs actually started */ + return mp_naps; +} + +/* + * load the 1st level AP boot code into base memory. + */ + +/* targets for relocation */ +extern void bigJump(void); +extern void bootCodeSeg(void); +extern void bootDataSeg(void); +extern void MPentry(void); +extern u_int MP_GDT; +extern u_int mp_gdtbase; + +static void +install_ap_tramp(void) +{ + int x; + int size = *(int *) ((u_long) & bootMP_size); + vm_offset_t va = boot_address + KERNBASE; + u_char *src = (u_char *) ((u_long) bootMP); + u_char *dst = (u_char *) va; + u_int boot_base = (u_int) bootMP; + u_int8_t *dst8; + u_int16_t *dst16; + u_int32_t *dst32; + + POSTCODE(INSTALL_AP_TRAMP_POST); + + KASSERT (size <= PAGE_SIZE, + ("'size' do not fit into PAGE_SIZE, as expected.")); + pmap_kenter(va, boot_address); + pmap_invalidate_page (kernel_pmap, va); + for (x = 0; x < size; ++x) + *dst++ = *src++; + + /* + * modify addresses in code we just moved to basemem. unfortunately we + * need fairly detailed info about mpboot.s for this to work. changes + * to mpboot.s might require changes here. + */ + + /* boot code is located in KERNEL space */ + dst = (u_char *) va; + + /* modify the lgdt arg */ + dst32 = (u_int32_t *) (dst + ((u_int) & mp_gdtbase - boot_base)); + *dst32 = boot_address + ((u_int) & MP_GDT - boot_base); + + /* modify the ljmp target for MPentry() */ + dst32 = (u_int32_t *) (dst + ((u_int) bigJump - boot_base) + 1); + *dst32 = ((u_int) MPentry - KERNBASE); + + /* modify the target for boot code segment */ + dst16 = (u_int16_t *) (dst + ((u_int) bootCodeSeg - boot_base)); + dst8 = (u_int8_t *) (dst16 + 1); + *dst16 = (u_int) boot_address & 0xffff; + *dst8 = ((u_int) boot_address >> 16) & 0xff; + + /* modify the target for boot data segment */ + dst16 = (u_int16_t *) (dst + ((u_int) bootDataSeg - boot_base)); + dst8 = (u_int8_t *) (dst16 + 1); + *dst16 = (u_int) boot_address & 0xffff; + *dst8 = ((u_int) boot_address >> 16) & 0xff; +} + +/* + * This function starts the AP (application processor) identified + * by the APIC ID 'physicalCpu'. It does quite a "song and dance" + * to accomplish this. This is necessary because of the nuances + * of the different hardware we might encounter. It isn't pretty, + * but it seems to work. + */ +static int +start_ap(int apic_id) +{ + int vector, ms; + int cpus; + + POSTCODE(START_AP_POST); + + /* calculate the vector */ + vector = (boot_address >> 12) & 0xff; + + /* used as a watchpoint to signal AP startup */ + cpus = mp_naps; + + /* + * first we do an INIT/RESET IPI this INIT IPI might be run, reseting + * and running the target CPU. OR this INIT IPI might be latched (P5 + * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be + * ignored. + */ + + /* do an INIT IPI: assert RESET */ + lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | + APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id); + + /* wait for pending status end */ + lapic_ipi_wait(-1); + + /* do an INIT IPI: deassert RESET */ + lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL | + APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0); + + /* wait for pending status end */ + DELAY(10000); /* wait ~10mS */ + lapic_ipi_wait(-1); + + /* + * next we do a STARTUP IPI: the previous INIT IPI might still be + * latched, (P5 bug) this 1st STARTUP would then terminate + * immediately, and the previously started INIT IPI would continue. OR + * the previous INIT IPI has already run. and this STARTUP IPI will + * run. OR the previous INIT IPI was ignored. and this STARTUP IPI + * will run. + */ + + /* do a STARTUP IPI */ + lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | + APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | + vector, apic_id); + lapic_ipi_wait(-1); + DELAY(200); /* wait ~200uS */ + + /* + * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF + * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR + * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is + * recognized after hardware RESET or INIT IPI. + */ + + lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE | + APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP | + vector, apic_id); + lapic_ipi_wait(-1); + DELAY(200); /* wait ~200uS */ + + /* Wait up to 5 seconds for it to start. */ + for (ms = 0; ms < 5000; ms++) { + if (mp_naps > cpus) + return 1; /* return SUCCESS */ + DELAY(1000); + } + return 0; /* return FAILURE */ +} + +#ifdef COUNT_XINVLTLB_HITS +u_int xhits_gbl[MAXCPU]; +u_int xhits_pg[MAXCPU]; +u_int xhits_rng[MAXCPU]; +SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, ""); +SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl, + sizeof(xhits_gbl), "IU", ""); +SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg, + sizeof(xhits_pg), "IU", ""); +SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng, + sizeof(xhits_rng), "IU", ""); + +u_int ipi_global; +u_int ipi_page; +u_int ipi_range; +u_int ipi_range_size; +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size, + 0, ""); + +u_int ipi_masked_global; +u_int ipi_masked_page; +u_int ipi_masked_range; +u_int ipi_masked_range_size; +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW, + &ipi_masked_global, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW, + &ipi_masked_page, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW, + &ipi_masked_range, 0, ""); +SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW, + &ipi_masked_range_size, 0, ""); +#endif /* COUNT_XINVLTLB_HITS */ + +/* + * Flush the TLB on all other CPU's + */ +static void +smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) +{ + u_int ncpu; + + ncpu = mp_ncpus - 1; /* does not shootdown self */ + if (ncpu < 1) + return; /* no other cpus */ + mtx_assert(&smp_rv_mtx, MA_OWNED); + smp_tlb_addr1 = addr1; + smp_tlb_addr2 = addr2; + atomic_store_rel_int(&smp_tlb_wait, 0); + ipi_all_but_self(vector); + while (smp_tlb_wait < ncpu) + ia32_pause(); +} + +/* + * This is about as magic as it gets. fortune(1) has got similar code + * for reversing bits in a word. Who thinks up this stuff?? + * + * Yes, it does appear to be consistently faster than: + * while (i = ffs(m)) { + * m >>= i; + * bits++; + * } + * and + * while (lsb = (m & -m)) { // This is magic too + * m &= ~lsb; // or: m ^= lsb + * bits++; + * } + * Both of these latter forms do some very strange things on gcc-3.1 with + * -mcpu=pentiumpro and/or -march=pentiumpro and/or -O or -O2. + * There is probably an SSE or MMX popcnt instruction. + * + * I wonder if this should be in libkern? + * + * XXX Stop the presses! Another one: + * static __inline u_int32_t + * popcnt1(u_int32_t v) + * { + * v -= ((v >> 1) & 0x55555555); + * v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + * v = (v + (v >> 4)) & 0x0F0F0F0F; + * return (v * 0x01010101) >> 24; + * } + * The downside is that it has a multiply. With a pentium3 with + * -mcpu=pentiumpro and -march=pentiumpro then gcc-3.1 will use + * an imull, and in that case it is faster. In most other cases + * it appears slightly slower. + * + * Another variant (also from fortune): + * #define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255) + * #define BX_(x) ((x) - (((x)>>1)&0x77777777) \ + * - (((x)>>2)&0x33333333) \ + * - (((x)>>3)&0x11111111)) + */ +static __inline u_int32_t +popcnt(u_int32_t m) +{ + + m = (m & 0x55555555) + ((m & 0xaaaaaaaa) >> 1); + m = (m & 0x33333333) + ((m & 0xcccccccc) >> 2); + m = (m & 0x0f0f0f0f) + ((m & 0xf0f0f0f0) >> 4); + m = (m & 0x00ff00ff) + ((m & 0xff00ff00) >> 8); + m = (m & 0x0000ffff) + ((m & 0xffff0000) >> 16); + return m; +} + +static void +smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) +{ + int ncpu, othercpus; + + othercpus = mp_ncpus - 1; + if (mask == (u_int)-1) { + ncpu = othercpus; + if (ncpu < 1) + return; + } else { + mask &= ~PCPU_GET(cpumask); + if (mask == 0) + return; + ncpu = popcnt(mask); + if (ncpu > othercpus) { + /* XXX this should be a panic offence */ + printf("SMP: tlb shootdown to %d other cpus (only have %d)\n", + ncpu, othercpus); + ncpu = othercpus; + } + /* XXX should be a panic, implied by mask == 0 above */ + if (ncpu < 1) + return; + } + mtx_assert(&smp_rv_mtx, MA_OWNED); + smp_tlb_addr1 = addr1; + smp_tlb_addr2 = addr2; + atomic_store_rel_int(&smp_tlb_wait, 0); + if (mask == (u_int)-1) + ipi_all_but_self(vector); + else + ipi_selected(mask, vector); + while (smp_tlb_wait < ncpu) + ia32_pause(); +} + +void +smp_invltlb(void) +{ + if (smp_started) { + smp_tlb_shootdown(IPI_INVLTLB, 0, 0); +#ifdef COUNT_XINVLTLB_HITS + ipi_global++; +#endif + } +} + +void +smp_invlpg(vm_offset_t addr) +{ + if (smp_started) { + smp_tlb_shootdown(IPI_INVLPG, addr, 0); +#ifdef COUNT_XINVLTLB_HITS + ipi_page++; +#endif + } +} + +void +smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2) +{ + if (smp_started) { + smp_tlb_shootdown(IPI_INVLRNG, addr1, addr2); +#ifdef COUNT_XINVLTLB_HITS + ipi_range++; + ipi_range_size += (addr2 - addr1) / PAGE_SIZE; +#endif + } +} + +void +smp_masked_invltlb(u_int mask) +{ + if (smp_started) { + smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, 0, 0); +#ifdef COUNT_XINVLTLB_HITS + ipi_masked_global++; +#endif + } +} + +void +smp_masked_invlpg(u_int mask, vm_offset_t addr) +{ + if (smp_started) { + smp_targeted_tlb_shootdown(mask, IPI_INVLPG, addr, 0); +#ifdef COUNT_XINVLTLB_HITS + ipi_masked_page++; +#endif + } +} + +void +smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2) +{ + if (smp_started) { + smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, addr1, addr2); +#ifdef COUNT_XINVLTLB_HITS + ipi_masked_range++; + ipi_masked_range_size += (addr2 - addr1) / PAGE_SIZE; +#endif + } +} + + +/* + * For statclock, we send an IPI to all CPU's to have them call this + * function. + */ +void +forwarded_statclock(struct clockframe frame) +{ + struct thread *td; + + CTR0(KTR_SMP, "forwarded_statclock"); + td = curthread; + td->td_intr_nesting_level++; + if (profprocs != 0) + profclock(&frame); + if (pscnt == psdiv) + statclock(&frame); + td->td_intr_nesting_level--; +} + +void +forward_statclock(void) +{ + int map; + + CTR0(KTR_SMP, "forward_statclock"); + + if (!smp_started || cold || panicstr) + return; + + map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); + if (map != 0) + ipi_selected(map, IPI_STATCLOCK); +} + +/* + * For each hardclock(), we send an IPI to all other CPU's to have them + * execute this function. It would be nice to reduce contention on + * sched_lock if we could simply peek at the CPU to determine the user/kernel + * state and call hardclock_process() on the CPU receiving the clock interrupt + * and then just use a simple IPI to handle any ast's if needed. + */ +void +forwarded_hardclock(struct clockframe frame) +{ + struct thread *td; + + CTR0(KTR_SMP, "forwarded_hardclock"); + td = curthread; + td->td_intr_nesting_level++; + hardclock_process(&frame); + td->td_intr_nesting_level--; +} + +void +forward_hardclock(void) +{ + u_int map; + + CTR0(KTR_SMP, "forward_hardclock"); + + if (!smp_started || cold || panicstr) + return; + + map = PCPU_GET(other_cpus) & ~(stopped_cpus|hlt_cpus_mask); + if (map != 0) + ipi_selected(map, IPI_HARDCLOCK); +} + +/* + * send an IPI to a set of cpus. + */ +void +ipi_selected(u_int32_t cpus, u_int ipi) +{ + int cpu; + + CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); + while ((cpu = ffs(cpus)) != 0) { + cpu--; + KASSERT(cpu_apic_ids[cpu] != -1, + ("IPI to non-existent CPU %d", cpu)); + lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]); + cpus &= ~(1 << cpu); + } +} + +/* + * send an IPI INTerrupt containing 'vector' to all CPUs, including myself + */ +void +ipi_all(u_int ipi) +{ + + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); + lapic_ipi_vectored(ipi, APIC_IPI_DEST_ALL); +} + +/* + * send an IPI to all CPUs EXCEPT myself + */ +void +ipi_all_but_self(u_int ipi) +{ + + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); + lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS); +} + +/* + * send an IPI to myself + */ +void +ipi_self(u_int ipi) +{ + + CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi); + lapic_ipi_vectored(ipi, APIC_IPI_DEST_SELF); +} + +/* + * This is called once the rest of the system is up and running and we're + * ready to let the AP's out of the pen. + */ +static void +release_aps(void *dummy __unused) +{ + + if (mp_ncpus == 1) + return; + mtx_lock_spin(&sched_lock); + atomic_store_rel_int(&aps_ready, 1); + while (smp_started == 0) + ia32_pause(); + mtx_unlock_spin(&sched_lock); +} +SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); + +static int +sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) +{ + u_int mask; + int error; + + mask = hlt_cpus_mask; + error = sysctl_handle_int(oidp, &mask, 0, req); + if (error || !req->newptr) + return (error); + + if (logical_cpus_mask != 0 && + (mask & logical_cpus_mask) == logical_cpus_mask) + hlt_logical_cpus = 1; + else + hlt_logical_cpus = 0; + + if ((mask & all_cpus) == all_cpus) + mask &= ~(1<<0); + hlt_cpus_mask = mask; + return (error); +} +SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW, + 0, 0, sysctl_hlt_cpus, "IU", + "Bitmap of CPUs to halt. 101 (binary) will halt CPUs 0 and 2."); + +static int +sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS) +{ + int disable, error; + + disable = hlt_logical_cpus; + error = sysctl_handle_int(oidp, &disable, 0, req); + if (error || !req->newptr) + return (error); + + if (disable) + hlt_cpus_mask |= logical_cpus_mask; + else + hlt_cpus_mask &= ~logical_cpus_mask; + + if ((hlt_cpus_mask & all_cpus) == all_cpus) + hlt_cpus_mask &= ~(1<<0); + + hlt_logical_cpus = disable; + return (error); +} + +static void +cpu_hlt_setup(void *dummy __unused) +{ + + if (logical_cpus_mask != 0) { + TUNABLE_INT_FETCH("machdep.hlt_logical_cpus", + &hlt_logical_cpus); + sysctl_ctx_init(&logical_cpu_clist); + SYSCTL_ADD_PROC(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0, + sysctl_hlt_logical_cpus, "IU", ""); + SYSCTL_ADD_UINT(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, + &logical_cpus_mask, 0, ""); + + if (hlt_logical_cpus) + hlt_cpus_mask |= logical_cpus_mask; + } +} +SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL); + +int +mp_grab_cpu_hlt(void) +{ + u_int mask = PCPU_GET(cpumask); +#ifdef MP_WATCHDOG + u_int cpuid = PCPU_GET(cpuid); +#endif + int retval; + +#ifdef MP_WATCHDOG + ap_watchdog(cpuid); +#endif + + retval = mask & hlt_cpus_mask; + while (mask & hlt_cpus_mask) + __asm __volatile("sti; hlt" : : : "memory"); + return (retval); +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mptable.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mptable.c new file mode 100644 index 0000000000..2f0aff0055 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/mptable.c @@ -0,0 +1,974 @@ +/*- + * Copyright (c) 2003 John Baldwin + * Copyright (c) 1996, by Steve Passe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the developer may NOT be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/mptable.c,v 1.235.2.1 2004/09/28 16:24:09 jhb Exp $"); + +#include "opt_mptable_force_htt.h" +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* string defined by the Intel MP Spec as identifying the MP table */ +#define MP_SIG 0x5f504d5f /* _MP_ */ + +#define NAPICID 32 /* Max number of APIC's */ + +#ifdef PC98 +#define BIOS_BASE (0xe8000) +#define BIOS_SIZE (0x18000) +#else +#define BIOS_BASE (0xf0000) +#define BIOS_SIZE (0x10000) +#endif +#define BIOS_COUNT (BIOS_SIZE/4) + +typedef void mptable_entry_handler(u_char *entry, void *arg); + +static basetable_entry basetable_entry_types[] = +{ + {0, 20, "Processor"}, + {1, 8, "Bus"}, + {2, 8, "I/O APIC"}, + {3, 8, "I/O INT"}, + {4, 8, "Local INT"} +}; + +typedef struct BUSDATA { + u_char bus_id; + enum busTypes bus_type; +} bus_datum; + +typedef struct INTDATA { + u_char int_type; + u_short int_flags; + u_char src_bus_id; + u_char src_bus_irq; + u_char dst_apic_id; + u_char dst_apic_int; + u_char int_vector; +} io_int, local_int; + +typedef struct BUSTYPENAME { + u_char type; + char name[7]; +} bus_type_name; + +/* From MP spec v1.4, table 4-8. */ +static bus_type_name bus_type_table[] = +{ + {UNKNOWN_BUSTYPE, "CBUS "}, + {UNKNOWN_BUSTYPE, "CBUSII"}, + {EISA, "EISA "}, + {UNKNOWN_BUSTYPE, "FUTURE"}, + {UNKNOWN_BUSTYPE, "INTERN"}, + {ISA, "ISA "}, + {UNKNOWN_BUSTYPE, "MBI "}, + {UNKNOWN_BUSTYPE, "MBII "}, + {MCA, "MCA "}, + {UNKNOWN_BUSTYPE, "MPI "}, + {UNKNOWN_BUSTYPE, "MPSA "}, + {UNKNOWN_BUSTYPE, "NUBUS "}, + {PCI, "PCI "}, + {UNKNOWN_BUSTYPE, "PCMCIA"}, + {UNKNOWN_BUSTYPE, "TC "}, + {UNKNOWN_BUSTYPE, "VL "}, + {UNKNOWN_BUSTYPE, "VME "}, + {UNKNOWN_BUSTYPE, "XPRESS"} +}; + +/* From MP spec v1.4, table 5-1. */ +static int default_data[7][5] = +{ +/* nbus, id0, type0, id1, type1 */ + {1, 0, ISA, 255, NOBUS}, + {1, 0, EISA, 255, NOBUS}, + {1, 0, EISA, 255, NOBUS}, + {1, 0, MCA, 255, NOBUS}, + {2, 0, ISA, 1, PCI}, + {2, 0, EISA, 1, PCI}, + {2, 0, MCA, 1, PCI} +}; + +struct pci_probe_table_args { + u_char bus; + u_char found; +}; + +struct pci_route_interrupt_args { + u_char bus; /* Source bus. */ + u_char irq; /* Source slot:pin. */ + int vector; /* Return value. */ +}; + +static mpfps_t mpfps; +static mpcth_t mpct; +static void *ioapics[NAPICID]; +static bus_datum *busses; +static int mptable_nioapics, mptable_nbusses, mptable_maxbusid; +static int pci0 = -1; + +MALLOC_DEFINE(M_MPTABLE, "MP Table", "MP Table Items"); + +static enum intr_polarity conforming_polarity(u_char src_bus, + u_char src_bus_irq); +static enum intr_trigger conforming_trigger(u_char src_bus, u_char src_bus_irq); +static enum intr_polarity intentry_polarity(int_entry_ptr intr); +static enum intr_trigger intentry_trigger(int_entry_ptr intr); +static int lookup_bus_type(char *name); +static void mptable_count_items(void); +static void mptable_count_items_handler(u_char *entry, void *arg); +#ifdef MPTABLE_FORCE_HTT +static void mptable_hyperthread_fixup(u_int id_mask); +#endif +static void mptable_parse_apics_and_busses(void); +static void mptable_parse_apics_and_busses_handler(u_char *entry, + void *arg); +static void mptable_parse_ints(void); +static void mptable_parse_ints_handler(u_char *entry, void *arg); +static void mptable_parse_io_int(int_entry_ptr intr); +static void mptable_parse_local_int(int_entry_ptr intr); +static void mptable_pci_probe_table_handler(u_char *entry, void *arg); +static void mptable_pci_route_interrupt_handler(u_char *entry, void *arg); +static void mptable_pci_setup(void); +static int mptable_probe(void); +static int mptable_probe_cpus(void); +static void mptable_probe_cpus_handler(u_char *entry, void *arg __unused); +static void mptable_register(void *dummy); +static int mptable_setup_local(void); +static int mptable_setup_io(void); +static void mptable_walk_table(mptable_entry_handler *handler, void *arg); +static int search_for_sig(u_int32_t target, int count); + +static struct apic_enumerator mptable_enumerator = { + "MPTable", + mptable_probe, + mptable_probe_cpus, + mptable_setup_local, + mptable_setup_io +}; + +/* + * look for the MP spec signature + */ + +static int +search_for_sig(u_int32_t target, int count) +{ + int x; + u_int32_t *addr = (u_int32_t *) (KERNBASE + target); + + for (x = 0; x < count; x += 4) + if (addr[x] == MP_SIG) + /* make array index a byte index */ + return (target + (x * sizeof(u_int32_t))); + return (-1); +} + +static int +lookup_bus_type(char *name) +{ + int x; + + for (x = 0; x < MAX_BUSTYPE; ++x) + if (strncmp(bus_type_table[x].name, name, 6) == 0) + return (bus_type_table[x].type); + + return (UNKNOWN_BUSTYPE); +} + +/* + * Look for an Intel MP spec table (ie, SMP capable hardware). + */ +static int +mptable_probe(void) +{ + int x; + u_long segment; + u_int32_t target; + + /* see if EBDA exists */ + if ((segment = (u_long) * (u_short *) (KERNBASE + 0x40e)) != 0) { + /* search first 1K of EBDA */ + target = (u_int32_t) (segment << 4); + if ((x = search_for_sig(target, 1024 / 4)) >= 0) + goto found; + } else { + /* last 1K of base memory, effective 'top of base' passed in */ + target = (u_int32_t) ((basemem * 1024) - 0x400); + if ((x = search_for_sig(target, 1024 / 4)) >= 0) + goto found; + } + + /* search the BIOS */ + target = (u_int32_t) BIOS_BASE; + if ((x = search_for_sig(target, BIOS_COUNT)) >= 0) + goto found; + + /* nothing found */ + return (ENXIO); + +found: + mpfps = (mpfps_t)(KERNBASE + x); + + /* Map in the configuration table if it exists. */ + if (mpfps->config_type != 0) + mpct = NULL; + else { + if ((uintptr_t)mpfps->pap >= 1024 * 1024) { + printf("%s: Unable to map MP Configuration Table\n", + __func__); + return (ENXIO); + } + mpct = (mpcth_t)(KERNBASE + (uintptr_t)mpfps->pap); + if (mpct->base_table_length + (uintptr_t)mpfps->pap >= + 1024 * 1024) { + printf("%s: Unable to map end of MP Config Table\n", + __func__); + return (ENXIO); + } + if (mpct->signature[0] != 'P' || mpct->signature[1] != 'C' || + mpct->signature[2] != 'M' || mpct->signature[3] != 'P') { + printf("%s: MP Config Table has bad signature: %c%c%c%c\n", + __func__, mpct->signature[0], mpct->signature[1], + mpct->signature[2], mpct->signature[3]); + return (ENXIO); + } + if (bootverbose) + printf( + "MP Configuration Table version 1.%d found at %p\n", + mpct->spec_rev, mpct); + } + + return (-100); +} + +/* + * Run through the MP table enumerating CPUs. + */ +static int +mptable_probe_cpus(void) +{ + u_int cpu_mask; + + /* Is this a pre-defined config? */ + if (mpfps->config_type != 0) { + lapic_create(0, 1); + lapic_create(1, 0); + } else { + cpu_mask = 0; + mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask); +#ifdef MPTABLE_FORCE_HTT + mptable_hyperthread_fixup(cpu_mask); +#endif + } + return (0); +} + +/* + * Initialize the local APIC on the BSP. + */ +static int +mptable_setup_local(void) +{ + + /* Is this a pre-defined config? */ + printf("MPTable: <"); + if (mpfps->config_type != 0) { + lapic_init(DEFAULT_APIC_BASE); + printf("Preset Config %d", mpfps->config_type); + } else { + lapic_init((uintptr_t)mpct->apic_address); + printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id, + (int)sizeof(mpct->product_id), mpct->product_id); + } + printf(">\n"); + return (0); +} + +/* + * Run through the MP table enumerating I/O APICs. + */ +static int +mptable_setup_io(void) +{ + int i; + u_char byte; + + /* First, we count individual items and allocate arrays. */ + mptable_count_items(); + busses = malloc((mptable_maxbusid + 1) * sizeof(bus_datum), M_MPTABLE, + M_WAITOK); + for (i = 0; i <= mptable_maxbusid; i++) + busses[i].bus_type = NOBUS; + + /* Second, we run through adding I/O APIC's and busses. */ + ioapic_enable_mixed_mode(); + mptable_parse_apics_and_busses(); + + /* Third, we run through the table tweaking interrupt sources. */ + mptable_parse_ints(); + + /* Fourth, we register all the I/O APIC's. */ + for (i = 0; i < NAPICID; i++) + if (ioapics[i] != NULL) + ioapic_register(ioapics[i]); + + /* Fifth, we setup data structures to handle PCI interrupt routing. */ + mptable_pci_setup(); + + /* Finally, we throw the switch to enable the I/O APIC's. */ + if (mpfps->mpfb2 & MPFB2_IMCR_PRESENT) { + outb(0x22, 0x70); /* select IMCR */ + byte = inb(0x23); /* current contents */ + byte |= 0x01; /* mask external INTR */ + outb(0x23, byte); /* disconnect 8259s/NMI */ + } + + return (0); +} + +static void +mptable_register(void *dummy __unused) +{ + + apic_register_enumerator(&mptable_enumerator); +} +SYSINIT(mptable_register, SI_SUB_CPU - 1, SI_ORDER_FIRST, mptable_register, + NULL) + +/* + * Call the handler routine for each entry in the MP config table. + */ +static void +mptable_walk_table(mptable_entry_handler *handler, void *arg) +{ + u_int i; + u_char *entry; + + entry = (u_char *)(mpct + 1); + for (i = 0; i < mpct->entry_count; i++) { + switch (*entry) { + case MPCT_ENTRY_PROCESSOR: + case MPCT_ENTRY_IOAPIC: + case MPCT_ENTRY_BUS: + case MPCT_ENTRY_INT: + case MPCT_ENTRY_LOCAL_INT: + break; + default: + panic("%s: Unknown MP Config Entry %d\n", __func__, + (int)*entry); + } + handler(entry, arg); + entry += basetable_entry_types[*entry].length; + } +} + +static void +mptable_probe_cpus_handler(u_char *entry, void *arg) +{ + proc_entry_ptr proc; + u_int *cpu_mask; + + switch (*entry) { + case MPCT_ENTRY_PROCESSOR: + proc = (proc_entry_ptr)entry; + if (proc->cpu_flags & PROCENTRY_FLAG_EN) { + lapic_create(proc->apic_id, proc->cpu_flags & + PROCENTRY_FLAG_BP); + cpu_mask = (u_int *)arg; + *cpu_mask |= (1 << proc->apic_id); + } + break; + } +} + +static void +mptable_count_items_handler(u_char *entry, void *arg __unused) +{ + io_apic_entry_ptr apic; + bus_entry_ptr bus; + + switch (*entry) { + case MPCT_ENTRY_BUS: + bus = (bus_entry_ptr)entry; + mptable_nbusses++; + if (bus->bus_id > mptable_maxbusid) + mptable_maxbusid = bus->bus_id; + break; + case MPCT_ENTRY_IOAPIC: + apic = (io_apic_entry_ptr)entry; + if (apic->apic_flags & IOAPICENTRY_FLAG_EN) + mptable_nioapics++; + break; + } +} + +/* + * Count items in the table. + */ +static void +mptable_count_items(void) +{ + + /* Is this a pre-defined config? */ + if (mpfps->config_type != 0) { + mptable_nioapics = 1; + switch (mpfps->config_type) { + case 1: + case 2: + case 3: + case 4: + mptable_nbusses = 1; + break; + case 5: + case 6: + case 7: + mptable_nbusses = 2; + break; + default: + panic("Unknown pre-defined MP Table config type %d", + mpfps->config_type); + } + mptable_maxbusid = mptable_nbusses - 1; + } else + mptable_walk_table(mptable_count_items_handler, NULL); +} + +/* + * Add a bus or I/O APIC from an entry in the table. + */ +static void +mptable_parse_apics_and_busses_handler(u_char *entry, void *arg __unused) +{ + io_apic_entry_ptr apic; + bus_entry_ptr bus; + enum busTypes bus_type; + int i; + + + switch (*entry) { + case MPCT_ENTRY_BUS: + bus = (bus_entry_ptr)entry; + bus_type = lookup_bus_type(bus->bus_type); + if (bus_type == UNKNOWN_BUSTYPE) { + printf("MPTable: Unknown bus %d type \"", bus->bus_id); + for (i = 0; i < 6; i++) + printf("%c", bus->bus_type[i]); + printf("\"\n"); + } + busses[bus->bus_id].bus_id = bus->bus_id; + busses[bus->bus_id].bus_type = bus_type; + break; + case MPCT_ENTRY_IOAPIC: + apic = (io_apic_entry_ptr)entry; + if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN)) + break; + if (apic->apic_id >= NAPICID) + panic("%s: I/O APIC ID %d too high", __func__, + apic->apic_id); + if (ioapics[apic->apic_id] != NULL) + panic("%s: Double APIC ID %d", __func__, + apic->apic_id); + ioapics[apic->apic_id] = ioapic_create( + (uintptr_t)apic->apic_address, apic->apic_id, -1); + break; + default: + break; + } +} + +/* + * Enumerate I/O APIC's and busses. + */ +static void +mptable_parse_apics_and_busses(void) +{ + + /* Is this a pre-defined config? */ + if (mpfps->config_type != 0) { + ioapics[0] = ioapic_create(DEFAULT_IO_APIC_BASE, 2, 0); + busses[0].bus_id = 0; + busses[0].bus_type = default_data[mpfps->config_type][2]; + if (mptable_nbusses > 1) { + busses[1].bus_id = 1; + busses[1].bus_type = + default_data[mpfps->config_type][4]; + } + } else + mptable_walk_table(mptable_parse_apics_and_busses_handler, + NULL); +} + +/* + * Determine conforming polarity for a given bus type. + */ +static enum intr_polarity +conforming_polarity(u_char src_bus, u_char src_bus_irq) +{ + + KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus)); + switch (busses[src_bus].bus_type) { + case ISA: + case EISA: + return (INTR_POLARITY_HIGH); + case PCI: + return (INTR_POLARITY_LOW); + default: + panic("%s: unknown bus type %d", __func__, + busses[src_bus].bus_type); + } +} + +/* + * Determine conforming trigger for a given bus type. + */ +static enum intr_trigger +conforming_trigger(u_char src_bus, u_char src_bus_irq) +{ + + KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus)); + switch (busses[src_bus].bus_type) { + case ISA: + return (INTR_TRIGGER_EDGE); + case PCI: + return (INTR_TRIGGER_LEVEL); +#if !defined(PC98) && !defined(XEN) + case EISA: + KASSERT(src_bus_irq < 16, ("Invalid EISA IRQ %d", src_bus_irq)); + return (elcr_read_trigger(src_bus_irq)); +#endif + default: + panic("%s: unknown bus type %d", __func__, + busses[src_bus].bus_type); + } +} + +static enum intr_polarity +intentry_polarity(int_entry_ptr intr) +{ + + switch (intr->int_flags & INTENTRY_FLAGS_POLARITY) { + case INTENTRY_FLAGS_POLARITY_CONFORM: + return (conforming_polarity(intr->src_bus_id, + intr->src_bus_irq)); + case INTENTRY_FLAGS_POLARITY_ACTIVEHI: + return (INTR_POLARITY_HIGH); + case INTENTRY_FLAGS_POLARITY_ACTIVELO: + return (INTR_POLARITY_LOW); + default: + panic("Bogus interrupt flags"); + } +} + +static enum intr_trigger +intentry_trigger(int_entry_ptr intr) +{ + + switch (intr->int_flags & INTENTRY_FLAGS_TRIGGER) { + case INTENTRY_FLAGS_TRIGGER_CONFORM: + return (conforming_trigger(intr->src_bus_id, + intr->src_bus_irq)); + case INTENTRY_FLAGS_TRIGGER_EDGE: + return (INTR_TRIGGER_EDGE); + case INTENTRY_FLAGS_TRIGGER_LEVEL: + return (INTR_TRIGGER_LEVEL); + default: + panic("Bogus interrupt flags"); + } +} + +/* + * Parse an interrupt entry for an I/O interrupt routed to a pin on an I/O APIC. + */ +static void +mptable_parse_io_int(int_entry_ptr intr) +{ + void *ioapic; + u_int pin; + + if (intr->dst_apic_id == 0xff) { + printf("MPTable: Ignoring global interrupt entry for pin %d\n", + intr->dst_apic_int); + return; + } + if (intr->dst_apic_id >= NAPICID) { + printf("MPTable: Ignoring interrupt entry for ioapic%d\n", + intr->dst_apic_id); + return; + } + ioapic = ioapics[intr->dst_apic_id]; + if (ioapic == NULL) { + printf( + "MPTable: Ignoring interrupt entry for missing ioapic%d\n", + intr->dst_apic_id); + return; + } + pin = intr->dst_apic_int; + switch (intr->int_type) { + case INTENTRY_TYPE_INT: + switch (busses[intr->src_bus_id].bus_type) { + case NOBUS: + panic("interrupt from missing bus"); + case ISA: + case EISA: + if (busses[intr->src_bus_id].bus_type == ISA) + ioapic_set_bus(ioapic, pin, APIC_BUS_ISA); + else + ioapic_set_bus(ioapic, pin, APIC_BUS_EISA); + if (intr->src_bus_irq == pin) + break; + ioapic_remap_vector(ioapic, pin, intr->src_bus_irq); + if (ioapic_get_vector(ioapic, intr->src_bus_irq) == + intr->src_bus_irq) + ioapic_disable_pin(ioapic, intr->src_bus_irq); + break; + case PCI: + ioapic_set_bus(ioapic, pin, APIC_BUS_PCI); + break; + default: + ioapic_set_bus(ioapic, pin, APIC_BUS_UNKNOWN); + break; + } + break; + case INTENTRY_TYPE_NMI: + ioapic_set_nmi(ioapic, pin); + break; + case INTENTRY_TYPE_SMI: + ioapic_set_smi(ioapic, pin); + break; + case INTENTRY_TYPE_EXTINT: + ioapic_set_extint(ioapic, pin); + break; + default: + panic("%s: invalid interrupt entry type %d\n", __func__, + intr->int_type); + } + if (intr->int_type == INTENTRY_TYPE_INT || + (intr->int_flags & INTENTRY_FLAGS_TRIGGER) != + INTENTRY_FLAGS_TRIGGER_CONFORM) + ioapic_set_triggermode(ioapic, pin, intentry_trigger(intr)); + if (intr->int_type == INTENTRY_TYPE_INT || + (intr->int_flags & INTENTRY_FLAGS_POLARITY) != + INTENTRY_FLAGS_POLARITY_CONFORM) + ioapic_set_polarity(ioapic, pin, intentry_polarity(intr)); +} + +/* + * Parse an interrupt entry for a local APIC LVT pin. + */ +static void +mptable_parse_local_int(int_entry_ptr intr) +{ + u_int apic_id, pin; + + if (intr->dst_apic_id == 0xff) + apic_id = APIC_ID_ALL; + else + apic_id = intr->dst_apic_id; + if (intr->dst_apic_int == 0) + pin = LVT_LINT0; + else + pin = LVT_LINT1; + switch (intr->int_type) { + case INTENTRY_TYPE_INT: +#if 1 + printf( + "MPTable: Ignoring vectored local interrupt for LINTIN%d vector %d\n", + intr->dst_apic_int, intr->src_bus_irq); + return; +#else + lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_FIXED); + break; +#endif + case INTENTRY_TYPE_NMI: + lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); + break; + case INTENTRY_TYPE_SMI: + lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_SMI); + break; + case INTENTRY_TYPE_EXTINT: + lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_EXTINT); + break; + default: + panic("%s: invalid interrupt entry type %d\n", __func__, + intr->int_type); + } + if ((intr->int_flags & INTENTRY_FLAGS_TRIGGER) != + INTENTRY_FLAGS_TRIGGER_CONFORM) + lapic_set_lvt_triggermode(apic_id, pin, + intentry_trigger(intr)); + if ((intr->int_flags & INTENTRY_FLAGS_POLARITY) != + INTENTRY_FLAGS_POLARITY_CONFORM) + lapic_set_lvt_polarity(apic_id, pin, intentry_polarity(intr)); +} + +/* + * Parse interrupt entries. + */ +static void +mptable_parse_ints_handler(u_char *entry, void *arg __unused) +{ + int_entry_ptr intr; + + intr = (int_entry_ptr)entry; + switch (*entry) { + case MPCT_ENTRY_INT: + mptable_parse_io_int(intr); + break; + case MPCT_ENTRY_LOCAL_INT: + mptable_parse_local_int(intr); + break; + } +} + +/* + * Configure the interrupt pins + */ +static void +mptable_parse_ints(void) +{ + + /* Is this a pre-defined config? */ + if (mpfps->config_type != 0) { + /* Configure LINT pins. */ + lapic_set_lvt_mode(APIC_ID_ALL, LVT_LINT0, APIC_LVT_DM_EXTINT); + lapic_set_lvt_mode(APIC_ID_ALL, LVT_LINT1, APIC_LVT_DM_NMI); + + /* Configure I/O APIC pins. */ + if (mpfps->config_type != 7) + ioapic_set_extint(ioapics[0], 0); + else + ioapic_disable_pin(ioapics[0], 0); + if (mpfps->config_type != 2) + ioapic_remap_vector(ioapics[0], 2, 0); + else + ioapic_disable_pin(ioapics[0], 2); + if (mpfps->config_type == 2) + ioapic_disable_pin(ioapics[0], 13); + } else + mptable_walk_table(mptable_parse_ints_handler, NULL); +} + +#ifdef MPTABLE_FORCE_HTT +/* + * Perform a hyperthreading "fix-up" to enumerate any logical CPU's + * that aren't already listed in the table. + * + * XXX: We assume that all of the physical CPUs in the + * system have the same number of logical CPUs. + * + * XXX: We assume that APIC ID's are allocated such that + * the APIC ID's for a physical processor are aligned + * with the number of logical CPU's in the processor. + */ +static void +mptable_hyperthread_fixup(u_int id_mask) +{ + u_int i, id, logical_cpus; + + /* Nothing to do if there is no HTT support. */ + if ((cpu_feature & CPUID_HTT) == 0) + return; + logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16; + if (logical_cpus <= 1) + return; + + /* + * For each APIC ID of a CPU that is set in the mask, + * scan the other candidate APIC ID's for this + * physical processor. If any of those ID's are + * already in the table, then kill the fixup. + */ + for (id = 0; id < NAPICID; id++) { + if ((id_mask & 1 << id) == 0) + continue; + /* First, make sure we are on a logical_cpus boundary. */ + if (id % logical_cpus != 0) + return; + for (i = id + 1; i < id + logical_cpus; i++) + if ((id_mask & 1 << i) != 0) + return; + } + + /* + * Ok, the ID's checked out, so perform the fixup by + * adding the logical CPUs. + */ + while ((id = ffs(id_mask)) != 0) { + id--; + for (i = id + 1; i < id + logical_cpus; i++) { + if (bootverbose) + printf( + "MPTable: Adding logical CPU %d from main CPU %d\n", + i, id); + lapic_create(i, 0); + } + id_mask &= ~(1 << id); + } +} +#endif /* MPTABLE_FORCE_HTT */ + +/* + * Support code for routing PCI interrupts using the MP Table. + */ +static void +mptable_pci_setup(void) +{ + int i; + + /* + * Find the first pci bus and call it 0. Panic if pci0 is not + * bus zero and there are multiple PCI busses. + */ + for (i = 0; i <= mptable_maxbusid; i++) + if (busses[i].bus_type == PCI) { + if (pci0 == -1) + pci0 = i; + else if (pci0 != 0) + panic( + "MPTable contains multiple PCI busses but no PCI bus 0"); + } +} + +static void +mptable_pci_probe_table_handler(u_char *entry, void *arg) +{ + struct pci_probe_table_args *args; + int_entry_ptr intr; + + if (*entry != MPCT_ENTRY_INT) + return; + intr = (int_entry_ptr)entry; + args = (struct pci_probe_table_args *)arg; + KASSERT(args->bus <= mptable_maxbusid, + ("bus %d is too big", args->bus)); + KASSERT(busses[args->bus].bus_type == PCI, ("probing for non-PCI bus")); + if (intr->src_bus_id == args->bus) + args->found = 1; +} + +int +mptable_pci_probe_table(int bus) +{ + struct pci_probe_table_args args; + + if (bus < 0) + return (EINVAL); + if (pci0 == -1 || pci0 + bus > mptable_maxbusid) + return (ENXIO); + if (busses[pci0 + bus].bus_type != PCI) + return (ENXIO); + args.bus = pci0 + bus; + args.found = 0; + mptable_walk_table(mptable_pci_probe_table_handler, &args); + if (args.found == 0) + return (ENXIO); + return (0); +} + +static void +mptable_pci_route_interrupt_handler(u_char *entry, void *arg) +{ + struct pci_route_interrupt_args *args; + int_entry_ptr intr; + int vector; + + if (*entry != MPCT_ENTRY_INT) + return; + intr = (int_entry_ptr)entry; + args = (struct pci_route_interrupt_args *)arg; + if (intr->src_bus_id != args->bus || intr->src_bus_irq != args->irq) + return; + + /* Make sure the APIC maps to a known APIC. */ + KASSERT(ioapics[intr->dst_apic_id] != NULL, + ("No I/O APIC %d to route interrupt to", intr->dst_apic_id)); + + /* + * Look up the vector for this APIC / pin combination. If we + * have previously matched an entry for this PCI IRQ but it + * has the same vector as this entry, just return. Otherwise, + * we use the vector for this APIC / pin combination. + */ + vector = ioapic_get_vector(ioapics[intr->dst_apic_id], + intr->dst_apic_int); + if (args->vector == vector) + return; + KASSERT(args->vector == -1, + ("Multiple IRQs for PCI interrupt %d.%d.INT%c: %d and %d\n", + args->bus, args->irq >> 2, 'A' + (args->irq & 0x3), args->vector, + vector)); + args->vector = vector; +} + +int +mptable_pci_route_interrupt(device_t pcib, device_t dev, int pin) +{ + struct pci_route_interrupt_args args; + int slot; + + /* Like ACPI, pin numbers are 0-3, not 1-4. */ + pin--; + KASSERT(pci0 != -1, ("do not know how to route PCI interrupts")); + args.bus = pci_get_bus(dev) + pci0; + slot = pci_get_slot(dev); + + /* + * PCI interrupt entries in the MP Table encode both the slot and + * pin into the IRQ with the pin being the two least significant + * bits, the slot being the next five bits, and the most significant + * bit being reserved. + */ + args.irq = slot << 2 | pin; + args.vector = -1; + mptable_walk_table(mptable_pci_route_interrupt_handler, &args); + if (args.vector < 0) { + device_printf(pcib, "unable to route slot %d INT%c\n", slot, + 'A' + pin); + return (PCI_INVALID_IRQ); + } + if (bootverbose) + device_printf(pcib, "slot %d INT%c routed to irq %d\n", slot, + 'A' + pin, args.vector); + return (args.vector); +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c new file mode 100644 index 0000000000..ee61e80ed9 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c @@ -0,0 +1,3381 @@ +/*- + * Copyright (c) 1991 Regents of the University of California. + * All rights reserved. + * Copyright (c) 1994 John S. Dyson + * All rights reserved. + * Copyright (c) 1994 David Greenman + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department and William Jolitz of UUNET Technologies Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91 + */ +/*- + * Copyright (c) 2003 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Jake Burkholder, + * Safeport Network Services, and Network Associates Laboratories, the + * Security Research Division of Network Associates, Inc. under + * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA + * CHATS research program. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/pmap.c,v 1.494.2.6 2004/10/10 19:08:00 alc Exp $"); + +/* + * Manages physical address maps. + * XEN NOTES: page table entries (pt_entry_t) and + * page directory entries (pd_entry_t) contain machine + * addresses and not physical addresses. Use PT_GET() before + * dereferencing these structures to convert them into a + * physical address. Use the PT_SET_VA operations to commit + * page changes back to XEN. PT_SET_VA_MA should be used with + * great care! + * + * + * In addition to hardware address maps, this + * module is called upon to provide software-use-only + * maps which may or may not be stored in the same + * form as hardware maps. These pseudo-maps are + * used to store intermediate results from copy + * operations to and from address spaces. + * + * Since the information managed by this module is + * also stored by the logical address mapping module, + * this module may throw away valid virtual-to-physical + * mappings at almost any time. However, invalidations + * of virtual-to-physical mappings must be done as + * requested. + * + * In order to cope with hardware architectures which + * make virtual-to-physical map invalidates expensive, + * this module may delay invalidate or reduced protection + * operations until such time as they are actually + * necessary. This module is given full information as + * to which processors are currently using which maps, + * and to when physical maps must be made correct. + */ + +#include "opt_cpu.h" +#include "opt_pmap.h" +#include "opt_msgbuf.h" +#include "opt_kstack_pages.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef SMP +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef SMP +#include +#endif + +#include + +#if !defined(CPU_ENABLE_SSE) && defined(I686_CPU) +#define CPU_ENABLE_SSE +#endif +#if defined(CPU_DISABLE_SSE) +#undef CPU_ENABLE_SSE +#endif + +#ifndef PMAP_SHPGPERPROC +#define PMAP_SHPGPERPROC 200 +#endif + +#if defined(DIAGNOSTIC) +#define PMAP_DIAGNOSTIC +#endif + +#define MINPV 2048 + +#if !defined(PMAP_DIAGNOSTIC) +#define PMAP_INLINE __inline +#else +#define PMAP_INLINE +#endif + +/* + * Get PDEs and PTEs for user/kernel address space + */ +#define pmap_pde(m, v) (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT])) +#define pdir_pde(m, v) (m[(vm_offset_t)(v) >> PDRSHIFT]) + +#define pmap_pde_v(pte) ((*(int *)pte & PG_V) != 0) +#define pmap_pte_w(pte) ((*(int *)pte & PG_W) != 0) +#define pmap_pte_m(pte) ((*(int *)pte & PG_M) != 0) +#define pmap_pte_u(pte) ((*(int *)pte & PG_A) != 0) +#define pmap_pte_v(pte) ((*(int *)pte & PG_V) != 0) + +#if 0 +#define pmap_pte_set_w(pte, v) ((v) ? atomic_set_int((u_int *)(pte), PG_W) : \ + atomic_clear_int((u_int *)(pte), PG_W)) +#else +#define pmap_pte_set_w(pte, v) { \ + if (v) \ + PT_SET_VA_MA(pte, *pte | PG_W, TRUE); \ + else \ + PT_SET_VA_MA(pte, *pte & ~PG_W, TRUE); \ +} +#endif + +struct pmap kernel_pmap_store; +LIST_HEAD(pmaplist, pmap); +static struct pmaplist allpmaps; +static struct mtx allpmaps_lock; + +vm_paddr_t avail_end; /* PA of last available physical page */ +vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */ +vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ +static boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ +int pgeflag = 0; /* PG_G or-in */ +int pseflag = 0; /* PG_PS or-in */ + +static int nkpt; +vm_offset_t kernel_vm_end; +extern u_int32_t KERNend; + +#ifdef PAE +static uma_zone_t pdptzone; +#endif + +/* + * Data for the pv entry allocation mechanism + */ +static uma_zone_t pvzone; +static struct vm_object pvzone_obj; +static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0; +int pmap_pagedaemon_waken; + +/* + * All those kernel PT submaps that BSD is so fond of + */ +pt_entry_t *CMAP1 = 0; +static pt_entry_t *CMAP2, *CMAP3; +caddr_t CADDR1 = 0, ptvmmap = 0; +static caddr_t CADDR2, CADDR3; +static struct mtx CMAPCADDR12_lock; +struct msgbuf *msgbufp = 0; + +/* + * Crashdump maps. + */ +static caddr_t crashdumpmap; + +#ifdef SMP +extern pt_entry_t *SMPpt; +#endif +static pt_entry_t *PMAP1 = 0, *PMAP2; +static pt_entry_t *PADDR1 = 0, *PADDR2; +#ifdef SMP +static int PMAP1cpu; +static int PMAP1changedcpu; +SYSCTL_INT(_debug, OID_AUTO, PMAP1changedcpu, CTLFLAG_RD, + &PMAP1changedcpu, 0, + "Number of times pmap_pte_quick changed CPU with same PMAP1"); +#endif +static int PMAP1changed; +SYSCTL_INT(_debug, OID_AUTO, PMAP1changed, CTLFLAG_RD, + &PMAP1changed, 0, + "Number of times pmap_pte_quick changed PMAP1"); +static int PMAP1unchanged; +SYSCTL_INT(_debug, OID_AUTO, PMAP1unchanged, CTLFLAG_RD, + &PMAP1unchanged, 0, + "Number of times pmap_pte_quick didn't change PMAP1"); +static struct mtx PMAP2mutex; + +static PMAP_INLINE void free_pv_entry(pv_entry_t pv); +static pv_entry_t get_pv_entry(void); +static void pmap_clear_ptes(vm_page_t m, int bit); + +static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva); +static void pmap_remove_page(struct pmap *pmap, vm_offset_t va); +static int pmap_remove_entry(struct pmap *pmap, vm_page_t m, + vm_offset_t va); +static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m); + +static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags); + +static vm_page_t _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags); +static int _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m); +static pt_entry_t *pmap_pte_quick(pmap_t pmap, vm_offset_t va); +static void pmap_pte_release(pt_entry_t *pte); +static int pmap_unuse_pt(pmap_t, vm_offset_t); +static vm_offset_t pmap_kmem_choose(vm_offset_t addr); +#ifdef PAE +static void *pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait); +#endif + +CTASSERT(1 << PDESHIFT == sizeof(pd_entry_t)); +CTASSERT(1 << PTESHIFT == sizeof(pt_entry_t)); + +#ifndef DEBUG +#define DEBUG +#endif +#ifdef PMAP_DEBUG +static void pmap_dec_ref(unsigned long ma); +static void pmap_mark_privileged(unsigned long pa); +static void pmap_mark_unprivileged(unsigned long pa); +static void pmap_dec_ref_page(vm_page_t m); +int pmap_pid_dump(int pid); +#endif +/* + * Move the kernel virtual free pointer to the next + * 4MB. This is used to help improve performance + * by using a large (4MB) page for much of the kernel + * (.text, .data, .bss) + */ +static vm_offset_t +pmap_kmem_choose(vm_offset_t addr) +{ + vm_offset_t newaddr = addr; + +#ifndef DISABLE_PSE + if (cpu_feature & CPUID_PSE) + newaddr = (addr + PDRMASK) & ~PDRMASK; +#endif + return newaddr; +} + +/* + * Bootstrap the system enough to run with virtual memory. + * + * On the i386 this is called after mapping has already been enabled + * and just syncs the pmap module with what has already been done. + * [We can't call it easily with mapping off since the kernel is not + * mapped with PA == VA, hence we would have to relocate every address + * from the linked base (virtual) address "KERNBASE" to the actual + * (physical) address starting relative to 0] + */ +void +pmap_bootstrap(firstaddr, loadaddr) + vm_paddr_t firstaddr; + vm_paddr_t loadaddr; +{ + vm_offset_t va; + pt_entry_t *pte, *unused; + int i; + + /* + * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too + * large. It should instead be correctly calculated in locore.s and + * not based on 'first' (which is a physical address, not a virtual + * address, for the start of unused physical memory). The kernel + * page tables are NOT double mapped and thus should not be included + * in this calculation. + */ + virtual_avail = (vm_offset_t) KERNBASE + firstaddr; + virtual_avail = pmap_kmem_choose(virtual_avail); + + virtual_end = VM_MAX_KERNEL_ADDRESS; + + /* + * Initialize the kernel pmap (which is statically allocated). + */ + PMAP_LOCK_INIT(kernel_pmap); + kernel_pmap->pm_pdir = (pd_entry_t *) xen_start_info->pt_base; +#ifdef PAE + kernel_pmap->pm_pdpt = (pdpt_entry_t *) (KERNBASE + (u_int)IdlePDPT); +#endif + kernel_pmap->pm_active = -1; /* don't allow deactivation */ + TAILQ_INIT(&kernel_pmap->pm_pvlist); + LIST_INIT(&allpmaps); + mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN); + mtx_lock_spin(&allpmaps_lock); + LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list); + mtx_unlock_spin(&allpmaps_lock); + nkpt = NKPT; + + /* + * Reserve some special page table entries/VA space for temporary + * mapping of pages. + */ +#define SYSMAP(c, p, v, n) \ + v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n); + + va = virtual_avail; + pte = vtopte(va); + + /* + * CMAP1/CMAP2 are used for zeroing and copying pages. + * CMAP3 is used for the idle process page zeroing. + */ + SYSMAP(caddr_t, CMAP1, CADDR1, 1) + SYSMAP(caddr_t, CMAP2, CADDR2, 1) + SYSMAP(caddr_t, CMAP3, CADDR3, 1) + PT_CLEAR_VA(CMAP3, TRUE); + + mtx_init(&CMAPCADDR12_lock, "CMAPCADDR12", NULL, MTX_DEF); + + /* + * Crashdump maps. + */ + SYSMAP(caddr_t, unused, crashdumpmap, MAXDUMPPGS) + + /* + * ptvmmap is used for reading arbitrary physical pages via /dev/mem. + */ + SYSMAP(caddr_t, unused, ptvmmap, 1) + + /* + * msgbufp is used to map the system message buffer. + */ + SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(MSGBUF_SIZE))) + + /* + * ptemap is used for pmap_pte_quick + */ + SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1); + SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1); + + mtx_init(&PMAP2mutex, "PMAP2", NULL, MTX_DEF); + + virtual_avail = va; + PT_CLEAR_VA(CMAP1, FALSE); + PT_CLEAR_VA(CMAP2, FALSE); + + for (i = 0; i < NKPT; i++) + PT_CLEAR_VA(&PTD[i], FALSE); + PT_UPDATES_FLUSH(); +#ifdef XEN_UNNEEDED + /* Turn on PG_G on kernel page(s) */ + pmap_set_pg(); +#endif +} + +/* + * Set PG_G on kernel pages. Only the BSP calls this when SMP is turned on. + */ +void +pmap_set_pg(void) +{ + pd_entry_t pdir; + pt_entry_t *pte; + vm_offset_t va, endva; + int i; + + if (pgeflag == 0) + return; + panic("this won't work"); + i = KERNLOAD/NBPDR; + endva = KERNBASE + KERNend; + + if (pseflag) { + va = KERNBASE + KERNLOAD; + while (va < endva) { + pdir = kernel_pmap->pm_pdir[KPTDI+i]; + pdir |= pgeflag; + kernel_pmap->pm_pdir[KPTDI+i] = PTD[KPTDI+i] = pdir; + invltlb(); /* Play it safe, invltlb() every time */ + i++; + va += NBPDR; + } + } else { + va = (vm_offset_t)btext; + while (va < endva) { + pte = vtopte(va); + if (*pte) + *pte |= pgeflag; + invltlb(); /* Play it safe, invltlb() every time */ + va += PAGE_SIZE; + } + } +} + +#ifdef PAE + +static MALLOC_DEFINE(M_PMAPPDPT, "pmap", "pmap pdpt"); + +static void * +pmap_pdpt_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) +{ + *flags = UMA_SLAB_PRIV; + return (contigmalloc(PAGE_SIZE, M_PMAPPDPT, 0, 0x0ULL, 0xffffffffULL, + 1, 0)); +} +#endif + +/* + * Initialize the pmap module. + * Called by vm_init, to initialize any structures that the pmap + * system needs to map virtual memory. + * pmap_init has been enhanced to support in a fairly consistant + * way, discontiguous physical memory. + */ +void +pmap_init(void) +{ + int i; + + /* + * Allocate memory for random pmap data structures. Includes the + * pv_head_table. + */ + + for(i = 0; i < vm_page_array_size; i++) { + vm_page_t m; + + m = &vm_page_array[i]; + TAILQ_INIT(&m->md.pv_list); + m->md.pv_list_count = 0; + } + + /* + * init the pv free list + */ + pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL, + NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); + uma_prealloc(pvzone, MINPV); + +#ifdef PAE + pdptzone = uma_zcreate("PDPT", NPGPTD * sizeof(pdpt_entry_t), NULL, + NULL, NULL, NULL, (NPGPTD * sizeof(pdpt_entry_t)) - 1, + UMA_ZONE_VM | UMA_ZONE_NOFREE); + uma_zone_set_allocf(pdptzone, pmap_pdpt_allocf); +#endif + + /* + * Now it is safe to enable pv_table recording. + */ + pmap_initialized = TRUE; +} + +/* + * Initialize the address space (zone) for the pv_entries. Set a + * high water mark so that the system can recover from excessive + * numbers of pv entries. + */ +void +pmap_init2() +{ + int shpgperproc = PMAP_SHPGPERPROC; + + TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc); + pv_entry_max = shpgperproc * maxproc + vm_page_array_size; + TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max); + pv_entry_high_water = 9 * (pv_entry_max / 10); + uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max); +} + + +/*************************************************** + * Low level helper routines..... + ***************************************************/ + +#if defined(PMAP_DIAGNOSTIC) + +/* + * This code checks for non-writeable/modified pages. + * This should be an invalid condition. + */ +static int +pmap_nw_modified(pt_entry_t ptea) +{ + int pte; + + pte = (int) ptea; + + if ((pte & (PG_M|PG_RW)) == PG_M) + return 1; + else + return 0; +} +#endif + + +/* + * this routine defines the region(s) of memory that should + * not be tested for the modified bit. + */ +static PMAP_INLINE int +pmap_track_modified(vm_offset_t va) +{ + if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) + return 1; + else + return 0; +} + +#ifdef I386_CPU +/* + * i386 only has "invalidate everything" and no SMP to worry about. + */ +PMAP_INLINE void +pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +{ + + if (pmap == kernel_pmap || pmap->pm_active) + invltlb(); +} + +PMAP_INLINE void +pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + + if (pmap == kernel_pmap || pmap->pm_active) + invltlb(); +} + +PMAP_INLINE void +pmap_invalidate_all(pmap_t pmap) +{ + + if (pmap == kernel_pmap || pmap->pm_active) + invltlb(); +} +#else /* !I386_CPU */ +#ifdef SMP +/* + * For SMP, these functions have to use the IPI mechanism for coherence. + */ +void +pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +{ + u_int cpumask; + u_int other_cpus; + + if (smp_started) { + if (!(read_eflags() & PSL_I)) + panic("%s: interrupts disabled", __func__); + mtx_lock_spin(&smp_rv_mtx); + } else + critical_enter(); + /* + * We need to disable interrupt preemption but MUST NOT have + * interrupts disabled here. + * XXX we may need to hold schedlock to get a coherent pm_active + * XXX critical sections disable interrupts again + */ + if (pmap == kernel_pmap || pmap->pm_active == all_cpus) { + invlpg(va); + smp_invlpg(va); + } else { + cpumask = PCPU_GET(cpumask); + other_cpus = PCPU_GET(other_cpus); + if (pmap->pm_active & cpumask) + invlpg(va); + if (pmap->pm_active & other_cpus) + smp_masked_invlpg(pmap->pm_active & other_cpus, va); + } + if (smp_started) + mtx_unlock_spin(&smp_rv_mtx); + else + critical_exit(); +} + +void +pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + u_int cpumask; + u_int other_cpus; + vm_offset_t addr; + + if (smp_started) { + if (!(read_eflags() & PSL_I)) + panic("%s: interrupts disabled", __func__); + mtx_lock_spin(&smp_rv_mtx); + } else + critical_enter(); + /* + * We need to disable interrupt preemption but MUST NOT have + * interrupts disabled here. + * XXX we may need to hold schedlock to get a coherent pm_active + * XXX critical sections disable interrupts again + */ + if (pmap == kernel_pmap || pmap->pm_active == all_cpus) { + for (addr = sva; addr < eva; addr += PAGE_SIZE) + invlpg(addr); + smp_invlpg_range(sva, eva); + } else { + cpumask = PCPU_GET(cpumask); + other_cpus = PCPU_GET(other_cpus); + if (pmap->pm_active & cpumask) + for (addr = sva; addr < eva; addr += PAGE_SIZE) + invlpg(addr); + if (pmap->pm_active & other_cpus) + smp_masked_invlpg_range(pmap->pm_active & other_cpus, + sva, eva); + } + if (smp_started) + mtx_unlock_spin(&smp_rv_mtx); + else + critical_exit(); +} + +void +pmap_invalidate_all(pmap_t pmap) +{ + u_int cpumask; + u_int other_cpus; + + if (smp_started) { + if (!(read_eflags() & PSL_I)) + panic("%s: interrupts disabled", __func__); + mtx_lock_spin(&smp_rv_mtx); + } else + critical_enter(); + /* + * We need to disable interrupt preemption but MUST NOT have + * interrupts disabled here. + * XXX we may need to hold schedlock to get a coherent pm_active + * XXX critical sections disable interrupts again + */ + if (pmap == kernel_pmap || pmap->pm_active == all_cpus) { + invltlb(); + smp_invltlb(); + } else { + cpumask = PCPU_GET(cpumask); + other_cpus = PCPU_GET(other_cpus); + if (pmap->pm_active & cpumask) + invltlb(); + if (pmap->pm_active & other_cpus) + smp_masked_invltlb(pmap->pm_active & other_cpus); + } + if (smp_started) + mtx_unlock_spin(&smp_rv_mtx); + else + critical_exit(); +} +#else /* !SMP */ +/* + * Normal, non-SMP, 486+ invalidation functions. + * We inline these within pmap.c for speed. + */ +PMAP_INLINE void +pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +{ + + if (pmap == kernel_pmap || pmap->pm_active) + invlpg(va); + PT_UPDATES_FLUSH(); + +} + +PMAP_INLINE void +pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + vm_offset_t addr; + + if (pmap == kernel_pmap || pmap->pm_active) + for (addr = sva; addr < eva; addr += PAGE_SIZE) + invlpg(addr); + PT_UPDATES_FLUSH(); + +} + +PMAP_INLINE void +pmap_invalidate_all(pmap_t pmap) +{ + + if (pmap == kernel_pmap || pmap->pm_active) + invltlb(); +} +#endif /* !SMP */ +#endif /* !I386_CPU */ + +/* + * Are we current address space or kernel? N.B. We return FALSE when + * a pmap's page table is in use because a kernel thread is borrowing + * it. The borrowed page table can change spontaneously, making any + * dependence on its continued use subject to a race condition. + */ +static __inline int +pmap_is_current(pmap_t pmap) +{ + + return (pmap == kernel_pmap || + (pmap == vmspace_pmap(curthread->td_proc->p_vmspace) && + (pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] & PG_FRAME))); +} + +/* + * If the given pmap is not the current or kernel pmap, the returned pte must + * be released by passing it to pmap_pte_release(). + */ +pt_entry_t * +pmap_pte(pmap_t pmap, vm_offset_t va) +{ + pd_entry_t tmppf, newpf; + pd_entry_t *pde; + + pde = pmap_pde(pmap, va); + if (*pde & PG_PS) + return (pde); + if (*pde != 0) { + /* are we current address space or kernel? */ + if (pmap_is_current(pmap)) + return (vtopte(va)); + mtx_lock(&PMAP2mutex); + newpf = PT_GET(pde) & PG_FRAME; + tmppf = PT_GET(PMAP2) & PG_FRAME; + if (tmppf != newpf) { + PT_SET_VA(PMAP2, newpf | PG_V | PG_A, FALSE); + pmap_invalidate_page(kernel_pmap, (vm_offset_t)PADDR2); + } + return (PADDR2 + (i386_btop(va) & (NPTEPG - 1))); + } + return (0); +} + +/* + * Releases a pte that was obtained from pmap_pte(). Be prepared for the pte + * being NULL. + */ +static __inline void +pmap_pte_release(pt_entry_t *pte) +{ + + if ((pt_entry_t *)((vm_offset_t)pte & ~PAGE_MASK) == PADDR2) + mtx_unlock(&PMAP2mutex); +} + +static __inline void +invlcaddr(void *caddr) +{ +#ifdef I386_CPU + invltlb(); +#else + invlpg((u_int)caddr); +#endif + PT_UPDATES_FLUSH(); +} + +/* + * Super fast pmap_pte routine best used when scanning + * the pv lists. This eliminates many coarse-grained + * invltlb calls. Note that many of the pv list + * scans are across different pmaps. It is very wasteful + * to do an entire invltlb for checking a single mapping. + * + * If the given pmap is not the current pmap, vm_page_queue_mtx + * must be held and curthread pinned to a CPU. + */ +static pt_entry_t * +pmap_pte_quick(pmap_t pmap, vm_offset_t va) +{ + pd_entry_t tmppf, newpf; + pd_entry_t *pde; + + pde = pmap_pde(pmap, va); + if (*pde & PG_PS) + return (pde); + if (*pde != 0) { + /* are we current address space or kernel? */ + if (pmap_is_current(pmap)) + return (vtopte(va)); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); + newpf = PT_GET(pde) & PG_FRAME; + tmppf = PT_GET(PMAP1) & PG_FRAME; + if (tmppf != newpf) { + PT_SET_VA(PMAP1, newpf | PG_V | PG_A, TRUE); +#ifdef SMP + PMAP1cpu = PCPU_GET(cpuid); +#endif + invlcaddr(PADDR1); + PMAP1changed++; + } else +#ifdef SMP + if (PMAP1cpu != PCPU_GET(cpuid)) { + PMAP1cpu = PCPU_GET(cpuid); + invlcaddr(PADDR1); + PMAP1changedcpu++; + } else +#endif + PMAP1unchanged++; + return (PADDR1 + (i386_btop(va) & (NPTEPG - 1))); + } + return (0); +} + +/* + * Routine: pmap_extract + * Function: + * Extract the physical page address associated + * with the given map/virtual_address pair. + */ +vm_paddr_t +pmap_extract(pmap_t pmap, vm_offset_t va) +{ + vm_paddr_t rtval; + pt_entry_t *pte; + pd_entry_t pde; + + rtval = 0; + PMAP_LOCK(pmap); + pde = PT_GET(&pmap->pm_pdir[va >> PDRSHIFT]); + if (pde != 0) { + if ((pde & PG_PS) != 0) { + rtval = (pde & ~PDRMASK) | (va & PDRMASK); + PMAP_UNLOCK(pmap); + return rtval; + } + pte = pmap_pte(pmap, va); + rtval = (PT_GET(pte) & PG_FRAME) | (va & PAGE_MASK); + pmap_pte_release(pte); + } + PMAP_UNLOCK(pmap); + return (rtval); +} + +/* + * Routine: pmap_extract_and_hold + * Function: + * Atomically extract and hold the physical page + * with the given pmap and virtual address pair + * if that mapping permits the given protection. + */ +vm_page_t +pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) +{ + pd_entry_t pde; + pt_entry_t pte; + vm_page_t m; + + m = NULL; + vm_page_lock_queues(); + PMAP_LOCK(pmap); + pde = PT_GET(pmap_pde(pmap, va)); + if (pde != 0) { + if (pde & PG_PS) { + panic("4MB pages not currently supported"); + if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) { + m = PHYS_TO_VM_PAGE((pde & ~PDRMASK) | + (va & PDRMASK)); + vm_page_hold(m); + } + } else { + sched_pin(); + pte = PT_GET(pmap_pte_quick(pmap, va)); + if (pte != 0 && + ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) { + m = PHYS_TO_VM_PAGE(pte & PG_FRAME); + vm_page_hold(m); + } + sched_unpin(); + } + } + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); + return (m); +} + +/*************************************************** + * Low level mapping routines..... + ***************************************************/ + +/* + * Add a wired page to the kva. + * Note: not SMP coherent. + */ +PMAP_INLINE void +pmap_kenter(vm_offset_t va, vm_paddr_t pa) +{ + PT_SET(va, pa | PG_RW | PG_V | pgeflag, TRUE); +} + +/* + * Remove a page from the kernel pagetables. + * Note: not SMP coherent. + */ +PMAP_INLINE void +pmap_kremove(vm_offset_t va) +{ + PT_CLEAR(va, TRUE); +} + +/* + * Used to map a range of physical addresses into kernel + * virtual address space. + * + * The value passed in '*virt' is a suggested virtual address for + * the mapping. Architectures which can support a direct-mapped + * physical to virtual region can return the appropriate address + * within that region, leaving '*virt' unchanged. Other + * architectures should map the pages starting at '*virt' and + * update '*virt' with the first usable address after the mapped + * region. + */ +vm_offset_t +pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) +{ + vm_offset_t va, sva; + pt_entry_t *pte; + + va = sva = *virt; + while (start < end) { + pte = vtopte(va); + PT_SET_VA(pte, start | PG_RW | PG_V | pgeflag, FALSE); + va += PAGE_SIZE; + start += PAGE_SIZE; + } + /* invalidate will flush the update queue */ + pmap_invalidate_range(kernel_pmap, sva, va); + *virt = va; + return (sva); +} + + +/* + * Add a list of wired pages to the kva + * this routine is only used for temporary + * kernel mappings that do not need to have + * page modification or references recorded. + * Note that old mappings are simply written + * over. The page *must* be wired. + * Note: SMP coherent. Uses a ranged shootdown IPI. + */ +void +pmap_qenter(vm_offset_t sva, vm_page_t *m, int count) +{ + vm_offset_t va; + + va = sva; + while (count-- > 0) { + PT_SET(va, VM_PAGE_TO_PHYS(*m) | PG_RW | PG_V | pgeflag, + FALSE); + va += PAGE_SIZE; + m++; + } + /* invalidate will flush the update queue */ + pmap_invalidate_range(kernel_pmap, sva, va); +} + +/* + * This routine tears out page mappings from the + * kernel -- it is meant only for temporary mappings. + * Note: SMP coherent. Uses a ranged shootdown IPI. + */ +void +pmap_qremove(vm_offset_t sva, int count) +{ + vm_offset_t va; + + va = sva; + while (count-- > 0) { + PT_CLEAR(va, FALSE); + va += PAGE_SIZE; + } + /* invalidate will flush the update queue */ + pmap_invalidate_range(kernel_pmap, sva, va); +} + +/*************************************************** + * Page table page management routines..... + ***************************************************/ + +/* + * This routine unholds page table pages, and if the hold count + * drops to zero, then it decrements the wire count. + */ +static PMAP_INLINE int +pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) +{ + + --m->wire_count; + if (m->wire_count == 0) + return _pmap_unwire_pte_hold(pmap, m); + else + return 0; +} + +static int +_pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) +{ + vm_offset_t pteva; + /* + * unmap the page table page + */ + xpq_queue_unpin_table(pmap->pm_pdir[m->pindex]); + PT_CLEAR_VA(&pmap->pm_pdir[m->pindex], TRUE); + --pmap->pm_stats.resident_count; + + /* + * Do an invltlb to make the invalidated mapping + * take effect immediately. + */ + pteva = VM_MAXUSER_ADDRESS + i386_ptob(m->pindex); + pmap_invalidate_page(pmap, pteva); + + vm_page_free_zero(m); + atomic_subtract_int(&cnt.v_wire_count, 1); + return 1; +} + +/* + * After removing a page table entry, this routine is used to + * conditionally free the page, and manage the hold/wire counts. + */ +static int +pmap_unuse_pt(pmap_t pmap, vm_offset_t va) +{ + pd_entry_t ptepde; + vm_page_t mpte; + + if (va >= VM_MAXUSER_ADDRESS) + return 0; + ptepde = PT_GET(pmap_pde(pmap, va)); + mpte = PHYS_TO_VM_PAGE(ptepde & PG_FRAME); + return pmap_unwire_pte_hold(pmap, mpte); +} + +void +pmap_pinit0(pmap) + struct pmap *pmap; +{ + + PMAP_LOCK_INIT(pmap); + pmap->pm_pdir = (pd_entry_t *)(xen_start_info->pt_base); +#ifdef PAE + pmap->pm_pdpt = (pdpt_entry_t *)(KERNBASE + (vm_offset_t)IdlePDPT); +#endif + pmap->pm_active = 0; + PCPU_SET(curpmap, pmap); + TAILQ_INIT(&pmap->pm_pvlist); + bzero(&pmap->pm_stats, sizeof pmap->pm_stats); + mtx_lock_spin(&allpmaps_lock); + LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); + mtx_unlock_spin(&allpmaps_lock); +} + +/* + * Initialize a preallocated and zeroed pmap structure, + * such as one in a vmspace structure. + */ +void +pmap_pinit(struct pmap *pmap) +{ + vm_page_t m, ptdpg[NPGPTD]; + vm_paddr_t ma; + static int color; + int i; + + PMAP_LOCK_INIT(pmap); + + /* + * No need to allocate page table space yet but we do need a valid + * page directory table. + */ + if (pmap->pm_pdir == NULL) { + pmap->pm_pdir = (pd_entry_t *)kmem_alloc_nofault(kernel_map, + NBPTD); +#ifdef PAE + pmap->pm_pdpt = uma_zalloc(pdptzone, M_WAITOK | M_ZERO); + KASSERT(((vm_offset_t)pmap->pm_pdpt & + ((NPGPTD * sizeof(pdpt_entry_t)) - 1)) == 0, + ("pmap_pinit: pdpt misaligned")); + KASSERT(pmap_kextract((vm_offset_t)pmap->pm_pdpt) < (4ULL<<30), + ("pmap_pinit: pdpt above 4g")); +#endif + } + + /* + * allocate the page directory page(s) + */ + for (i = 0; i < NPGPTD;) { + m = vm_page_alloc(NULL, color++, + VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | + VM_ALLOC_ZERO); + if (m == NULL) + VM_WAIT; + else { + pmap_zero_page(m); + ptdpg[i++] = m; + } + } + + pmap_qenter((vm_offset_t)pmap->pm_pdir, ptdpg, NPGPTD); + + for (i = 0; i < NPGPTD; i++) { + if ((ptdpg[i]->flags & PG_ZERO) == 0) + bzero(pmap->pm_pdir + (i * NPDEPG), PAGE_SIZE); + } + + mtx_lock_spin(&allpmaps_lock); + LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); + mtx_unlock_spin(&allpmaps_lock); + /* Wire in kernel global address entries. */ + /* XXX copies current process, does not fill in MPPTDI */ + bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * sizeof(pd_entry_t)); +#ifdef SMP + pmap->pm_pdir[MPPTDI] = PTD[MPPTDI]; +#endif + + /* install self-referential address mapping entry(s) */ + for (i = 0; i < NPGPTD; i++) { + ma = xpmap_ptom(VM_PAGE_TO_PHYS(ptdpg[i])); + pmap->pm_pdir[PTDPTDI + i] = ma | PG_V | PG_A; +#ifdef PAE + pmap->pm_pdpt[i] = ma | PG_V; +#endif +#ifndef PAE + PT_SET_MA(pmap->pm_pdir, ma | PG_V | PG_A, TRUE); +#else + panic("FIX ME!"); +#endif + xpq_queue_pin_table(ma, XPQ_PIN_L2_TABLE); + } + + pmap->pm_active = 0; + TAILQ_INIT(&pmap->pm_pvlist); + bzero(&pmap->pm_stats, sizeof pmap->pm_stats); +} + +/* + * this routine is called if the page table page is not + * mapped correctly. + */ +static vm_page_t +_pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags) +{ + vm_paddr_t ptepa; + vm_page_t m; + + KASSERT((flags & (M_NOWAIT | M_WAITOK)) == M_NOWAIT || + (flags & (M_NOWAIT | M_WAITOK)) == M_WAITOK, + ("_pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK")); + + /* + * Allocate a page table page. + */ + if ((m = vm_page_alloc(NULL, ptepindex, VM_ALLOC_NOOBJ | + VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL) { + if (flags & M_WAITOK) { + PMAP_UNLOCK(pmap); + vm_page_unlock_queues(); + VM_WAIT; + vm_page_lock_queues(); + PMAP_LOCK(pmap); + } + + /* + * Indicate the need to retry. While waiting, the page table + * page may have been allocated. + */ + return (NULL); + } + if ((m->flags & PG_ZERO) == 0) + pmap_zero_page(m); + + /* + * Map the pagetable page into the process address space, if + * it isn't already there. + */ + + pmap->pm_stats.resident_count++; + + ptepa = VM_PAGE_TO_PHYS(m); + xpq_queue_pin_table(xpmap_ptom(ptepa), XPQ_PIN_L1_TABLE); + PT_SET_VA(&pmap->pm_pdir[ptepindex], + (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_A | PG_M), TRUE); + + return m; +} + +static vm_page_t +pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags) +{ + unsigned ptepindex; + pd_entry_t ptepa; + vm_page_t m; + + KASSERT((flags & (M_NOWAIT | M_WAITOK)) == M_NOWAIT || + (flags & (M_NOWAIT | M_WAITOK)) == M_WAITOK, + ("pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK")); + + /* + * Calculate pagetable page index + */ + ptepindex = va >> PDRSHIFT; +retry: + /* + * Get the page directory entry + */ + ptepa = PT_GET(&pmap->pm_pdir[ptepindex]); + + /* + * This supports switching from a 4MB page to a + * normal 4K page. + */ + if (ptepa & PG_PS) { + pmap->pm_pdir[ptepindex] = 0; + ptepa = 0; + pmap_invalidate_all(kernel_pmap); + } + + /* + * If the page table page is mapped, we just increment the + * hold count, and activate it. + */ + if (ptepa) { + m = PHYS_TO_VM_PAGE(ptepa); + m->wire_count++; + } else { + /* + * Here if the pte page isn't mapped, or if it has + * been deallocated. + */ + m = _pmap_allocpte(pmap, ptepindex, flags); + if (m == NULL && (flags & M_WAITOK)) + goto retry; + } + return (m); +} + + +/*************************************************** +* Pmap allocation/deallocation routines. + ***************************************************/ + +#ifdef SMP +/* + * Deal with a SMP shootdown of other users of the pmap that we are + * trying to dispose of. This can be a bit hairy. + */ +static u_int *lazymask; +static u_int lazyptd; +static volatile u_int lazywait; + +void pmap_lazyfix_action(void); + +void +pmap_lazyfix_action(void) +{ + u_int mymask = PCPU_GET(cpumask); + + if (PCPU_GET(curpcb)->pcb_cr3 == lazyptd) + load_cr3(PCPU_GET(curpcb)->pcb_cr3); + atomic_clear_int(lazymask, mymask); + atomic_store_rel_int(&lazywait, 1); +} + +static void +pmap_lazyfix_self(u_int mymask) +{ + + if (PCPU_GET(curpcb)->pcb_cr3 == lazyptd) + load_cr3(PCPU_GET(curpcb)->pcb_cr3); + atomic_clear_int(lazymask, mymask); +} + + +static void +pmap_lazyfix(pmap_t pmap) +{ + u_int mymask = PCPU_GET(cpumask); + u_int mask; + register u_int spins; + + while ((mask = pmap->pm_active) != 0) { + spins = 50000000; + mask = mask & -mask; /* Find least significant set bit */ + mtx_lock_spin(&smp_rv_mtx); +#ifdef PAE + lazyptd = vtophys(pmap->pm_pdpt); +#else + lazyptd = vtophys(pmap->pm_pdir); +#endif + if (mask == mymask) { + lazymask = &pmap->pm_active; + pmap_lazyfix_self(mymask); + } else { + atomic_store_rel_int((u_int *)&lazymask, + (u_int)&pmap->pm_active); + atomic_store_rel_int(&lazywait, 0); + ipi_selected(mask, IPI_LAZYPMAP); + while (lazywait == 0) { + ia32_pause(); + if (--spins == 0) + break; + } + } + mtx_unlock_spin(&smp_rv_mtx); + if (spins == 0) + printf("pmap_lazyfix: spun for 50000000\n"); + } +} + +#else /* SMP */ + +/* + * Cleaning up on uniprocessor is easy. For various reasons, we're + * unlikely to have to even execute this code, including the fact + * that the cleanup is deferred until the parent does a wait(2), which + * means that another userland process has run. + */ +static void +pmap_lazyfix(pmap_t pmap) +{ + u_int cr3; + + cr3 = vtophys(pmap->pm_pdir); + if (cr3 == PCPU_GET(curpcb)->pcb_cr3) { + load_cr3(PCPU_GET(curpcb)->pcb_cr3); + pmap->pm_active &= ~(PCPU_GET(cpumask)); + } +} +#endif /* SMP */ + +/* + * Release any resources held by the given physical map. + * Called when a pmap initialized by pmap_pinit is being released. + * Should only be called if the map contains no valid mappings. + */ +void +pmap_release(pmap_t pmap) +{ + vm_page_t m, ptdpg[NPGPTD]; + vm_paddr_t ma; + int i; + + KASSERT(pmap->pm_stats.resident_count == 0, + ("pmap_release: pmap resident count %ld != 0", + pmap->pm_stats.resident_count)); + + pmap_lazyfix(pmap); + mtx_lock_spin(&allpmaps_lock); + LIST_REMOVE(pmap, pm_list); + mtx_unlock_spin(&allpmaps_lock); + + for (i = 0; i < NPGPTD; i++) + ptdpg[i] = PHYS_TO_VM_PAGE(PT_GET(&pmap->pm_pdir[PTDPTDI + i])); + + for (i = 0; i < nkpt + NPGPTD; i++) + PT_CLEAR_VA(&pmap->pm_pdir[PTDPTDI + i], FALSE); + + bzero(pmap->pm_pdir + PTDPTDI, (nkpt + NPGPTD) * + sizeof(*pmap->pm_pdir)); +#ifdef SMP + PT_CLEAR_VA(&pmap->pm_pdir[MPPTDI], FALSE); +#endif + PT_UPDATES_FLUSH(); + pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD); + + vm_page_lock_queues(); + for (i = 0; i < NPGPTD; i++) { + m = ptdpg[i]; + + ma = xpmap_ptom(VM_PAGE_TO_PHYS(m)); + xpq_queue_unpin_table(ma); + pmap_zero_page(m); +#ifdef PAE + KASSERT(VM_PAGE_TO_PHYS(m) == (pmap->pm_pdpt[i] & PG_FRAME), + ("pmap_release: got wrong ptd page")); +#endif + m->wire_count--; + atomic_subtract_int(&cnt.v_wire_count, 1); + + vm_page_free_zero(m); + } + vm_page_unlock_queues(); + PMAP_LOCK_DESTROY(pmap); +} + +static int +kvm_size(SYSCTL_HANDLER_ARGS) +{ + unsigned long ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE; + + return sysctl_handle_long(oidp, &ksize, 0, req); +} +SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD, + 0, 0, kvm_size, "IU", "Size of KVM"); + +static int +kvm_free(SYSCTL_HANDLER_ARGS) +{ + unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end; + + return sysctl_handle_long(oidp, &kfree, 0, req); +} +SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD, + 0, 0, kvm_free, "IU", "Amount of KVM free"); + +/* + * grow the number of kernel page table entries, if needed + */ +void +pmap_growkernel(vm_offset_t addr) +{ + struct pmap *pmap; + vm_paddr_t ptppaddr; + vm_page_t nkpg; + pd_entry_t newpdir; + pt_entry_t *pde; + + mtx_assert(&kernel_map->system_mtx, MA_OWNED); + if (kernel_vm_end == 0) { + kernel_vm_end = KERNBASE; + nkpt = 0; + while (pdir_pde(PTD, kernel_vm_end)) { + kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); + nkpt++; + } + } + addr = roundup2(addr, PAGE_SIZE * NPTEPG); + while (kernel_vm_end < addr) { + if (pdir_pde(PTD, kernel_vm_end)) { + kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); + continue; + } + + /* + * This index is bogus, but out of the way + */ + nkpg = vm_page_alloc(NULL, nkpt, + VM_ALLOC_NOOBJ | VM_ALLOC_SYSTEM | VM_ALLOC_WIRED); + if (!nkpg) + panic("pmap_growkernel: no memory to grow kernel"); + + nkpt++; + + pmap_zero_page(nkpg); + ptppaddr = VM_PAGE_TO_PHYS(nkpg); + newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M); + PT_SET_VA(&pdir_pde(PTD, kernel_vm_end), newpdir, TRUE); + + mtx_lock_spin(&allpmaps_lock); + LIST_FOREACH(pmap, &allpmaps, pm_list) { + pde = pmap_pde(pmap, kernel_vm_end); + PT_SET_VA(pde, newpdir, FALSE); + } + PT_UPDATES_FLUSH(); + mtx_unlock_spin(&allpmaps_lock); + kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1); + } +} + + +/*************************************************** + * page management routines. + ***************************************************/ + +/* + * free the pv_entry back to the free list + */ +static PMAP_INLINE void +free_pv_entry(pv_entry_t pv) +{ + pv_entry_count--; + uma_zfree(pvzone, pv); +} + +/* + * get a new pv_entry, allocating a block from the system + * when needed. + * the memory allocation is performed bypassing the malloc code + * because of the possibility of allocations at interrupt time. + */ +static pv_entry_t +get_pv_entry(void) +{ + pv_entry_count++; + if (pv_entry_high_water && + (pv_entry_count > pv_entry_high_water) && + (pmap_pagedaemon_waken == 0)) { + pmap_pagedaemon_waken = 1; + wakeup (&vm_pages_needed); + } + return uma_zalloc(pvzone, M_NOWAIT); +} + + +static int +pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va) +{ + pv_entry_t pv; + int rtval; + + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + if (m->md.pv_list_count < pmap->pm_stats.resident_count) { + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + if (pmap == pv->pv_pmap && va == pv->pv_va) + break; + } + } else { + TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) { + if (va == pv->pv_va) + break; + } + } + + rtval = 0; + if (pv) { + rtval = pmap_unuse_pt(pmap, va); + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + m->md.pv_list_count--; + if (TAILQ_FIRST(&m->md.pv_list) == NULL) + vm_page_flag_clear(m, PG_WRITEABLE); + + TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist); + free_pv_entry(pv); + } + + return rtval; +} + +/* + * Create a pv entry for page at pa for + * (pmap, va). + */ +static void +pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m) +{ + pv_entry_t pv; + pv = get_pv_entry(); + pv->pv_va = va; + pv->pv_pmap = pmap; + + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist); + TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list); + m->md.pv_list_count++; +} + +/* + * pmap_remove_pte: do the things to unmap a page in a process + */ +static int +pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va) +{ + pt_entry_t oldpte; + vm_page_t m; + + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + oldpte = pte_load_clear(ptq); + if (oldpte & PG_W) + pmap->pm_stats.wired_count -= 1; + /* + * Machines that don't support invlpg, also don't support + * PG_G. + */ + if (oldpte & PG_G) + pmap_invalidate_page(kernel_pmap, va); + pmap->pm_stats.resident_count -= 1; + if (oldpte & PG_MANAGED) { + m = PHYS_TO_VM_PAGE(oldpte); + if (oldpte & PG_M) { +#if defined(PMAP_DIAGNOSTIC) + if (pmap_nw_modified((pt_entry_t) oldpte)) { + printf( + "pmap_remove: modified page not writable: va: 0x%x, pte: 0x%x\n", + va, oldpte); + } +#endif + if (pmap_track_modified(va)) + vm_page_dirty(m); + } + if (oldpte & PG_A) + vm_page_flag_set(m, PG_REFERENCED); + return pmap_remove_entry(pmap, m, va); + } else { + return pmap_unuse_pt(pmap, va); + } +} + +/* + * Remove a single page from a process address space + */ +static void +pmap_remove_page(pmap_t pmap, vm_offset_t va) +{ + pt_entry_t *pte; + + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + if ((pte = pmap_pte_quick(pmap, va)) == NULL || *pte == 0) + return; + pmap_remove_pte(pmap, pte, va); + pmap_invalidate_page(pmap, va); +} + +/* + * Remove the given range of addresses from the specified map. + * + * It is assumed that the start and end are properly + * rounded to the page size. + */ +void +pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + vm_offset_t pdnxt; + pd_entry_t ptpaddr; + pt_entry_t *pte; + int anyvalid; + + /* + * Perform an unsynchronized read. This is, however, safe. + */ + if (pmap->pm_stats.resident_count == 0) + return; + + anyvalid = 0; + + vm_page_lock_queues(); + sched_pin(); + PMAP_LOCK(pmap); + + /* + * special handling of removing one page. a very + * common operation and easy to short circuit some + * code. + */ + if ((sva + PAGE_SIZE == eva) && + ((pmap->pm_pdir[(sva >> PDRSHIFT)] & PG_PS) == 0)) { + pmap_remove_page(pmap, sva); + goto out; + } + + for (; sva < eva; sva = pdnxt) { + unsigned pdirindex; + + /* + * Calculate index for next page table. + */ + pdnxt = (sva + NBPDR) & ~PDRMASK; + if (pmap->pm_stats.resident_count == 0) + break; + + pdirindex = sva >> PDRSHIFT; + ptpaddr = PT_GET(&pmap->pm_pdir[pdirindex]); + + /* + * Weed out invalid mappings. Note: we assume that the page + * directory table is always allocated, and in kernel virtual. + */ + if (ptpaddr == 0) + continue; + + /* + * Check for large page. + */ + if ((ptpaddr & PG_PS) != 0) { + PT_CLEAR_VA(pmap->pm_pdir[pdirindex], TRUE); + pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE; + anyvalid = 1; + continue; + } + + /* + * Limit our scan to either the end of the va represented + * by the current page table page, or to the end of the + * range being removed. + */ + if (pdnxt > eva) + pdnxt = eva; + + for (; sva != pdnxt; sva += PAGE_SIZE) { + if ((pte = pmap_pte_quick(pmap, sva)) == NULL || + *pte == 0) + continue; + anyvalid = 1; + if (pmap_remove_pte(pmap, pte, sva)) + break; + } + } +out: + sched_unpin(); + vm_page_unlock_queues(); + if (anyvalid) + pmap_invalidate_all(pmap); + PMAP_UNLOCK(pmap); +} + +/* + * Routine: pmap_remove_all + * Function: + * Removes this physical page from + * all physical maps in which it resides. + * Reflects back modify bits to the pager. + * + * Notes: + * Original versions of this routine were very + * inefficient because they iteratively called + * pmap_remove (slow...) + */ + +void +pmap_remove_all(vm_page_t m) +{ + pv_entry_t pv; + pt_entry_t *pte, tpte; + +#if defined(PMAP_DIAGNOSTIC) + /* + * XXX This makes pmap_remove_all() illegal for non-managed pages! + */ + if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) { + panic("pmap_remove_all: illegal for unmanaged page, va: 0x%x", + VM_PAGE_TO_PHYS(m)); + } +#endif + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + sched_pin(); + while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { + PMAP_LOCK(pv->pv_pmap); + pv->pv_pmap->pm_stats.resident_count--; + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); + tpte = pte_load_clear(pte); + if (tpte & PG_W) + pv->pv_pmap->pm_stats.wired_count--; + if (tpte & PG_A) + vm_page_flag_set(m, PG_REFERENCED); + + /* + * Update the vm_page_t clean and reference bits. + */ + if (tpte & PG_M) { +#if defined(PMAP_DIAGNOSTIC) + if (pmap_nw_modified((pt_entry_t) tpte)) { + printf( + "pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x\n", + pv->pv_va, tpte); + } +#endif + if (pmap_track_modified(pv->pv_va)) + vm_page_dirty(m); + } + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist); + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + m->md.pv_list_count--; + pmap_unuse_pt(pv->pv_pmap, pv->pv_va); + PMAP_UNLOCK(pv->pv_pmap); + free_pv_entry(pv); + } + vm_page_flag_clear(m, PG_WRITEABLE); + sched_unpin(); +} + +/* + * Set the physical protection on the + * specified range of this map as requested. + */ +void +pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) +{ + vm_offset_t pdnxt; + pd_entry_t ptpaddr; + int anychanged; + + if ((prot & VM_PROT_READ) == VM_PROT_NONE) { + pmap_remove(pmap, sva, eva); + return; + } + + if (prot & VM_PROT_WRITE) + return; + + anychanged = 0; + + vm_page_lock_queues(); + sched_pin(); + PMAP_LOCK(pmap); + for (; sva < eva; sva = pdnxt) { + unsigned obits, pbits, pdirindex; + + pdnxt = (sva + NBPDR) & ~PDRMASK; + + pdirindex = sva >> PDRSHIFT; + ptpaddr = PT_GET(&pmap->pm_pdir[pdirindex]); + + /* + * Weed out invalid mappings. Note: we assume that the page + * directory table is always allocated, and in kernel virtual. + */ + if (ptpaddr == 0) + continue; + + /* + * Check for large page. + */ + if ((ptpaddr & PG_PS) != 0) { + pmap->pm_pdir[pdirindex] &= ~(PG_M|PG_RW); + pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE; + anychanged = 1; + continue; + } + + if (pdnxt > eva) + pdnxt = eva; + + for (; sva != pdnxt; sva += PAGE_SIZE) { + pt_entry_t *pte; + vm_page_t m; + + if ((pte = pmap_pte_quick(pmap, sva)) == NULL) + continue; +#ifdef notyet +retry: +#endif + /* + * Regardless of whether a pte is 32 or 64 bits in + * size, PG_RW, PG_A, and PG_M are among the least + * significant 32 bits. + */ + obits = pbits = PT_GET(pte); + if (pbits & PG_MANAGED) { + m = NULL; + if (pbits & PG_A) { + m = PHYS_TO_VM_PAGE(pbits); + vm_page_flag_set(m, PG_REFERENCED); + pbits &= ~PG_A; + } + if ((pbits & PG_M) != 0 && + pmap_track_modified(sva)) { + if (m == NULL) + m = PHYS_TO_VM_PAGE(pbits); + vm_page_dirty(m); + } + } + + pbits &= ~(PG_RW | PG_M); + + if (pbits != obits) { +#ifdef notyet + if (!atomic_cmpset_int((u_int *)pte, obits, + pbits)) + goto retry; +#endif + PT_SET_VA(pte, pbits, FALSE); + anychanged = 1; + } + } + } + sched_unpin(); + vm_page_unlock_queues(); + if (anychanged) + pmap_invalidate_all(pmap); + PMAP_UNLOCK(pmap); +} + +/* + * Insert the given physical page (p) at + * the specified virtual address (v) in the + * target physical map with the protection requested. + * + * If specified, the page will be wired down, meaning + * that the related pte can not be reclaimed. + * + * NB: This is the only routine which MAY NOT lazy-evaluate + * or lose information. That is, this routine must actually + * insert this page into the given map NOW. + */ +void +pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, + boolean_t wired) +{ + vm_paddr_t pa; + register pt_entry_t *pte; + vm_paddr_t opa; + pt_entry_t origpte, newpte; + vm_page_t mpte, om; + + va &= PG_FRAME; +#ifdef PMAP_DIAGNOSTIC + if (va > VM_MAX_KERNEL_ADDRESS) + panic("pmap_enter: toobig"); + if ((va >= UPT_MIN_ADDRESS) && (va < UPT_MAX_ADDRESS)) + panic("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)", va); +#endif + + mpte = NULL; + + vm_page_lock_queues(); + PMAP_LOCK(pmap); + sched_pin(); + + /* + * In the case that a page table page is not + * resident, we are creating it here. + */ + if (va < VM_MAXUSER_ADDRESS) { + mpte = pmap_allocpte(pmap, va, M_WAITOK); + } +#if 0 && defined(PMAP_DIAGNOSTIC) + else { + pd_entry_t *pdeaddr = pmap_pde(pmap, va); + origpte = PT_GET(pdeaddr); + if ((origpte & PG_V) == 0) { + panic("pmap_enter: invalid kernel page table page, pdir=%p, pde=%p, va=%p\n", + pmap->pm_pdir[PTDPTDI], origpte, va); + } + } +#endif + + pte = pmap_pte_quick(pmap, va); + + /* + * Page Directory table entry not valid, we need a new PT page + */ + if (pte == NULL) { + panic("pmap_enter: invalid page directory pdir=%#jx, va=%#x\n", + (uintmax_t)pmap->pm_pdir[PTDPTDI], va); + } + + pa = VM_PAGE_TO_PHYS(m); + om = NULL; + origpte = PT_GET(pte); + opa = origpte & PG_FRAME; + + if (origpte & PG_PS) { + /* + * Yes, I know this will truncate upper address bits for PAE, + * but I'm actually more interested in the lower bits + */ + printf("pmap_enter: va %p, pte %p, origpte %p\n", + (void *)va, (void *)pte, (void *)(uintptr_t)origpte); + panic("pmap_enter: attempted pmap_enter on 4MB page"); + } + + /* + * Mapping has not changed, must be protection or wiring change. + */ + if (origpte && (opa == pa)) { + /* + * Wiring change, just update stats. We don't worry about + * wiring PT pages as they remain resident as long as there + * are valid mappings in them. Hence, if a user page is wired, + * the PT page will be also. + */ + if (wired && ((origpte & PG_W) == 0)) + pmap->pm_stats.wired_count++; + else if (!wired && (origpte & PG_W)) + pmap->pm_stats.wired_count--; + +#if defined(PMAP_DIAGNOSTIC) + if (pmap_nw_modified((pt_entry_t) origpte)) { + printf( + "pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x\n", + va, origpte); + } +#endif + + /* + * Remove extra pte reference + */ + if (mpte) + mpte->wire_count--; + + /* + * We might be turning off write access to the page, + * so we go ahead and sense modify status. + */ + if (origpte & PG_MANAGED) { + om = m; + pa |= PG_MANAGED; + } + goto validate; + } + /* + * Mapping has changed, invalidate old range and fall through to + * handle validating new mapping. + */ + if (opa) { + int err; + if (origpte & PG_W) + pmap->pm_stats.wired_count--; + if (origpte & PG_MANAGED) { + om = PHYS_TO_VM_PAGE(opa); + err = pmap_remove_entry(pmap, om, va); + } else + err = pmap_unuse_pt(pmap, va); + if (err) + panic("pmap_enter: pte vanished, va: 0x%x", va); + } else + pmap->pm_stats.resident_count++; + + /* + * Enter on the PV list if part of our managed memory. Note that we + * raise IPL while manipulating pv_table since pmap_enter can be + * called at interrupt time. + */ + if (pmap_initialized && + (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) { + pmap_insert_entry(pmap, va, m); + pa |= PG_MANAGED; + } + + /* + * Increment counters + */ + if (wired) + pmap->pm_stats.wired_count++; + +validate: + /* + * Now validate mapping with desired protection/wiring. + */ + newpte = (pt_entry_t)(pa | PG_V); + if ((prot & VM_PROT_WRITE) != 0) + newpte |= PG_RW; + if (wired) + newpte |= PG_W; + if (va < VM_MAXUSER_ADDRESS) + newpte |= PG_U; + if (pmap == kernel_pmap) + newpte |= pgeflag; + + /* + * if the mapping or permission bits are different, we need + * to update the pte. + */ + if ((origpte & ~(PG_M|PG_A)) != newpte) { + if (origpte & PG_MANAGED) { + origpte = PT_GET(pte); + PT_SET_VA(pte, newpte | PG_A, TRUE); + if ((origpte & PG_M) && pmap_track_modified(va)) + vm_page_dirty(om); + if (origpte & PG_A) + vm_page_flag_set(om, PG_REFERENCED); + } else + PT_SET_VA(pte, newpte | PG_A, TRUE); + if (origpte) { + pmap_invalidate_page(pmap, va); + } + } + sched_unpin(); + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); +} + +/* + * this code makes some *MAJOR* assumptions: + * 1. Current pmap & pmap exists. + * 2. Not wired. + * 3. Read access. + * 4. No page table pages. + * 5. Tlbflush is deferred to calling procedure. + * 6. Page IS managed. + * but is *MUCH* faster than pmap_enter... + */ + +vm_page_t +pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t mpte) +{ + pt_entry_t *pte; + vm_paddr_t pa; + + vm_page_lock_queues(); + PMAP_LOCK(pmap); + + /* + * In the case that a page table page is not + * resident, we are creating it here. + */ + if (va < VM_MAXUSER_ADDRESS) { + unsigned ptepindex; + pd_entry_t ptepa; + + /* + * Calculate pagetable page index + */ + ptepindex = va >> PDRSHIFT; + if (mpte && (mpte->pindex == ptepindex)) { + mpte->wire_count++; + } else { +retry: + /* + * Get the page directory entry + */ + ptepa = PT_GET(&pmap->pm_pdir[ptepindex]); + + /* + * If the page table page is mapped, we just increment + * the hold count, and activate it. + */ + if (ptepa) { + if (ptepa & PG_PS) + panic("pmap_enter_quick: unexpected mapping into 4MB page"); + mpte = PHYS_TO_VM_PAGE(ptepa); + mpte->wire_count++; + } else { + mpte = _pmap_allocpte(pmap, ptepindex, + M_WAITOK); + if (mpte == NULL) + goto retry; + } + } + } else { + mpte = NULL; + } + + /* + * This call to vtopte makes the assumption that we are + * entering the page into the current pmap. In order to support + * quick entry into any pmap, one would likely use pmap_pte_quick. + * But that isn't as quick as vtopte. + */ + pte = vtopte(va); + if (PT_GET(pte)) { + if (mpte != NULL) { + pmap_unwire_pte_hold(pmap, mpte); + mpte = NULL; + } + goto out; + } + + /* + * Enter on the PV list if part of our managed memory. Note that we + * raise IPL while manipulating pv_table since pmap_enter can be + * called at interrupt time. + */ + if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) + pmap_insert_entry(pmap, va, m); + + /* + * Increment counters + */ + pmap->pm_stats.resident_count++; + + pa = VM_PAGE_TO_PHYS(m); + + /* + * Now validate mapping with RO protection + */ + if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) + PT_SET(va, pa | PG_V | PG_U, TRUE); + else + PT_SET(va, pa | PG_V | PG_U | PG_MANAGED, TRUE); +out: + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); + return mpte; +} + +/* + * Make a temporary mapping for a physical address. This is only intended + * to be used for panic dumps. + */ +void * +pmap_kenter_temporary(vm_paddr_t pa, int i) +{ + vm_offset_t va; + + va = (vm_offset_t)crashdumpmap + (i * PAGE_SIZE); + pmap_kenter(va, pa); +#ifndef I386_CPU + invlpg(va); +#else + invltlb(); +#endif + return ((void *)crashdumpmap); +} + +/* + * This code maps large physical mmap regions into the + * processor address space. Note that some shortcuts + * are taken, but the code works. + */ +void +pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, + vm_object_t object, vm_pindex_t pindex, + vm_size_t size) +{ + vm_page_t p; + + VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + KASSERT(object->type == OBJT_DEVICE, + ("pmap_object_init_pt: non-device object")); + if (pseflag && + ((addr & (NBPDR - 1)) == 0) && ((size & (NBPDR - 1)) == 0)) { + int i; + vm_page_t m[1]; + unsigned int ptepindex; + int npdes; + pd_entry_t ptepa; + + PMAP_LOCK(pmap); + if (pmap->pm_pdir[ptepindex = (addr >> PDRSHIFT)]) + goto out; + PMAP_UNLOCK(pmap); +retry: + p = vm_page_lookup(object, pindex); + if (p != NULL) { + vm_page_lock_queues(); + if (vm_page_sleep_if_busy(p, FALSE, "init4p")) + goto retry; + } else { + p = vm_page_alloc(object, pindex, VM_ALLOC_NORMAL); + if (p == NULL) + return; + m[0] = p; + + if (vm_pager_get_pages(object, m, 1, 0) != VM_PAGER_OK) { + vm_page_lock_queues(); + vm_page_free(p); + vm_page_unlock_queues(); + return; + } + + p = vm_page_lookup(object, pindex); + vm_page_lock_queues(); + vm_page_wakeup(p); + } + vm_page_unlock_queues(); + + ptepa = VM_PAGE_TO_PHYS(p); + if (ptepa & (NBPDR - 1)) + return; + + p->valid = VM_PAGE_BITS_ALL; + + PMAP_LOCK(pmap); + pmap->pm_stats.resident_count += size >> PAGE_SHIFT; + npdes = size >> PDRSHIFT; + for(i = 0; i < npdes; i++) { + PT_SET_VA(&pmap->pm_pdir[ptepindex], + ptepa | PG_U | PG_RW | PG_V | PG_PS, FALSE); + ptepa += NBPDR; + ptepindex += 1; + } + pmap_invalidate_all(pmap); +out: + PMAP_UNLOCK(pmap); + } +} + +void +pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len) +{ + int i, npages = round_page(len) >> PAGE_SHIFT; + for (i = 0; i < npages; i++) { + pt_entry_t *pte; + pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE)); + PT_SET_MA(va + i*PAGE_SIZE, *pte & ~(PG_RW|PG_M), FALSE); + PMAP_MARK_PRIV(xpmap_mtop(*pte)); + pmap_pte_release(pte); + } + PT_UPDATES_FLUSH(); +} + +void +pmap_map_readwrite(pmap_t pmap, vm_offset_t va, int len) +{ + int i, npages = round_page(len) >> PAGE_SHIFT; + for (i = 0; i < npages; i++) { + pt_entry_t *pte; + pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE)); + PMAP_MARK_UNPRIV(xpmap_mtop(*pte)); + PT_SET_MA(va + i*PAGE_SIZE, *pte | (PG_RW|PG_M), FALSE); + pmap_pte_release(pte); + } + PT_UPDATES_FLUSH(); +} + +/* + * Routine: pmap_change_wiring + * Function: Change the wiring attribute for a map/virtual-address + * pair. + * In/out conditions: + * The mapping must already exist in the pmap. + */ +void +pmap_change_wiring(pmap, va, wired) + register pmap_t pmap; + vm_offset_t va; + boolean_t wired; +{ + register pt_entry_t *pte; + + PMAP_LOCK(pmap); + pte = pmap_pte(pmap, va); + + if (wired && !pmap_pte_w(pte)) + pmap->pm_stats.wired_count++; + else if (!wired && pmap_pte_w(pte)) + pmap->pm_stats.wired_count--; + + /* + * Wiring is not a hardware characteristic so there is no need to + * invalidate TLB. + */ + pmap_pte_set_w(pte, wired); + pmap_pte_release(pte); + PMAP_UNLOCK(pmap); +} + + + +/* + * Copy the range specified by src_addr/len + * from the source map to the range dst_addr/len + * in the destination map. + * + * This routine is only advisory and need not do anything. + */ + +void +pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, + vm_offset_t src_addr) +{ + vm_offset_t addr; + vm_offset_t end_addr = src_addr + len; + vm_offset_t pdnxt; + vm_page_t m; + + if (dst_addr != src_addr) + return; + + if (!pmap_is_current(src_pmap)) + return; + + vm_page_lock_queues(); + if (dst_pmap < src_pmap) { + PMAP_LOCK(dst_pmap); + PMAP_LOCK(src_pmap); + } else { + PMAP_LOCK(src_pmap); + PMAP_LOCK(dst_pmap); + } + sched_pin(); + for (addr = src_addr; addr < end_addr; addr = pdnxt) { + pt_entry_t *src_pte, *dst_pte; + vm_page_t dstmpte, srcmpte; + pd_entry_t srcptepaddr; + unsigned ptepindex; + + if (addr >= UPT_MIN_ADDRESS) + panic("pmap_copy: invalid to pmap_copy page tables"); + + /* + * Don't let optional prefaulting of pages make us go + * way below the low water mark of free pages or way + * above high water mark of used pv entries. + */ + if (cnt.v_free_count < cnt.v_free_reserved || + pv_entry_count > pv_entry_high_water) + break; + + pdnxt = (addr + NBPDR) & ~PDRMASK; + ptepindex = addr >> PDRSHIFT; + + srcptepaddr = PT_GET(&src_pmap->pm_pdir[ptepindex]); + if (srcptepaddr == 0) + continue; + + if (srcptepaddr & PG_PS) { + if (dst_pmap->pm_pdir[ptepindex] == 0) { + PT_SET_VA(&dst_pmap->pm_pdir[ptepindex], srcptepaddr, TRUE); + dst_pmap->pm_stats.resident_count += + NBPDR / PAGE_SIZE; + } + continue; + } + + srcmpte = PHYS_TO_VM_PAGE(srcptepaddr); + if (srcmpte->wire_count == 0) + panic("pmap_copy: source page table page is unused"); + + if (pdnxt > end_addr) + pdnxt = end_addr; + + src_pte = vtopte(addr); + while (addr < pdnxt) { + pt_entry_t ptetemp; + ptetemp = PT_GET(src_pte); + /* + * we only virtual copy managed pages + */ + if ((ptetemp & PG_MANAGED) != 0) { + /* + * We have to check after allocpte for the + * pte still being around... allocpte can + * block. + */ + dstmpte = pmap_allocpte(dst_pmap, addr, + M_NOWAIT); + if (dstmpte == NULL) + break; + dst_pte = pmap_pte_quick(dst_pmap, addr); + if (*dst_pte == 0) { + /* + * Clear the modified and + * accessed (referenced) bits + * during the copy. + */ + m = PHYS_TO_VM_PAGE(ptetemp); + PT_SET_VA(dst_pte, ptetemp & ~(PG_M | PG_A), FALSE); + dst_pmap->pm_stats.resident_count++; + pmap_insert_entry(dst_pmap, addr, m); + } else + pmap_unwire_pte_hold(dst_pmap, dstmpte); + if (dstmpte->wire_count >= srcmpte->wire_count) + break; + } + addr += PAGE_SIZE; + src_pte++; + } + } + PT_UPDATES_FLUSH(); + sched_unpin(); + vm_page_unlock_queues(); + PMAP_UNLOCK(src_pmap); + PMAP_UNLOCK(dst_pmap); +} + +static __inline void +pagezero(void *page) +{ +#if defined(I686_CPU) + if (cpu_class == CPUCLASS_686) { +#if defined(CPU_ENABLE_SSE) + if (cpu_feature & CPUID_SSE2) + sse2_pagezero(page); + else +#endif + i686_pagezero(page); + } else +#endif + bzero(page, PAGE_SIZE); +} + +/* + * pmap_zero_page zeros the specified hardware page by mapping + * the page into KVM and using bzero to clear its contents. + */ +void +pmap_zero_page(vm_page_t m) +{ + + mtx_lock(&CMAPCADDR12_lock); + if (*CMAP2) + panic("pmap_zero_page: CMAP2 busy"); + sched_pin(); + PT_SET_VA(CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, FALSE); + invlcaddr(CADDR2); + pagezero(CADDR2); + PT_CLEAR_VA(CMAP2, TRUE); + sched_unpin(); + mtx_unlock(&CMAPCADDR12_lock); +} + +/* + * pmap_zero_page_area zeros the specified hardware page by mapping + * the page into KVM and using bzero to clear its contents. + * + * off and size may not cover an area beyond a single hardware page. + */ +void +pmap_zero_page_area(vm_page_t m, int off, int size) +{ + + mtx_lock(&CMAPCADDR12_lock); + if (*CMAP2) + panic("pmap_zero_page: CMAP2 busy"); + sched_pin(); + PT_SET_VA(CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, FALSE); + invlcaddr(CADDR2); + if (off == 0 && size == PAGE_SIZE) + pagezero(CADDR2); + else + bzero((char *)CADDR2 + off, size); + PT_CLEAR_VA(CMAP2, TRUE); + sched_unpin(); + mtx_unlock(&CMAPCADDR12_lock); +} + +/* + * pmap_zero_page_idle zeros the specified hardware page by mapping + * the page into KVM and using bzero to clear its contents. This + * is intended to be called from the vm_pagezero process only and + * outside of Giant. + */ +void +pmap_zero_page_idle(vm_page_t m) +{ + + if (*CMAP3) + panic("pmap_zero_page: CMAP3 busy"); + sched_pin(); + PT_SET_VA(CMAP3, PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, TRUE); + invlcaddr(CADDR3); + pagezero(CADDR3); + PT_CLEAR_VA(CMAP3, TRUE); + sched_unpin(); +} + +/* + * pmap_copy_page copies the specified (machine independent) + * page by mapping the page into virtual memory and using + * bcopy to copy the page, one machine dependent page at a + * time. + */ +void +pmap_copy_page(vm_page_t src, vm_page_t dst) +{ + + mtx_lock(&CMAPCADDR12_lock); + if (*CMAP1) + panic("pmap_copy_page: CMAP1 busy"); + if (*CMAP2) + panic("pmap_copy_page: CMAP2 busy"); + sched_pin(); +#ifdef I386_CPU + invltlb(); +#else + invlpg((u_int)CADDR1); + invlpg((u_int)CADDR2); +#endif + PT_SET_VA(CMAP1, PG_V | VM_PAGE_TO_PHYS(src) | PG_A, FALSE); + PT_SET_VA(CMAP2, PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M, TRUE); + + bcopy(CADDR1, CADDR2, PAGE_SIZE); + PT_CLEAR_VA(CMAP1, FALSE); + PT_CLEAR_VA(CMAP2, TRUE); + sched_unpin(); + mtx_unlock(&CMAPCADDR12_lock); +} + +/* + * Returns true if the pmap's pv is one of the first + * 16 pvs linked to from this page. This count may + * be changed upwards or downwards in the future; it + * is only necessary that true be returned for a small + * subset of pmaps for proper page aging. + */ +boolean_t +pmap_page_exists_quick(pmap, m) + pmap_t pmap; + vm_page_t m; +{ + pv_entry_t pv; + int loops = 0; + + if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) + return FALSE; + + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + if (pv->pv_pmap == pmap) { + return TRUE; + } + loops++; + if (loops >= 16) + break; + } + return (FALSE); +} + +#define PMAP_REMOVE_PAGES_CURPROC_ONLY +/* + * Remove all pages from specified address space + * this aids process exit speeds. Also, this code + * is special cased for current process only, but + * can have the more generic (and slightly slower) + * mode enabled. This is much faster than pmap_remove + * in the case of running down an entire address space. + */ +void +pmap_remove_pages(pmap, sva, eva) + pmap_t pmap; + vm_offset_t sva, eva; +{ + pt_entry_t *pte, tpte; + vm_page_t m; + pv_entry_t pv, npv; + +#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY + if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) { + printf("warning: pmap_remove_pages called with non-current pmap\n"); + return; + } +#endif + vm_page_lock_queues(); + PMAP_LOCK(pmap); + sched_pin(); + + for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) { + if (pv->pv_va >= eva || pv->pv_va < sva) { + npv = TAILQ_NEXT(pv, pv_plist); + continue; + } + +#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY + pte = vtopte(pv->pv_va); +#else + pte = pmap_pte_quick(pmap, pv->pv_va); +#endif + tpte = PT_GET(pte); + + if (tpte == 0) { + printf("TPTE at %p IS ZERO @ VA %08x\n", + pte, pv->pv_va); + panic("bad pte"); + } + +/* + * We cannot remove wired pages from a process' mapping at this time + */ + if (tpte & PG_W) { + npv = TAILQ_NEXT(pv, pv_plist); + continue; + } + + m = PHYS_TO_VM_PAGE(tpte); + KASSERT(m->phys_addr == (tpte & PG_FRAME), + ("vm_page_t %p phys_addr mismatch %016jx %016jx", + m, (uintmax_t)m->phys_addr, (uintmax_t)tpte)); + + KASSERT(m < &vm_page_array[vm_page_array_size], + ("pmap_remove_pages: bad tpte %#jx", (uintmax_t)tpte)); + + pmap->pm_stats.resident_count--; + + pte_clear(pte); + + /* + * Update the vm_page_t clean and reference bits. + */ + if (tpte & PG_M) { + vm_page_dirty(m); + } + + npv = TAILQ_NEXT(pv, pv_plist); + TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist); + + m->md.pv_list_count--; + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + if (TAILQ_EMPTY(&m->md.pv_list)) + vm_page_flag_clear(m, PG_WRITEABLE); + + pmap_unuse_pt(pmap, pv->pv_va); + free_pv_entry(pv); + } + sched_unpin(); + pmap_invalidate_all(pmap); + PMAP_UNLOCK(pmap); + vm_page_unlock_queues(); +} + +/* + * pmap_is_modified: + * + * Return whether or not the specified physical page was modified + * in any physical maps. + */ +boolean_t +pmap_is_modified(vm_page_t m) +{ + pv_entry_t pv; + pt_entry_t *pte; + boolean_t rv; + + rv = FALSE; + if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) + return (rv); + + sched_pin(); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + /* + * if the bit being tested is the modified bit, then + * mark clean_map and ptes as never + * modified. + */ + if (!pmap_track_modified(pv->pv_va)) + continue; +#if defined(PMAP_DIAGNOSTIC) + if (!pv->pv_pmap) { + printf("Null pmap (tb) at va: 0x%x\n", pv->pv_va); + continue; + } +#endif + PMAP_LOCK(pv->pv_pmap); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); + rv = (*pte & PG_M) != 0; + PMAP_UNLOCK(pv->pv_pmap); + if (rv) + break; + } + sched_unpin(); + return (rv); +} + +/* + * pmap_is_prefaultable: + * + * Return whether or not the specified virtual address is elgible + * for prefault. + */ +boolean_t +pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr) +{ + pt_entry_t *pte; + boolean_t rv; + + rv = FALSE; + + return (rv); + PMAP_LOCK(pmap); + if (pmap_pde(pmap, addr)) { + pte = vtopte(addr); + rv = *pte == 0; + } + PMAP_UNLOCK(pmap); + return (rv); +} + +/* + * Clear the given bit in each of the given page's ptes. The bit is + * expressed as a 32-bit mask. Consequently, if the pte is 64 bits in + * size, only a bit within the least significant 32 can be cleared. + */ +static __inline void +pmap_clear_ptes(vm_page_t m, int bit) +{ + register pv_entry_t pv; + pt_entry_t pbits, *pte; + + if (!pmap_initialized || (m->flags & PG_FICTITIOUS) || + (bit == PG_RW && (m->flags & PG_WRITEABLE) == 0)) + return; + + sched_pin(); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + /* + * Loop over all current mappings setting/clearing as appropos If + * setting RO do we need to clear the VAC? + */ + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + /* + * don't write protect pager mappings + */ + if (bit == PG_RW) { + if (!pmap_track_modified(pv->pv_va)) + continue; + } + +#if defined(PMAP_DIAGNOSTIC) + if (!pv->pv_pmap) { + printf("Null pmap (cb) at va: 0x%x\n", pv->pv_va); + continue; + } +#endif + + PMAP_LOCK(pv->pv_pmap); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); +#ifdef notyet +retry: +#endif + pbits = PT_GET(pte); + if (pbits & bit) { + if (bit == PG_RW) { + /* + * Regardless of whether a pte is 32 or 64 bits + * in size, PG_RW and PG_M are among the least + * significant 32 bits. + */ +#ifdef notyet + if (!atomic_cmpset_int((u_int *)pte, pbits, + pbits & ~(PG_RW | PG_M))) + goto retry; +#endif + PT_SET_VA(pte, pbits & ~(PG_M|PG_RW), TRUE); + + + if (pbits & PG_M) { + vm_page_dirty(m); + } + } else { +#ifdef notyet + atomic_clear_int((u_int *)pte, bit); +#endif + /* XXX */ + PT_SET_VA(pte, pbits & ~bit, TRUE); + } + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + } + PMAP_UNLOCK(pv->pv_pmap); + } + if (bit == PG_RW) + vm_page_flag_clear(m, PG_WRITEABLE); + sched_unpin(); +} + +/* + * pmap_page_protect: + * + * Lower the permission for all mappings to a given page. + */ +void +pmap_page_protect(vm_page_t m, vm_prot_t prot) +{ + if ((prot & VM_PROT_WRITE) == 0) { + if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { + pmap_clear_ptes(m, PG_RW); + } else { + pmap_remove_all(m); + } + } +} + +/* + * pmap_ts_referenced: + * + * Return a count of reference bits for a page, clearing those bits. + * It is not necessary for every reference bit to be cleared, but it + * is necessary that 0 only be returned when there are truly no + * reference bits set. + * + * XXX: The exact number of bits to check and clear is a matter that + * should be tested and standardized at some point in the future for + * optimal aging of shared pages. + */ +int +pmap_ts_referenced(vm_page_t m) +{ + register pv_entry_t pv, pvf, pvn; + pt_entry_t *pte; + pt_entry_t v; + int rtval = 0; + + if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) + return (rtval); + + sched_pin(); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { + + pvf = pv; + + do { + pvn = TAILQ_NEXT(pv, pv_list); + + TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); + + TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list); + + if (!pmap_track_modified(pv->pv_va)) + continue; + + PMAP_LOCK(pv->pv_pmap); + pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va); + + if (pte && ((v = PT_GET(pte)) & PG_A) != 0) { +#ifdef notyet + atomic_clear_int((u_int *)pte, PG_A); +#endif + PT_SET_VA(pte, v & ~PG_A, FALSE); + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + + rtval++; + if (rtval > 4) { + PMAP_UNLOCK(pv->pv_pmap); + break; + } + } + PMAP_UNLOCK(pv->pv_pmap); + } while ((pv = pvn) != NULL && pv != pvf); + } + sched_unpin(); + + return (rtval); +} + +/* + * Clear the modify bits on the specified physical page. + */ +void +pmap_clear_modify(vm_page_t m) +{ + pmap_clear_ptes(m, PG_M); +} + +/* + * pmap_clear_reference: + * + * Clear the reference bit on the specified physical page. + */ +void +pmap_clear_reference(vm_page_t m) +{ + pmap_clear_ptes(m, PG_A); +} + +/* + * Miscellaneous support routines follow + */ + +/* + * Map a set of physical memory pages into the kernel virtual + * address space. Return a pointer to where it is mapped. This + * routine is intended to be used for mapping device memory, + * NOT real memory. + */ +void * +pmap_mapdev(pa, size) + vm_paddr_t pa; + vm_size_t size; +{ + vm_offset_t va, tmpva, offset; + + offset = pa & PAGE_MASK; + size = roundup(offset + size, PAGE_SIZE); + pa = pa & PG_FRAME; + + if (pa < KERNLOAD && pa + size <= KERNLOAD) + va = KERNBASE + pa; + else + va = kmem_alloc_nofault(kernel_map, size); + if (!va) + panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); + + for (tmpva = va; size > 0; ) { + PT_SET(tmpva, pa | PG_RW | PG_V | pgeflag, FALSE); + size -= PAGE_SIZE; + tmpva += PAGE_SIZE; + pa += PAGE_SIZE; + } + pmap_invalidate_range(kernel_pmap, va, tmpva); + return ((void *)(va + offset)); +} + +void +pmap_unmapdev(va, size) + vm_offset_t va; + vm_size_t size; +{ + vm_offset_t base, offset, tmpva; + panic("unused"); + if (va >= KERNBASE && va + size <= KERNBASE + KERNLOAD) + return; + base = va & PG_FRAME; + offset = va & PAGE_MASK; + size = roundup(offset + size, PAGE_SIZE); + for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) + PT_CLEAR(tmpva, FALSE); + pmap_invalidate_range(kernel_pmap, va, tmpva); + kmem_free(kernel_map, base, size); +} + +/* + * perform the pmap work for mincore + */ +int +pmap_mincore(pmap, addr) + pmap_t pmap; + vm_offset_t addr; +{ + pt_entry_t *ptep, pte; + vm_page_t m; + int val = 0; + + PMAP_LOCK(pmap); + ptep = pmap_pte(pmap, addr); + pte = (ptep != NULL) ? PT_GET(ptep) : 0; + pmap_pte_release(ptep); + PMAP_UNLOCK(pmap); + + if (pte != 0) { + vm_paddr_t pa; + + val = MINCORE_INCORE; + if ((pte & PG_MANAGED) == 0) + return val; + + pa = pte & PG_FRAME; + + m = PHYS_TO_VM_PAGE(pa); + + /* + * Modified by us + */ + if (pte & PG_M) + val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER; + else { + /* + * Modified by someone else + */ + vm_page_lock_queues(); + if (m->dirty || pmap_is_modified(m)) + val |= MINCORE_MODIFIED_OTHER; + vm_page_unlock_queues(); + } + /* + * Referenced by us + */ + if (pte & PG_A) + val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER; + else { + /* + * Referenced by someone else + */ + vm_page_lock_queues(); + if ((m->flags & PG_REFERENCED) || + pmap_ts_referenced(m)) { + val |= MINCORE_REFERENCED_OTHER; + vm_page_flag_set(m, PG_REFERENCED); + } + vm_page_unlock_queues(); + } + } + return val; +} + +void +pmap_activate(struct thread *td) +{ + struct proc *p = td->td_proc; + pmap_t pmap, oldpmap; + u_int32_t cr3; + + critical_enter(); + pmap = vmspace_pmap(td->td_proc->p_vmspace); + oldpmap = PCPU_GET(curpmap); +#if defined(SMP) + atomic_clear_int(&oldpmap->pm_active, PCPU_GET(cpumask)); + atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask)); +#else + oldpmap->pm_active &= ~1; + pmap->pm_active |= 1; +#endif +#ifdef PAE + cr3 = vtophys(pmap->pm_pdpt); +#else + cr3 = vtophys(pmap->pm_pdir); +#endif + /* XXXKSE this is wrong. + * pmap_activate is for the current thread on the current cpu + */ + if (p->p_flag & P_SA) { + /* Make sure all other cr3 entries are updated. */ + /* what if they are running? XXXKSE (maybe abort them) */ + FOREACH_THREAD_IN_PROC(p, td) { + td->td_pcb->pcb_cr3 = cr3; + } + } else { + td->td_pcb->pcb_cr3 = cr3; + } + load_cr3(cr3); + PCPU_SET(curpmap, pmap); + critical_exit(); +} + +vm_offset_t +pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) +{ + + if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) { + return addr; + } + + addr = (addr + PDRMASK) & ~PDRMASK; + return addr; +} + + +#if defined(PMAP_DEBUG) +extern int init_first; +void +pmap_ref(pt_entry_t *pte, unsigned long ma) +{ + int ind, i, count; + unsigned long ebp_prev, eip_prev, oma = 0; + unsigned long pa = xpmap_mtop(ma); + + /* are we to the point where mappings are set up? */ + if (!init_first) + return; + + ind = pa >> PAGE_SHIFT; + /* privileged? */ + if ((pa & PG_RW) && pteinfo_list[ind].pt_ref & (1 << 31)) + BKPT; + + /* is MA already mapped ? */ + oma = *pte; + + /* old reference being lost */ + if (oma && (oma & PG_RW) && ((oma & PG_FRAME) != (ma & PG_FRAME))) + pmap_dec_ref(oma); + + /* ignore RO mappings - unless were downgrading */ + if (!(ma & PG_RW)) { + /* downgrading mapping - lose reference */ + if (((oma & PG_FRAME) == (ma & PG_FRAME)) && + (oma & PG_RW)) + pmap_dec_ref(ma); + return; + } + + if (pteinfo_list[ind].pt_ref < 0) + BKPT; + + + /* same address and not upgrading the mapping */ + if (((oma & PG_FRAME) == (ma & PG_FRAME)) && + (oma & PG_RW)) + return; + + count = pteinfo_list[ind].pt_ref; + __asm__("movl %%ebp, %0" : "=r" (ebp_prev)); + for (i = 0; i < XPQ_CALL_DEPTH && ebp_prev > KERNBASE; i++) { + __asm__("movl 4(%1), %0" : "=r" (eip_prev) : "r" (ebp_prev)); + pteinfo_list[ind].pt_eip[count%XPQ_CALL_COUNT][i] = eip_prev; + __asm__("movl (%1), %0" : "=r" (ebp_prev) : "r" (ebp_prev)); + } + + pteinfo_list[ind].pt_ref++; + +} + +void +pmap_dec_ref(unsigned long ma) +{ + unsigned long pa; + int ind, count; + + if (!ma) BKPT; + + pa = xpmap_mtop(ma); + + ind = pa >> PAGE_SHIFT; + if (pteinfo_list[ind].pt_ref & (1 << 31)) BKPT; + + count = pteinfo_list[ind].pt_ref & ~(1 << 31); + if (count < 1) { + printk("ma: %lx has ref count of 0\n", ma); + BKPT; + } + pteinfo_list[ind].pt_ref = (--count | (pteinfo_list[ind].pt_ref & (1 << 31))); + +} + +void +pmap_dec_ref_page(vm_page_t m) +{ + unsigned long *pt; + int i; + mtx_lock(&CMAPCADDR12_lock); + if (*CMAP2) + panic("pmap_zero_page: CMAP2 busy"); + sched_pin(); + PT_SET_VA(CMAP2, PG_V | VM_PAGE_TO_PHYS(m) | PG_A | PG_M, FALSE); + invlcaddr(CADDR2); + pt = (unsigned long *)CADDR2; + for (i = 0; i < 1024; i++) + if (pt[i] & PG_RW) + pmap_dec_ref(xpmap_ptom(pt[i])); + PT_CLEAR_VA(CMAP2, TRUE); + sched_unpin(); + mtx_unlock(&CMAPCADDR12_lock); +} + +void +pmap_mark_privileged(unsigned long pa) +{ + int ind = pa >> PAGE_SHIFT; + + if (pteinfo_list[ind].pt_ref & (1 << 31)) BKPT; + if ((pteinfo_list[ind].pt_ref & ~(1 << 31)) > 0) BKPT; + + pteinfo_list[ind].pt_ref |= (1 << 31); + +} + +void +pmap_mark_unprivileged(unsigned long pa) +{ + int ind = pa >> PAGE_SHIFT; + + if (pteinfo_list[ind].pt_ref != (1 << 31)) BKPT; + + pteinfo_list[ind].pt_ref &= ~(1 << 31); + +} + + +int +pmap_pid_dump(int pid) +{ + pmap_t pmap; + struct proc *p; + int npte = 0; + int index; + + sx_slock(&allproc_lock); + LIST_FOREACH(p, &allproc, p_list) { + if (p->p_pid != pid) + continue; + + if (p->p_vmspace) { + int i,j; + index = 0; + pmap = vmspace_pmap(p->p_vmspace); + for (i = 0; i < NPDEPTD; i++) { + pd_entry_t *pde; + pt_entry_t *pte; + vm_offset_t base = i << PDRSHIFT; + + pde = &pmap->pm_pdir[i]; + if (pde && pmap_pde_v(pde)) { + for (j = 0; j < NPTEPG; j++) { + vm_offset_t va = base + (j << PAGE_SHIFT); + if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) { + if (index) { + index = 0; + printf("\n"); + } + sx_sunlock(&allproc_lock); + return npte; + } + pte = pmap_pte(pmap, va); + if (pte && pmap_pte_v(pte)) { + pt_entry_t pa; + vm_page_t m; + pa = PT_GET(pte); + m = PHYS_TO_VM_PAGE(pa); + printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x", + va, pa, m->hold_count, m->wire_count, m->flags); + npte++; + index++; + if (index >= 2) { + index = 0; + printf("\n"); + } else { + printf(" "); + } + } + } + } + } + } + } + sx_sunlock(&allproc_lock); + return npte; +} +#endif /* PMAP_DEBUG */ + +#if defined(DEBUG) + +static void pads(pmap_t pm); +void pmap_pvdump(vm_offset_t pa); + +/* print address space of pmap*/ +static void +pads(pm) + pmap_t pm; +{ + int i, j; + vm_paddr_t va; + pt_entry_t *ptep; + + if (pm == kernel_pmap) + return; + for (i = 0; i < NPDEPTD; i++) + if (pm->pm_pdir[i]) + for (j = 0; j < NPTEPG; j++) { + va = (i << PDRSHIFT) + (j << PAGE_SHIFT); + if (pm == kernel_pmap && va < KERNBASE) + continue; + if (pm != kernel_pmap && va > UPT_MAX_ADDRESS) + continue; + ptep = pmap_pte(pm, va); + if (pmap_pte_v(ptep)) + printf("%x:%x ", va, *ptep); + }; + +} + +void +pmap_pvdump(pa) + vm_paddr_t pa; +{ + pv_entry_t pv; + vm_page_t m; + + printf("pa %x", pa); + m = PHYS_TO_VM_PAGE(pa); + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + printf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va); + pads(pv->pv_pmap); + } + printf(" "); +} +#endif diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/support.s b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/support.s new file mode 100644 index 0000000000..deb4a94859 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/support.s @@ -0,0 +1,1553 @@ +/*- + * Copyright (c) 1993 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/i386/support.s,v 1.100 2003/11/03 21:28:54 jhb Exp $ + */ + +#include "opt_npx.h" + +#include +#include +#include +#include +#include + +#include "assym.s" + +#define IDXSHIFT 10 + + .data + .globl bcopy_vector +bcopy_vector: + .long generic_bcopy + .globl bzero_vector +bzero_vector: + .long generic_bzero + .globl copyin_vector +copyin_vector: + .long generic_copyin + .globl copyout_vector +copyout_vector: + .long generic_copyout +#if defined(I586_CPU) && defined(DEV_NPX) +kernel_fpu_lock: + .byte 0xfe + .space 3 +#endif + ALIGN_DATA + .globl intrcnt, eintrcnt +intrcnt: + .space INTRCNT_COUNT * 4 +eintrcnt: + + .globl intrnames, eintrnames +intrnames: + .space INTRCNT_COUNT * (MAXCOMLEN + 1) +eintrnames: + + .text + +/* + * bcopy family + * void bzero(void *buf, u_int len) + */ + +ENTRY(bzero) + MEXITCOUNT + jmp *bzero_vector + +ENTRY(generic_bzero) + pushl %edi + movl 8(%esp),%edi + movl 12(%esp),%ecx + xorl %eax,%eax + shrl $2,%ecx + cld + rep + stosl + movl 12(%esp),%ecx + andl $3,%ecx + rep + stosb + popl %edi + ret + +#ifdef I486_CPU +ENTRY(i486_bzero) + movl 4(%esp),%edx + movl 8(%esp),%ecx + xorl %eax,%eax +/* + * do 64 byte chunks first + * + * XXX this is probably over-unrolled at least for DX2's + */ +2: + cmpl $64,%ecx + jb 3f + movl %eax,(%edx) + movl %eax,4(%edx) + movl %eax,8(%edx) + movl %eax,12(%edx) + movl %eax,16(%edx) + movl %eax,20(%edx) + movl %eax,24(%edx) + movl %eax,28(%edx) + movl %eax,32(%edx) + movl %eax,36(%edx) + movl %eax,40(%edx) + movl %eax,44(%edx) + movl %eax,48(%edx) + movl %eax,52(%edx) + movl %eax,56(%edx) + movl %eax,60(%edx) + addl $64,%edx + subl $64,%ecx + jnz 2b + ret + +/* + * do 16 byte chunks + */ + SUPERALIGN_TEXT +3: + cmpl $16,%ecx + jb 4f + movl %eax,(%edx) + movl %eax,4(%edx) + movl %eax,8(%edx) + movl %eax,12(%edx) + addl $16,%edx + subl $16,%ecx + jnz 3b + ret + +/* + * do 4 byte chunks + */ + SUPERALIGN_TEXT +4: + cmpl $4,%ecx + jb 5f + movl %eax,(%edx) + addl $4,%edx + subl $4,%ecx + jnz 4b + ret + +/* + * do 1 byte chunks + * a jump table seems to be faster than a loop or more range reductions + * + * XXX need a const section for non-text + */ + .data +jtab: + .long do0 + .long do1 + .long do2 + .long do3 + + .text + SUPERALIGN_TEXT +5: + jmp *jtab(,%ecx,4) + + SUPERALIGN_TEXT +do3: + movw %ax,(%edx) + movb %al,2(%edx) + ret + + SUPERALIGN_TEXT +do2: + movw %ax,(%edx) + ret + + SUPERALIGN_TEXT +do1: + movb %al,(%edx) + ret + + SUPERALIGN_TEXT +do0: + ret +#endif + +#if defined(I586_CPU) && defined(DEV_NPX) +ENTRY(i586_bzero) + movl 4(%esp),%edx + movl 8(%esp),%ecx + + /* + * The FPU register method is twice as fast as the integer register + * method unless the target is in the L1 cache and we pre-allocate a + * cache line for it (then the integer register method is 4-5 times + * faster). However, we never pre-allocate cache lines, since that + * would make the integer method 25% or more slower for the common + * case when the target isn't in either the L1 cache or the L2 cache. + * Thus we normally use the FPU register method unless the overhead + * would be too large. + */ + cmpl $256,%ecx /* empirical; clts, fninit, smsw cost a lot */ + jb intreg_i586_bzero + + /* + * The FPU registers may belong to an application or to fastmove() + * or to another invocation of bcopy() or ourself in a higher level + * interrupt or trap handler. Preserving the registers is + * complicated since we avoid it if possible at all levels. We + * want to localize the complications even when that increases them. + * Here the extra work involves preserving CR0_TS in TS. + * `fpcurthread != NULL' is supposed to be the condition that all the + * FPU resources belong to an application, but fpcurthread and CR0_TS + * aren't set atomically enough for this condition to work in + * interrupt handlers. + * + * Case 1: FPU registers belong to the application: we must preserve + * the registers if we use them, so we only use the FPU register + * method if the target size is large enough to amortize the extra + * overhead for preserving them. CR0_TS must be preserved although + * it is very likely to end up as set. + * + * Case 2: FPU registers belong to fastmove(): fastmove() currently + * makes the registers look like they belong to an application so + * that cpu_switch() and savectx() don't have to know about it, so + * this case reduces to case 1. + * + * Case 3: FPU registers belong to the kernel: don't use the FPU + * register method. This case is unlikely, and supporting it would + * be more complicated and might take too much stack. + * + * Case 4: FPU registers don't belong to anyone: the FPU registers + * don't need to be preserved, so we always use the FPU register + * method. CR0_TS must be preserved although it is very likely to + * always end up as clear. + */ + cmpl $0,PCPU(FPCURTHREAD) + je i586_bz1 + + /* + * XXX don't use the FPU for cases 1 and 2, since preemptive + * scheduling of ithreads broke these cases. Note that we can + * no longer get here from an interrupt handler, since the + * context sitch to the interrupt handler will have saved the + * FPU state. + */ + jmp intreg_i586_bzero + + cmpl $256+184,%ecx /* empirical; not quite 2*108 more */ + jb intreg_i586_bzero + sarb $1,kernel_fpu_lock + jc intreg_i586_bzero + smsw %ax + clts + subl $108,%esp + fnsave 0(%esp) + jmp i586_bz2 + +i586_bz1: + sarb $1,kernel_fpu_lock + jc intreg_i586_bzero + smsw %ax + clts + fninit /* XXX should avoid needing this */ +i586_bz2: + fldz + + /* + * Align to an 8 byte boundary (misalignment in the main loop would + * cost a factor of >= 2). Avoid jumps (at little cost if it is + * already aligned) by always zeroing 8 bytes and using the part up + * to the _next_ alignment position. + */ + fstl 0(%edx) + addl %edx,%ecx /* part of %ecx -= new_%edx - %edx */ + addl $8,%edx + andl $~7,%edx + subl %edx,%ecx + + /* + * Similarly align `len' to a multiple of 8. + */ + fstl -8(%edx,%ecx) + decl %ecx + andl $~7,%ecx + + /* + * This wouldn't be any faster if it were unrolled, since the loop + * control instructions are much faster than the fstl and/or done + * in parallel with it so their overhead is insignificant. + */ +fpureg_i586_bzero_loop: + fstl 0(%edx) + addl $8,%edx + subl $8,%ecx + cmpl $8,%ecx + jae fpureg_i586_bzero_loop + + cmpl $0,PCPU(FPCURTHREAD) + je i586_bz3 + + /* XXX check that the condition for cases 1-2 stayed false. */ +i586_bzero_oops: + int $3 + jmp i586_bzero_oops + + frstor 0(%esp) + addl $108,%esp + lmsw %ax + movb $0xfe,kernel_fpu_lock + ret + +i586_bz3: + fstp %st(0) + lmsw %ax + movb $0xfe,kernel_fpu_lock + ret + +intreg_i586_bzero: + /* + * `rep stos' seems to be the best method in practice for small + * counts. Fancy methods usually take too long to start up due + * to cache and BTB misses. + */ + pushl %edi + movl %edx,%edi + xorl %eax,%eax + shrl $2,%ecx + cld + rep + stosl + movl 12(%esp),%ecx + andl $3,%ecx + jne 1f + popl %edi + ret + +1: + rep + stosb + popl %edi + ret +#endif /* I586_CPU && defined(DEV_NPX) */ + +ENTRY(sse2_pagezero) + pushl %ebx + movl 8(%esp),%ecx + movl %ecx,%eax + addl $4096,%eax + xor %ebx,%ebx +1: + movnti %ebx,(%ecx) + addl $4,%ecx + cmpl %ecx,%eax + jne 1b + sfence + popl %ebx + ret + +ENTRY(i686_pagezero) + pushl %edi + pushl %ebx + + movl 12(%esp), %edi + movl $1024, %ecx + cld + + ALIGN_TEXT +1: + xorl %eax, %eax + repe + scasl + jnz 2f + + popl %ebx + popl %edi + ret + + ALIGN_TEXT + +2: + incl %ecx + subl $4, %edi + + movl %ecx, %edx + cmpl $16, %ecx + + jge 3f + + movl %edi, %ebx + andl $0x3f, %ebx + shrl %ebx + shrl %ebx + movl $16, %ecx + subl %ebx, %ecx + +3: + subl %ecx, %edx + rep + stosl + + movl %edx, %ecx + testl %edx, %edx + jnz 1b + + popl %ebx + popl %edi + ret + +/* fillw(pat, base, cnt) */ +ENTRY(fillw) + pushl %edi + movl 8(%esp),%eax + movl 12(%esp),%edi + movl 16(%esp),%ecx + cld + rep + stosw + popl %edi + ret + +ENTRY(bcopyb) + pushl %esi + pushl %edi + movl 12(%esp),%esi + movl 16(%esp),%edi + movl 20(%esp),%ecx + movl %edi,%eax + subl %esi,%eax + cmpl %ecx,%eax /* overlapping && src < dst? */ + jb 1f + cld /* nope, copy forwards */ + rep + movsb + popl %edi + popl %esi + ret + + ALIGN_TEXT +1: + addl %ecx,%edi /* copy backwards. */ + addl %ecx,%esi + decl %edi + decl %esi + std + rep + movsb + popl %edi + popl %esi + cld + ret + +ENTRY(bcopy) + MEXITCOUNT + jmp *bcopy_vector + +/* + * generic_bcopy(src, dst, cnt) + * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 + */ +ENTRY(generic_bcopy) + pushl %esi + pushl %edi + movl 12(%esp),%esi + movl 16(%esp),%edi + movl 20(%esp),%ecx + + movl %edi,%eax + subl %esi,%eax + cmpl %ecx,%eax /* overlapping && src < dst? */ + jb 1f + + shrl $2,%ecx /* copy by 32-bit words */ + cld /* nope, copy forwards */ + rep + movsl + movl 20(%esp),%ecx + andl $3,%ecx /* any bytes left? */ + rep + movsb + popl %edi + popl %esi + ret + + ALIGN_TEXT +1: + addl %ecx,%edi /* copy backwards */ + addl %ecx,%esi + decl %edi + decl %esi + andl $3,%ecx /* any fractional bytes? */ + std + rep + movsb + movl 20(%esp),%ecx /* copy remainder by 32-bit words */ + shrl $2,%ecx + subl $3,%esi + subl $3,%edi + rep + movsl + popl %edi + popl %esi + cld + ret + +#if defined(I586_CPU) && defined(DEV_NPX) +ENTRY(i586_bcopy) + pushl %esi + pushl %edi + movl 12(%esp),%esi + movl 16(%esp),%edi + movl 20(%esp),%ecx + + movl %edi,%eax + subl %esi,%eax + cmpl %ecx,%eax /* overlapping && src < dst? */ + jb 1f + + cmpl $1024,%ecx + jb small_i586_bcopy + + sarb $1,kernel_fpu_lock + jc small_i586_bcopy + cmpl $0,PCPU(FPCURTHREAD) + je i586_bc1 + + /* XXX turn off handling of cases 1-2, as above. */ + movb $0xfe,kernel_fpu_lock + jmp small_i586_bcopy + + smsw %dx + clts + subl $108,%esp + fnsave 0(%esp) + jmp 4f + +i586_bc1: + smsw %dx + clts + fninit /* XXX should avoid needing this */ + + ALIGN_TEXT +4: + pushl %ecx +#define DCACHE_SIZE 8192 + cmpl $(DCACHE_SIZE-512)/2,%ecx + jbe 2f + movl $(DCACHE_SIZE-512)/2,%ecx +2: + subl %ecx,0(%esp) + cmpl $256,%ecx + jb 5f /* XXX should prefetch if %ecx >= 32 */ + pushl %esi + pushl %ecx + ALIGN_TEXT +3: + movl 0(%esi),%eax + movl 32(%esi),%eax + movl 64(%esi),%eax + movl 96(%esi),%eax + movl 128(%esi),%eax + movl 160(%esi),%eax + movl 192(%esi),%eax + movl 224(%esi),%eax + addl $256,%esi + subl $256,%ecx + cmpl $256,%ecx + jae 3b + popl %ecx + popl %esi +5: + ALIGN_TEXT +large_i586_bcopy_loop: + fildq 0(%esi) + fildq 8(%esi) + fildq 16(%esi) + fildq 24(%esi) + fildq 32(%esi) + fildq 40(%esi) + fildq 48(%esi) + fildq 56(%esi) + fistpq 56(%edi) + fistpq 48(%edi) + fistpq 40(%edi) + fistpq 32(%edi) + fistpq 24(%edi) + fistpq 16(%edi) + fistpq 8(%edi) + fistpq 0(%edi) + addl $64,%esi + addl $64,%edi + subl $64,%ecx + cmpl $64,%ecx + jae large_i586_bcopy_loop + popl %eax + addl %eax,%ecx + cmpl $64,%ecx + jae 4b + + cmpl $0,PCPU(FPCURTHREAD) + je i586_bc2 + + /* XXX check that the condition for cases 1-2 stayed false. */ +i586_bcopy_oops: + int $3 + jmp i586_bcopy_oops + + frstor 0(%esp) + addl $108,%esp +i586_bc2: + lmsw %dx + movb $0xfe,kernel_fpu_lock + +/* + * This is a duplicate of the main part of generic_bcopy. See the comments + * there. Jumping into generic_bcopy would cost a whole 0-1 cycles and + * would mess up high resolution profiling. + */ + ALIGN_TEXT +small_i586_bcopy: + shrl $2,%ecx + cld + rep + movsl + movl 20(%esp),%ecx + andl $3,%ecx + rep + movsb + popl %edi + popl %esi + ret + + ALIGN_TEXT +1: + addl %ecx,%edi + addl %ecx,%esi + decl %edi + decl %esi + andl $3,%ecx + std + rep + movsb + movl 20(%esp),%ecx + shrl $2,%ecx + subl $3,%esi + subl $3,%edi + rep + movsl + popl %edi + popl %esi + cld + ret +#endif /* I586_CPU && defined(DEV_NPX) */ + +/* + * Note: memcpy does not support overlapping copies + */ +ENTRY(memcpy) + pushl %edi + pushl %esi + movl 12(%esp),%edi + movl 16(%esp),%esi + movl 20(%esp),%ecx + movl %edi,%eax + shrl $2,%ecx /* copy by 32-bit words */ + cld /* nope, copy forwards */ + rep + movsl + movl 20(%esp),%ecx + andl $3,%ecx /* any bytes left? */ + rep + movsb + popl %esi + popl %edi + ret + + +/*****************************************************************************/ +/* copyout and fubyte family */ +/*****************************************************************************/ +/* + * Access user memory from inside the kernel. These routines and possibly + * the math- and DOS emulators should be the only places that do this. + * + * We have to access the memory with user's permissions, so use a segment + * selector with RPL 3. For writes to user space we have to additionally + * check the PTE for write permission, because the 386 does not check + * write permissions when we are executing with EPL 0. The 486 does check + * this if the WP bit is set in CR0, so we can use a simpler version here. + * + * These routines set curpcb->onfault for the time they execute. When a + * protection violation occurs inside the functions, the trap handler + * returns to *curpcb->onfault instead of the function. + */ + +/* + * copyout(from_kernel, to_user, len) - MP SAFE (if not I386_CPU) + */ +ENTRY(copyout) + MEXITCOUNT + jmp *copyout_vector + +ENTRY(generic_copyout) + movl PCPU(CURPCB),%eax + movl $copyout_fault,PCB_ONFAULT(%eax) + pushl %esi + pushl %edi + pushl %ebx + movl 16(%esp),%esi + movl 20(%esp),%edi + movl 24(%esp),%ebx + testl %ebx,%ebx /* anything to do? */ + jz done_copyout + + /* + * Check explicitly for non-user addresses. If 486 write protection + * is being used, this check is essential because we are in kernel + * mode so the h/w does not provide any protection against writing + * kernel addresses. + */ + + /* + * First, prevent address wrapping. + */ + movl %edi,%eax + addl %ebx,%eax + jc copyout_fault +/* + * XXX STOP USING VM_MAXUSER_ADDRESS. + * It is an end address, not a max, so every time it is used correctly it + * looks like there is an off by one error, and of course it caused an off + * by one error in several places. + */ + cmpl $VM_MAXUSER_ADDRESS,%eax + ja copyout_fault + + /* bcopy(%esi, %edi, %ebx) */ + movl %ebx,%ecx + +#if defined(I586_CPU) && defined(DEV_NPX) + ALIGN_TEXT +slow_copyout: +#endif + shrl $2,%ecx + cld + rep + movsl + movb %bl,%cl + andb $3,%cl + rep + movsb + +done_copyout: + popl %ebx + popl %edi + popl %esi + xorl %eax,%eax + movl PCPU(CURPCB),%edx + movl %eax,PCB_ONFAULT(%edx) + ret + + ALIGN_TEXT +copyout_fault: + popl %ebx + popl %edi + popl %esi + movl PCPU(CURPCB),%edx + movl $0,PCB_ONFAULT(%edx) + movl $EFAULT,%eax + ret + +#if defined(I586_CPU) && defined(DEV_NPX) +ENTRY(i586_copyout) + /* + * Duplicated from generic_copyout. Could be done a bit better. + */ + movl PCPU(CURPCB),%eax + movl $copyout_fault,PCB_ONFAULT(%eax) + pushl %esi + pushl %edi + pushl %ebx + movl 16(%esp),%esi + movl 20(%esp),%edi + movl 24(%esp),%ebx + testl %ebx,%ebx /* anything to do? */ + jz done_copyout + + /* + * Check explicitly for non-user addresses. If 486 write protection + * is being used, this check is essential because we are in kernel + * mode so the h/w does not provide any protection against writing + * kernel addresses. + */ + + /* + * First, prevent address wrapping. + */ + movl %edi,%eax + addl %ebx,%eax + jc copyout_fault +/* + * XXX STOP USING VM_MAXUSER_ADDRESS. + * It is an end address, not a max, so every time it is used correctly it + * looks like there is an off by one error, and of course it caused an off + * by one error in several places. + */ + cmpl $VM_MAXUSER_ADDRESS,%eax + ja copyout_fault + + /* bcopy(%esi, %edi, %ebx) */ +3: + movl %ebx,%ecx + /* + * End of duplicated code. + */ + + cmpl $1024,%ecx + jb slow_copyout + + pushl %ecx + call fastmove + addl $4,%esp + jmp done_copyout +#endif /* I586_CPU && defined(DEV_NPX) */ + +/* + * copyin(from_user, to_kernel, len) - MP SAFE + */ +ENTRY(copyin) + MEXITCOUNT + jmp *copyin_vector + +ENTRY(generic_copyin) + movl PCPU(CURPCB),%eax + movl $copyin_fault,PCB_ONFAULT(%eax) + pushl %esi + pushl %edi + movl 12(%esp),%esi /* caddr_t from */ + movl 16(%esp),%edi /* caddr_t to */ + movl 20(%esp),%ecx /* size_t len */ + + /* + * make sure address is valid + */ + movl %esi,%edx + addl %ecx,%edx + jc copyin_fault + cmpl $VM_MAXUSER_ADDRESS,%edx + ja copyin_fault + +#if defined(I586_CPU) && defined(DEV_NPX) + ALIGN_TEXT +slow_copyin: +#endif + movb %cl,%al + shrl $2,%ecx /* copy longword-wise */ + cld + rep + movsl + movb %al,%cl + andb $3,%cl /* copy remaining bytes */ + rep + movsb + +#if defined(I586_CPU) && defined(DEV_NPX) + ALIGN_TEXT +done_copyin: +#endif + popl %edi + popl %esi + xorl %eax,%eax + movl PCPU(CURPCB),%edx + movl %eax,PCB_ONFAULT(%edx) + ret + + ALIGN_TEXT +copyin_fault: + popl %edi + popl %esi + movl PCPU(CURPCB),%edx + movl $0,PCB_ONFAULT(%edx) + movl $EFAULT,%eax + ret + +#if defined(I586_CPU) && defined(DEV_NPX) +ENTRY(i586_copyin) + /* + * Duplicated from generic_copyin. Could be done a bit better. + */ + movl PCPU(CURPCB),%eax + movl $copyin_fault,PCB_ONFAULT(%eax) + pushl %esi + pushl %edi + movl 12(%esp),%esi /* caddr_t from */ + movl 16(%esp),%edi /* caddr_t to */ + movl 20(%esp),%ecx /* size_t len */ + + /* + * make sure address is valid + */ + movl %esi,%edx + addl %ecx,%edx + jc copyin_fault + cmpl $VM_MAXUSER_ADDRESS,%edx + ja copyin_fault + /* + * End of duplicated code. + */ + + cmpl $1024,%ecx + jb slow_copyin + + pushl %ebx /* XXX prepare for fastmove_fault */ + pushl %ecx + call fastmove + addl $8,%esp + jmp done_copyin +#endif /* I586_CPU && defined(DEV_NPX) */ + +#if defined(I586_CPU) && defined(DEV_NPX) +/* fastmove(src, dst, len) + src in %esi + dst in %edi + len in %ecx XXX changed to on stack for profiling + uses %eax and %edx for tmp. storage + */ +/* XXX use ENTRY() to get profiling. fastmove() is actually a non-entry. */ +ENTRY(fastmove) + pushl %ebp + movl %esp,%ebp + subl $PCB_SAVEFPU_SIZE+3*4,%esp + + movl 8(%ebp),%ecx + cmpl $63,%ecx + jbe fastmove_tail + + testl $7,%esi /* check if src addr is multiple of 8 */ + jnz fastmove_tail + + testl $7,%edi /* check if dst addr is multiple of 8 */ + jnz fastmove_tail + + /* XXX grab FPU context atomically. */ + call ni_cli + +/* if (fpcurthread != NULL) { */ + cmpl $0,PCPU(FPCURTHREAD) + je 6f +/* fnsave(&curpcb->pcb_savefpu); */ + movl PCPU(CURPCB),%eax + fnsave PCB_SAVEFPU(%eax) +/* FPCURTHREAD = NULL; */ + movl $0,PCPU(FPCURTHREAD) +/* } */ +6: +/* now we own the FPU. */ + +/* + * The process' FP state is saved in the pcb, but if we get + * switched, the cpu_switch() will store our FP state in the + * pcb. It should be possible to avoid all the copying for + * this, e.g., by setting a flag to tell cpu_switch() to + * save the state somewhere else. + */ +/* tmp = curpcb->pcb_savefpu; */ + movl %ecx,-12(%ebp) + movl %esi,-8(%ebp) + movl %edi,-4(%ebp) + movl %esp,%edi + movl PCPU(CURPCB),%esi + addl $PCB_SAVEFPU,%esi + cld + movl $PCB_SAVEFPU_SIZE>>2,%ecx + rep + movsl + movl -12(%ebp),%ecx + movl -8(%ebp),%esi + movl -4(%ebp),%edi +/* stop_emulating(); */ + clts +/* fpcurthread = curthread; */ + movl PCPU(CURTHREAD),%eax + movl %eax,PCPU(FPCURTHREAD) + movl PCPU(CURPCB),%eax + + /* XXX end of atomic FPU context grab. */ + call ni_sti + + movl $fastmove_fault,PCB_ONFAULT(%eax) +4: + movl %ecx,-12(%ebp) + cmpl $1792,%ecx + jbe 2f + movl $1792,%ecx +2: + subl %ecx,-12(%ebp) + cmpl $256,%ecx + jb 5f + movl %ecx,-8(%ebp) + movl %esi,-4(%ebp) + ALIGN_TEXT +3: + movl 0(%esi),%eax + movl 32(%esi),%eax + movl 64(%esi),%eax + movl 96(%esi),%eax + movl 128(%esi),%eax + movl 160(%esi),%eax + movl 192(%esi),%eax + movl 224(%esi),%eax + addl $256,%esi + subl $256,%ecx + cmpl $256,%ecx + jae 3b + movl -8(%ebp),%ecx + movl -4(%ebp),%esi +5: + ALIGN_TEXT +fastmove_loop: + fildq 0(%esi) + fildq 8(%esi) + fildq 16(%esi) + fildq 24(%esi) + fildq 32(%esi) + fildq 40(%esi) + fildq 48(%esi) + fildq 56(%esi) + fistpq 56(%edi) + fistpq 48(%edi) + fistpq 40(%edi) + fistpq 32(%edi) + fistpq 24(%edi) + fistpq 16(%edi) + fistpq 8(%edi) + fistpq 0(%edi) + addl $-64,%ecx + addl $64,%esi + addl $64,%edi + cmpl $63,%ecx + ja fastmove_loop + movl -12(%ebp),%eax + addl %eax,%ecx + cmpl $64,%ecx + jae 4b + + /* XXX ungrab FPU context atomically. */ + call ni_cli + +/* curpcb->pcb_savefpu = tmp; */ + movl %ecx,-12(%ebp) + movl %esi,-8(%ebp) + movl %edi,-4(%ebp) + movl PCPU(CURPCB),%edi + addl $PCB_SAVEFPU,%edi + movl %esp,%esi + cld + movl $PCB_SAVEFPU_SIZE>>2,%ecx + rep + movsl + movl -12(%ebp),%ecx + movl -8(%ebp),%esi + movl -4(%ebp),%edi + +/* start_emulating(); */ + smsw %ax + orb $CR0_TS,%al + lmsw %ax +/* fpcurthread = NULL; */ + movl $0,PCPU(FPCURTHREAD) + + /* XXX end of atomic FPU context ungrab. */ + call ni_sti + + ALIGN_TEXT +fastmove_tail: + movl PCPU(CURPCB),%eax + movl $fastmove_tail_fault,PCB_ONFAULT(%eax) + + movb %cl,%al + shrl $2,%ecx /* copy longword-wise */ + cld + rep + movsl + movb %al,%cl + andb $3,%cl /* copy remaining bytes */ + rep + movsb + + movl %ebp,%esp + popl %ebp + ret + + ALIGN_TEXT +fastmove_fault: + /* XXX ungrab FPU context atomically. */ + call ni_cli + + movl PCPU(CURPCB),%edi + addl $PCB_SAVEFPU,%edi + movl %esp,%esi + cld + movl $PCB_SAVEFPU_SIZE>>2,%ecx + rep + movsl + + smsw %ax + orb $CR0_TS,%al + lmsw %ax + movl $0,PCPU(FPCURTHREAD) + + /* XXX end of atomic FPU context ungrab. */ + call ni_sti + +fastmove_tail_fault: + movl %ebp,%esp + popl %ebp + addl $8,%esp + popl %ebx + popl %edi + popl %esi + movl PCPU(CURPCB),%edx + movl $0,PCB_ONFAULT(%edx) + movl $EFAULT,%eax + ret +#endif /* I586_CPU && defined(DEV_NPX) */ + +/* + * casuptr. Compare and set user pointer. Returns -1 or the current value. + */ +ENTRY(casuptr) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx /* dst */ + movl 8(%esp),%eax /* old */ + movl 12(%esp),%ecx /* new */ + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ + ja fusufault + +#ifdef SMP + lock +#endif + cmpxchgl %ecx, (%edx) /* Compare and set. */ + + /* + * The old value is in %eax. If the store succeeded it will be the + * value we expected (old) from before the store, otherwise it will + * be the current value. + */ + + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl $0,PCB_ONFAULT(%ecx) + ret + +/* + * fu{byte,sword,word} - MP SAFE + * + * Fetch a byte (sword, word) from user memory + */ +ENTRY(fuword) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx /* from */ + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address is valid */ + ja fusufault + + movl (%edx),%eax + movl $0,PCB_ONFAULT(%ecx) + ret + +ENTRY(fuword32) + jmp fuword + +/* + * These two routines are called from the profiling code, potentially + * at interrupt time. If they fail, that's okay, good things will + * happen later. Fail all the time for now - until the trap code is + * able to deal with this. + */ +ALTENTRY(suswintr) +ENTRY(fuswintr) + movl $-1,%eax + ret + +/* + * fuword16 - MP SAFE + */ +ENTRY(fuword16) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx + + cmpl $VM_MAXUSER_ADDRESS-2,%edx + ja fusufault + + movzwl (%edx),%eax + movl $0,PCB_ONFAULT(%ecx) + ret + +/* + * fubyte - MP SAFE + */ +ENTRY(fubyte) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx + + cmpl $VM_MAXUSER_ADDRESS-1,%edx + ja fusufault + + movzbl (%edx),%eax + movl $0,PCB_ONFAULT(%ecx) + ret + + ALIGN_TEXT +fusufault: + movl PCPU(CURPCB),%ecx + xorl %eax,%eax + movl %eax,PCB_ONFAULT(%ecx) + decl %eax + ret + +/* + * su{byte,sword,word} - MP SAFE (if not I386_CPU) + * + * Write a byte (word, longword) to user memory + */ +ENTRY(suword) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx + + cmpl $VM_MAXUSER_ADDRESS-4,%edx /* verify address validity */ + ja fusufault + + movl 8(%esp),%eax + movl %eax,(%edx) + xorl %eax,%eax + movl PCPU(CURPCB),%ecx + movl %eax,PCB_ONFAULT(%ecx) + ret + +ENTRY(suword32) + jmp suword + +/* + * suword16 - MP SAFE (if not I386_CPU) + */ +ENTRY(suword16) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx + + cmpl $VM_MAXUSER_ADDRESS-2,%edx /* verify address validity */ + ja fusufault + + movw 8(%esp),%ax + movw %ax,(%edx) + xorl %eax,%eax + movl PCPU(CURPCB),%ecx /* restore trashed register */ + movl %eax,PCB_ONFAULT(%ecx) + ret + +/* + * subyte - MP SAFE (if not I386_CPU) + */ +ENTRY(subyte) + movl PCPU(CURPCB),%ecx + movl $fusufault,PCB_ONFAULT(%ecx) + movl 4(%esp),%edx + + cmpl $VM_MAXUSER_ADDRESS-1,%edx /* verify address validity */ + ja fusufault + + movb 8(%esp),%al + movb %al,(%edx) + xorl %eax,%eax + movl PCPU(CURPCB),%ecx /* restore trashed register */ + movl %eax,PCB_ONFAULT(%ecx) + ret + +/* + * copyinstr(from, to, maxlen, int *lencopied) - MP SAFE + * + * copy a string from from to to, stop when a 0 character is reached. + * return ENAMETOOLONG if string is longer than maxlen, and + * EFAULT on protection violations. If lencopied is non-zero, + * return the actual length in *lencopied. + */ +ENTRY(copyinstr) + pushl %esi + pushl %edi + movl PCPU(CURPCB),%ecx + movl $cpystrflt,PCB_ONFAULT(%ecx) + + movl 12(%esp),%esi /* %esi = from */ + movl 16(%esp),%edi /* %edi = to */ + movl 20(%esp),%edx /* %edx = maxlen */ + + movl $VM_MAXUSER_ADDRESS,%eax + + /* make sure 'from' is within bounds */ + subl %esi,%eax + jbe cpystrflt + + /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */ + cmpl %edx,%eax + jae 1f + movl %eax,%edx + movl %eax,20(%esp) +1: + incl %edx + cld + +2: + decl %edx + jz 3f + + lodsb + stosb + orb %al,%al + jnz 2b + + /* Success -- 0 byte reached */ + decl %edx + xorl %eax,%eax + jmp cpystrflt_x +3: + /* edx is zero - return ENAMETOOLONG or EFAULT */ + cmpl $VM_MAXUSER_ADDRESS,%esi + jae cpystrflt +4: + movl $ENAMETOOLONG,%eax + jmp cpystrflt_x + +cpystrflt: + movl $EFAULT,%eax + +cpystrflt_x: + /* set *lencopied and return %eax */ + movl PCPU(CURPCB),%ecx + movl $0,PCB_ONFAULT(%ecx) + movl 20(%esp),%ecx + subl %edx,%ecx + movl 24(%esp),%edx + testl %edx,%edx + jz 1f + movl %ecx,(%edx) +1: + popl %edi + popl %esi + ret + + +/* + * copystr(from, to, maxlen, int *lencopied) - MP SAFE + */ +ENTRY(copystr) + pushl %esi + pushl %edi + + movl 12(%esp),%esi /* %esi = from */ + movl 16(%esp),%edi /* %edi = to */ + movl 20(%esp),%edx /* %edx = maxlen */ + incl %edx + cld +1: + decl %edx + jz 4f + lodsb + stosb + orb %al,%al + jnz 1b + + /* Success -- 0 byte reached */ + decl %edx + xorl %eax,%eax + jmp 6f +4: + /* edx is zero -- return ENAMETOOLONG */ + movl $ENAMETOOLONG,%eax + +6: + /* set *lencopied and return %eax */ + movl 20(%esp),%ecx + subl %edx,%ecx + movl 24(%esp),%edx + testl %edx,%edx + jz 7f + movl %ecx,(%edx) +7: + popl %edi + popl %esi + ret + +ENTRY(bcmp) + pushl %edi + pushl %esi + movl 12(%esp),%edi + movl 16(%esp),%esi + movl 20(%esp),%edx + xorl %eax,%eax + + movl %edx,%ecx + shrl $2,%ecx + cld /* compare forwards */ + repe + cmpsl + jne 1f + + movl %edx,%ecx + andl $3,%ecx + repe + cmpsb + je 2f +1: + incl %eax +2: + popl %esi + popl %edi + ret + + +/* + * Handling of special 386 registers and descriptor tables etc + */ +/* void lgdt(struct region_descriptor *rdp); */ +ENTRY(lgdt_finish) +#if 0 + /* reload the descriptor table */ + movl 4(%esp),%eax + lgdt (%eax) +#endif + /* flush the prefetch q */ + jmp 1f + nop +1: + /* reload "stale" selectors */ + movl $KDSEL,%eax + movl %eax,%ds + movl %eax,%es + movl %eax,%gs + movl %eax,%ss + movl $KPSEL,%eax + movl %eax,%fs + + /* reload code selector by turning return into intersegmental return */ + movl (%esp),%eax + pushl %eax + movl $KCSEL,4(%esp) + lret + +/* ssdtosd(*ssdp,*sdp) */ +ENTRY(ssdtosd) + pushl %ebx + movl 8(%esp),%ecx + movl 8(%ecx),%ebx + shll $16,%ebx + movl (%ecx),%edx + roll $16,%edx + movb %dh,%bl + movb %dl,%bh + rorl $8,%ebx + movl 4(%ecx),%eax + movw %ax,%dx + andl $0xf0000,%eax + orl %eax,%ebx + movl 12(%esp),%ecx + movl %edx,(%ecx) + movl %ebx,4(%ecx) + popl %ebx + ret + +/* void reset_dbregs() */ +ENTRY(reset_dbregs) + movl $0,%eax + movl %eax,%dr7 /* disable all breapoints first */ + movl %eax,%dr0 + movl %eax,%dr1 + movl %eax,%dr2 + movl %eax,%dr3 + movl %eax,%dr6 + ret + +/*****************************************************************************/ +/* setjump, longjump */ +/*****************************************************************************/ + +ENTRY(setjmp) + movl 4(%esp),%eax + movl %ebx,(%eax) /* save ebx */ + movl %esp,4(%eax) /* save esp */ + movl %ebp,8(%eax) /* save ebp */ + movl %esi,12(%eax) /* save esi */ + movl %edi,16(%eax) /* save edi */ + movl (%esp),%edx /* get rta */ + movl %edx,20(%eax) /* save eip */ + xorl %eax,%eax /* return(0); */ + ret + +ENTRY(longjmp) + movl 4(%esp),%eax + movl (%eax),%ebx /* restore ebx */ + movl 4(%eax),%esp /* restore esp */ + movl 8(%eax),%ebp /* restore ebp */ + movl 12(%eax),%esi /* restore esi */ + movl 16(%eax),%edi /* restore edi */ + movl 20(%eax),%edx /* get rta */ + movl %edx,(%esp) /* put in return frame */ + xorl %eax,%eax /* return(1); */ + incl %eax + ret + +/* + * Support for BB-profiling (gcc -a). The kernbb program will extract + * the data from the kernel. + */ + + .data + ALIGN_DATA + .globl bbhead +bbhead: + .long 0 + + .text +NON_GPROF_ENTRY(__bb_init_func) + movl 4(%esp),%eax + movl $1,(%eax) + movl bbhead,%edx + movl %edx,16(%eax) + movl %eax,bbhead + NON_GPROF_RET diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/swtch.s b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/swtch.s new file mode 100644 index 0000000000..f468c429bd --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/swtch.s @@ -0,0 +1,445 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/i386/swtch.s,v 1.143 2003/09/30 08:11:35 jeff Exp $ + */ + +#include "opt_npx.h" + +#include + +#include "assym.s" + + +/*****************************************************************************/ +/* Scheduling */ +/*****************************************************************************/ + + .text + +/* + * cpu_throw() + * + * This is the second half of cpu_swtch(). It is used when the current + * thread is either a dummy or slated to die, and we no longer care + * about its state. This is only a slight optimization and is probably + * not worth it anymore. Note that we need to clear the pm_active bits so + * we do need the old proc if it still exists. + * 0(%esp) = ret + * 4(%esp) = oldtd + * 8(%esp) = newtd + */ +ENTRY(cpu_throw) + movl PCPU(CPUID), %esi + movl 4(%esp),%ecx /* Old thread */ + testl %ecx,%ecx /* no thread? */ + jz 1f + /* release bit from old pm_active */ + movl PCPU(CURPMAP), %ebx +#ifdef SMP + lock +#endif + btrl %esi, PM_ACTIVE(%ebx) /* clear old */ +1: + movl 8(%esp),%ecx /* New thread */ + movl TD_PCB(%ecx),%edx + movl PCB_CR3(%edx),%eax + + movl %eax,PCPU(CR3) /* new address space */ + + pushl %ecx + pushl %edx + pushl %esi + pushl %eax + call load_cr3 + addl $4,%esp + popl %esi + popl %edx + popl %ecx + + /* set bit in new pm_active */ + movl TD_PROC(%ecx),%eax + movl P_VMSPACE(%eax), %ebx + addl $VM_PMAP, %ebx + movl %ebx, PCPU(CURPMAP) +#ifdef SMP + lock +#endif + btsl %esi, PM_ACTIVE(%ebx) /* set new */ + jmp sw1 + +/* + * cpu_switch(old, new) + * + * Save the current thread state, then select the next thread to run + * and load its state. + * 0(%esp) = ret + * 4(%esp) = oldtd + * 8(%esp) = newtd + */ +ENTRY(cpu_switch) + + /* Switch to new thread. First, save context. */ + movl 4(%esp),%ecx + +#ifdef INVARIANTS + testl %ecx,%ecx /* no thread? */ + jz badsw2 /* no, panic */ +#endif + + movl TD_PCB(%ecx),%edx + + movl (%esp),%eax /* Hardware registers */ + movl %eax,PCB_EIP(%edx) + movl %ebx,PCB_EBX(%edx) + movl %esp,PCB_ESP(%edx) + movl %ebp,PCB_EBP(%edx) + movl %esi,PCB_ESI(%edx) + movl %edi,PCB_EDI(%edx) + movl %gs,PCB_GS(%edx) +#if 0 + pushfl /* PSL */ + popl PCB_PSL(%edx) +#endif + /* Check to see if we need to call a switchout function. */ + movl PCB_SWITCHOUT(%edx),%eax + cmpl $0, %eax + je 1f + call *%eax +1: + /* Test if debug registers should be saved. */ + testl $PCB_DBREGS,PCB_FLAGS(%edx) + jz 1f /* no, skip over */ + movl %dr7,%eax /* yes, do the save */ + movl %eax,PCB_DR7(%edx) + andl $0x0000fc00, %eax /* disable all watchpoints */ + movl %eax,%dr7 + movl %dr6,%eax + movl %eax,PCB_DR6(%edx) + movl %dr3,%eax + movl %eax,PCB_DR3(%edx) + movl %dr2,%eax + movl %eax,PCB_DR2(%edx) + movl %dr1,%eax + movl %eax,PCB_DR1(%edx) + movl %dr0,%eax + movl %eax,PCB_DR0(%edx) +1: + +#ifdef DEV_NPX + /* have we used fp, and need a save? */ + cmpl %ecx,PCPU(FPCURTHREAD) + jne 1f + addl $PCB_SAVEFPU,%edx /* h/w bugs make saving complicated */ + pushl %edx + call npxsave /* do it in a big C function */ + popl %eax +1: +#endif + + + /* Save is done. Now fire up new thread. Leave old vmspace. */ + movl %ecx,%edi + movl 8(%esp),%ecx /* New thread */ +#ifdef INVARIANTS + testl %ecx,%ecx /* no thread? */ + jz badsw3 /* no, panic */ +#endif + movl TD_PCB(%ecx),%edx + movl PCPU(CPUID), %esi + + /* switch address space */ + movl PCB_CR3(%edx),%eax + + cmpl %eax,IdlePTD /* Kernel address space? */ + + je sw1 + /* XXX optimize later KMM */ +#if 0 + movl %cr3,%ebx /* The same address space? */ +#else + movl PCPU(CR3),%ebx +#endif + cmpl %ebx,%eax + je sw1 + + movl %eax,PCPU(CR3) /* new address space */ + + pushl %edx + pushl %ecx + pushl %esi + pushl %eax + call load_cr3 /* inform xen of the switch */ + addl $4,%esp + popl %esi + popl %ecx + popl %edx + + /* Release bit from old pmap->pm_active */ + movl PCPU(CURPMAP), %ebx + +#ifdef SMP + lock +#endif + btrl %esi, PM_ACTIVE(%ebx) /* clear old */ + /* Set bit in new pmap->pm_active */ + movl TD_PROC(%ecx),%eax /* newproc */ + movl P_VMSPACE(%eax), %ebx + addl $VM_PMAP, %ebx + movl %ebx, PCPU(CURPMAP) +#ifdef SMP + lock +#endif + btsl %esi, PM_ACTIVE(%ebx) /* set new */ +sw1: + +#if 0 + + /* only one task selector under Xen */ + /* + * At this point, we've switched address spaces and are ready + * to load up the rest of the next context. + */ + cmpl $0, PCB_EXT(%edx) /* has pcb extension? */ + je 1f /* If not, use the default */ + btsl %esi, private_tss /* mark use of private tss */ + movl PCB_EXT(%edx), %edi /* new tss descriptor */ + jmp 2f /* Load it up */ + +1: /* + * Use the common default TSS instead of our own. + * Set our stack pointer into the TSS, it's set to just + * below the PCB. In C, common_tss.tss_esp0 = &pcb - 16; + */ + leal -16(%edx), %ebx /* leave space for vm86 */ + movl %ebx, PCPU(COMMON_TSS) + TSS_ESP0 + + /* + * Test this CPU's bit in the bitmap to see if this + * CPU was using a private TSS. + */ + btrl %esi, private_tss /* Already using the common? */ + jae 3f /* if so, skip reloading */ + PCPU_ADDR(COMMON_TSSD, %edi) +2: + /* Move correct tss descriptor into GDT slot, then reload tr. */ + movl PCPU(TSS_GDT), %ebx /* entry in GDT */ + movl 0(%edi), %eax + movl %eax, 0(%ebx) + movl 4(%edi), %eax + movl %eax, 4(%ebx) + + movl $GPROC0_SEL*8, %esi /* GSEL(entry, SEL_KPL) */ + ltr %si +#endif /* !XEN */ +3: + /* notify Xen of task switch */ + pushl %edx /* &pcb is the new stack base */ + pushl $KDSEL + pushl $HYPERVISOR_STACK_SWITCH + call ni_queue_multicall2 + addl $12,%esp + /* XXX handle DOM0 IOPL case here (KMM) */ + /* we currently don't support running FreeBSD */ + /* in DOM0 so we can skip for now */ + + call ni_execute_multicall_list + + /* Restore context. */ + movl PCB_EBX(%edx),%ebx + movl PCB_ESP(%edx),%esp + movl PCB_EBP(%edx),%ebp + movl PCB_ESI(%edx),%esi + movl PCB_EDI(%edx),%edi + movl PCB_EIP(%edx),%eax + movl %eax,(%esp) +#if 0 + pushl PCB_PSL(%edx) + popfl +#endif + movl %edx, PCPU(CURPCB) + movl %ecx, PCPU(CURTHREAD) /* into next thread */ + + /* + * Determine the LDT to use and load it if is the default one and + * that is not the current one. + */ + movl TD_PROC(%ecx),%eax + cmpl $0,P_MD+MD_LDT(%eax) + jnz 1f + movl _default_ldt,%eax + cmpl PCPU(CURRENTLDT),%eax + je 2f + pushl %edx + pushl %eax + xorl %eax,%eax + movl %eax,%gs + call i386_reset_ldt + popl %eax + popl %edx + + movl %eax,PCPU(CURRENTLDT) + jmp 2f +1: + /* Load the LDT when it is not the default one. */ + pushl %edx /* Preserve pointer to pcb. */ + addl $P_MD,%eax /* Pointer to mdproc is arg. */ + pushl %eax + call set_user_ldt + addl $4,%esp + popl %edx +2: + /* This must be done after loading the user LDT. */ + .globl cpu_switch_load_gs +cpu_switch_load_gs: + movl PCB_GS(%edx),%gs + + /* XXX evidently setting debug registers needs to be + * routed through Xen - this appears to work - so I + * am leaving it as it is for now - (KMM) + */ + + /* Test if debug registers should be restored. */ + testl $PCB_DBREGS,PCB_FLAGS(%edx) + jz 1f + + /* + * Restore debug registers. The special code for dr7 is to + * preserve the current values of its reserved bits. + */ + movl PCB_DR6(%edx),%eax + movl %eax,%dr6 + movl PCB_DR3(%edx),%eax + movl %eax,%dr3 + movl PCB_DR2(%edx),%eax + movl %eax,%dr2 + movl PCB_DR1(%edx),%eax + movl %eax,%dr1 + movl PCB_DR0(%edx),%eax + movl %eax,%dr0 + movl %dr7,%eax + andl $0x0000fc00,%eax + movl PCB_DR7(%edx),%ecx + andl $~0x0000fc00,%ecx + orl %ecx,%eax + movl %eax,%dr7 +1: + ret + +#ifdef INVARIANTS +badsw1: + pushal + pushl $sw0_1 + call panic +sw0_1: .asciz "cpu_throw: no newthread supplied" + +badsw2: + pushal + pushl $sw0_2 + call panic +sw0_2: .asciz "cpu_switch: no curthread supplied" + +badsw3: + pushal + pushl $sw0_3 + call panic +sw0_3: .asciz "cpu_switch: no newthread supplied" +#endif + +/* + * savectx(pcb) + * Update pcb, saving current processor state. + */ +ENTRY(savectx) + /* Fetch PCB. */ + movl 4(%esp),%ecx + + /* Save caller's return address. Child won't execute this routine. */ + movl (%esp),%eax + movl %eax,PCB_EIP(%ecx) + +#if 0 + movl %cr3,%eax +#else + movl PCPU(CR3),%eax +#endif + movl %eax,PCB_CR3(%ecx) + + movl %ebx,PCB_EBX(%ecx) + movl %esp,PCB_ESP(%ecx) + movl %ebp,PCB_EBP(%ecx) + movl %esi,PCB_ESI(%ecx) + movl %edi,PCB_EDI(%ecx) + movl %gs,PCB_GS(%ecx) +#if 0 + pushfl + popl PCB_PSL(%ecx) +#endif +#ifdef DEV_NPX + /* + * If fpcurthread == NULL, then the npx h/w state is irrelevant and the + * state had better already be in the pcb. This is true for forks + * but not for dumps (the old book-keeping with FP flags in the pcb + * always lost for dumps because the dump pcb has 0 flags). + * + * If fpcurthread != NULL, then we have to save the npx h/w state to + * fpcurthread's pcb and copy it to the requested pcb, or save to the + * requested pcb and reload. Copying is easier because we would + * have to handle h/w bugs for reloading. We used to lose the + * parent's npx state for forks by forgetting to reload. + */ + pushfl + call ni_cli + movl PCPU(FPCURTHREAD),%eax + testl %eax,%eax + je 1f + + pushl %ecx + movl TD_PCB(%eax),%eax + leal PCB_SAVEFPU(%eax),%eax + pushl %eax + pushl %eax + call npxsave + addl $4,%esp + popl %eax + popl %ecx + + pushl $PCB_SAVEFPU_SIZE + leal PCB_SAVEFPU(%ecx),%ecx + pushl %ecx + pushl %eax + call bcopy + addl $12,%esp +1: + popfl +#endif /* DEV_NPX */ + + ret diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/symbols.raw b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/symbols.raw new file mode 100644 index 0000000000..014c6442ad --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/symbols.raw @@ -0,0 +1,75 @@ +# @(#)symbols.raw 7.6 (Berkeley) 5/8/91 +# +# $FreeBSD: src/sys/i386/i386/symbols.raw,v 1.15 1999/08/28 00:43:51 peter Exp $ +# + + +#gdb + _IdlePTD + _PTD + _panicstr + _atdevbase +# _version +#dmesg + _msgbufp +# _msgbuf +#iostat + _tk_nin + _tk_nout + _cp_time +# _io_info +#ps + _nswap + _maxslp + _ccpu + _fscale + _avail_start + _avail_end +#pstat +# _cons + _nswap + _swapblist +# _swaplist +#vmstat + _cp_time +# _rate +# _total +# _sum +# _rectime +# _pgintime + _boottime +#w + _swapdev + _nswap + _averunnable + _boottime +#netstat + _mbstat + _ipstat + _tcb + _tcpstat + _udb + _udpstat +# _rawcb + _ifnet +# _rthost +# _rtnet + _icmpstat + _filehead + _nfiles +# _rthashsize +# _radix_node_head +#routed + _ifnet +#rwho + _boottime +#savecore + _dumpdev + _dumplo + _time_second + _version + _dumpsize + _panicstr + _dumpmag +#deprecated +# _avenrun diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/sys_machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/sys_machdep.c new file mode 100644 index 0000000000..8f85c128ba --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/sys_machdep.c @@ -0,0 +1,703 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/sys_machdep.c,v 1.91 2003/09/07 05:23:28 davidxu Exp $"); + +#include "opt_kstack_pages.h" +#include "opt_mac.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include /* pcb.h included by sys/user.h */ +#include +#include +#include + +#include /* for kernel_map */ + +#define MAX_LD 8192 +#define LD_PER_PAGE 512 +#define NEW_MAX_LD(num) ((num + LD_PER_PAGE) & ~(LD_PER_PAGE-1)) +#define SIZE_FROM_LARGEST_LD(num) (NEW_MAX_LD(num) << 3) + +void i386_reset_ldt(struct proc_ldt *pldt); + +static int i386_get_ldt(struct thread *, char *); +static int i386_set_ldt(struct thread *, char *); +static int i386_set_ldt_data(struct thread *, int start, int num, + union descriptor *descs); +static int i386_ldt_grow(struct thread *td, int len); +static int i386_get_ioperm(struct thread *, char *); +static int i386_set_ioperm(struct thread *, char *); +#ifdef SMP +static void set_user_ldt_rv(struct thread *); +#endif + +#ifndef _SYS_SYSPROTO_H_ +struct sysarch_args { + int op; + char *parms; +}; +#endif + +int +sysarch(td, uap) + struct thread *td; + register struct sysarch_args *uap; +{ + int error; + + mtx_lock(&Giant); + switch(uap->op) { + case I386_GET_LDT: + error = i386_get_ldt(td, uap->parms); + break; + + case I386_SET_LDT: + error = i386_set_ldt(td, uap->parms); + break; + case I386_GET_IOPERM: + error = i386_get_ioperm(td, uap->parms); + break; + case I386_SET_IOPERM: + error = i386_set_ioperm(td, uap->parms); + break; +#if 0 + case I386_VM86: + error = vm86_sysarch(td, uap->parms); + break; +#endif + default: + error = EINVAL; + break; + } + mtx_unlock(&Giant); + return (error); +} + +int +i386_extend_pcb(struct thread *td) +{ + int i, offset; + u_long *addr; + struct pcb_ext *ext; + struct soft_segment_descriptor ssd = { + 0, /* segment base address (overwritten) */ + ctob(IOPAGES + 1) - 1, /* length */ + SDT_SYS386TSS, /* segment type */ + 0, /* priority level */ + 1, /* descriptor present */ + 0, 0, + 0, /* default 32 size */ + 0 /* granularity */ + }; + + if (td->td_proc->p_flag & P_SA) + return (EINVAL); /* XXXKSE */ +/* XXXKSE All the code below only works in 1:1 needs changing */ + ext = (struct pcb_ext *)kmem_alloc(kernel_map, ctob(IOPAGES+1)); + if (ext == 0) + return (ENOMEM); + bzero(ext, sizeof(struct pcb_ext)); + /* -16 is so we can convert a trapframe into vm86trapframe inplace */ + ext->ext_tss.tss_esp0 = td->td_kstack + ctob(KSTACK_PAGES) - + sizeof(struct pcb) - 16; + ext->ext_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); + /* + * The last byte of the i/o map must be followed by an 0xff byte. + * We arbitrarily allocate 16 bytes here, to keep the starting + * address on a doubleword boundary. + */ + offset = PAGE_SIZE - 16; + ext->ext_tss.tss_ioopt = + (offset - ((unsigned)&ext->ext_tss - (unsigned)ext)) << 16; + ext->ext_iomap = (caddr_t)ext + offset; + ext->ext_vm86.vm86_intmap = (caddr_t)ext + offset - 32; + + addr = (u_long *)ext->ext_vm86.vm86_intmap; + for (i = 0; i < (ctob(IOPAGES) + 32 + 16) / sizeof(u_long); i++) + *addr++ = ~0; + + ssd.ssd_base = (unsigned)&ext->ext_tss; + ssd.ssd_limit -= ((unsigned)&ext->ext_tss - (unsigned)ext); + ssdtosd(&ssd, &ext->ext_tssd); + + KASSERT(td->td_proc == curthread->td_proc, ("giving TSS to !curproc")); + KASSERT(td->td_pcb->pcb_ext == 0, ("already have a TSS!")); + mtx_lock_spin(&sched_lock); + td->td_pcb->pcb_ext = ext; + + /* switch to the new TSS after syscall completes */ + td->td_flags |= TDF_NEEDRESCHED; + mtx_unlock_spin(&sched_lock); + + return 0; +} + +static int +i386_set_ioperm(td, args) + struct thread *td; + char *args; +{ + int i, error; + struct i386_ioperm_args ua; + char *iomap; + + if ((error = copyin(args, &ua, sizeof(struct i386_ioperm_args))) != 0) + return (error); + +#ifdef MAC + if ((error = mac_check_sysarch_ioperm(td->td_ucred)) != 0) + return (error); +#endif + if ((error = suser(td)) != 0) + return (error); + if ((error = securelevel_gt(td->td_ucred, 0)) != 0) + return (error); + /* + * XXX + * While this is restricted to root, we should probably figure out + * whether any other driver is using this i/o address, as so not to + * cause confusion. This probably requires a global 'usage registry'. + */ + + if (td->td_pcb->pcb_ext == 0) + if ((error = i386_extend_pcb(td)) != 0) + return (error); + iomap = (char *)td->td_pcb->pcb_ext->ext_iomap; + + if (ua.start + ua.length > IOPAGES * PAGE_SIZE * NBBY) + return (EINVAL); + + for (i = ua.start; i < ua.start + ua.length; i++) { + if (ua.enable) + iomap[i >> 3] &= ~(1 << (i & 7)); + else + iomap[i >> 3] |= (1 << (i & 7)); + } + return (error); +} + +static int +i386_get_ioperm(td, args) + struct thread *td; + char *args; +{ + int i, state, error; + struct i386_ioperm_args ua; + char *iomap; + + if ((error = copyin(args, &ua, sizeof(struct i386_ioperm_args))) != 0) + return (error); + if (ua.start >= IOPAGES * PAGE_SIZE * NBBY) + return (EINVAL); + + if (td->td_pcb->pcb_ext == 0) { + ua.length = 0; + goto done; + } + + iomap = (char *)td->td_pcb->pcb_ext->ext_iomap; + + i = ua.start; + state = (iomap[i >> 3] >> (i & 7)) & 1; + ua.enable = !state; + ua.length = 1; + + for (i = ua.start + 1; i < IOPAGES * PAGE_SIZE * NBBY; i++) { + if (state != ((iomap[i >> 3] >> (i & 7)) & 1)) + break; + ua.length++; + } + +done: + error = copyout(&ua, args, sizeof(struct i386_ioperm_args)); + return (error); +} + +/* + * Update the GDT entry pointing to the LDT to point to the LDT of the + * current process. + * + * This must be called with sched_lock held. Unfortunately, we can't use a + * mtx_assert() here because cpu_switch() calls this function after changing + * curproc but before sched_lock's owner is updated in mi_switch(). + */ +void +set_user_ldt(struct mdproc *mdp) +{ + struct proc_ldt *pldt; + pldt = mdp->md_ldt; + i386_reset_ldt(pldt); + PCPU_SET(currentldt, (int)pldt); + +} + +#ifdef SMP +static void +set_user_ldt_rv(struct thread *td) +{ + + if (td->td_proc != curthread->td_proc) + return; + + set_user_ldt(&td->td_proc->p_md); +} +#endif + +/* + * Must be called with either sched_lock free or held but not recursed. + * If it does not return NULL, it will return with it owned. + */ +struct proc_ldt * +user_ldt_alloc(struct mdproc *mdp, int len) +{ + struct proc_ldt *pldt,*new_ldt; + + + if (mtx_owned(&sched_lock)) + mtx_unlock_spin(&sched_lock); + mtx_assert(&sched_lock, MA_NOTOWNED); + MALLOC(new_ldt, struct proc_ldt *, sizeof(struct proc_ldt), + M_SUBPROC, M_WAITOK); + + new_ldt->ldt_len = len = NEW_MAX_LD(len); + new_ldt->ldt_base = (caddr_t)kmem_alloc(kernel_map, + round_page(len * sizeof(union descriptor))); + if (new_ldt->ldt_base == NULL) { + FREE(new_ldt, M_SUBPROC); + return NULL; + } + new_ldt->ldt_refcnt = 1; + new_ldt->ldt_active = 0; + + mtx_lock_spin(&sched_lock); + + if ((pldt = mdp->md_ldt)) { + if (len > pldt->ldt_len) + len = pldt->ldt_len; + bcopy(pldt->ldt_base, new_ldt->ldt_base, + len * sizeof(union descriptor)); + } else { + bcopy(ldt, new_ldt->ldt_base, PAGE_SIZE); + } + pmap_map_readonly(kernel_pmap, (vm_offset_t)new_ldt->ldt_base, + new_ldt->ldt_len*sizeof(union descriptor)); + return new_ldt; +} + +/* + * Must be called either with sched_lock free or held but not recursed. + * If md_ldt is not NULL, it will return with sched_lock released. + */ +void +user_ldt_free(struct thread *td) +{ + struct mdproc *mdp = &td->td_proc->p_md; + struct proc_ldt *pldt = mdp->md_ldt; + if (pldt == NULL) + return; + + if (!mtx_owned(&sched_lock)) + mtx_lock_spin(&sched_lock); + mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); + if (td == PCPU_GET(curthread)) { + PCPU_SET(currentldt, _default_ldt); + i386_reset_ldt((struct proc_ldt *)_default_ldt); + } + + mdp->md_ldt = NULL; + if (--pldt->ldt_refcnt == 0) { + mtx_unlock_spin(&sched_lock); + + pmap_map_readwrite(kernel_pmap,(vm_offset_t) pldt->ldt_base, + pldt->ldt_len*sizeof(union descriptor)); + kmem_free(kernel_map, (vm_offset_t)pldt->ldt_base, + pldt->ldt_len * sizeof(union descriptor)); + FREE(pldt, M_SUBPROC); + } else + mtx_unlock_spin(&sched_lock); +} + +void +i386_reset_ldt(struct proc_ldt *pldt) +{ + xen_set_ldt((vm_offset_t)pldt->ldt_base, pldt->ldt_len); +} + +static int +i386_get_ldt(td, args) + struct thread *td; + char *args; +{ + int error = 0; + struct proc_ldt *pldt = td->td_proc->p_md.md_ldt; + int nldt, num; + union descriptor *lp; + struct i386_ldt_args ua, *uap = &ua; + + if ((error = copyin(args, uap, sizeof(struct i386_ldt_args))) < 0) + return(error); + +#ifdef DEBUG + printf("i386_get_ldt: start=%d num=%d descs=%p\n", + uap->start, uap->num, (void *)uap->descs); +#endif + + /* verify range of LDTs exist */ + if ((uap->start < 0) || (uap->num <= 0)) + return(EINVAL); + + if (pldt) { + nldt = pldt->ldt_len; + num = min(uap->num, nldt); + lp = &((union descriptor *)(pldt->ldt_base))[uap->start]; + } else { + nldt = sizeof(ldt)/sizeof(ldt[0]); + num = min(uap->num, nldt); + lp = &ldt[uap->start]; + } + if (uap->start + num > nldt) + return(EINVAL); + + error = copyout(lp, uap->descs, num * sizeof(union descriptor)); + if (!error) + td->td_retval[0] = num; + + return(error); +} + +static int ldt_warnings; +#define NUM_LDT_WARNINGS 10 + +static int +i386_set_ldt(struct thread *td, char *args) +{ + int error = 0, i; + int largest_ld; + struct mdproc *mdp = &td->td_proc->p_md; + struct proc_ldt *pldt = 0; + struct i386_ldt_args ua, *uap = &ua; + union descriptor *descs, *dp; + int descs_size; + + if ((error = copyin(args, uap, sizeof(struct i386_ldt_args))) < 0) + return(error); +#ifdef DEBUG + printf("i386_set_ldt: start=%d num=%d descs=%p\n", + uap->start, uap->num, (void *)uap->descs); + +#endif + + if (uap->descs == NULL) { + /* Free descriptors */ + if (uap->start == 0 && uap->num == 0) { + /* + * Treat this as a special case, so userland needn't + * know magic number NLDT. + */ + uap->start = NLDT; + uap->num = MAX_LD - NLDT; + } + if (uap->start <= LUDATA_SEL || uap->num <= 0) + return (EINVAL); + mtx_lock_spin(&sched_lock); + pldt = mdp->md_ldt; + if (pldt == NULL || uap->start >= pldt->ldt_len) { + mtx_unlock_spin(&sched_lock); + return (0); + } + largest_ld = uap->start + uap->num; + if (largest_ld > pldt->ldt_len) + largest_ld = pldt->ldt_len; + i = largest_ld - uap->start; + bzero(&((union descriptor *)(pldt->ldt_base))[uap->start], + sizeof(union descriptor) * i); + mtx_unlock_spin(&sched_lock); + return (0); + } + + if (!(uap->start == LDT_AUTO_ALLOC && uap->num == 1)) { + /* complain a for a while if using old methods */ + if (ldt_warnings++ < NUM_LDT_WARNINGS) { + printf("Warning: pid %d used static ldt allocation.\n", + td->td_proc->p_pid); + printf("See the i386_set_ldt man page for more info\n"); + } + /* verify range of descriptors to modify */ + largest_ld = uap->start + uap->num; + if (uap->start >= MAX_LD || + uap->num < 0 || largest_ld > MAX_LD) { + return (EINVAL); + } + } + + descs_size = uap->num * sizeof(union descriptor); + descs = (union descriptor *)kmem_alloc(kernel_map, descs_size); + if (descs == NULL) + return (ENOMEM); + error = copyin(uap->descs, descs, descs_size); + if (error) { + kmem_free(kernel_map, (vm_offset_t)descs, descs_size); + return (error); + } + + /* Check descriptors for access violations */ + for (i = 0; i < uap->num; i++) { + dp = &descs[i]; + + switch (dp->sd.sd_type) { + case SDT_SYSNULL: /* system null */ + dp->sd.sd_p = 0; + break; + case SDT_SYS286TSS: /* system 286 TSS available */ + case SDT_SYSLDT: /* system local descriptor table */ + case SDT_SYS286BSY: /* system 286 TSS busy */ + case SDT_SYSTASKGT: /* system task gate */ + case SDT_SYS286IGT: /* system 286 interrupt gate */ + case SDT_SYS286TGT: /* system 286 trap gate */ + case SDT_SYSNULL2: /* undefined by Intel */ + case SDT_SYS386TSS: /* system 386 TSS available */ + case SDT_SYSNULL3: /* undefined by Intel */ + case SDT_SYS386BSY: /* system 386 TSS busy */ + case SDT_SYSNULL4: /* undefined by Intel */ + case SDT_SYS386IGT: /* system 386 interrupt gate */ + case SDT_SYS386TGT: /* system 386 trap gate */ + case SDT_SYS286CGT: /* system 286 call gate */ + case SDT_SYS386CGT: /* system 386 call gate */ + /* I can't think of any reason to allow a user proc + * to create a segment of these types. They are + * for OS use only. + */ + kmem_free(kernel_map, (vm_offset_t)descs, descs_size); + return (EACCES); + /*NOTREACHED*/ + + /* memory segment types */ + case SDT_MEMEC: /* memory execute only conforming */ + case SDT_MEMEAC: /* memory execute only accessed conforming */ + case SDT_MEMERC: /* memory execute read conforming */ + case SDT_MEMERAC: /* memory execute read accessed conforming */ + /* Must be "present" if executable and conforming. */ + if (dp->sd.sd_p == 0) { + kmem_free(kernel_map, (vm_offset_t)descs, + descs_size); + return (EACCES); + } + break; + case SDT_MEMRO: /* memory read only */ + case SDT_MEMROA: /* memory read only accessed */ + case SDT_MEMRW: /* memory read write */ + case SDT_MEMRWA: /* memory read write accessed */ + case SDT_MEMROD: /* memory read only expand dwn limit */ + case SDT_MEMRODA: /* memory read only expand dwn lim accessed */ + case SDT_MEMRWD: /* memory read write expand dwn limit */ + case SDT_MEMRWDA: /* memory read write expand dwn lim acessed */ + case SDT_MEME: /* memory execute only */ + case SDT_MEMEA: /* memory execute only accessed */ + case SDT_MEMER: /* memory execute read */ + case SDT_MEMERA: /* memory execute read accessed */ + break; + default: + kmem_free(kernel_map, (vm_offset_t)descs, descs_size); + return(EINVAL); + /*NOTREACHED*/ + } + + /* Only user (ring-3) descriptors may be present. */ + if ((dp->sd.sd_p != 0) && (dp->sd.sd_dpl != SEL_UPL)) { + kmem_free(kernel_map, (vm_offset_t)descs, descs_size); + return (EACCES); + } + } + + if (uap->start == LDT_AUTO_ALLOC && uap->num == 1) { + /* Allocate a free slot */ + pldt = mdp->md_ldt; + if (pldt == NULL) { + load_gs(0); + error = i386_ldt_grow(td, NLDT+1); + if (error) { + kmem_free(kernel_map, (vm_offset_t)descs, + descs_size); + return (error); + } + pldt = mdp->md_ldt; + } +again: + mtx_lock_spin(&sched_lock); + /* + * start scanning a bit up to leave room for NVidia and + * Wine, which still user the "Blat" method of allocation. + */ + dp = &((union descriptor *)(pldt->ldt_base))[NLDT]; + for (i = NLDT; i < pldt->ldt_len; ++i) { + if (dp->sd.sd_type == SDT_SYSNULL) + break; + dp++; + } + if (i >= pldt->ldt_len) { + mtx_unlock_spin(&sched_lock); + error = i386_ldt_grow(td, pldt->ldt_len+1); + if (error) { + kmem_free(kernel_map, (vm_offset_t)descs, + descs_size); + return (error); + } + goto again; + } + uap->start = i; + error = i386_set_ldt_data(td, i, 1, descs); + mtx_unlock_spin(&sched_lock); + } else { + largest_ld = uap->start + uap->num; + error = i386_ldt_grow(td, largest_ld); + if (error == 0) { + mtx_lock_spin(&sched_lock); + error = i386_set_ldt_data(td, uap->start, uap->num, + descs); + mtx_unlock_spin(&sched_lock); + } + } + kmem_free(kernel_map, (vm_offset_t)descs, descs_size); + if (error == 0) + td->td_retval[0] = uap->start; + return (error); +} +typedef struct uint64_lohi { + unsigned long lo; + unsigned long hi; +} uint64_lohi; + +static int +i386_set_ldt_data(struct thread *td, int start, int num, + union descriptor *descs) +{ + struct mdproc *mdp = &td->td_proc->p_md; + struct proc_ldt *pldt = mdp->md_ldt; + int i, error; + + mtx_assert(&sched_lock, MA_OWNED); + + /* Fill in range */ + for (i = 0; i < num; i++) { + error = HYPERVISOR_update_descriptor(vtomach(&((union descriptor *)(pldt->ldt_base))[start + i]), ((uint64_lohi *)descs)[i].lo, ((uint64_lohi *)descs)[i].hi); + if (error) + panic("failed to update ldt: %d", error); + } + return (0); +} + +static int +i386_ldt_grow(struct thread *td, int len) +{ + struct mdproc *mdp = &td->td_proc->p_md; + struct proc_ldt *pldt; + caddr_t old_ldt_base; + int old_ldt_len; + + if (len > MAX_LD) + return (ENOMEM); + if (len < NLDT+1) + len = NLDT+1; + pldt = mdp->md_ldt; + /* allocate user ldt */ + if (!pldt || len > pldt->ldt_len) { + struct proc_ldt *new_ldt = user_ldt_alloc(mdp, len); + if (new_ldt == NULL) + return (ENOMEM); + pldt = mdp->md_ldt; + /* sched_lock was held by user_ldt_alloc */ + if (pldt) { + if (new_ldt->ldt_len > pldt->ldt_len) { + old_ldt_base = pldt->ldt_base; + old_ldt_len = pldt->ldt_len; + pldt->ldt_sd = new_ldt->ldt_sd; + pldt->ldt_base = new_ldt->ldt_base; + pldt->ldt_len = new_ldt->ldt_len; + mtx_unlock_spin(&sched_lock); + pmap_map_readwrite(kernel_pmap, + (vm_offset_t)old_ldt_base, + old_ldt_len * sizeof(union descriptor)); + kmem_free(kernel_map, (vm_offset_t)old_ldt_base, + old_ldt_len * sizeof(union descriptor)); + FREE(new_ldt, M_SUBPROC); + mtx_lock_spin(&sched_lock); + } else { + /* + * If other threads already did the work, + * do nothing + */ + mtx_unlock_spin(&sched_lock); + pmap_map_readwrite(kernel_pmap, + (vm_offset_t)new_ldt->ldt_base, + new_ldt->ldt_len * sizeof(union descriptor)); + kmem_free(kernel_map, + (vm_offset_t)new_ldt->ldt_base, + new_ldt->ldt_len * sizeof(union descriptor)); + FREE(new_ldt, M_SUBPROC); + return (0); + } + } else { + mdp->md_ldt = pldt = new_ldt; + } +#ifdef SMP + mtx_unlock_spin(&sched_lock); + /* signal other cpus to reload ldt */ + smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, + NULL, td); +#else + set_user_ldt(mdp); + mtx_unlock_spin(&sched_lock); +#endif + } + return (0); +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/trap.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/trap.c new file mode 100644 index 0000000000..a74986ed18 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/trap.c @@ -0,0 +1,1006 @@ +/*- + * Copyright (C) 1994, David Greenman + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the University of Utah, and William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/trap.c,v 1.260 2003/11/03 21:53:37 jhb Exp $"); + +/* + * 386 Trap and System call handling + */ + +#include "opt_clock.h" +#include "opt_cpu.h" +#include "opt_isa.h" +#include "opt_ktrace.h" +#include "opt_npx.h" +#include "opt_trap.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTRACE +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef SMP +#include +#endif +#include +#ifdef POWERFAIL_NMI +#include +#include +#endif + + +#include +#include +#include +#include + + +extern void trap(struct trapframe frame); +extern void syscall(struct trapframe frame); + +static int trap_pfault(struct trapframe *, int, vm_offset_t); +static void trap_fatal(struct trapframe *, vm_offset_t); +void dblfault_handler(void); + +extern inthand_t IDTVEC(lcall_syscall); + +#define MAX_TRAP_MSG 28 +static char *trap_msg[] = { + "", /* 0 unused */ + "privileged instruction fault", /* 1 T_PRIVINFLT */ + "", /* 2 unused */ + "breakpoint instruction fault", /* 3 T_BPTFLT */ + "", /* 4 unused */ + "", /* 5 unused */ + "arithmetic trap", /* 6 T_ARITHTRAP */ + "", /* 7 unused */ + "", /* 8 unused */ + "general protection fault", /* 9 T_PROTFLT */ + "trace trap", /* 10 T_TRCTRAP */ + "", /* 11 unused */ + "page fault", /* 12 T_PAGEFLT */ + "", /* 13 unused */ + "alignment fault", /* 14 T_ALIGNFLT */ + "", /* 15 unused */ + "", /* 16 unused */ + "hypervisor callback", /* 17 T_HYPCALLBACK */ + "integer divide fault", /* 18 T_DIVIDE */ + "non-maskable interrupt trap", /* 19 T_NMI */ + "overflow trap", /* 20 T_OFLOW */ + "FPU bounds check fault", /* 21 T_BOUND */ + "FPU device not available", /* 22 T_DNA */ + "double fault", /* 23 T_DOUBLEFLT */ + "FPU operand fetch fault", /* 24 T_FPOPFLT */ + "invalid TSS fault", /* 25 T_TSSFLT */ + "segment not present fault", /* 26 T_SEGNPFLT */ + "stack fault", /* 27 T_STKFLT */ + "machine check trap", /* 28 T_MCHK */ +}; + +#if defined(I586_CPU) && !defined(NO_F00F_HACK) +extern int has_f00f_bug; +#endif + +#ifdef KDB +static int kdb_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RW, + &kdb_on_nmi, 0, "Go to KDB on NMI"); +#endif +static int panic_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW, + &panic_on_nmi, 0, "Panic on NMI"); + +#ifdef WITNESS +extern char *syscallnames[]; +#endif + +#ifdef DEVICE_POLLING +extern u_int32_t poll_in_trap; +extern int ether_poll(int count); +#endif /* DEVICE_POLLING */ + + +/* + * Exception, fault, and trap interface to the FreeBSD kernel. + * This common code is called from assembly language IDT gate entry + * routines that prepare a suitable stack frame, and restore this + * frame after the exception has been processed. + */ + +void +trap(struct trapframe frame) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + u_int sticks = 0; + int i = 0, ucode = 0, type, code; + vm_offset_t eva; +#ifdef STACK_DEBUGGING + int nesting, current_sp; + static int prev_csp = 0, prev_ssp = 0; + nesting = PCPU_GET(trap_nesting); +#endif + +#ifdef POWERFAIL_NMI + static int lastalert = 0; +#endif + + atomic_add_int(&cnt.v_trap, 1); + type = frame.tf_trapno; +#ifdef KDB + if (kdb_active) { + kdb_reenter(); + goto out; + } +#endif + + eva = 0; + code = frame.tf_err; + + if (type == T_HYPCALLBACK) { + evtchn_do_upcall((struct intrframe *)&frame); + if (ISPL(frame.tf_cs) == SEL_KPL) + goto out; + goto userout; + } else if (type == 0) + panic("invalid trap type/code %d/%d\n",type, code); + + + if (type == T_PAGEFLT) { + /* + * For some Cyrix CPUs, %cr2 is clobbered by + * interrupts. This problem is worked around by using + * an interrupt gate for the pagefault handler. We + * are finally ready to read %cr2 and then must + * reenable interrupts. + * + * If we get a page fault while in a critical section, then + * it is most likely a fatal kernel page fault. The kernel + * is already going to panic trying to get a sleep lock to + * do the VM lookup, so just consider it a fatal trap so the + * kernel can print out a useful trap message and even get + * to the debugger. + */ + eva = frame.tf_cr2; + + if (td->td_critnest != 0) + trap_fatal(&frame, eva); + } + +#ifdef DEVICE_POLLING + if (poll_in_trap) + ether_poll(poll_in_trap); +#endif /* DEVICE_POLLING */ + + if ((ISPL(frame.tf_cs) == SEL_UPL) + || ((frame.tf_eflags & PSL_VM) && + !(PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL))) { + /* user trap */ + + sticks = td->td_sticks; + td->td_frame = &frame; + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); + + switch (type) { + case T_PRIVINFLT: /* privileged instruction fault */ + ucode = type; + i = SIGILL; + break; + + case T_BPTFLT: /* bpt instruction fault */ + case T_TRCTRAP: /* trace trap */ + enable_intr(); + frame.tf_eflags &= ~PSL_T; + i = SIGTRAP; + break; + + case T_ARITHTRAP: /* arithmetic trap */ +#ifdef DEV_NPX + ucode = npxtrap(); + if (ucode == -1) + goto userout; +#else + ucode = code; +#endif + i = SIGFPE; + break; + + case T_PROTFLT: /* general protection fault */ + case T_STKFLT: /* stack fault */ + case T_SEGNPFLT: /* segment not present fault */ + case T_TSSFLT: /* invalid TSS fault */ + case T_DOUBLEFLT: /* double fault */ + default: + ucode = code + BUS_SEGM_FAULT ; + printf("unexpected trap type/code %d/%d\n",type, code); /* XXX temporary */ + + i = SIGBUS; + break; + + case T_PAGEFLT: /* page fault */ + if (td->td_pflags & TDP_SA) + thread_user_enter(td); + + i = trap_pfault(&frame, TRUE, eva); +#if defined(I586_CPU) && !defined(NO_F00F_HACK) + if (i == -2) { + /* + * The f00f hack workaround has triggered, so + * treat the fault as an illegal instruction + * (T_PRIVINFLT) instead of a page fault. + */ + type = frame.tf_trapno = T_PRIVINFLT; + + /* Proceed as in that case. */ + ucode = type; + i = SIGILL; + break; + } +#endif + if (i == -1) + goto userout; + if (i == 0) + goto user; + + ucode = T_PAGEFLT; + break; + + case T_DIVIDE: /* integer divide fault */ + ucode = FPE_INTDIV; + i = SIGFPE; + break; + +#ifdef DEV_ISA + case T_NMI: +#ifdef POWERFAIL_NMI +#ifndef TIMER_FREQ +# define TIMER_FREQ 1193182 +#endif + mtx_lock(&Giant); + if (time_second - lastalert > 10) { + log(LOG_WARNING, "NMI: power fail\n"); + sysbeep(TIMER_FREQ/880, hz); + lastalert = time_second; + } + mtx_unlock(&Giant); + goto userout; +#else /* !POWERFAIL_NMI */ + /* machine/parity/power fail/"kitchen sink" faults */ + /* XXX Giant */ + if (isa_nmi(code) == 0) { +#ifdef KDB + /* + * NMI can be hooked up to a pushbutton + * for debugging. + */ + if (kdb_on_nmi) { + printf ("NMI ... going to debugger\n"); + kdb_trap (type, 0, &frame); + } +#endif /* KDB */ + goto userout; + } else if (panic_on_nmi) + panic("NMI indicates hardware failure"); + break; +#endif /* POWERFAIL_NMI */ +#endif /* DEV_ISA */ + + case T_OFLOW: /* integer overflow fault */ + ucode = FPE_INTOVF; + i = SIGFPE; + break; + + case T_BOUND: /* bounds check fault */ + ucode = FPE_FLTSUB; + i = SIGFPE; + break; + + case T_DNA: +#ifdef DEV_NPX + /* transparent fault (due to context switch "late") */ + if (npxdna()) + goto userout; +#endif + i = SIGFPE; + ucode = FPE_FPU_NP_TRAP; + break; + + case T_FPOPFLT: /* FPU operand fetch fault */ + ucode = T_FPOPFLT; + i = SIGILL; + break; + + case T_XMMFLT: /* SIMD floating-point exception */ + ucode = 0; /* XXX */ + i = SIGFPE; + break; + } + } else { + /* kernel trap */ + + KASSERT(cold || td->td_ucred != NULL, + ("kernel trap doesn't have ucred")); + switch (type) { + case T_PAGEFLT: /* page fault */ + (void) trap_pfault(&frame, FALSE, eva); + goto out; + + case T_DNA: +#ifdef DEV_NPX + /* + * The kernel is apparently using npx for copying. + * XXX this should be fatal unless the kernel has + * registered such use. + */ + if (npxdna()) + goto out; +#endif + break; + + /* + * The following two traps can happen in + * vm86 mode, and, if so, we want to handle + * them specially. + */ + case T_PROTFLT: /* general protection fault */ + case T_STKFLT: /* stack fault */ +#if 0 + if (frame.tf_eflags & PSL_VM) { + i = vm86_emulate((struct vm86frame *)&frame); + if (i != 0) + /* + * returns to original process + */ + vm86_trap((struct vm86frame *)&frame); + goto out; + } +#endif + if (type == T_STKFLT) + break; + + /* FALL THROUGH */ + + case T_SEGNPFLT: /* segment not present fault */ + if (PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL) + break; + + /* + * Invalid %fs's and %gs's can be created using + * procfs or PT_SETREGS or by invalidating the + * underlying LDT entry. This causes a fault + * in kernel mode when the kernel attempts to + * switch contexts. Lose the bad context + * (XXX) so that we can continue, and generate + * a signal. + */ + if (frame.tf_eip == (int)cpu_switch_load_gs) { + PCPU_GET(curpcb)->pcb_gs = 0; +#if 0 + PROC_LOCK(p); + psignal(p, SIGBUS); + PROC_UNLOCK(p); +#endif + goto out; + } + + if (td->td_intr_nesting_level != 0) + break; + + /* + * Invalid segment selectors and out of bounds + * %eip's and %esp's can be set up in user mode. + * This causes a fault in kernel mode when the + * kernel tries to return to user mode. We want + * to get this fault so that we can fix the + * problem here and not have to check all the + * selectors and pointers when the user changes + * them. + */ + if (frame.tf_eip == (int)doreti_iret) { + frame.tf_eip = (int)doreti_iret_fault; + goto out; + } + if (frame.tf_eip == (int)doreti_popl_ds) { + frame.tf_eip = (int)doreti_popl_ds_fault; + goto out; + } + if (frame.tf_eip == (int)doreti_popl_es) { + frame.tf_eip = (int)doreti_popl_es_fault; + goto out; + } + if (frame.tf_eip == (int)doreti_popl_fs) { + frame.tf_eip = (int)doreti_popl_fs_fault; + goto out; + } + if (PCPU_GET(curpcb)->pcb_onfault != NULL) { + frame.tf_eip = + (int)PCPU_GET(curpcb)->pcb_onfault; + goto out; + } + break; + + case T_TSSFLT: + /* + * PSL_NT can be set in user mode and isn't cleared + * automatically when the kernel is entered. This + * causes a TSS fault when the kernel attempts to + * `iret' because the TSS link is uninitialized. We + * want to get this fault so that we can fix the + * problem here and not every time the kernel is + * entered. + */ + if (frame.tf_eflags & PSL_NT) { + frame.tf_eflags &= ~PSL_NT; + goto out; + } + break; + + case T_TRCTRAP: /* trace trap */ + if (frame.tf_eip == (int)IDTVEC(lcall_syscall)) { + /* + * We've just entered system mode via the + * syscall lcall. Continue single stepping + * silently until the syscall handler has + * saved the flags. + */ + goto out; + } + if (frame.tf_eip == (int)IDTVEC(lcall_syscall) + 1) { + /* + * The syscall handler has now saved the + * flags. Stop single stepping it. + */ + frame.tf_eflags &= ~PSL_T; + goto out; + } + /* + * Ignore debug register trace traps due to + * accesses in the user's address space, which + * can happen under several conditions such as + * if a user sets a watchpoint on a buffer and + * then passes that buffer to a system call. + * We still want to get TRCTRAPS for addresses + * in kernel space because that is useful when + * debugging the kernel. + */ + /* XXX Giant */ + if (user_dbreg_trap() && + !(PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL)) { + /* + * Reset breakpoint bits because the + * processor doesn't + */ + load_dr6(rdr6() & 0xfffffff0); + goto out; + } + /* + * FALLTHROUGH (TRCTRAP kernel mode, kernel address) + */ + case T_BPTFLT: + /* + * If KDB is enabled, let it handle the debugger trap. + * Otherwise, debugger traps "can't happen". + */ +#ifdef KDB + /* XXX Giant */ + if (kdb_trap (type, 0, &frame)) + goto out; +#endif + break; + +#ifdef DEV_ISA + case T_NMI: +#ifdef POWERFAIL_NMI + mtx_lock(&Giant); + if (time_second - lastalert > 10) { + log(LOG_WARNING, "NMI: power fail\n"); + sysbeep(TIMER_FREQ/880, hz); + lastalert = time_second; + } + mtx_unlock(&Giant); + goto out; +#else /* !POWERFAIL_NMI */ + /* XXX Giant */ + /* machine/parity/power fail/"kitchen sink" faults */ + if (isa_nmi(code) == 0) { +#ifdef KDB + /* + * NMI can be hooked up to a pushbutton + * for debugging. + */ + if (kdb_on_nmi) { + printf ("NMI ... going to debugger\n"); + kdb_trap (type, 0, &frame); + } +#endif /* KDB */ + goto out; + } else if (panic_on_nmi == 0) + goto out; + /* FALLTHROUGH */ +#endif /* POWERFAIL_NMI */ +#endif /* DEV_ISA */ + } + + trap_fatal(&frame, eva); + goto out; + } + + /* Translate fault for emulators (e.g. Linux) */ + if (*p->p_sysent->sv_transtrap) + i = (*p->p_sysent->sv_transtrap)(i, type); + + trapsignal(td, i, ucode); + +#if 1 /* DEBUG */ + if (type <= MAX_TRAP_MSG) { + uprintf("fatal process exception: %s", + trap_msg[type]); + if ((type == T_PAGEFLT) || (type == T_PROTFLT)) + uprintf(", fault VA = 0x%lx", (u_long)eva); + uprintf("\n"); + } +#endif + +user: + userret(td, &frame, sticks); + mtx_assert(&Giant, MA_NOTOWNED); +userout: +out: +#ifdef STACK_DEBUGGING + PCPU_SET(trap_nesting, nesting); +#endif + return; +} + +static int +trap_pfault(frame, usermode, eva) + struct trapframe *frame; + int usermode; + vm_offset_t eva; +{ + vm_offset_t va; + struct vmspace *vm = NULL; + vm_map_t map = 0; + int rv = 0; + vm_prot_t ftype; + struct thread *td = curthread; + struct proc *p = td->td_proc; + + va = trunc_page(eva); + if (va >= KERNBASE) { + /* + * Don't allow user-mode faults in kernel address space. + * An exception: if the faulting address is the invalid + * instruction entry in the IDT, then the Intel Pentium + * F00F bug workaround was triggered, and we need to + * treat it is as an illegal instruction, and not a page + * fault. + */ +#if defined(I586_CPU) && !defined(NO_F00F_HACK) + if ((eva == (unsigned int)&idt[6]) && has_f00f_bug) + return -2; +#endif + if (usermode) + goto nogo; + + map = kernel_map; + } else { + /* + * This is a fault on non-kernel virtual memory. + * vm is initialized above to NULL. If curproc is NULL + * or curproc->p_vmspace is NULL the fault is fatal. + */ + if (p != NULL) + vm = p->p_vmspace; + + if (vm == NULL) + goto nogo; + + map = &vm->vm_map; + } + + if (frame->tf_err & PGEX_W) + ftype = VM_PROT_WRITE; + else + ftype = VM_PROT_READ; + + if (map != kernel_map) { + /* + * Keep swapout from messing with us during this + * critical time. + */ + PROC_LOCK(p); + ++p->p_lock; + PROC_UNLOCK(p); + + /* Fault in the user page: */ + rv = vm_fault(map, va, ftype, + (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY + : VM_FAULT_NORMAL); + + PROC_LOCK(p); + --p->p_lock; + PROC_UNLOCK(p); + } else { + /* + * Don't have to worry about process locking or stacks in the + * kernel. + */ + rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); + } + if (rv == KERN_SUCCESS) + return (0); +nogo: + if (!usermode) { + if (td->td_intr_nesting_level == 0 && + PCPU_GET(curpcb)->pcb_onfault != NULL) { + frame->tf_eip = (int)PCPU_GET(curpcb)->pcb_onfault; + return (0); + } + trap_fatal(frame, eva); + return (-1); + } + + /* kludge to pass faulting virtual address to sendsig */ + frame->tf_err = eva; + + return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); +} + +static void +trap_fatal(struct trapframe *frame, vm_offset_t eva) +{ + int code, type, ss, esp; + struct soft_segment_descriptor softseg; + + code = frame->tf_err; + type = frame->tf_trapno; +#if 0 + XENPRINTF("trying to read gdt\n"); + sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)].sd, &softseg); + XENPRINTF("read gdt\n"); +#endif + if (type <= MAX_TRAP_MSG) + printf("\n\nFatal trap %d: %s while in %s mode\n", + type, trap_msg[type], + frame->tf_eflags & PSL_VM ? "vm86" : + ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel"); +#ifdef SMP + /* two separate prints in case of a trap on an unmapped page */ + printf("cpuid = %d; ", PCPU_GET(cpuid)); + printf("apic id = %02x\n", PCPU_GET(apic_id)); +#endif + if (type == T_PAGEFLT) { + printf("fault virtual address = 0x%x\n", eva); + printf("fault code = %s %s, %s\n", + code & PGEX_U ? "user" : "supervisor", + code & PGEX_W ? "write" : "read", + code & PGEX_P ? "protection violation" : "page not present"); + } + printf("instruction pointer = 0x%x:0x%x\n", + frame->tf_cs & 0xffff, frame->tf_eip); + if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) { + ss = frame->tf_ss & 0xffff; + esp = frame->tf_esp; + } else { + ss = GSEL(GDATA_SEL, SEL_KPL); + esp = (int)&frame->tf_esp; + } + printf("stack pointer = 0x%x:0x%x\n", ss, esp); + printf("frame pointer = 0x%x:0x%x\n", ss, frame->tf_ebp); + printf("code segment = base 0x%x, limit 0x%x, type 0x%x\n", + softseg.ssd_base, softseg.ssd_limit, softseg.ssd_type); + printf(" = DPL %d, pres %d, def32 %d, gran %d\n", + softseg.ssd_dpl, softseg.ssd_p, softseg.ssd_def32, + softseg.ssd_gran); + printf("processor eflags = "); + if (frame->tf_eflags & PSL_T) + printf("trace trap, "); + if (frame->tf_eflags & PSL_I) + printf("interrupt enabled, "); + if (frame->tf_eflags & PSL_NT) + printf("nested task, "); + if (frame->tf_eflags & PSL_RF) + printf("resume, "); + if (frame->tf_eflags & PSL_VM) + printf("vm86, "); + printf("IOPL = %d\n", (frame->tf_eflags & PSL_IOPL) >> 12); + printf("current process = "); + if (curproc) { + printf("%lu (%s)\n", + (u_long)curproc->p_pid, curproc->p_comm ? + curproc->p_comm : ""); + } else { + printf("Idle\n"); + } + /* XXX */ + +#ifdef KDB + if (kdb_trap(type, 0, frame)) + return; +#endif + printf("trap number = %d\n", type); + if (type <= MAX_TRAP_MSG) + panic("%s", trap_msg[type]); + else + panic("unknown/reserved trap"); +} + +/* + * Double fault handler. Called when a fault occurs while writing + * a frame for a trap/exception onto the stack. This usually occurs + * when the stack overflows (such is the case with infinite recursion, + * for example). + * + * XXX Note that the current PTD gets replaced by IdlePTD when the + * task switch occurs. This means that the stack that was active at + * the time of the double fault is not available at unless + * the machine was idle when the double fault occurred. The downside + * of this is that "trace " in ddb won't work. + */ +void +dblfault_handler() +{ + printf("\nFatal double fault:\n"); + printf("eip = 0x%x\n", PCPU_GET(common_tss.tss_eip)); + printf("esp = 0x%x\n", PCPU_GET(common_tss.tss_esp)); + printf("ebp = 0x%x\n", PCPU_GET(common_tss.tss_ebp)); +#ifdef SMP + /* two separate prints in case of a trap on an unmapped page */ + printf("cpuid = %d; ", PCPU_GET(cpuid)); + printf("apic id = %02x\n", PCPU_GET(apic_id)); +#endif + panic("double fault"); +} + +/* + * syscall - system call request C handler + * + * A system call is essentially treated as a trap. + */ +void +syscall(frame) + struct trapframe frame; +{ + caddr_t params; + struct sysent *callp; + struct thread *td = curthread; + struct proc *p = td->td_proc; + register_t orig_tf_eflags; + u_int sticks; + int error; + int narg; + int args[8]; + u_int code; + + /* + * note: PCPU_LAZY_INC() can only be used if we can afford + * occassional inaccuracy in the count. + */ + PCPU_LAZY_INC(cnt.v_syscall); + +#ifdef DIAGNOSTIC + if (ISPL(frame.tf_cs) != SEL_UPL) { + mtx_lock(&Giant); /* try to stabilize the system XXX */ + panic("syscall"); + /* NOT REACHED */ + mtx_unlock(&Giant); + } +#endif + + sticks = td->td_sticks; + td->td_frame = &frame; + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); + if (p->p_flag & P_SA) + thread_user_enter(td); + params = (caddr_t)frame.tf_esp + sizeof(int); + code = frame.tf_eax; + orig_tf_eflags = frame.tf_eflags; + + if (p->p_sysent->sv_prepsyscall) { + /* + * The prep code is MP aware. + */ + (*p->p_sysent->sv_prepsyscall)(&frame, args, &code, ¶ms); + } else { + /* + * Need to check if this is a 32 bit or 64 bit syscall. + * fuword is MP aware. + */ + if (code == SYS_syscall) { + /* + * Code is first argument, followed by actual args. + */ + code = fuword(params); + params += sizeof(int); + } else if (code == SYS___syscall) { + /* + * Like syscall, but code is a quad, so as to maintain + * quad alignment for the rest of the arguments. + */ + code = fuword(params); + params += sizeof(quad_t); + } + } + + if (p->p_sysent->sv_mask) + code &= p->p_sysent->sv_mask; + + if (code >= p->p_sysent->sv_size) + callp = &p->p_sysent->sv_table[0]; + else + callp = &p->p_sysent->sv_table[code]; + + narg = callp->sy_narg & SYF_ARGMASK; + + /* + * copyin and the ktrsyscall()/ktrsysret() code is MP-aware + */ + if (params != NULL && narg != 0) + error = copyin(params, (caddr_t)args, + (u_int)(narg * sizeof(int))); + else + error = 0; + +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSCALL)) + ktrsyscall(code, narg, args); +#endif + CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td, + td->td_proc->p_pid, td->td_proc->p_comm, code); + + /* + * Try to run the syscall without Giant if the syscall + * is MP safe. + */ + if ((callp->sy_narg & SYF_MPSAFE) == 0) + mtx_lock(&Giant); + + if (error == 0) { + td->td_retval[0] = 0; + td->td_retval[1] = frame.tf_edx; + + STOPEVENT(p, S_SCE, narg); + + PTRACESTOP_SC(p, td, S_PT_SCE); + + error = (*callp->sy_call)(td, args); + } + + switch (error) { + case 0: + frame.tf_eax = td->td_retval[0]; + frame.tf_edx = td->td_retval[1]; + frame.tf_eflags &= ~PSL_C; + break; + + case ERESTART: + /* + * Reconstruct pc, assuming lcall $X,y is 7 bytes, + * int 0x80 is 2 bytes. We saved this in tf_err. + */ + frame.tf_eip -= frame.tf_err; + break; + + case EJUSTRETURN: + break; + + default: + if (p->p_sysent->sv_errsize) { + if (error >= p->p_sysent->sv_errsize) + error = -1; /* XXX */ + else + error = p->p_sysent->sv_errtbl[error]; + } + frame.tf_eax = error; + frame.tf_eflags |= PSL_C; + break; + } + + /* + * Release Giant if we previously set it. + */ + if ((callp->sy_narg & SYF_MPSAFE) == 0) + mtx_unlock(&Giant); + + /* + * Traced syscall. + */ + if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) { + frame.tf_eflags &= ~PSL_T; + trapsignal(td, SIGTRAP, 0); + } + + /* + * Handle reschedule and other end-of-syscall issues + */ + userret(td, &frame, sticks); + +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSRET)) + ktrsysret(code, error, td->td_retval[0]); +#endif + + /* + * This works because errno is findable through the + * register set. If we ever support an emulation where this + * is not the case, this code will need to be revisited. + */ + STOPEVENT(p, S_SCX, code); + + PTRACESTOP_SC(p, td, S_PT_SCX); + + WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", + (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); + mtx_assert(&sched_lock, MA_NOTOWNED); + mtx_assert(&Giant, MA_NOTOWNED); +} + diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/vm_machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/vm_machdep.c new file mode 100644 index 0000000000..cff67833f7 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/vm_machdep.c @@ -0,0 +1,618 @@ +/*- + * Copyright (c) 1982, 1986 The Regents of the University of California. + * Copyright (c) 1989, 1990 William Jolitz + * Copyright (c) 1994 John Dyson + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department, and William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 + * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.219 2003/11/17 18:22:24 alc Exp $"); + +#include "opt_npx.h" +#ifdef PC98 +#include "opt_pc98.h" +#endif +#include "opt_reset.h" +#include "opt_cpu.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef PC98 +#include +#else +#include +#endif + +#ifndef NSFBUFS +#define NSFBUFS (512 + maxusers * 16) +#endif + +#include + +#ifdef SMP +static void cpu_reset_proxy(void); +static u_int cpu_reset_proxyid; +static volatile u_int cpu_reset_proxy_active; +#endif +static void sf_buf_init(void *arg); +SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) + +LIST_HEAD(sf_head, sf_buf); + +/* + * A hash table of active sendfile(2) buffers + */ +static TAILQ_HEAD(, sf_buf) sf_buf_freelist; + + +static struct sf_head *sf_buf_active; +static u_long sf_buf_hashmask; + + +#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask) + +static u_int sf_buf_alloc_want; + +/* + * A lock used to synchronize access to the hash table and free list + */ +static struct mtx sf_buf_lock; + +extern int _ucodesel, _udatasel; + +/* + * Finish a fork operation, with process p2 nearly set up. + * Copy and update the pcb, set up the stack so that the child + * ready to run and return to user mode. + */ +void +cpu_fork(struct thread *td1, + struct proc *p2, + struct thread *td2, + int flags) +{ + register struct proc *p1; + struct pcb *pcb2; + struct mdproc *mdp2; +#ifdef DEV_NPX + register_t savecrit; +#endif + + p1 = td1->td_proc; + if ((flags & RFPROC) == 0) { + if ((flags & RFMEM) == 0) { + /* unshare user LDT */ + struct mdproc *mdp1 = &p1->p_md; + struct proc_ldt *pldt = mdp1->md_ldt; + if (pldt && pldt->ldt_refcnt > 1) { + pldt = user_ldt_alloc(mdp1, pldt->ldt_len); + if (pldt == NULL) + panic("could not copy LDT"); + mdp1->md_ldt = pldt; + set_user_ldt(mdp1); + user_ldt_free(td1); + } + } + return; + } + + /* Ensure that p1's pcb is up to date. */ +#ifdef DEV_NPX + if (td1 == curthread) + td1->td_pcb->pcb_gs = rgs(); + savecrit = intr_disable(); + if (PCPU_GET(fpcurthread) == td1) + npxsave(&td1->td_pcb->pcb_save); + intr_restore(savecrit); +#endif + + /* Point the pcb to the top of the stack */ + pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1; + td2->td_pcb = pcb2; + + /* Copy p1's pcb */ + bcopy(td1->td_pcb, pcb2, sizeof(*pcb2)); + + /* Point mdproc and then copy over td1's contents */ + mdp2 = &p2->p_md; + bcopy(&p1->p_md, mdp2, sizeof(*mdp2)); + + /* + * Create a new fresh stack for the new process. + * Copy the trap frame for the return to user mode as if from a + * syscall. This copies most of the user mode register values. + */ + td2->td_frame = (struct trapframe *)((caddr_t)td2->td_pcb) - 1; + bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe)); + + td2->td_frame->tf_eax = 0; /* Child returns zero */ + td2->td_frame->tf_eflags &= ~PSL_C; /* success */ + td2->td_frame->tf_edx = 1; + /* + * Set registers for trampoline to user mode. Leave space for the + * return address on stack. These are the kernel mode register values. + */ + pcb2->pcb_cr3 = vtophys(vmspace_pmap(p2->p_vmspace)->pm_pdir); + pcb2->pcb_edi = 0; + pcb2->pcb_esi = (int)fork_return; /* fork_trampoline argument */ + pcb2->pcb_ebp = 0; + pcb2->pcb_esp = (int)td2->td_frame - sizeof(void *); + pcb2->pcb_ebx = (int)td2; /* fork_trampoline argument */ + pcb2->pcb_eip = (int)fork_trampoline; + pcb2->pcb_psl = PSL_KERNEL; /* ints disabled */ + pcb2->pcb_gs = rgs(); + /*- + * pcb2->pcb_dr*: cloned above. + * pcb2->pcb_savefpu: cloned above. + * pcb2->pcb_flags: cloned above. + * pcb2->pcb_onfault: cloned above (always NULL here?). + * pcb2->pcb_gs: cloned above. + * pcb2->pcb_ext: cleared below. + */ + + /* + * XXX don't copy the i/o pages. this should probably be fixed. + */ + pcb2->pcb_ext = 0; + + /* Copy the LDT, if necessary. */ + mtx_lock_spin(&sched_lock); + + if (mdp2->md_ldt != 0) { + if (flags & RFMEM) { + mdp2->md_ldt->ldt_refcnt++; + } else { + mdp2->md_ldt = user_ldt_alloc(mdp2, + mdp2->md_ldt->ldt_len); + if (mdp2->md_ldt == NULL) + panic("could not copy LDT"); + } + } + mtx_unlock_spin(&sched_lock); + + /* + * Now, cpu_switch() can schedule the new process. + * pcb_esp is loaded pointing to the cpu_switch() stack frame + * containing the return address when exiting cpu_switch. + * This will normally be to fork_trampoline(), which will have + * %ebx loaded with the new proc's pointer. fork_trampoline() + * will set up a stack to call fork_return(p, frame); to complete + * the return to user-mode. + */ +} + +/* + * Intercept the return address from a freshly forked process that has NOT + * been scheduled yet. + * + * This is needed to make kernel threads stay in kernel mode. + */ +void +cpu_set_fork_handler(td, func, arg) + struct thread *td; + void (*func)(void *); + void *arg; +{ + /* + * Note that the trap frame follows the args, so the function + * is really called like this: func(arg, frame); + */ + td->td_pcb->pcb_esi = (int) func; /* function */ + td->td_pcb->pcb_ebx = (int) arg; /* first arg */ +} + +void +cpu_exit(struct thread *td) +{ + struct mdproc *mdp; + struct pcb *pcb = td->td_pcb; + + + /* Reset pc->pcb_gs and %gs before possibly invalidating it. */ + mdp = &td->td_proc->p_md; + if (mdp->md_ldt) { + td->td_pcb->pcb_gs = _udatasel; + load_gs(_udatasel); + user_ldt_free(td); + } + if (pcb->pcb_flags & PCB_DBREGS) { + /* disable all hardware breakpoints */ + reset_dbregs(); + pcb->pcb_flags &= ~PCB_DBREGS; + } +} + +void +cpu_thread_exit(struct thread *td) +{ + struct pcb *pcb = td->td_pcb; +#ifdef DEV_NPX + if (td == PCPU_GET(fpcurthread)) + npxdrop(); +#endif + if (pcb->pcb_flags & PCB_DBREGS) { + /* disable all hardware breakpoints */ + reset_dbregs(); + pcb->pcb_flags &= ~PCB_DBREGS; + } +} + +void +cpu_thread_clean(struct thread *td) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + if (pcb->pcb_ext != 0) { + /* XXXKSE XXXSMP not SMP SAFE.. what locks do we have? */ + /* if (pcb->pcb_ext->ext_refcount-- == 1) ?? */ + /* + * XXX do we need to move the TSS off the allocated pages + * before freeing them? (not done here) + */ + kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ext, + ctob(IOPAGES + 1)); + pcb->pcb_ext = 0; + } +} + +void +cpu_thread_swapin(struct thread *td) +{ +} + +void +cpu_thread_swapout(struct thread *td) +{ +} + +void +cpu_thread_setup(struct thread *td) +{ + + td->td_pcb = + (struct pcb *)(td->td_kstack + td->td_kstack_pages * PAGE_SIZE) - 1; + td->td_frame = (struct trapframe *)((caddr_t)td->td_pcb - 16) - 1; + td->td_pcb->pcb_ext = NULL; +} + +/* + * Initialize machine state (pcb and trap frame) for a new thread about to + * upcall. Pu t enough state in the new thread's PCB to get it to go back + * userret(), where we can intercept it again to set the return (upcall) + * Address and stack, along with those from upcals that are from other sources + * such as those generated in thread_userret() itself. + */ +void +cpu_set_upcall(struct thread *td, struct thread *td0) +{ + struct pcb *pcb2; + + /* Point the pcb to the top of the stack. */ + pcb2 = td->td_pcb; + + /* + * Copy the upcall pcb. This loads kernel regs. + * Those not loaded individually below get their default + * values here. + * + * XXXKSE It might be a good idea to simply skip this as + * the values of the other registers may be unimportant. + * This would remove any requirement for knowing the KSE + * at this time (see the matching comment below for + * more analysis) (need a good safe default). + */ + bcopy(td0->td_pcb, pcb2, sizeof(*pcb2)); + pcb2->pcb_flags &= ~(PCB_NPXTRAP|PCB_NPXINITDONE); + + /* + * Create a new fresh stack for the new thread. + * Don't forget to set this stack value into whatever supplies + * the address for the fault handlers. + * The contexts are filled in at the time we actually DO the + * upcall as only then do we know which KSE we got. + */ + bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe)); + + /* + * Set registers for trampoline to user mode. Leave space for the + * return address on stack. These are the kernel mode register values. + */ +#ifdef PAE + pcb2->pcb_cr3 = vtophys(vmspace_pmap(td->td_proc->p_vmspace)->pm_pdpt); +#else + pcb2->pcb_cr3 = vtophys(vmspace_pmap(td->td_proc->p_vmspace)->pm_pdir); +#endif + pcb2->pcb_edi = 0; + pcb2->pcb_esi = (int)fork_return; /* trampoline arg */ + pcb2->pcb_ebp = 0; + pcb2->pcb_esp = (int)td->td_frame - sizeof(void *); /* trampoline arg */ + pcb2->pcb_ebx = (int)td; /* trampoline arg */ + pcb2->pcb_eip = (int)fork_trampoline; + pcb2->pcb_psl &= ~(PSL_I); /* interrupts must be disabled */ + pcb2->pcb_gs = rgs(); + /* + * If we didn't copy the pcb, we'd need to do the following registers: + * pcb2->pcb_dr*: cloned above. + * pcb2->pcb_savefpu: cloned above. + * pcb2->pcb_flags: cloned above. + * pcb2->pcb_onfault: cloned above (always NULL here?). + * pcb2->pcb_gs: cloned above. XXXKSE ??? + * pcb2->pcb_ext: cleared below. + */ + pcb2->pcb_ext = NULL; +} + +/* + * Set that machine state for performing an upcall that has to + * be done in thread_userret() so that those upcalls generated + * in thread_userret() itself can be done as well. + */ +void +cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku) +{ + + /* + * Do any extra cleaning that needs to be done. + * The thread may have optional components + * that are not present in a fresh thread. + * This may be a recycled thread so make it look + * as though it's newly allocated. + */ + cpu_thread_clean(td); + + /* + * Set the trap frame to point at the beginning of the uts + * function. + */ + td->td_frame->tf_ebp = 0; + td->td_frame->tf_esp = + (int)ku->ku_stack.ss_sp + ku->ku_stack.ss_size - 16; + td->td_frame->tf_eip = (int)ku->ku_func; + + /* + * Pass the address of the mailbox for this kse to the uts + * function as a parameter on the stack. + */ + suword((void *)(td->td_frame->tf_esp + sizeof(void *)), + (int)ku->ku_mailbox); +} + +/* + * Convert kernel VA to physical address + */ +vm_paddr_t +kvtop(void *addr) +{ + vm_paddr_t pa; + + pa = pmap_kextract((vm_offset_t)addr); + if (pa == 0) + panic("kvtop: zero page frame"); + return (pa); +} + +/* + * Force reset the processor by invalidating the entire address space! + */ + +#ifdef SMP +static void +cpu_reset_proxy() +{ + + cpu_reset_proxy_active = 1; + while (cpu_reset_proxy_active == 1) + ; /* Wait for other cpu to see that we've started */ + stop_cpus((1<m == m) { + sf->ref_count++; + if (sf->ref_count == 1) { + TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry); + nsfbufsused++; + nsfbufspeak = imax(nsfbufspeak, nsfbufsused); + } + goto done; + } + } + while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) { + sf_buf_alloc_want++; + mbstat.sf_allocwait++; + error = msleep(&sf_buf_freelist, &sf_buf_lock, PVM | pri, + "sfbufa", 0); + sf_buf_alloc_want--; + + /* + * If we got a signal, don't risk going back to sleep. + */ + if (error) + goto done; + } + TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry); + if (sf->m != NULL) + LIST_REMOVE(sf, list_entry); + LIST_INSERT_HEAD(hash_list, sf, list_entry); + sf->ref_count = 1; + sf->m = m; + nsfbufsused++; + nsfbufspeak = imax(nsfbufspeak, nsfbufsused); + pmap_qenter(sf->kva, &sf->m, 1); +done: + mtx_unlock(&sf_buf_lock); + return (sf); +} + +/* + * Detatch mapped page and release resources back to the system. + */ +void +sf_buf_free(struct sf_buf *sf) +{ + mtx_lock(&sf_buf_lock); + sf->ref_count--; + if (sf->ref_count == 0) { + TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry); + nsfbufsused--; + /* XEN only */ + pmap_qremove(sf->kva, 1); + sf->m = NULL; + LIST_REMOVE(sf, list_entry); + /* ----- */ + if (sf_buf_alloc_want > 0) + wakeup_one(&sf_buf_freelist); + } + mtx_unlock(&sf_buf_lock); +} + +/* + * Software interrupt handler for queued VM system processing. + */ +void +swi_vm(void *dummy) +{ + if (busdma_swi_pending != 0) + busdma_swi(); +} + +/* + * Tell whether this address is in some physical memory region. + * Currently used by the kernel coredump code in order to avoid + * dumping the ``ISA memory hole'' which could cause indefinite hangs, + * or other unpredictable behaviour. + */ + +int +is_physical_memory(vm_paddr_t addr) +{ + +#ifdef DEV_ISA + /* The ISA ``memory hole''. */ + if (addr >= 0xa0000 && addr < 0x100000) + return 0; +#endif + + /* + * stuff other tests for known memory-mapped devices (PCI?) + * here + */ + + return 1; +} diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_bus.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_bus.c new file mode 100644 index 0000000000..96f6ca086b --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_bus.c @@ -0,0 +1,238 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +static MALLOC_DEFINE(M_XENDEV, "xenintrdrv", "xen system device"); + +struct xenbus_device { + struct resource_list xen_resources; +}; + +#define DEVTOXEN(dev) ((struct xenbus_device *)device_get_ivars(dev)) + +static void xenbus_identify(driver_t *, device_t); +static int xenbus_probe(device_t); +static int xenbus_attach(device_t); +static int xenbus_print_child(device_t, device_t); +static device_t xenbus_add_child(device_t bus, int order, const char *name, + int unit); +static struct resource *xenbus_alloc_resource(device_t, device_t, int, int *, + u_long, u_long, u_long, u_int); +static int xenbus_release_resource(device_t, device_t, int, int, + struct resource *); +static int xenbus_set_resource(device_t, device_t, int, int, u_long, u_long); +static int xenbus_get_resource(device_t, device_t, int, int, u_long *, u_long *); +static void xenbus_delete_resource(device_t, device_t, int, int); + + +static device_method_t xenbus_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, xenbus_identify), + DEVMETHOD(device_probe, xenbus_probe), + DEVMETHOD(device_attach, xenbus_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, xenbus_print_child), + DEVMETHOD(bus_add_child, xenbus_add_child), + DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), + DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), + DEVMETHOD(bus_set_resource, xenbus_set_resource), + DEVMETHOD(bus_get_resource, xenbus_get_resource), + DEVMETHOD(bus_alloc_resource, xenbus_alloc_resource), + DEVMETHOD(bus_release_resource, xenbus_release_resource), + DEVMETHOD(bus_delete_resource, xenbus_delete_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + + +static driver_t xenbus_driver = { + "xenbus", + xenbus_methods, + 1, /* no softc */ +}; +static devclass_t xenbus_devclass; +static device_t xenbus_dev; +static boolean_t xenbus_probe_delay = TRUE; /* delay child probes */ + +DRIVER_MODULE(xenbus, nexus, xenbus_driver, xenbus_devclass, 0, 0); + +static void +xenbus_identify(driver_t *driver, device_t parent) +{ + + /* + * Add child device with order of 0 so it gets probed + * first + */ + xenbus_dev = BUS_ADD_CHILD(parent, 0, "xenbus", 0); + if (xenbus_dev == NULL) + panic("xenbus: could not attach"); +} + +static int +xenbus_probe(device_t dev) +{ + device_set_desc(dev, "xen system"); + device_quiet(dev); + return (0); +} + +static int +xenbus_attach(device_t dev) +{ + /* + * First, let our child driver's identify any child devices that + * they can find. Once that is done attach any devices that we + * found. + */ + if (!xenbus_probe_delay) { + bus_generic_probe(dev); + bus_generic_attach(dev); + } + + return 0; +} + + +static int +xenbus_print_all_resources(device_t dev) +{ + struct xenbus_device *xdev = device_get_ivars(dev); + struct resource_list *rl = &xdev->xen_resources; + int retval = 0; + + if (SLIST_FIRST(rl)) + retval += printf(" at"); + + retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); + retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx"); + retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + + return retval; +} + + +static int +xenbus_print_child(device_t bus, device_t child) +{ + int retval = 0; + + retval += bus_print_child_header(bus, child); + retval += xenbus_print_all_resources(child); + retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */ + + return (retval); +} + +static device_t +xenbus_add_child(device_t bus, int order, const char *name, int unit) +{ + device_t child; + struct xenbus_device *xendev; + + xendev = malloc(sizeof(struct xenbus_device), M_XENDEV, + M_NOWAIT | M_ZERO); + if (!xendev) + return(0); + resource_list_init(&xendev->xen_resources); + + child = device_add_child_ordered(bus, order, name, unit); + + /* should we free this in xenbus_child_detached? */ + device_set_ivars(child, xendev); + + return(child); +} + +static struct resource * +xenbus_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct xenbus_device *xendev = DEVTOXEN(child); + struct resource_list *rl = &xendev->xen_resources; + + return (resource_list_alloc(rl, bus, child, type, rid, start, end, + count, flags)); +} + + +static int +xenbus_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + struct xenbus_device *xendev = DEVTOXEN(child); + struct resource_list *rl = &xendev->xen_resources; + + return (resource_list_release(rl, bus, child, type, rid, r)); +} + +static int +xenbus_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct xenbus_device *xendev = DEVTOXEN(child); + struct resource_list *rl = &xendev->xen_resources; + + resource_list_add(rl, type, rid, start, start + count - 1, count); + return(0); +} + +static int +xenbus_get_resource(device_t dev, device_t child, int type, int rid, + u_long *startp, u_long *countp) +{ + struct xenbus_device *xendev = DEVTOXEN(child); + struct resource_list *rl = &xendev->xen_resources; + struct resource_list_entry *rle; + + rle = resource_list_find(rl, type, rid); + if (!rle) + return(ENOENT); + if (startp) + *startp = rle->start; + if (countp) + *countp = rle->count; + return(0); +} + +static void +xenbus_delete_resource(device_t dev, device_t child, int type, int rid) +{ + struct xenbus_device *xendev = DEVTOXEN(child); + struct resource_list *rl = &xendev->xen_resources; + + resource_list_delete(rl, type, rid); +} + +static void +xenbus_init(void *unused) +{ + xenbus_probe_delay = FALSE; + xenbus_attach(xenbus_dev); +} +SYSINIT(xenbusdev, SI_SUB_PSEUDO, SI_ORDER_FIRST, xenbus_init, NULL); diff --git a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c new file mode 100644 index 0000000000..dd24a206b1 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/xen_machdep.c @@ -0,0 +1,687 @@ +/* $NetBSD:$ */ + +/* + * + * Copyright (c) 2004 Christian Limpach. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christian Limpach. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +shared_info_t *HYPERVISOR_shared_info; + +void ni_cli(void); +void ni_sti(void); +#ifdef NFS_ROOT + +static int +xdr_opaque_decode(struct mbuf **mptr, u_char *buf, int len) +{ + struct mbuf *m; + int alignedlen; + + m = *mptr; + alignedlen = ( len + 3 ) & ~3; + + if (m->m_len < alignedlen) { + m = m_pullup(m, alignedlen); + if (m == NULL) { + *mptr = NULL; + return EBADRPC; + } + } + bcopy(mtod(m, u_char *), buf, len); + m_adj(m, alignedlen); + *mptr = m; + return 0; +} + + +static int +getdec(char **ptr) +{ + char *p; + int ret; + + p = *ptr; + ret = 0; + if ((*p < '0') || (*p > '9')) + return -1; + while ((*p >= '0') && (*p <= '9')) { + ret = ret * 10 + (*p - '0'); + p++; + } + *ptr = p; + return ret; +} + +int +setinaddr(struct sockaddr_in *addr, char *ipstr) +{ + unsigned int ip; + int val; + + ip = 0; + if (((val = getdec(&ipstr)) < 0) || (val > 255)) + return 1; + ip = val << 24; + if (*ipstr != '.') + return 1; + ipstr++; + if (((val = getdec(&ipstr)) < 0) || (val > 255)) + return 1; + ip |= (val << 16); + if (*ipstr != '.') + return 1; + ipstr++; + if (((val = getdec(&ipstr)) < 0) || (val > 255)) + return 1; + ip |= (val << 8); + if (*ipstr != '.') + return 1; + ipstr++; + if (((val = getdec(&ipstr)) < 0) || (val > 255)) + return 1; + ip |= val; + + addr->sin_addr.s_addr = htonl(ip); + addr->sin_len = sizeof(struct sockaddr_in); + addr->sin_family = AF_INET; + + return 0; +} + +static int +hwaddr_to_sockaddr(char *ev, struct sockaddr_dl *sa) +{ + char *cp; + u_int32_t a[6]; + int count; + + bzero(sa, sizeof(*sa)); + sa->sdl_len = sizeof(*sa); + sa->sdl_family = AF_LINK; + sa->sdl_type = IFT_ETHER; + sa->sdl_alen = ETHER_ADDR_LEN; + if ((cp = getenv(ev)) == NULL) + return (1); + count = sscanf(cp, "%x:%x:%x:%x:%x:%x", + &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]); + freeenv(cp); + if (count != 6) + return (1); + sa->sdl_data[0] = a[0]; + sa->sdl_data[1] = a[1]; + sa->sdl_data[2] = a[2]; + sa->sdl_data[3] = a[3]; + sa->sdl_data[4] = a[4]; + sa->sdl_data[5] = a[5]; + return (0); +} +extern int in_control(struct socket *so, u_long cmd, + caddr_t data, struct ifnet *ifp, + struct thread *td); + +static int +xen_setnetwork(void) +{ + int error = 0; + struct ifaddr *ifa; + struct ifnet *ifp; + struct sockaddr_dl *sdl, ourdl; + + if (sizeof(struct sockaddr) != sizeof(struct sockaddr_in)) + panic("sizes not equal\n"); + + if (hwaddr_to_sockaddr("boot.netif.hwaddr", &ourdl)) { + printf("nfs_diskless: no hardware address\n"); + return -1; + } + + + ifa = NULL; + IFNET_RLOCK(); + TAILQ_FOREACH(ifp, &ifnet, if_link) { + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if ((ifa->ifa_addr->sa_family == AF_LINK) && + (sdl = ((struct sockaddr_dl *)ifa->ifa_addr))) { + if ((sdl->sdl_type == ourdl.sdl_type) && + (sdl->sdl_alen == ourdl.sdl_alen) && + !bcmp(sdl->sdl_data + sdl->sdl_nlen, + ourdl.sdl_data + ourdl.sdl_nlen, + sdl->sdl_alen)) { + IFNET_RUNLOCK(); + goto match_done; + } + } + } + } + IFNET_RUNLOCK(); + printf("nfs_diskless: no interface\n"); + return -1; /* no matching interface */ + match_done: + + if (getenv("boot.netif.ip") && getenv("boot.netif.gateway") && + getenv("boot.netif.netmask")) { + struct ifaliasreq ifra; + char *ip; + + bzero(&ifra, sizeof(ifra)); + strcpy(ifra.ifra_name, "xn0"); + ip = getenv("boot.netif.ip"); + setinaddr((struct sockaddr_in *)&(ifra.ifra_addr), ip); + printf("setting ip to %s\n", ip); + ip = getenv("boot.netif.netmask"); + setinaddr((struct sockaddr_in *)&ifra.ifra_mask, ip); + setinaddr((struct sockaddr_in *)&ifra.ifra_broadaddr, "255.255.255.255"); + + + if ((error = in_control(NULL, SIOCAIFADDR, (caddr_t) &ifra, ifp, curthread))) + printf("couldn't set interface address %d\n", error); +#if 0 + if ((error = xn_ioctl(ifp, SIOCSIFNETMASK, (caddr_t)&ifa))) + printf("couldn't set interface netmask %d\n", error); +#endif + } + return error; +} + +int +xen_setnfshandle(void) +{ + char *path, *ip; + u_char fhp[NFSX_V2FH]; + int error = 0; + struct sockaddr_in sin_local, *sin ; + struct mbuf *m; + + if ((error = xen_setnetwork())) + return error; + + sin = &sin_local; + + path = getenv("boot.nfsroot.path"); + ip = getenv("boot.nfsroot.server"); + + /* we aren't configured for NFS root */ + if (!path || !ip) + return 0; + + error = setinaddr(sin, ip); + if (error) { + printf("invalid ip address %s\n", ip); + return error; + } + + error = krpc_portmap(sin, RPCPROG_MNT, RPCMNT_VER1, + &sin->sin_port, curthread); + if (error) { + printf("failed to find port number for mountd\n"); + return error; + } + m = xdr_string_encode(path, strlen(path)); + + /* Do RPC to mountd */ + error = krpc_call(sin, RPCPROG_MNT, RPCMNT_VER1, + RPCMNT_MOUNT, &m, NULL, curthread); + if (error) { + printf("call to mountd failed\n"); + return error; + } + + if (xdr_opaque_decode(&m, fhp, NFSX_V2FH) != 0) { + printf("failed to decode nfs file handle\n"); + return error; + } + + setenv("boot.nfsroot.nfshandle", fhp); + + return 0; +} +#endif +void +ni_cli(void) +{ + __asm__("pushl %edx;" + "pushl %eax;" + ); + __cli(); + __asm__("popl %eax;" + "popl %edx;" + ); +} + + +void +ni_sti(void) +{ + __asm__("pushl %edx;" + "pushl %esi;" + "pushl %eax;" + ); + __sti(); + __asm__("popl %eax;" + "popl %esi;" + "popl %edx;" + ); +} + +/* + * Modify the cmd_line by converting ',' to NULLs so that it is in a format + * suitable for the static env vars. + */ +char * +xen_setbootenv(char *cmd_line) +{ + char *cmd_line_next; + + for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;); + return cmd_line; +} + +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + {"boot_askname", RB_ASKNAME}, + {"boot_cdrom", RB_CDROM}, + {"boot_userconfig", RB_CONFIG}, + {"boot_ddb", RB_KDB}, + {"boot_gdb", RB_GDB}, + {"boot_gdb_pause", RB_GDB_PAUSE}, + {"boot_single", RB_SINGLE}, + {"boot_verbose", RB_VERBOSE}, + {"boot_multicons", RB_MULTIPLE}, + {"boot_serial", RB_SERIAL}, + {NULL, 0} +}; + +int +xen_boothowto(char *envp) +{ + int i, howto = 0; + + /* get equivalents from the environment */ + for (i = 0; howto_names[i].ev != NULL; i++) + if (getenv(howto_names[i].ev) != NULL) + howto |= howto_names[i].mask; + return howto; +} + +#define PRINTK_BUFSIZE 1024 +void +printk(const char *fmt, ...) +{ + __va_list ap; + int ret; + static char buf[PRINTK_BUFSIZE]; + + va_start(ap, fmt); + ret = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap); + va_end(ap); + buf[ret] = 0; + (void)HYPERVISOR_console_write(buf, ret); +} + +#define XPQUEUE_SIZE 2048 + +typedef struct xpq_queue { + uint32_t ptr; + uint32_t val; +} xpq_queue_t; + +#define MCLQUEUE_SIZE 512 +static multicall_entry_t mcl_queue[MCLQUEUE_SIZE]; +static int mcl_idx = 0; + +static xpq_queue_t xpq_queue[XPQUEUE_SIZE]; +static boolean_t xpq_initialized; +static struct mtx update_lock; +static int xpq_idx = 0; + +/* + * Don't attempt to lock until after lock & memory initialization + */ +#define XPQ_LOCK(lock, flags) \ + if (likely(xpq_initialized)) \ + mtx_lock_irqsave(lock, flags) +#define XPQ_UNLOCK(lock, flags) \ + if (likely(xpq_initialized)) \ + mtx_unlock_irqrestore(lock, flags) + +void +xpq_init(void) +{ + xpq_initialized = TRUE; + mtx_init(&update_lock, "mmu", "MMU LOCK", MTX_SPIN); +} + +static __inline void +_xpq_flush_queue(void) +{ + int _xpq_idx = xpq_idx; + int error, i; + + xpq_idx = 0; + /* Make sure index is cleared first to avoid double updates. */ + error = HYPERVISOR_mmu_update((mmu_update_t *)xpq_queue, _xpq_idx, + NULL); + + if (__predict_false(error < 0)) { + for (i = 0; i < _xpq_idx; i++) + printk("val: %x ptr: %p\n", xpq_queue[i].val, xpq_queue[i].ptr); + panic("Failed to execute MMU updates: %d", error); + } + +} +static void +xpq_flush_queue(void) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + if (xpq_idx != 0) _xpq_flush_queue(); + XPQ_UNLOCK(&update_lock, flags); +} + +static __inline void +_mcl_flush_queue(void) +{ + int _mcl_idx = mcl_idx; + mcl_idx = 0; + (void)HYPERVISOR_multicall(mcl_queue, _mcl_idx); +} + +void +mcl_flush_queue(void) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + if (__predict_true(mcl_idx != 0)) _mcl_flush_queue(); + XPQ_UNLOCK(&update_lock, flags); + /* XXX: until we can remove the pervasive + * __HYPERVISOR_update_va_mapping calls, we have 2 queues. In order + * to ensure that they never get out of sync, only 1 flush interface + * is provided. + */ + xpq_flush_queue(); +} + + +static __inline void +xpq_increment_idx(void) +{ + xpq_idx++; + if (__predict_false(xpq_idx == XPQUEUE_SIZE)) + xpq_flush_queue(); +} + +static __inline void +mcl_increment_idx(void) +{ + mcl_idx++; + if (__predict_false(mcl_idx == MCLQUEUE_SIZE)) + mcl_flush_queue(); +} + +void +xpq_queue_invlpg(vm_offset_t va) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = (va & ~PAGE_MASK) | MMU_EXTENDED_COMMAND; + xpq_queue[xpq_idx].val = MMUEXT_INVLPG; + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +load_cr3(uint32_t val) +{ + xpq_queue_pt_switch(val); + xpq_flush_queue(); +} + +void +xen_set_ldt(vm_offset_t base, uint32_t entries) +{ + xpq_queue_set_ldt(base, entries); + _xpq_flush_queue(); +} + +void +xen_machphys_update(unsigned long mfn, unsigned long pfn) +{ + unsigned long flags = 0; + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; + xpq_queue[xpq_idx].val = pfn; + xpq_increment_idx(); + _xpq_flush_queue(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +xpq_queue_pt_update(pt_entry_t *ptr, pt_entry_t val) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = (uint32_t)ptr; + xpq_queue[xpq_idx].val = val; + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +mcl_queue_pt_update(vm_offset_t va, vm_paddr_t ma) +{ +#if 0 + printf("setting va %x to ma %x\n", va, ma); +#endif + unsigned long flags = 0; + XPQ_LOCK(&update_lock, flags); + mcl_queue[mcl_idx].op = __HYPERVISOR_update_va_mapping; + mcl_queue[mcl_idx].args[0] = (unsigned long)(va >> PAGE_SHIFT); + mcl_queue[mcl_idx].args[1] = (unsigned long)ma; + mcl_queue[mcl_idx].args[2] = 0; + mcl_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + + + +void +xpq_queue_pt_switch(uint32_t val) +{ + unsigned long flags = 0; + vm_paddr_t ma = xpmap_ptom(val) & PG_FRAME; + + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = ma | MMU_EXTENDED_COMMAND; + xpq_queue[xpq_idx].val = MMUEXT_NEW_BASEPTR; + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + + +void +xpq_queue_pin_table(uint32_t pa, int type) +{ + unsigned long flags = 0; + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND; + switch (type) { + case XPQ_PIN_L1_TABLE: + xpq_queue[xpq_idx].val = MMUEXT_PIN_L1_TABLE; + break; + case XPQ_PIN_L2_TABLE: + xpq_queue[xpq_idx].val = MMUEXT_PIN_L2_TABLE; + break; + } + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +xpq_queue_unpin_table(uint32_t pa) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + xpq_queue[xpq_idx].ptr = pa | MMU_EXTENDED_COMMAND; + xpq_queue[xpq_idx].val = MMUEXT_UNPIN_TABLE; + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +xpq_queue_set_ldt(vm_offset_t va, uint32_t entries) +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + KASSERT(va == (va & PG_FRAME), ("ldt not page aligned")); + xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND | va; + xpq_queue[xpq_idx].val = MMUEXT_SET_LDT | + (entries << MMUEXT_CMD_SHIFT); + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + +void +xpq_queue_tlb_flush() +{ + unsigned long flags = 0; + + XPQ_LOCK(&update_lock, flags); + + xpq_queue[xpq_idx].ptr = MMU_EXTENDED_COMMAND; + xpq_queue[xpq_idx].val = MMUEXT_TLB_FLUSH; + xpq_increment_idx(); + XPQ_UNLOCK(&update_lock, flags); +} + + +/********** CODE WORTH KEEPING ABOVE HERE *****************/ + +void xen_failsafe_handler(void); + +void +xen_failsafe_handler(void) +{ + + panic("xen_failsafe_handler called!\n"); +} + + +void +xen_update_descriptor(union descriptor *table, union descriptor *entry) +{ + vm_paddr_t pa; + pt_entry_t *ptp; + uint32_t raw[2]; + + bcopy(entry, raw, 2*sizeof(int32_t)); + ptp = vtopte((vm_offset_t)table); + pa = (*ptp & PG_FRAME) | ((vm_offset_t)table & PAGE_MASK); + if (HYPERVISOR_update_descriptor(pa, raw[0], raw[1])) + panic("HYPERVISOR_update_descriptor failed\n"); +} + + + +#if defined(XENDEBUG) +static void +xpmap_dump_pt(pt_entry_t *ptp, int p) +{ + pt_entry_t pte; + int j; + int bufpos; + + pte = xpmap_ptom((uint32_t)ptp - KERNTEXTOFF); + PRINTK(("%03x: %p(%p) %08x\n", p, ptp, (void *)pte, p << PDRSHIFT)); + + bufpos = 0; + for (j = 0; j < PTES_PER_PTP; j++) { + if ((ptp[j] & PG_V) == 0) + continue; + pte = ptp[j] /* & PG_FRAME */; + bufpos += sprintf(XBUF + bufpos, "%x:%03x:%08x ", + p, j, pte); + if (bufpos > 70) { + int k; + sprintf(XBUF + bufpos, "\n"); + PRINTK((XBUF)); + bufpos = 0; + for (k = 0; k < 1000000; k++); + } + } + if (bufpos) { + PRINTK((XBUF)); + bufpos = 0; + } +} +#endif + + diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/cpufunc.h b/freebsd-5.3-xen-sparse/i386-xen/include/cpufunc.h new file mode 100644 index 0000000000..fadc3a4a26 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/cpufunc.h @@ -0,0 +1,601 @@ +/*- + * Copyright (c) 1993 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/include/cpufunc.h,v 1.135 2003/08/06 18:21:27 bde Exp $ + */ + +/* + * Functions to provide access to special i386 instructions. + * This in included in sys/systm.h, and that file should be + * used in preference to this. + */ + +#ifndef _MACHINE_CPUFUNC_H_ +#define _MACHINE_CPUFUNC_H_ + +#include +#include +#define NO_EXCHANGE +#include +#include +#include +struct thread; +struct region_descriptor; + +__BEGIN_DECLS +#define readb(va) (*(volatile u_int8_t *) (va)) +#define readw(va) (*(volatile u_int16_t *) (va)) +#define readl(va) (*(volatile u_int32_t *) (va)) + +#define writeb(va, d) (*(volatile u_int8_t *) (va) = (d)) +#define writew(va, d) (*(volatile u_int16_t *) (va) = (d)) +#define writel(va, d) (*(volatile u_int32_t *) (va) = (d)) + +static __inline u_int +read_eflags(void) +{ + u_int ef; + __asm __volatile("pushfl; popl %0" : "=r" (ef)); + return (ef); +} + +static __inline void +write_eflags(u_int ef) +{ + __asm __volatile("pushl %0; popfl" : : "r" (ef)); +} +#ifdef __GNUC__ + +static __inline void +breakpoint(void) +{ + __asm __volatile("int $3"); +} + +static __inline u_int +bsfl(u_int mask) +{ + u_int result; + + __asm __volatile("bsfl %1,%0" : "=r" (result) : "rm" (mask)); + return (result); +} + +static __inline u_int +bsrl(u_int mask) +{ + u_int result; + + __asm __volatile("bsrl %1,%0" : "=r" (result) : "rm" (mask)); + return (result); +} +static __inline void +disable_intr(void) +{ + __cli(); +} +static __inline void +do_cpuid(u_int ax, u_int *p) +{ + __asm __volatile("cpuid" + : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); +} + +static __inline void +enable_intr(void) +{ + __sti(); +} + + +#define HAVE_INLINE_FFS + +static __inline int +ffs(int mask) +{ + /* + * Note that gcc-2's builtin ffs would be used if we didn't declare + * this inline or turn off the builtin. The builtin is faster but + * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later + * versions. + */ + return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1); +} + +#define HAVE_INLINE_FLS + +static __inline int +fls(int mask) +{ + return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); +} + +static __inline void +halt(void) +{ + __asm __volatile("hlt"); +} + +#if __GNUC__ < 2 + +#define inb(port) inbv(port) +#define outb(port, data) outbv(port, data) + +#else /* __GNUC >= 2 */ + +/* + * The following complications are to get around gcc not having a + * constraint letter for the range 0..255. We still put "d" in the + * constraint because "i" isn't a valid constraint when the port + * isn't constant. This only matters for -O0 because otherwise + * the non-working version gets optimized away. + * + * Use an expression-statement instead of a conditional expression + * because gcc-2.6.0 would promote the operands of the conditional + * and produce poor code for "if ((inb(var) & const1) == const2)". + * + * The unnecessary test `(port) < 0x10000' is to generate a warning if + * the `port' has type u_short or smaller. Such types are pessimal. + * This actually only works for signed types. The range check is + * careful to avoid generating warnings. + */ +#define inb(port) __extension__ ({ \ + u_char _data; \ + if (__builtin_constant_p(port) && ((port) & 0xffff) < 0x100 \ + && (port) < 0x10000) \ + _data = inbc(port); \ + else \ + _data = inbv(port); \ + _data; }) + +#define outb(port, data) ( \ + __builtin_constant_p(port) && ((port) & 0xffff) < 0x100 \ + && (port) < 0x10000 \ + ? outbc(port, data) : outbv(port, data)) + +static __inline u_char +inbc(u_int port) +{ + u_char data; + + __asm __volatile("inb %1,%0" : "=a" (data) : "id" ((u_short)(port))); + return (data); +} + +static __inline void +outbc(u_int port, u_char data) +{ + __asm __volatile("outb %0,%1" : : "a" (data), "id" ((u_short)(port))); +} + +#endif /* __GNUC <= 2 */ + +static __inline u_char +inbv(u_int port) +{ + u_char data; + /* + * We use %%dx and not %1 here because i/o is done at %dx and not at + * %edx, while gcc generates inferior code (movw instead of movl) + * if we tell it to load (u_short) port. + */ + __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); + return (data); +} + +static __inline u_int +inl(u_int port) +{ + u_int data; + + __asm __volatile("inl %%dx,%0" : "=a" (data) : "d" (port)); + return (data); +} + +static __inline void +insb(u_int port, void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; insb" + : "+D" (addr), "+c" (cnt) + : "d" (port) + : "memory"); +} + +static __inline void +insw(u_int port, void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; insw" + : "+D" (addr), "+c" (cnt) + : "d" (port) + : "memory"); +} + +static __inline void +insl(u_int port, void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; insl" + : "+D" (addr), "+c" (cnt) + : "d" (port) + : "memory"); +} + +static __inline void +invd(void) +{ + __asm __volatile("invd"); +} + +static __inline u_short +inw(u_int port) +{ + u_short data; + + __asm __volatile("inw %%dx,%0" : "=a" (data) : "d" (port)); + return (data); +} + +static __inline void +outbv(u_int port, u_char data) +{ + u_char al; + /* + * Use an unnecessary assignment to help gcc's register allocator. + * This make a large difference for gcc-1.40 and a tiny difference + * for gcc-2.6.0. For gcc-1.40, al had to be ``asm("ax")'' for + * best results. gcc-2.6.0 can't handle this. + */ + al = data; + __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port)); +} + +static __inline void +outl(u_int port, u_int data) +{ + /* + * outl() and outw() aren't used much so we haven't looked at + * possible micro-optimizations such as the unnecessary + * assignment for them. + */ + __asm __volatile("outl %0,%%dx" : : "a" (data), "d" (port)); +} + +static __inline void +outsb(u_int port, const void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; outsb" + : "+S" (addr), "+c" (cnt) + : "d" (port)); +} + +static __inline void +outsw(u_int port, const void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; outsw" + : "+S" (addr), "+c" (cnt) + : "d" (port)); +} + +static __inline void +outsl(u_int port, const void *addr, size_t cnt) +{ + __asm __volatile("cld; rep; outsl" + : "+S" (addr), "+c" (cnt) + : "d" (port)); +} + +static __inline void +outw(u_int port, u_short data) +{ + __asm __volatile("outw %0,%%dx" : : "a" (data), "d" (port)); +} + +static __inline void +ia32_pause(void) +{ + __asm __volatile("pause"); +} + +static __inline u_int64_t +rdmsr(u_int msr) +{ + u_int64_t rv; + + __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr)); + return (rv); +} + +static __inline u_int64_t +rdpmc(u_int pmc) +{ + u_int64_t rv; + + __asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc)); + return (rv); +} + +static __inline u_int64_t +rdtsc(void) +{ + u_int64_t rv; + + __asm __volatile("rdtsc" : "=A" (rv)); + return (rv); +} + +static __inline void +wbinvd(void) +{ + __asm __volatile("wbinvd"); +} + +static __inline void +wrmsr(u_int msr, u_int64_t newval) +{ + __asm __volatile("wrmsr" : : "A" (newval), "c" (msr)); +} + +static __inline u_int +rfs(void) +{ + u_int sel; + __asm __volatile("movl %%fs,%0" : "=rm" (sel)); + return (sel); +} + +static __inline u_int +rgs(void) +{ + u_int sel; + __asm __volatile("movl %%gs,%0" : "=rm" (sel)); + return (sel); +} + +static __inline void +load_fs(u_int sel) +{ + __asm __volatile("movl %0,%%fs" : : "rm" (sel)); +} + +static __inline void +load_gs(u_int sel) +{ + __asm __volatile("movl %0,%%gs" : : "rm" (sel)); +} + +/* void lidt(struct region_descriptor *addr); */ +static __inline void +lidt(struct region_descriptor *addr) +{ + __asm __volatile("lidt (%0)" : : "r" (addr)); +} + +static __inline u_int +rdr0(void) +{ + u_int data; + __asm __volatile("movl %%dr0,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr0(u_int dr0) +{ + __asm __volatile("movl %0,%%dr0" : : "r" (dr0)); +} + +static __inline u_int +rdr1(void) +{ + u_int data; + __asm __volatile("movl %%dr1,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr1(u_int dr1) +{ + __asm __volatile("movl %0,%%dr1" : : "r" (dr1)); +} + +static __inline u_int +rdr2(void) +{ + u_int data; + __asm __volatile("movl %%dr2,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr2(u_int dr2) +{ + __asm __volatile("movl %0,%%dr2" : : "r" (dr2)); +} + +static __inline u_int +rdr3(void) +{ + u_int data; + __asm __volatile("movl %%dr3,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr3(u_int dr3) +{ + __asm __volatile("movl %0,%%dr3" : : "r" (dr3)); +} + +static __inline u_int +rdr4(void) +{ + u_int data; + __asm __volatile("movl %%dr4,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr4(u_int dr4) +{ + __asm __volatile("movl %0,%%dr4" : : "r" (dr4)); +} + +static __inline u_int +rdr5(void) +{ + u_int data; + __asm __volatile("movl %%dr5,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr5(u_int dr5) +{ + __asm __volatile("movl %0,%%dr5" : : "r" (dr5)); +} + +static __inline u_int +rdr6(void) +{ + u_int data; + __asm __volatile("movl %%dr6,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr6(u_int dr6) +{ + __asm __volatile("movl %0,%%dr6" : : "r" (dr6)); +} + +static __inline u_int +rdr7(void) +{ + u_int data; + __asm __volatile("movl %%dr7,%0" : "=r" (data)); + return (data); +} + +static __inline void +load_dr7(u_int dr7) +{ + __asm __volatile("movl %0,%%dr7" : : "r" (dr7)); +} + +static __inline register_t +intr_disable(void) +{ + register_t eflags; + + __save_and_cli(eflags); + return (eflags); +} + +static __inline void +intr_restore(register_t eflags) +{ + __restore_flags(eflags); +} + +#else /* !__GNUC__ */ + +int breakpoint(void); +u_int bsfl(u_int mask); +u_int bsrl(u_int mask); +void cpu_invlpg(u_int addr); +void cpu_invlpg_range(u_int start, u_int end); +void disable_intr(void); +void do_cpuid(u_int ax, u_int *p); +void enable_intr(void); +void halt(void); +u_char inb(u_int port); +u_int inl(u_int port); +void insb(u_int port, void *addr, size_t cnt); +void insl(u_int port, void *addr, size_t cnt); +void insw(u_int port, void *addr, size_t cnt); +void invd(void); +void invlpg(u_int addr); +void invlpg_range(u_int start, u_int end); +void invltlb(void); +u_short inw(u_int port); +void load_cr3(u_int cr3); +void load_cr4(u_int cr4); +void load_fs(u_int sel); +void load_gs(u_int sel); +struct region_descriptor; +void lidt(struct region_descriptor *addr); +void ltr(u_short sel); +void outb(u_int port, u_char data); +void outl(u_int port, u_int data); +void outsb(u_int port, void *addr, size_t cnt); +void outsl(u_int port, void *addr, size_t cnt); +void outsw(u_int port, void *addr, size_t cnt); +void outw(u_int port, u_short data); +void ia32_pause(void); +u_int rcr2(void); +u_int rcr3(void); +u_int rcr4(void); +u_int rfs(void); +u_int rgs(void); +u_int64_t rdmsr(u_int msr); +u_int64_t rdpmc(u_int pmc); +u_int64_t rdtsc(void); +u_int read_eflags(void); +void wbinvd(void); +void write_eflags(u_int ef); +void wrmsr(u_int msr, u_int64_t newval); +u_int rdr0(void); +void load_dr0(u_int dr0); +u_int rdr1(void); +void load_dr1(u_int dr1); +u_int rdr2(void); +void load_dr2(u_int dr2); +u_int rdr3(void); +void load_dr3(u_int dr3); +u_int rdr4(void); +void load_dr4(u_int dr4); +u_int rdr5(void); +void load_dr5(u_int dr5); +u_int rdr6(void); +void load_dr6(u_int dr6); +u_int rdr7(void); +void load_dr7(u_int dr7); +register_t intr_disable(void); +void intr_restore(register_t ef); + +#endif /* __GNUC__ */ + +void reset_dbregs(void); + +__END_DECLS + +#endif /* !_MACHINE_CPUFUNC_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/ctrl_if.h b/freebsd-5.3-xen-sparse/i386-xen/include/ctrl_if.h new file mode 100644 index 0000000000..1ccd49d448 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/ctrl_if.h @@ -0,0 +1,120 @@ +/****************************************************************************** + * ctrl_if.h + * + * Management functions for special interface to the domain controller. + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __I386_XENO__CTRL_IF_H__ +#define __I386_XENO__CTRL_IF_H__ + +#include +#include + + +typedef control_msg_t ctrl_msg_t; + +/* + * Callback function type. Called for asynchronous processing of received + * request messages, and responses to previously-transmitted request messages. + * The parameters are (@msg, @id). + * @msg: Original request/response message (not a copy). The message can be + * modified in-place by the handler (e.g., a response callback can + * turn a request message into a response message in place). The message + * is no longer accessible after the callback handler returns -- if the + * message is required to persist for longer then it must be copied. + * @id: (Response callbacks only) The 'id' that was specified when the + * original request message was queued for transmission. + */ +typedef void (*ctrl_msg_handler_t)(ctrl_msg_t *, unsigned long); + +/* + * Send @msg to the domain controller. Execute @hnd when a response is + * received, passing the response message and the specified @id. This + * operation will not block: it will return -EAGAIN if there is no space. + * Notes: + * 1. The @msg is copied if it is transmitted and so can be freed after this + * function returns. + * 2. If @hnd is NULL then no callback is executed. + */ +int ctrl_if_send_message_noblock( + ctrl_msg_t *msg, + ctrl_msg_handler_t hnd, + unsigned long id); + +/* + * Send @msg to the domain controller. Execute @hnd when a response is + * received, passing the response message and the specified @id. This + * operation will block until the message is sent, or a signal is received + * for the calling process (unless @wait_state is TASK_UNINTERRUPTIBLE). + * Notes: + * 1. The @msg is copied if it is transmitted and so can be freed after this + * function returns. + * 2. If @hnd is NULL then no callback is executed. + */ +int ctrl_if_send_message_block( + ctrl_msg_t *msg, + ctrl_msg_handler_t hnd, + unsigned long id, + long wait_state); + +/* + * Request a callback when there is /possibly/ space to immediately send a + * message to the domain controller. This function returns 0 if there is + * already space to trasnmit a message --- in this case the callback task /may/ + * still be executed. If this function returns 1 then the callback /will/ be + * executed when space becomes available. + */ +int ctrl_if_enqueue_space_callback(struct task *task); + +/* + * Send a response (@msg) to a message from the domain controller. This will + * never block. + * Notes: + * 1. The @msg is copied and so can be freed after this function returns. + * 2. The @msg may be the original request message, modified in-place. + */ +void ctrl_if_send_response(ctrl_msg_t *msg); + +/* + * Register a receiver for typed messages from the domain controller. The + * handler (@hnd) is called for every received message of specified @type. + * Returns TRUE (non-zero) if the handler was successfully registered. + * If CALLBACK_IN_BLOCKING CONTEXT is specified in @flags then callbacks will + * occur in a context in which it is safe to yield (i.e., process context). + */ +#define CALLBACK_IN_BLOCKING_CONTEXT 1 +int ctrl_if_register_receiver( + uint8_t type, + ctrl_msg_handler_t hnd, + unsigned int flags); + +/* + * Unregister a receiver for typed messages from the domain controller. The + * handler (@hnd) will not be executed after this function returns. + */ +void ctrl_if_unregister_receiver(uint8_t type, ctrl_msg_handler_t hnd); + +/* Suspend/resume notifications. */ +void ctrl_if_suspend(void); +void ctrl_if_resume(void); + + +/* + * Returns TRUE if there are no outstanding message requests at the domain + * controller. This can be used to ensure that messages have really flushed + * through when it is not possible to use the response-callback interface. + * WARNING: If other subsystems are using the control interface then this + * function might never return TRUE! + */ +int ctrl_if_transmitter_empty(void); /* !! DANGEROUS FUNCTION !! */ + +/* + * Manually discard response messages from the domain controller. + * WARNING: This is usually done automatically -- this function should only + * be called when normal interrupt mechanisms are disabled! + */ +void ctrl_if_discard_responses(void); /* !! DANGEROUS FUNCTION !! */ + +#endif /* __ASM_XEN__CONTROL_IF_H__ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/evtchn.h b/freebsd-5.3-xen-sparse/i386-xen/include/evtchn.h new file mode 100644 index 0000000000..3e962e3014 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/evtchn.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * evtchn.h + * + * Communication via Xen event channels. + * Also definitions for the device that demuxes notifications to userspace. + * + * Copyright (c) 2004, K A Fraser + */ + +#ifndef __ASM_EVTCHN_H__ +#define __ASM_EVTCHN_H__ + +#include +#include +#include + +/* + * LOW-LEVEL DEFINITIONS + */ + +/* Force a proper event-channel callback from Xen. */ +void force_evtchn_callback(void); + +/* Entry point for notifications into Linux subsystems. */ +void evtchn_do_upcall(struct intrframe *frame); + +/* Entry point for notifications into the userland character device. */ +void evtchn_device_upcall(int port); + +static inline void +mask_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + synch_set_bit(port, &s->evtchn_mask[0]); +} + +static inline void +unmask_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + + 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>>5, &s->evtchn_pending_sel) ) + { + s->vcpu_data[0].evtchn_upcall_pending = 1; + if ( !s->vcpu_data[0].evtchn_upcall_mask ) + force_evtchn_callback(); + } +} + +static inline void +clear_evtchn(int port) +{ + shared_info_t *s = HYPERVISOR_shared_info; + synch_clear_bit(port, &s->evtchn_pending[0]); +} + +static inline void +notify_via_evtchn(int port) +{ + evtchn_op_t op; + op.cmd = EVTCHNOP_send; + op.u.send.local_port = port; + (void)HYPERVISOR_event_channel_op(&op); +} + +/* + * CHARACTER-DEVICE DEFINITIONS + */ + +#define PORT_NORMAL 0x0000 +#define PORT_EXCEPTION 0x8000 +#define PORTIDX_MASK 0x7fff + +/* /dev/xen/evtchn resides at device number major=10, minor=200 */ +#define EVTCHN_MINOR 200 + +/* /dev/xen/evtchn ioctls: */ +/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */ +#define EVTCHN_RESET _IO('E', 1) +/* EVTCHN_BIND: Bind to the specified event-channel port. */ +#define EVTCHN_BIND _IO('E', 2) +/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */ +#define EVTCHN_UNBIND _IO('E', 3) + +#endif /* __ASM_EVTCHN_H__ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/frame.h b/freebsd-5.3-xen-sparse/i386-xen/include/frame.h new file mode 100644 index 0000000000..a6572d85a9 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/frame.h @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)frame.h 5.2 (Berkeley) 1/18/91 + * $FreeBSD: src/sys/i386/include/frame.h,v 1.23 2003/07/22 08:11:15 peter Exp $ + */ + +#ifndef _MACHINE_FRAME_H_ +#define _MACHINE_FRAME_H_ 1 + +/* + * System stack frames. + */ + +/* + * Exception/Trap Stack Frame + */ + +struct trapframe { + int tf_fs; + int tf_es; + int tf_ds; + int tf_edi; + int tf_esi; + int tf_ebp; + int tf_isp; + int tf_ebx; + int tf_edx; + int tf_ecx; + int tf_eax; + int tf_trapno; + int tf_cr2; + /* below portion defined in 386 hardware */ + int tf_err; + int tf_eip; + int tf_cs; + int tf_eflags; + /* below only when crossing rings (e.g. user to kernel) */ + int tf_esp; + int tf_ss; +}; + +/* Interrupt stack frame */ + +struct intrframe { + int if_fs; + int if_es; + int if_ds; + int if_edi; + int if_esi; + int if_ebp; + int :32; + int if_ebx; + int if_edx; + int if_ecx; + int if_eax; + int :32; /* for compat with trap frame - trapno */ + int if_vec; /* cr2 in trap frame */ + int :32; /* for compat with trap frame - err */ + /* below portion defined in 386 hardware */ + int if_eip; + int if_cs; + int if_eflags; + /* below only when crossing rings (e.g. user to kernel) */ + int if_esp; + int if_ss; +}; + +/* frame of clock (same as interrupt frame) */ + +struct clockframe { + int cf_fs; + int cf_es; + int cf_ds; + int cf_edi; + int cf_esi; + int cf_ebp; + int :32; + int cf_ebx; + int cf_edx; + int cf_ecx; + int cf_eax; + int :32; /* for compat with trap frame - trapno */ + int cf_vec; /* cr2 in trap frame */ + int :32; /* for compat with trap frame - err */ + /* below portion defined in 386 hardware */ + int cf_eip; + int cf_cs; + int cf_eflags; + /* below only when crossing rings (e.g. user to kernel) */ + int cf_esp; + int cf_ss; +}; + +#define INTR_TO_TRAPFRAME(frame) ((struct trapframe *)&(frame)->if_fs) + +#endif /* _MACHINE_FRAME_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h new file mode 100644 index 0000000000..4f75d27a9a --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h @@ -0,0 +1,36 @@ +#ifndef _HYPERVISOR_IFS_H_ +#define _HYPERVISOR_IFS_H_ + +#define s8 int8_t +#define s16 int16_t +#define s32 int32_t +#define s64 int64_t + +#define u8 uint8_t +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t + +#include +#include +#include +#include +#include +#include +#include +#include +#undef blkif_sector_t /* XXX pre-processor didn't do the */ +#define blkif_sector_t uint64_t /* right thing */ + +#undef s8 +#undef s16 +#undef s32 +#undef s64 + +#undef u8 +#undef u16 +#undef u32 +#undef u64 + + +#endif diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h new file mode 100644 index 0000000000..95ee85f352 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h @@ -0,0 +1,355 @@ +/****************************************************************************** + * hypervisor.h + * + * Linux-specific hypervisor handling. + * + * Copyright (c) 2002, K A Fraser + */ + +#ifndef __HYPERVISOR_H__ +#define __HYPERVISOR_H__ + + +#include +#include +#include "opt_xen.h" + +extern start_info_t *xen_start_info; + +/* arch/xen/mm/hypervisor.c */ +/* + * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already + * be MACHINE addresses. + */ + + +void MULTICALL_flush_page_update_queue(void); + +#ifdef CONFIG_XEN_PHYSDEV_ACCESS +/* Allocate a contiguous empty region of low memory. Return virtual start. */ +unsigned long allocate_empty_lowmem_region(unsigned long pages); +/* Deallocate a contiguous region of low memory. Return it to the allocator. */ +void deallocate_lowmem_region(unsigned long vstart, unsigned long pages); +#endif + +typedef struct { unsigned long pte_low, pte_high; } pte_t; + +/* + * Assembler stubs for hyper-calls. + */ + +static inline int HYPERVISOR_set_trap_table(trap_info_t *table) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table), + "b" (table) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_mmu_update(mmu_update_t *req, + int count, + int *success_count) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), + "b" (req), "c" (count), "d" (success_count) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), + "b" (frame_list), "c" (entries) : "memory" ); + + + return ret; +} + +static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_stack_switch), + "b" (ss), "c" (esp) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_set_callbacks( + unsigned long event_selector, unsigned long event_address, + unsigned long failsafe_selector, unsigned long failsafe_address) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), + "b" (event_selector), "c" (event_address), + "d" (failsafe_selector), "S" (failsafe_address) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_fpu_taskswitch(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_yield(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_yield) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_block(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_block) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_shutdown(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_reboot(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_suspend(unsigned long srec) +{ + int ret; + /* NB. On suspend, control software expects a suspend record in %esi. */ + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), + "S" (srec) : "memory" ); + + return ret; +} + +static inline long HYPERVISOR_set_timer_op(uint64_t timeout) +{ + int ret; + unsigned long timeout_hi = (unsigned long)(timeout>>32); + unsigned long timeout_lo = (unsigned long)timeout; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op), + "b" (timeout_hi), "c" (timeout_lo) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op) +{ + int ret; + dom0_op->interface_version = DOM0_INTERFACE_VERSION; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), + "b" (dom0_op) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), + "b" (reg), "c" (value) : "memory" ); + + return ret; +} + +static inline unsigned long HYPERVISOR_get_debugreg(int reg) +{ + unsigned long ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), + "b" (reg) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_update_descriptor( + unsigned long pa, unsigned long word1, unsigned long word2) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), + "b" (pa), "c" (word1), "d" (word2) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_set_fast_trap(int idx) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap), + "b" (idx) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_dom_mem_op(unsigned int op, + unsigned long *pages, + unsigned long nr_pages) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), + "b" (op), "c" (pages), "d" (nr_pages) : "memory" ); + return ret; +} + +static inline int HYPERVISOR_multicall(void *call_list, int nr_calls) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_multicall), + "b" (call_list), "c" (nr_calls) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_update_va_mapping( + unsigned long page_nr, pte_t new_val, unsigned long flags) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), + "b" (page_nr), "c" ((new_val).pte_low), "d" (flags): + "memory" ); + /* XXX */ +#if 0 + if ( unlikely(ret < 0) ) + panic("Failed update VA mapping: %08lx, %08lx, %08lx", + page_nr, (new_val).pte_low, flags); +#endif + return ret; +} + +static inline int HYPERVISOR_event_channel_op(void *op) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_event_channel_op), + "b" (op) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_xen_version(int cmd) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_xen_version), + "b" (cmd) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_console_io(int cmd, int count, char *str) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_console_io), + "b" (cmd), "c" (count), "d" (str) : "memory" ); + + return ret; +} + +static __inline int HYPERVISOR_console_write(char *str, int count) +{ + return HYPERVISOR_console_io(CONSOLEIO_write, count, str); +} + +static inline int HYPERVISOR_physdev_op(void *physdev_op) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_physdev_op), + "b" (physdev_op) : "memory" ); + + return ret; +} + +static inline int HYPERVISOR_update_va_mapping_otherdomain( + unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain), + "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) : + "memory" ); + + return ret; +} + +static inline int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_vm_assist), + "b" (cmd), "c" (type) : "memory" ); + + return ret; +} + +#endif /* __HYPERVISOR_H__ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/md_var.h b/freebsd-5.3-xen-sparse/i386-xen/include/md_var.h new file mode 100644 index 0000000000..5822a1e3d1 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/md_var.h @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 1995 Bruce D. Evans. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/include/md_var.h,v 1.66 2003/11/03 22:37:28 jhb Exp $ + */ + +#ifndef _MACHINE_MD_VAR_H_ +#define _MACHINE_MD_VAR_H_ + +/* + * Miscellaneous machine-dependent declarations. + */ + +extern void (*bcopy_vector)(const void *from, void *to, size_t len); +extern void (*bzero_vector)(void *buf, size_t len); +extern int (*copyin_vector)(const void *udaddr, void *kaddr, size_t len); +extern int (*copyout_vector)(const void *kaddr, void *udaddr, size_t len); + +extern long Maxmem; +extern u_int atdevbase; /* offset in virtual memory of ISA io mem */ +extern u_int basemem; /* PA of original top of base memory */ +extern int busdma_swi_pending; +extern u_int cpu_exthigh; +extern u_int cpu_feature; +extern u_int cpu_fxsr; +extern u_int cpu_high; +extern u_int cpu_id; +extern u_int cpu_procinfo; +extern char cpu_vendor[]; +extern u_int cyrix_did; +extern uint16_t *elan_mmcr; +extern char kstack[]; +#ifdef PC98 +extern int need_pre_dma_flush; +extern int need_post_dma_flush; +#endif +extern char sigcode[]; +extern int szsigcode; +#ifdef COMPAT_FREEBSD4 +extern int szfreebsd4_sigcode; +#endif +#ifdef COMPAT_43 +extern int szosigcode; +#endif + +typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss); +struct thread; +struct reg; +struct fpreg; +struct dbreg; + +void bcopyb(const void *from, void *to, size_t len); +void busdma_swi(void); +void cpu_setregs(void); +void cpu_switch_load_gs(void) __asm(__STRING(cpu_switch_load_gs)); +void doreti_iret(void) __asm(__STRING(doreti_iret)); +void doreti_iret_fault(void) __asm(__STRING(doreti_iret_fault)); +void doreti_popl_ds(void) __asm(__STRING(doreti_popl_ds)); +void doreti_popl_ds_fault(void) __asm(__STRING(doreti_popl_ds_fault)); +void doreti_popl_es(void) __asm(__STRING(doreti_popl_es)); +void doreti_popl_es_fault(void) __asm(__STRING(doreti_popl_es_fault)); +void doreti_popl_fs(void) __asm(__STRING(doreti_popl_fs)); +void doreti_popl_fs_fault(void) __asm(__STRING(doreti_popl_fs_fault)); +void scrit(void) __asm(__STRING(scrit)); +void ecrit(void) __asm(__STRING(ecrit)); +void critical_region_fixup(void) __asm(__STRING(critical_region_fixup)); +void enable_sse(void); +void fillw(int /*u_short*/ pat, void *base, size_t cnt); +void i486_bzero(void *buf, size_t len); +void i586_bcopy(const void *from, void *to, size_t len); +void i586_bzero(void *buf, size_t len); +int i586_copyin(const void *udaddr, void *kaddr, size_t len); +int i586_copyout(const void *kaddr, void *udaddr, size_t len); +void i686_pagezero(void *addr); +void sse2_pagezero(void *addr); +void init_AMD_Elan_sc520(void); +int is_physical_memory(vm_offset_t addr); +int isa_nmi(int cd); +vm_paddr_t kvtop(void *addr); +void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec); +int user_dbreg_trap(void); + +#endif /* !_MACHINE_MD_VAR_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/multicall.h b/freebsd-5.3-xen-sparse/i386-xen/include/multicall.h new file mode 100644 index 0000000000..30de865ee2 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/multicall.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * multicall.h + */ + +#ifndef __MULTICALL_H__ +#define __MULTICALL_H__ + +#include +#define MAX_MULTICALL_ENTS 8 +extern multicall_entry_t multicall_list[]; +extern int nr_multicall_ents; + +static inline void execute_multicall_list(void) +{ + if ( unlikely(nr_multicall_ents == 0) ) return; + (void)HYPERVISOR_multicall(multicall_list, nr_multicall_ents); + nr_multicall_ents = 0; +} + + +static inline void handle_edge(void) +{ + if (unlikely(nr_multicall_ents == MAX_MULTICALL_ENTS)) + execute_multicall_list(); +} + +static inline void queue_multicall0(unsigned long op) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + nr_multicall_ents = i+1; + handle_edge(); +} + +static inline void queue_multicall1(unsigned long op, unsigned long arg1) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + multicall_list[i].args[0] = arg1; + nr_multicall_ents = i+1; + handle_edge(); +} + +static inline void queue_multicall2( + unsigned long op, unsigned long arg1, unsigned long arg2) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + multicall_list[i].args[0] = arg1; + multicall_list[i].args[1] = arg2; + nr_multicall_ents = i+1; + handle_edge(); +} + +static inline void queue_multicall3( + unsigned long op, unsigned long arg1, unsigned long arg2, + unsigned long arg3) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + multicall_list[i].args[0] = arg1; + multicall_list[i].args[1] = arg2; + multicall_list[i].args[2] = arg3; + nr_multicall_ents = i+1; + handle_edge(); +} + +static inline void queue_multicall4( + unsigned long op, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + multicall_list[i].args[0] = arg1; + multicall_list[i].args[1] = arg2; + multicall_list[i].args[2] = arg3; + multicall_list[i].args[3] = arg4; + nr_multicall_ents = i+1; + handle_edge(); +} + +static inline void queue_multicall5( + unsigned long op, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5) +{ + int i = nr_multicall_ents; + multicall_list[i].op = op; + multicall_list[i].args[0] = arg1; + multicall_list[i].args[1] = arg2; + multicall_list[i].args[2] = arg3; + multicall_list[i].args[3] = arg4; + multicall_list[i].args[4] = arg5; + nr_multicall_ents = i+1; + handle_edge(); +} + + +#endif /* __MULTICALL_H__ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/param.h b/freebsd-5.3-xen-sparse/i386-xen/include/param.h new file mode 100644 index 0000000000..a45fdd67c3 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/param.h @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)param.h 5.8 (Berkeley) 6/28/91 + * $FreeBSD: src/sys/i386/include/param.h,v 1.69 2003/06/14 23:23:53 alc Exp $ + */ + +/* + * Machine dependent constants for Intel 386. + */ + +/* + * Round p (pointer or byte index) up to a correctly-aligned value + * for all data types (int, long, ...). The result is unsigned int + * and must be cast to any desired pointer type. + */ +#ifndef _ALIGNBYTES +#define _ALIGNBYTES (sizeof(int) - 1) +#endif +#ifndef _ALIGN +#define _ALIGN(p) (((unsigned)(p) + _ALIGNBYTES) & ~_ALIGNBYTES) +#endif + +#ifndef _MACHINE +#define _MACHINE i386-xen +#endif +#ifndef _MACHINE_ARCH +#define _MACHINE_ARCH i386-xen +#endif + +#ifndef _NO_NAMESPACE_POLLUTION + +#ifndef _MACHINE_PARAM_H_ +#define _MACHINE_PARAM_H_ + +#ifndef MACHINE +#define MACHINE "i386" +#endif +#ifndef MACHINE_ARCH +#define MACHINE_ARCH "i386" +#endif +#define MID_MACHINE MID_I386 + +#ifdef SMP +#define MAXCPU 16 +#else +#define MAXCPU 1 +#endif /* SMP */ + +#define ALIGNBYTES _ALIGNBYTES +#define ALIGN(p) _ALIGN(p) + +#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ +#define PAGE_SIZE (1<> PAGE_SHIFT) +#define ptoa(x) ((x) << PAGE_SHIFT) + +#define i386_btop(x) ((x) >> PAGE_SHIFT) +#define i386_ptob(x) ((x) << PAGE_SHIFT) + +#define pgtok(x) ((x) * (PAGE_SIZE / 1024)) + +#endif /* !_MACHINE_PARAM_H_ */ +#endif /* !_NO_NAMESPACE_POLLUTION */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/pcb.h b/freebsd-5.3-xen-sparse/i386-xen/include/pcb.h new file mode 100644 index 0000000000..ff68761540 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/pcb.h @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 + * $FreeBSD: src/sys/i386/include/pcb.h,v 1.50 2003/09/30 08:11:36 jeff Exp $ + */ + +#ifndef _I386_PCB_H_ +#define _I386_PCB_H_ + +/* + * Intel 386 process control block + */ +#include + +struct pcb { + int pcb_cr3; + int pcb_edi; + int pcb_esi; + int pcb_ebp; + int pcb_esp; + int pcb_eax; + int pcb_ebx; + int pcb_ecx; + int pcb_edx; + int pcb_eip; + + int pcb_dr0; + int pcb_dr1; + int pcb_dr2; + int pcb_dr3; + int pcb_dr6; + int pcb_dr7; + + union savefpu pcb_save; + u_int pcb_flags; +#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */ +#define PCB_DBREGS 0x02 /* process using debug registers */ +#define PCB_NPXTRAP 0x04 /* npx trap pending */ +#define PCB_NPXINITDONE 0x08 /* fpu state is initialized */ +#define PCB_VM86CALL 0x10 /* in vm86 call */ + + caddr_t pcb_onfault; /* copyin/out fault recovery */ + int pcb_cs; + int pcb_ds; + int pcb_ss; + int pcb_es; + int pcb_gs; + int pcb_fs; + struct pcb_ext *pcb_ext; /* optional pcb extension */ + int pcb_psl; /* process status long */ + void (*pcb_switchout)(void); /* Special switchout function. */ + u_long __pcb_spare[2]; /* adjust to avoid core dump size changes */ +}; + +#ifdef _KERNEL +struct trapframe; + +void makectx(struct trapframe *, struct pcb *); + +void savectx(struct pcb *); +#endif + +#endif /* _I386_PCB_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/pcpu.h b/freebsd-5.3-xen-sparse/i386-xen/include/pcpu.h new file mode 100644 index 0000000000..80a675cd4a --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/pcpu.h @@ -0,0 +1,173 @@ +/*- + * Copyright (c) Peter Wemm + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/include/pcpu.h,v 1.41 2003/11/20 23:23:22 peter Exp $ + */ + +#ifndef _MACHINE_PCPU_H_ +#define _MACHINE_PCPU_H_ + +#ifdef _KERNEL + +#include +#include + +/* + * The SMP parts are setup in pmap.c and locore.s for the BSP, and + * mp_machdep.c sets up the data for the AP's to "see" when they awake. + * The reason for doing it via a struct is so that an array of pointers + * to each CPU's data can be set up for things like "check curproc on all + * other processors" + */ +#define PCPU_MD_FIELDS \ + struct pcpu *pc_prvspace; /* Self-reference */ \ + struct pmap *pc_curpmap; \ + struct i386tss pc_common_tss; \ + struct segment_descriptor pc_common_tssd; \ + struct segment_descriptor *pc_tss_gdt; \ + int pc_currentldt; \ + u_int pc_acpi_id; \ + u_int pc_apic_id; \ + u_int pc_faultaddr; \ + u_int pc_trap_nesting; \ + u_int pc_pdir + +#if defined(lint) + +extern struct pcpu *pcpup; + +#define PCPU_GET(member) (pcpup->pc_ ## member) +#define PCPU_PTR(member) (&pcpup->pc_ ## member) +#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) + +#elif defined(__GNUC__) + +/* + * Evaluates to the byte offset of the per-cpu variable name. + */ +#define __pcpu_offset(name) \ + __offsetof(struct pcpu, name) + +/* + * Evaluates to the type of the per-cpu variable name. + */ +#define __pcpu_type(name) \ + __typeof(((struct pcpu *)0)->name) + +/* + * Evaluates to the address of the per-cpu variable name. + */ +#define __PCPU_PTR(name) __extension__ ({ \ + __pcpu_type(name) *__p; \ + \ + __asm __volatile("movl %%fs:%1,%0; addl %2,%0" \ + : "=r" (__p) \ + : "m" (*(struct pcpu *)(__pcpu_offset(pc_prvspace))), \ + "i" (__pcpu_offset(name))); \ + \ + __p; \ +}) + +/* + * Evaluates to the value of the per-cpu variable name. + */ +#define __PCPU_GET(name) __extension__ ({ \ + __pcpu_type(name) __result; \ + \ + if (sizeof(__result) == 1) { \ + u_char __b; \ + __asm __volatile("movb %%fs:%1,%0" \ + : "=r" (__b) \ + : "m" (*(u_char *)(__pcpu_offset(name)))); \ + __result = *(__pcpu_type(name) *)(void *)&__b; \ + } else if (sizeof(__result) == 2) { \ + u_short __w; \ + __asm __volatile("movw %%fs:%1,%0" \ + : "=r" (__w) \ + : "m" (*(u_short *)(__pcpu_offset(name)))); \ + __result = *(__pcpu_type(name) *)(void *)&__w; \ + } else if (sizeof(__result) == 4) { \ + u_int __i; \ + __asm __volatile("movl %%fs:%1,%0" \ + : "=r" (__i) \ + : "m" (*(u_int *)(__pcpu_offset(name)))); \ + __result = *(__pcpu_type(name) *)(void *)&__i; \ + } else { \ + __result = *__PCPU_PTR(name); \ + } \ + \ + __result; \ +}) + +/* + * Sets the value of the per-cpu variable name to value val. + */ +#define __PCPU_SET(name, val) { \ + __pcpu_type(name) __val = (val); \ + \ + if (sizeof(__val) == 1) { \ + u_char __b; \ + __b = *(u_char *)&__val; \ + __asm __volatile("movb %1,%%fs:%0" \ + : "=m" (*(u_char *)(__pcpu_offset(name))) \ + : "r" (__b)); \ + } else if (sizeof(__val) == 2) { \ + u_short __w; \ + __w = *(u_short *)&__val; \ + __asm __volatile("movw %1,%%fs:%0" \ + : "=m" (*(u_short *)(__pcpu_offset(name))) \ + : "r" (__w)); \ + } else if (sizeof(__val) == 4) { \ + u_int __i; \ + __i = *(u_int *)&__val; \ + __asm __volatile("movl %1,%%fs:%0" \ + : "=m" (*(u_int *)(__pcpu_offset(name))) \ + : "r" (__i)); \ + } else { \ + *__PCPU_PTR(name) = __val; \ + } \ +} + +#define PCPU_GET(member) __PCPU_GET(pc_ ## member) +#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member) +#define PCPU_SET(member, val) __PCPU_SET(pc_ ## member, val) + +static __inline struct thread * +__curthread(void) +{ + struct thread *td; + + __asm __volatile("movl %%fs:0,%0" : "=r" (td)); + return (td); +} +#define curthread (__curthread()) + +#else +#error gcc or lint is required to use this file +#endif + +#endif /* _KERNEL */ + +#endif /* ! _MACHINE_PCPU_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/pmap.h b/freebsd-5.3-xen-sparse/i386-xen/include/pmap.h new file mode 100644 index 0000000000..9e838b9bd4 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/pmap.h @@ -0,0 +1,355 @@ +/* + * Copyright (c) 1991 Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department and William Jolitz of UUNET Technologies Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Derived from hp300 version by Mike Hibler, this version by William + * Jolitz uses a recursive map [a pde points to the page directory] to + * map the page tables using the pagetables themselves. This is done to + * reduce the impact on kernel virtual memory for lots of sparse address + * space, and to reduce the cost of memory to each process. + * + * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90 + * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91 + * $FreeBSD: src/sys/i386/include/pmap.h,v 1.103 2003/11/08 03:01:26 alc Exp $ + */ + +#ifndef _MACHINE_PMAP_H_ +#define _MACHINE_PMAP_H_ + +/* + * Page-directory and page-table entires follow this format, with a few + * of the fields not present here and there, depending on a lot of things. + */ + /* ---- Intel Nomenclature ---- */ +#define PG_V 0x001 /* P Valid */ +#define PG_RW 0x002 /* R/W Read/Write */ +#define PG_U 0x004 /* U/S User/Supervisor */ +#define PG_NC_PWT 0x008 /* PWT Write through */ +#define PG_NC_PCD 0x010 /* PCD Cache disable */ +#define PG_A 0x020 /* A Accessed */ +#define PG_M 0x040 /* D Dirty */ +#define PG_PS 0x080 /* PS Page size (0=4k,1=4M) */ +#define PG_G 0x100 /* G Global */ +#define PG_AVAIL1 0x200 /* / Available for system */ +#define PG_AVAIL2 0x400 /* < programmers use */ +#define PG_AVAIL3 0x800 /* \ */ + + +/* Our various interpretations of the above */ +#define PG_W PG_AVAIL1 /* "Wired" pseudoflag */ +#define PG_MANAGED PG_AVAIL2 +#define PG_FRAME (~((vm_paddr_t)PAGE_MASK)) +#define PG_PROT (PG_RW|PG_U) /* all protection bits . */ +#define PG_N (PG_NC_PWT|PG_NC_PCD) /* Non-cacheable */ + +#define PG_KERNEL (PG_V | PG_RW | PG_M | PG_A) +#define PG_KERNEL_NC (PG_KERNEL | PG_N) +#define PG_KERNEL_RO (PG_VALID | PG_M | PG_A) + +/* + * Page Protection Exception bits + */ + +#define PGEX_P 0x01 /* Protection violation vs. not present */ +#define PGEX_W 0x02 /* during a Write cycle */ +#define PGEX_U 0x04 /* access from User mode (UPL) */ +#define XEN_PAGES 16 + +/* + * Size of Kernel address space. This is the number of page table pages + * (4MB each) to use for the kernel. 256 pages == 1 Gigabyte. + * This **MUST** be a multiple of 4 (eg: 252, 256, 260, etc). + */ + +#ifndef KVA_PAGES +#ifdef PAE +#define KVA_PAGES 512 +#else +#define KVA_PAGES 256 +#endif +#endif + +/* + * Pte related macros + */ +#define VADDR(pdi, pti) ((vm_offset_t)(((pdi)< 0xffbfffff + */ + +/* + * XEN NOTE: We need to shift down the start of KVA by 64MB to account for + * Xen using the upper 64MB. + * + * The layout of VA for XenoBSD is: + * | USER | PTDPTDI | KVA | XEN | + * | 0x00000000 | 0xbfc00000 | 0xc0000000 | 0xfc000000 - 0xffffffff| + * + * Normally it is just: + * | USER | PTDPTDI | KVA | + * | 0x00000000 | 0xbfc00000 | 0xc0000000 - 0xffffffff | + */ + +#ifdef SMP +#define MPPTDI (NPDEPTD-1) /* per cpu ptd entry */ +#define KPTDI (MPPTDI-NKPDE-XEN_PAGES /* start of kernel virtual pde's */ +#else +#define KPTDI (NPDEPTD-NKPDE-XEN_PAGES) /* start of kernel virtual pde's */ +#endif /* SMP */ + +#define PTDPTDI (KPTDI-NPGPTD) /* ptd entry that points to ptd! */ + +/* + * XXX doesn't really belong here I guess... + */ +#define ISA_HOLE_START 0xa0000 +#define ISA_HOLE_LENGTH (0x100000-ISA_HOLE_START) + +#ifndef LOCORE + +#include +#include +#include + + +typedef uint32_t pd_entry_t; +typedef uint32_t pt_entry_t; + +#define PTESHIFT (2) +#define PDESHIFT (2) + + +/* + * Address of current and alternate address space page table maps + * and directories. + */ +#ifdef _KERNEL +extern pt_entry_t PTmap[]; +extern pd_entry_t PTD[]; +extern pd_entry_t PTDpde[]; + +extern pd_entry_t *IdlePTD; /* physical address of "Idle" state directory */ + +#include +#include +#include + + +/* + * virtual address to page table entry and + * to physical address. Likewise for alternate address space. + * Note: these work recursively, thus vtopte of a pte will give + * the corresponding pde that in turn maps it. + */ +#define vtopte(va) (PTmap + i386_btop(va)) + +/* + * Given a virtual address, return the machine address of its PTE + * + */ +#define vtoptema(va) pmap_kextract_ma((vm_offset_t) vtopte(va)) + +/* + * Routine: pmap_kextract/pmap_kextract_ma + * Function: + * Extract the physical/machine page address associated + * kernel virtual address. + */ + +static __inline vm_paddr_t +pmap_kextract_ma(vm_offset_t va) +{ + vm_paddr_t ma; + if ((ma = PTD[va >> PDRSHIFT]) & PG_PS) { + ma = (ma & ~(NBPDR - 1)) | (va & (NBPDR - 1)); + } else { + ma = (*vtopte(va) & PG_FRAME) | (va & PAGE_MASK); + } + return ma; +} + +static __inline vm_paddr_t +pmap_kextract(vm_offset_t va) +{ + return xpmap_mtop(pmap_kextract_ma(va)); +} + +#define vtophys(va) pmap_kextract(((vm_offset_t) (va))) +#define vtomach(va) pmap_kextract_ma(((vm_offset_t) (va))) + +static __inline pt_entry_t +pte_load_clear(pt_entry_t *ptep) +{ + pt_entry_t r; + + r = PT_GET(ptep); + PT_CLEAR_VA(ptep, TRUE); + return (r); +} +static __inline pt_entry_t +pte_load_store(pt_entry_t *ptep, pt_entry_t v) +{ + pt_entry_t r; + r = PT_GET(ptep); + PT_SET_VA_MA(ptep, v, TRUE); + return (r); +} + +#define pte_store(ptep, pte) PT_SET_VA_MA(ptep, pte, TRUE); +#define pte_clear(pte) PT_CLEAR_VA(pte, TRUE); + + +#endif /* _KERNEL */ + +/* + * Pmap stuff + */ +struct pv_entry; + +struct md_page { + int pv_list_count; + TAILQ_HEAD(,pv_entry) pv_list; +}; + +struct pmap { + struct mtx pm_mtx; + pd_entry_t *pm_pdir; /* KVA of page directory */ + TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ + u_int pm_active; /* active on cpus */ + struct pmap_statistics pm_stats; /* pmap statistics */ + LIST_ENTRY(pmap) pm_list; /* List of all pmaps */ +}; + + +typedef struct pmap *pmap_t; + +#ifdef _KERNEL +extern struct pmap kernel_pmap_store; +#define kernel_pmap (&kernel_pmap_store) + +#define PMAP_LOCK(pmap)mtx_lock(&(pmap)->pm_mtx) +#define PMAP_LOCK_ASSERT(pmap, type) \ +mtx_assert(&(pmap)->pm_mtx, (type)) +#define PMAP_LOCK_DESTROY(pmap)mtx_destroy(&(pmap)->pm_mtx) +#define PMAP_LOCK_INIT(pmap)mtx_init(&(pmap)->pm_mtx, "pmap", \ + NULL, MTX_DEF | MTX_DUPOK) +#define PMAP_LOCKED(pmap)mtx_owned(&(pmap)->pm_mtx) +#define PMAP_MTX(pmap)(&(pmap)->pm_mtx) +#define PMAP_TRYLOCK(pmap)mtx_trylock(&(pmap)->pm_mtx) +#define PMAP_UNLOCK(pmap)mtx_unlock(&(pmap)->pm_mtx) + +#endif + +/* + * For each vm_page_t, there is a list of all currently valid virtual + * mappings of that page. An entry is a pv_entry_t, the list is pv_table. + */ +typedef struct pv_entry { + pmap_t pv_pmap; /* pmap where mapping lies */ + vm_offset_t pv_va; /* virtual address for mapping */ + TAILQ_ENTRY(pv_entry) pv_list; + TAILQ_ENTRY(pv_entry) pv_plist; +} *pv_entry_t; + +#ifdef _KERNEL + +#define NPPROVMTRR 8 +#define PPRO_VMTRRphysBase0 0x200 +#define PPRO_VMTRRphysMask0 0x201 +struct ppro_vmtrr { + u_int64_t base, mask; +}; +extern struct ppro_vmtrr PPro_vmtrr[NPPROVMTRR]; + +extern caddr_t CADDR1; +extern pt_entry_t *CMAP1; +extern vm_paddr_t avail_end; +extern vm_paddr_t phys_avail[]; +extern int pseflag; +extern int pgeflag; +extern char *ptvmmap; /* poor name! */ +extern vm_offset_t virtual_avail; +extern vm_offset_t virtual_end; + +#define pmap_page_is_mapped(m)(!TAILQ_EMPTY(&(m)->md.pv_list)) + +void pmap_bootstrap(vm_paddr_t, vm_paddr_t); +void pmap_kenter(vm_offset_t va, vm_paddr_t pa); +void pmap_kenter_ma(vm_offset_t va, vm_paddr_t pa); +void *pmap_kenter_temporary(vm_paddr_t pa, int i); +void pmap_kremove(vm_offset_t); +void *pmap_mapdev(vm_paddr_t, vm_size_t); +void pmap_unmapdev(vm_offset_t, vm_size_t); +pt_entry_t *pmap_pte(pmap_t, vm_offset_t) __pure2; +void pmap_set_pg(void); +void pmap_invalidate_page(pmap_t, vm_offset_t); +void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); +void pmap_invalidate_all(pmap_t); + +void pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len); +void pmap_map_readwrite(pmap_t pmap, vm_offset_t va, int len); + + +#endif /* _KERNEL */ + +#endif /* !LOCORE */ + +#endif /* !_MACHINE_PMAP_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/segments.h b/freebsd-5.3-xen-sparse/i386-xen/include/segments.h new file mode 100644 index 0000000000..85cc20c1f5 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/segments.h @@ -0,0 +1,260 @@ +/*- + * Copyright (c) 1989, 1990 William F. Jolitz + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 + * $FreeBSD: src/sys/i386/include/segments.h,v 1.36 2003/11/03 21:12:04 jhb Exp $ + */ + +#ifndef _MACHINE_SEGMENTS_H_ +#define _MACHINE_SEGMENTS_H_ + +/* + * 386 Segmentation Data Structures and definitions + * William F. Jolitz (william@ernie.berkeley.edu) 6/20/1989 + */ + +/* + * Selectors + */ + +#define ISPL(s) ((s)&3) /* what is the priority level of a selector */ +#define SEL_KPL 1 /* kernel priority level */ +#define SEL_UPL 3 /* user priority level */ +#define ISLDT(s) ((s)&SEL_LDT) /* is it local or global */ +#define SEL_LDT 4 /* local descriptor table */ +#define IDXSEL(s) (((s)>>3) & 0x1fff) /* index of selector */ +#define LSEL(s,r) (((s)<<3) | SEL_LDT | r) /* a local selector */ +#define GSEL(s,r) (((s)<<3) | r) /* a global selector */ + +/* + * Memory and System segment descriptors + */ +struct segment_descriptor { + unsigned sd_lolimit:16 ; /* segment extent (lsb) */ + unsigned sd_lobase:24 __packed; /* segment base address (lsb) */ + unsigned sd_type:5 ; /* segment type */ + unsigned sd_dpl:2 ; /* segment descriptor priority level */ + unsigned sd_p:1 ; /* segment descriptor present */ + unsigned sd_hilimit:4 ; /* segment extent (msb) */ + unsigned sd_xx:2 ; /* unused */ + unsigned sd_def32:1 ; /* default 32 vs 16 bit size */ + unsigned sd_gran:1 ; /* limit granularity (byte/page units)*/ + unsigned sd_hibase:8 ; /* segment base address (msb) */ +} ; + +/* + * Gate descriptors (e.g. indirect descriptors) + */ +struct gate_descriptor { + unsigned gd_looffset:16 ; /* gate offset (lsb) */ + unsigned gd_selector:16 ; /* gate segment selector */ + unsigned gd_stkcpy:5 ; /* number of stack wds to cpy */ + unsigned gd_xx:3 ; /* unused */ + unsigned gd_type:5 ; /* segment type */ + unsigned gd_dpl:2 ; /* segment descriptor priority level */ + unsigned gd_p:1 ; /* segment descriptor present */ + unsigned gd_hioffset:16 ; /* gate offset (msb) */ +} ; + +/* + * Generic descriptor + */ +union descriptor { + struct segment_descriptor sd; + struct gate_descriptor gd; +}; + + /* system segments and gate types */ +#define SDT_SYSNULL 0 /* system null */ +#define SDT_SYS286TSS 1 /* system 286 TSS available */ +#define SDT_SYSLDT 2 /* system local descriptor table */ +#define SDT_SYS286BSY 3 /* system 286 TSS busy */ +#define SDT_SYS286CGT 4 /* system 286 call gate */ +#define SDT_SYSTASKGT 5 /* system task gate */ +#define SDT_SYS286IGT 6 /* system 286 interrupt gate */ +#define SDT_SYS286TGT 7 /* system 286 trap gate */ +#define SDT_SYSNULL2 8 /* system null again */ +#define SDT_SYS386TSS 9 /* system 386 TSS available */ +#define SDT_SYSNULL3 10 /* system null again */ +#define SDT_SYS386BSY 11 /* system 386 TSS busy */ +#define SDT_SYS386CGT 12 /* system 386 call gate */ +#define SDT_SYSNULL4 13 /* system null again */ +#define SDT_SYS386IGT 14 /* system 386 interrupt gate */ +#define SDT_SYS386TGT 15 /* system 386 trap gate */ + + /* memory segment types */ +#define SDT_MEMRO 16 /* memory read only */ +#define SDT_MEMROA 17 /* memory read only accessed */ +#define SDT_MEMRW 18 /* memory read write */ +#define SDT_MEMRWA 19 /* memory read write accessed */ +#define SDT_MEMROD 20 /* memory read only expand dwn limit */ +#define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */ +#define SDT_MEMRWD 22 /* memory read write expand dwn limit */ +#define SDT_MEMRWDA 23 /* memory read write expand dwn limit accessed */ +#define SDT_MEME 24 /* memory execute only */ +#define SDT_MEMEA 25 /* memory execute only accessed */ +#define SDT_MEMER 26 /* memory execute read */ +#define SDT_MEMERA 27 /* memory execute read accessed */ +#define SDT_MEMEC 28 /* memory execute only conforming */ +#define SDT_MEMEAC 29 /* memory execute only accessed conforming */ +#define SDT_MEMERC 30 /* memory execute read conforming */ +#define SDT_MEMERAC 31 /* memory execute read accessed conforming */ + +/* + * Software definitions are in this convenient format, + * which are translated into inconvenient segment descriptors + * when needed to be used by the 386 hardware + */ + +struct soft_segment_descriptor { + unsigned ssd_base ; /* segment base address */ + unsigned ssd_limit ; /* segment extent */ + unsigned ssd_type:5 ; /* segment type */ + unsigned ssd_dpl:2 ; /* segment descriptor priority level */ + unsigned ssd_p:1 ; /* segment descriptor present */ + unsigned ssd_xx:4 ; /* unused */ + unsigned ssd_xx1:2 ; /* unused */ + unsigned ssd_def32:1 ; /* default 32 vs 16 bit size */ + unsigned ssd_gran:1 ; /* limit granularity (byte/page units)*/ +}; + +/* + * region descriptors, used to load gdt/idt tables before segments yet exist. + */ +struct region_descriptor { + unsigned rd_limit:16; /* segment extent */ + unsigned rd_base:32 __packed; /* base address */ +}; + +/* + * Segment Protection Exception code bits + */ + +#define SEGEX_EXT 0x01 /* recursive or externally induced */ +#define SEGEX_IDT 0x02 /* interrupt descriptor table */ +#define SEGEX_TI 0x04 /* local descriptor table */ + /* other bits are affected descriptor index */ +#define SEGEX_IDX(s) (((s)>>3)&0x1fff) + +/* + * Size of IDT table + */ + +#define NIDT 256 /* 32 reserved, 0x80 syscall, most are h/w */ +#define NRSVIDT 32 /* reserved entries for cpu exceptions */ + +/* + * Entries in the Interrupt Descriptor Table (IDT) + */ +#define IDT_DE 0 /* #DE: Divide Error */ +#define IDT_DB 1 /* #DB: Debug */ +#define IDT_NMI 2 /* Nonmaskable External Interrupt */ +#define IDT_BP 3 /* #BP: Breakpoint */ +#define IDT_OF 4 /* #OF: Overflow */ +#define IDT_BR 5 /* #BR: Bound Range Exceeded */ +#define IDT_UD 6 /* #UD: Undefined/Invalid Opcode */ +#define IDT_NM 7 /* #NM: No Math Coprocessor */ +#define IDT_DF 8 /* #DF: Double Fault */ +#define IDT_FPUGP 9 /* Coprocessor Segment Overrun */ +#define IDT_TS 10 /* #TS: Invalid TSS */ +#define IDT_NP 11 /* #NP: Segment Not Present */ +#define IDT_SS 12 /* #SS: Stack Segment Fault */ +#define IDT_GP 13 /* #GP: General Protection Fault */ +#define IDT_PF 14 /* #PF: Page Fault */ +#define IDT_MF 16 /* #MF: FPU Floating-Point Error */ +#define IDT_AC 17 /* #AC: Alignment Check */ +#define IDT_MC 18 /* #MC: Machine Check */ +#define IDT_XF 19 /* #XF: SIMD Floating-Point Exception */ +#define IDT_IO_INTS NRSVIDT /* Base of IDT entries for I/O interrupts. */ +#define IDT_SYSCALL 0x80 /* System Call Interrupt Vector */ + +/* + * Entries in the Global Descriptor Table (GDT) + */ +#define GNULL_SEL 0 /* Null Descriptor */ +#if 0 +#define GCODE_SEL 1 /* Kernel Code Descriptor */ +#define GDATA_SEL 2 /* Kernel Data Descriptor */ +#else +#define GCODE_SEL (__KERNEL_CS >> 3) /* Kernel Code Descriptor */ +#define GDATA_SEL (__KERNEL_DS >> 3) /* Kernel Data Descriptor */ +#endif +#define GPRIV_SEL 3 /* SMP Per-Processor Private Data */ +#define GPROC0_SEL 4 /* Task state process slot zero and up */ +#define GLDT_SEL 5 /* LDT - eventually one per process */ +#define GUSERLDT_SEL 6 /* User LDT */ +#define GTGATE_SEL 7 /* Process task switch gate */ +#define GBIOSLOWMEM_SEL 8 /* BIOS low memory access (must be entry 8) */ +#define GPANIC_SEL 9 /* Task state to consider panic from */ +#define GBIOSCODE32_SEL 10 /* BIOS interface (32bit Code) */ +#define GBIOSCODE16_SEL 11 /* BIOS interface (16bit Code) */ +#define GBIOSDATA_SEL 12 /* BIOS interface (Data) */ +#define GBIOSUTIL_SEL 13 /* BIOS interface (Utility) */ +#define GBIOSARGS_SEL 14 /* BIOS interface (Arguments) */ + +#define NGDT 4 + +/* + * Entries in the Local Descriptor Table (LDT) + */ +#define LSYS5CALLS_SEL 0 /* forced by intel BCS */ +#define LSYS5SIGR_SEL 1 +#define L43BSDCALLS_SEL 2 /* notyet */ +#define LUCODE_SEL 3 +#define LSOL26CALLS_SEL 4 /* Solaris >= 2.6 system call gate */ +#define LUDATA_SEL 5 +/* separate stack, es,fs,gs sels ? */ +/* #define LPOSIXCALLS_SEL 5*/ /* notyet */ +#define LBSDICALLS_SEL 16 /* BSDI system call gate */ +#define NLDT (LBSDICALLS_SEL + 1) + +#ifdef _KERNEL +extern int _default_ldt; +extern union descriptor *gdt; +extern struct soft_segment_descriptor gdt_segs[]; +extern struct gate_descriptor *idt; +extern union descriptor *ldt; +extern struct region_descriptor r_gdt, r_idt; + +void lgdt(struct region_descriptor *rdp); +void lgdt_finish(void); +void sdtossd(struct segment_descriptor *sdp, + struct soft_segment_descriptor *ssdp); +void ssdtosd(struct soft_segment_descriptor *ssdp, + struct segment_descriptor *sdp); +#endif /* _KERNEL */ + +#endif /* !_MACHINE_SEGMENTS_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/synch_bitops.h b/freebsd-5.3-xen-sparse/i386-xen/include/synch_bitops.h new file mode 100644 index 0000000000..31ec3d3468 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/synch_bitops.h @@ -0,0 +1,82 @@ +#ifndef __XEN_SYNCH_BITOPS_H__ +#define __XEN_SYNCH_BITOPS_H__ + +/* + * Copyright 1992, Linus Torvalds. + * Heavily modified to provide guaranteed strong synchronisation + * when communicating with Xen or other guest OSes running on other CPUs. + */ + + +#define ADDR (*(volatile long *) addr) + +static __inline__ void synch_set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__ ( + "lock btsl %1,%0" + : "=m" (ADDR) : "Ir" (nr) : "memory" ); +} + +static __inline__ void synch_clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__ ( + "lock btrl %1,%0" + : "=m" (ADDR) : "Ir" (nr) : "memory" ); +} + +static __inline__ void synch_change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__ ( + "lock btcl %1,%0" + : "=m" (ADDR) : "Ir" (nr) : "memory" ); +} + +static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + __asm__ __volatile__ ( + "lock btsl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); + return oldbit; +} + +static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + __asm__ __volatile__ ( + "lock btrl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); + return oldbit; +} + +static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__ ( + "lock btcl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); + return oldbit; +} + +static __inline__ int synch_const_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & + (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int synch_var_test_bit(int nr, volatile void * addr) +{ + int oldbit; + __asm__ __volatile__ ( + "btl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) ); + return oldbit; +} + +#define synch_test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + synch_const_test_bit((nr),(addr)) : \ + synch_var_test_bit((nr),(addr))) + +#endif /* __XEN_SYNCH_BITOPS_H__ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/trap.h b/freebsd-5.3-xen-sparse/i386-xen/include/trap.h new file mode 100644 index 0000000000..c61beb90aa --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/trap.h @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)trap.h 5.4 (Berkeley) 5/9/91 + * $FreeBSD: src/sys/i386/include/trap.h,v 1.13 2001/07/12 06:32:51 peter Exp $ + */ + +#ifndef _MACHINE_TRAP_H_ +#define _MACHINE_TRAP_H_ + +/* + * Trap type values + * also known in trap.c for name strings + */ + +#define T_PRIVINFLT 1 /* privileged instruction */ +#define T_BPTFLT 3 /* breakpoint instruction */ +#define T_ARITHTRAP 6 /* arithmetic trap */ +#define T_PROTFLT 9 /* protection fault */ +#define T_TRCTRAP 10 /* debug exception (sic) */ +#define T_PAGEFLT 12 /* page fault */ +#define T_ALIGNFLT 14 /* alignment fault */ + +#define T_NESTED 16 +#define T_HYPCALLBACK 17 /* hypervisor callback */ + + +#define T_DIVIDE 18 /* integer divide fault */ +#define T_NMI 19 /* non-maskable trap */ +#define T_OFLOW 20 /* overflow trap */ +#define T_BOUND 21 /* bound instruction fault */ +#define T_DNA 22 /* device not available fault */ +#define T_DOUBLEFLT 23 /* double fault */ +#define T_FPOPFLT 24 /* fp coprocessor operand fetch fault */ +#define T_TSSFLT 25 /* invalid tss fault */ +#define T_SEGNPFLT 26 /* segment not present fault */ +#define T_STKFLT 27 /* stack fault */ +#define T_MCHK 28 /* machine check trap */ +#define T_XMMFLT 29 /* SIMD floating-point exception */ +#define T_RESERVED 30 /* reserved (unknown) */ + +/* XXX most of the following codes aren't used, but could be. */ + +/* definitions for */ +#define ILL_RESAD_FAULT T_RESADFLT +#define ILL_PRIVIN_FAULT T_PRIVINFLT +#define ILL_RESOP_FAULT T_RESOPFLT +#define ILL_ALIGN_FAULT T_ALIGNFLT +#define ILL_FPOP_FAULT T_FPOPFLT /* coprocessor operand fault */ + +/* portable macros for SIGFPE/ARITHTRAP */ +#define FPE_INTOVF 1 /* integer overflow */ +#define FPE_INTDIV 2 /* integer divide by zero */ +#define FPE_FLTDIV 3 /* floating point divide by zero */ +#define FPE_FLTOVF 4 /* floating point overflow */ +#define FPE_FLTUND 5 /* floating point underflow */ +#define FPE_FLTRES 6 /* floating point inexact result */ +#define FPE_FLTINV 7 /* invalid floating point operation */ +#define FPE_FLTSUB 8 /* subscript out of range */ + +/* old FreeBSD macros, deprecated */ +#define FPE_INTOVF_TRAP 0x1 /* integer overflow */ +#define FPE_INTDIV_TRAP 0x2 /* integer divide by zero */ +#define FPE_FLTDIV_TRAP 0x3 /* floating/decimal divide by zero */ +#define FPE_FLTOVF_TRAP 0x4 /* floating overflow */ +#define FPE_FLTUND_TRAP 0x5 /* floating underflow */ +#define FPE_FPU_NP_TRAP 0x6 /* floating point unit not present */ +#define FPE_SUBRNG_TRAP 0x7 /* subrange out of bounds */ + +/* codes for SIGBUS */ +#define BUS_PAGE_FAULT T_PAGEFLT /* page fault protection base */ +#define BUS_SEGNP_FAULT T_SEGNPFLT /* segment not present */ +#define BUS_STK_FAULT T_STKFLT /* stack segment */ +#define BUS_SEGM_FAULT T_RESERVED /* segment protection base */ + +/* Trap's coming from user mode */ +#define T_USER 0x100 + +#endif /* !_MACHINE_TRAP_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/ucontext.h b/freebsd-5.3-xen-sparse/i386-xen/include/ucontext.h new file mode 100644 index 0000000000..eda584b62e --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/ucontext.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1999 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/i386/include/ucontext.h,v 1.10 2002/12/02 19:58:55 deischen Exp $ + */ + +#ifndef _MACHINE_UCONTEXT_H_ +#define _MACHINE_UCONTEXT_H_ + +typedef struct __mcontext { + /* + * The first 20 fields must match the definition of + * sigcontext. So that we can support sigcontext + * and ucontext_t at the same time. + */ + int mc_onstack; /* XXX - sigcontext compat. */ + int mc_gs; /* machine state (struct trapframe) */ + int mc_fs; + int mc_es; + int mc_ds; + int mc_edi; + int mc_esi; + int mc_ebp; + int mc_isp; + int mc_ebx; + int mc_edx; + int mc_ecx; + int mc_eax; + int mc_trapno; + int mc_cr2; + int mc_err; + int mc_eip; + int mc_cs; + int mc_eflags; + int mc_esp; + int mc_ss; + + int mc_len; /* sizeof(mcontext_t) */ +#define _MC_FPFMT_NODEV 0x10000 /* device not present or configured */ +#define _MC_FPFMT_387 0x10001 +#define _MC_FPFMT_XMM 0x10002 + int mc_fpformat; +#define _MC_FPOWNED_NONE 0x20000 /* FP state not used */ +#define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */ +#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */ + int mc_ownedfp; + /* + * See for the internals of mc_fpstate[]. + */ + int mc_fpstate[128] __aligned(16); + int mc_spare2[8]; +} mcontext_t; + +#if defined(_KERNEL) && defined(COMPAT_FREEBSD4) +struct mcontext4 { + int mc_onstack; /* XXX - sigcontext compat. */ + int mc_gs; /* machine state (struct trapframe) */ + int mc_fs; + int mc_es; + int mc_ds; + int mc_edi; + int mc_esi; + int mc_ebp; + int mc_isp; + int mc_ebx; + int mc_edx; + int mc_ecx; + int mc_eax; + int mc_trapno; + int mc_err; + int mc_eip; + int mc_cs; + int mc_eflags; + int mc_esp; /* machine state */ + int mc_ss; + int mc_fpregs[28]; /* env87 + fpacc87 + u_long */ + int __spare__[17]; +}; +#endif + +#endif /* !_MACHINE_UCONTEXT_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/vmparam.h b/freebsd-5.3-xen-sparse/i386-xen/include/vmparam.h new file mode 100644 index 0000000000..7fa9af3c68 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/vmparam.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * Copyright (c) 1994 John S. Dyson + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)vmparam.h 5.9 (Berkeley) 5/12/91 + * $FreeBSD: src/sys/i386/include/vmparam.h,v 1.37 2003/10/01 23:46:08 peter Exp $ + */ + + +#ifndef _MACHINE_VMPARAM_H_ +#define _MACHINE_VMPARAM_H_ 1 + +/* + * Machine dependent constants for 386. + */ + +#define VM_PROT_READ_IS_EXEC /* if you can read -- then you can exec */ + +/* + * Virtual memory related constants, all in bytes + */ +#define MAXTSIZ (128UL*1024*1024) /* max text size */ +#ifndef DFLDSIZ +#define DFLDSIZ (128UL*1024*1024) /* initial data size limit */ +#endif +#ifndef MAXDSIZ +#define MAXDSIZ (512UL*1024*1024) /* max data size */ +#endif +#ifndef DFLSSIZ +#define DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ +#endif +#ifndef MAXSSIZ +#define MAXSSIZ (64UL*1024*1024) /* max stack size */ +#endif +#ifndef SGROWSIZ +#define SGROWSIZ (128UL*1024) /* amount to grow stack */ +#endif + +#define USRTEXT (1*PAGE_SIZE) /* base of user text XXX bogus */ + +/* + * The time for a process to be blocked before being very swappable. + * This is a number of seconds which the system takes as being a non-trivial + * amount of real time. You probably shouldn't change this; + * it is used in subtle ways (fractions and multiples of it are, that is, like + * half of a ``long time'', almost a long time, etc.) + * It is related to human patience and other factors which don't really + * change over time. + */ +#define MAXSLP 20 + + +/* + * Kernel physical load address. + */ +#ifndef KERNLOAD +#define KERNLOAD (1 << PDRSHIFT) +#endif + +/* + * Virtual addresses of things. Derived from the page directory and + * page table indexes from pmap.h for precision. + * Because of the page that is both a PD and PT, it looks a little + * messy at times, but hey, we'll do anything to save a page :-) + */ + +#define VM_MAX_KERNEL_ADDRESS VADDR(KPTDI+NKPDE-1, NPTEPG-1) +#define VM_MIN_KERNEL_ADDRESS VADDR(PTDPTDI, PTDPTDI) + +#define KERNBASE VADDR(KPTDI, 0) + +#define UPT_MAX_ADDRESS VADDR(PTDPTDI, PTDPTDI) +#define UPT_MIN_ADDRESS VADDR(PTDPTDI, 0) + +#define VM_MAXUSER_ADDRESS VADDR(PTDPTDI-1, 0) + +#define USRSTACK VM_MAXUSER_ADDRESS + +#define VM_MAX_ADDRESS VADDR(PTDPTDI, PTDPTDI) +#define VM_MIN_ADDRESS ((vm_offset_t)0) + +/* virtual sizes (bytes) for various kernel submaps */ +#ifndef VM_KMEM_SIZE +#define VM_KMEM_SIZE (12 * 1024 * 1024) +#endif + +/* + * How many physical pages per KVA page allocated. + * min(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MAX) + * is the total KVA space allocated for kmem_map. + */ +#ifndef VM_KMEM_SIZE_SCALE +#define VM_KMEM_SIZE_SCALE (3) +#endif + +/* + * Ceiling on amount of kmem_map kva space. + */ +#ifndef VM_KMEM_SIZE_MAX +#define VM_KMEM_SIZE_MAX (320 * 1024 * 1024) +#endif + +/* initial pagein size of beginning of executable file */ +#ifndef VM_INITIAL_PAGEIN +#define VM_INITIAL_PAGEIN 16 +#endif + +#endif /* _MACHINE_VMPARAM_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/xen-os.h b/freebsd-5.3-xen-sparse/i386-xen/include/xen-os.h new file mode 100644 index 0000000000..e483fc535c --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xen-os.h @@ -0,0 +1,293 @@ +/****************************************************************************** + * os.h + * + * random collection of macros and definition + */ + +#ifndef _OS_H_ +#define _OS_H_ + +#ifndef NULL +#define NULL (void *)0 +#endif + +/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented + a mechanism by which the user can annotate likely branch directions and + expect the blocks to be reordered appropriately. Define __builtin_expect + to nothing for earlier compilers. */ + +#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 +#define __builtin_expect(x, expected_value) (x) +#endif + + + +/* + * These are the segment descriptors provided for us by the hypervisor. + * For now, these are hardwired -- guest OSes cannot update the GDT + * or LDT. + * + * It shouldn't be hard to support descriptor-table frobbing -- let me + * know if the BSD or XP ports require flexibility here. + */ + + +/* + * these are also defined in hypervisor-if.h but can't be pulled in as + * they are used in start of day assembly. Need to clean up the .h files + * a bit more... + */ + +#ifndef FLAT_RING1_CS +#define FLAT_RING1_CS 0x0819 +#define FLAT_RING1_DS 0x0821 +#define FLAT_RING3_CS 0x082b +#define FLAT_RING3_DS 0x0833 +#endif + +#define __KERNEL_CS FLAT_RING1_CS +#define __KERNEL_DS FLAT_RING1_DS + +/* Everything below this point is not included by assembler (.S) files. */ +#ifndef __ASSEMBLY__ +#include + +#include +void printk(const char *fmt, ...); + +/* some function prototypes */ +void trap_init(void); + + +/* + * STI/CLI equivalents. These basically set and clear the virtual + * event_enable flag in teh shared_info structure. Note that when + * the enable bit is set, there may be pending events to be handled. + * We may therefore call into do_hypervisor_callback() directly. + */ +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + +#define __cli() \ +do { \ + HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1; \ + barrier(); \ +} while (0) + +#define __sti() \ +do { \ + shared_info_t *_shared = HYPERVISOR_shared_info; \ + barrier(); \ + _shared->vcpu_data[0].evtchn_upcall_mask = 0; \ + barrier(); /* unmask then check (avoid races) */ \ + if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \ + force_evtchn_callback(); \ +} while (0) + +#define __save_flags(x) \ +do { \ + (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask; \ +} while (0) + +#define __restore_flags(x) \ +do { \ + shared_info_t *_shared = HYPERVISOR_shared_info; \ + barrier(); \ + if ( (_shared->vcpu_data[0].evtchn_upcall_mask = (x)) == 0 ) { \ + barrier(); /* unmask then check (avoid races) */ \ + if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \ + force_evtchn_callback(); \ + } \ +} while (0) + +#define __save_and_cli(x) \ +do { \ + (x) = HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask; \ + HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_mask = 1; \ + barrier(); \ +} while (0) + +#define __save_and_sti(x) \ +do { \ + shared_info_t *_shared = HYPERVISOR_shared_info; \ + barrier(); \ + (x) = _shared->vcpu_data[0].evtchn_upcall_mask; \ + _shared->vcpu_data[0].evtchn_upcall_mask = 0; \ + barrier(); /* unmask then check (avoid races) */ \ + if ( unlikely(_shared->vcpu_data[0].evtchn_upcall_pending) ) \ + force_evtchn_callback(); \ +} while (0) + +#ifdef SMP +/* extra macros need for the SMP case */ +#error "global_irq_* not defined" +#endif + +#define cli() __cli() +#define sti() __sti() +#define save_flags(x) __save_flags(x) +#define restore_flags(x) __restore_flags(x) +#define save_and_cli(x) __save_and_cli(x) +#define save_and_sti(x) __save_and_sti(x) + +#define local_irq_save(x) __save_and_cli(x) +#define local_irq_set(x) __save_and_sti(x) +#define local_irq_restore(x) __restore_flags(x) +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() + +#define mtx_lock_irqsave(lock, x) {local_irq_save((x)); mtx_lock_spin((lock));} +#define mtx_unlock_irqrestore(lock, x) {mtx_unlock_spin((lock)); local_irq_restore((x)); } + +#define mb() +#define rmb() +#define smp_mb() +#define wmb() + + + +/* This is a barrier for the compiler only, NOT the processor! */ +#define barrier() __asm__ __volatile__("": : :"memory") + +#define LOCK_PREFIX "" +#define LOCK "" +#define ADDR (*(volatile long *) addr) +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +typedef struct { volatile int counter; } atomic_t; + + + +#define xen_xchg(ptr,v) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) +static __inline unsigned long __xchg(unsigned long x, volatile void * ptr, + int size) +{ + switch (size) { + case 1: + __asm__ __volatile__("xchgb %b0,%1" + :"=q" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 2: + __asm__ __volatile__("xchgw %w0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 4: + __asm__ __volatile__("xchgl %0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + } + return x; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + + +#define rdtscll(val) \ + __asm__ __volatile__("rdtsc" : "=A" (val)) + + +#endif /* !__ASSEMBLY__ */ + +#endif /* _OS_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/xen_intr.h b/freebsd-5.3-xen-sparse/i386-xen/include/xen_intr.h new file mode 100644 index 0000000000..e35eafa5d2 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xen_intr.h @@ -0,0 +1,50 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */ +#ifndef _XEN_INTR_H_ +#define _XEN_INTR_H_ + +/* +* The flat IRQ space is divided into two regions: +* 1. A one-to-one mapping of real physical IRQs. This space is only used +* if we have physical device-access privilege. This region is at the +* start of the IRQ space so that existing device drivers do not need +* to be modified to translate physical IRQ numbers into our IRQ space. +* 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These +* are bound using the provided bind/unbind functions. +*/ + +#define PIRQ_BASE 0 +#define NR_PIRQS 128 + +#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS) +#define NR_DYNIRQS 128 + +#define NR_IRQS (NR_PIRQS + NR_DYNIRQS) + +#define pirq_to_irq(_x) ((_x) + PIRQ_BASE) +#define irq_to_pirq(_x) ((_x) - PIRQ_BASE) + +#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE) +#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE) + +/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */ +extern int bind_virq_to_irq(int virq); +extern void unbind_virq_from_irq(int virq); +extern int bind_evtchn_to_irq(int evtchn); +extern void unbind_evtchn_from_irq(int evtchn); + +static __inline__ int irq_cannonicalize(int irq) +{ + return (irq == 2) ? 9 : irq; +} + +extern void disable_irq(unsigned int); +extern void disable_irq_nosync(unsigned int); +extern void enable_irq(unsigned int); + +extern void irq_suspend(void); +extern void irq_resume(void); + +extern void idle_block(void); + + +#endif /* _XEN_INTR_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/xenfunc.h b/freebsd-5.3-xen-sparse/i386-xen/include/xenfunc.h new file mode 100644 index 0000000000..93ffd7853a --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xenfunc.h @@ -0,0 +1,85 @@ +/* $NetBSD:$ */ + +/* + * + * Copyright (c) 2004 Christian Limpach. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christian Limpach. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _XEN_XENFUNC_H_ +#define _XEN_XENFUNC_H_ + +#include +#include +#include +#include +#include +#define BKPT __asm__("int3"); +#define XPQ_CALL_DEPTH 5 +#define XPQ_CALL_COUNT 2 +#define PG_PRIV PG_AVAIL3 +typedef struct { + unsigned long pt_ref; + unsigned long pt_eip[XPQ_CALL_COUNT][XPQ_CALL_DEPTH]; +} pteinfo_t; + +extern pteinfo_t *pteinfo_list; +#ifdef XENDEBUG_LOW +#define __PRINTK(x) printk x +#else +#define __PRINTK(x) +#endif + +char *xen_setbootenv(char *cmd_line); +int xen_boothowto(char *envp); +void load_cr3(uint32_t val); +void xen_set_ldt(vm_offset_t, uint32_t); +void xen_machphys_update(unsigned long, unsigned long); +void xen_update_descriptor(union descriptor *, union descriptor *); +void lldt(u_short sel); +/* + * Invalidate a patricular VA on all cpus + * + * N.B. Made these global for external loadable modules to reference. + */ +static __inline void +invlpg(u_int addr) +{ + xpq_queue_invlpg(addr); +} + +static __inline void +invltlb(void) +{ + xpq_queue_tlb_flush(); + mcl_flush_queue(); +} + + +#endif /* _XEN_XENFUNC_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h b/freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h new file mode 100644 index 0000000000..f445096228 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h @@ -0,0 +1,132 @@ +/* $NetBSD:$ */ + +/* + * + * Copyright (c) 2004 Christian Limpach. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christian Limpach. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _XEN_XENPMAP_H_ +#define _XEN_XENPMAP_H_ +#include +void xpq_physbcopy(const unsigned long *, unsigned long, size_t); +void xpq_queue_invlpg(vm_offset_t); +void xpq_queue_pt_update(pt_entry_t *, pt_entry_t); +void xpq_queue_pt_switch(uint32_t); +void xpq_queue_set_ldt(vm_offset_t, uint32_t); +void xpq_queue_tlb_flush(void); +void xpq_queue_pin_table(uint32_t, int); +void xpq_queue_unpin_table(uint32_t); +void xpq_record(unsigned long, unsigned long); +void mcl_queue_pt_update(vm_offset_t, vm_offset_t); +void mcl_flush_queue(void); +void pmap_ref(pt_entry_t *pte, unsigned long ma); + + +#ifdef PMAP_DEBUG +#define PMAP_REF pmap_ref +#define PMAP_DEC_REF_PAGE pmap_dec_ref_page +#define PMAP_MARK_PRIV pmap_mark_privileged +#define PMAP_MARK_UNPRIV pmap_mark_unprivileged +#else +#define PMAP_MARK_PRIV(a) +#define PMAP_MARK_UNPRIV(a) +#define PMAP_REF(a, b) +#define PMAP_DEC_REF_PAGE(a) +#endif + +#define ALWAYS_SYNC 0 + +#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */ + +#define XPQ_PIN_L1_TABLE 1 +#define XPQ_PIN_L2_TABLE 2 + +#define PT_GET(_ptp) \ + (pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : *(_ptp)) +#define PT_SET_VA(_ptp,_npte,sync) do { \ + PMAP_REF((_ptp), xpmap_ptom(_npte)); \ + xpq_queue_pt_update((pt_entry_t *)vtomach((_ptp)), \ + xpmap_ptom((_npte))); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) +#define PT_SET_VA_MA(_ptp,_npte,sync) do { \ + PMAP_REF((_ptp), (_npte)); \ + xpq_queue_pt_update((pt_entry_t *)vtomach((_ptp)), (_npte)); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) +#define PT_CLEAR_VA(_ptp, sync) do { \ + PMAP_REF((pt_entry_t *)(_ptp), 0); \ + xpq_queue_pt_update((pt_entry_t *)vtomach(_ptp), 0); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) +#define PT_CLEAR(_ptp, sync) do { \ + PMAP_REF((pt_entry_t *)(vtopte(_ptp)), 0); \ + mcl_queue_pt_update((unsigned long)_ptp, 0); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) +#define PT_SET_MA(_va,_ma,sync) do { \ + PMAP_REF(vtopte((unsigned long)_va), (_ma)); \ + mcl_queue_pt_update((vm_offset_t )(_va), (_ma)); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) +#define PT_SET(_va,_pa,sync) do { \ + PMAP_REF((pt_entry_t *)(vtopte(_va)), xpmap_ptom(_pa)); \ + mcl_queue_pt_update((vm_offset_t)(_va), \ + xpmap_ptom((_pa))); \ + if (sync || ALWAYS_SYNC) \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) + + + +#define PT_UPDATES_FLUSH() do { \ + mcl_flush_queue(); \ +} while (/*CONSTCOND*/0) + + +static __inline uint32_t +xpmap_mtop(uint32_t mpa) +{ + return (((xen_machine_phys[(mpa >> PAGE_SHIFT)]) << PAGE_SHIFT) + | (mpa & ~PG_FRAME)); +} + +static __inline vm_paddr_t +xpmap_ptom(uint32_t ppa) +{ + return phystomach(ppa) | (ppa & ~PG_FRAME); +} + +#endif /* _XEN_XENPMAP_H_ */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/include/xenvar.h b/freebsd-5.3-xen-sparse/i386-xen/include/xenvar.h new file mode 100644 index 0000000000..5a3d3acb0b --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xenvar.h @@ -0,0 +1,30 @@ +#ifndef XENVAR_H_ +#define XENVAR_H_ + +#define XBOOTUP 0x1 +#define XPMAP 0x2 +extern int xendebug_flags; +#ifndef NOXENDEBUG +#define XENPRINTF printk +#else +#define XENPRINTF(x...) +#endif +extern unsigned long *xen_phys_machine; +#define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__) +#define TRACE_EXIT XENPRINTF("(file=%s, line=%d) exiting %s\n", __FILE__, __LINE__, __FUNCTION__) +#define TRACE_DEBUG(argflags, _f, _a...) \ +if (xendebug_flags & argflags) XENPRINTF("(file=%s, line=%d) " _f "\n", __FILE__, __LINE__, ## _a); + +extern unsigned long *xen_machine_phys; +#define PTOM(i) (((unsigned long *)xen_phys_machine)[i]) +#define phystomach(pa) ((((unsigned long *)xen_phys_machine)[(pa >> PAGE_SHIFT)]) << PAGE_SHIFT) +void xpq_init(void); + +struct sockaddr_in; + +int xen_setnfshandle(void); +int setinaddr(struct sockaddr_in *addr, char *ipstr); + +#define RB_GDB_PAUSE RB_RESERVED1 + +#endif diff --git a/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c b/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c new file mode 100644 index 0000000000..66c80f3ece --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c @@ -0,0 +1,925 @@ +/*- + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * XenoBSD block device driver + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* prototypes */ +struct xb_softc; +static void xb_startio(struct xb_softc *sc); +static void xb_vbdinit(void); +static void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp); +static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id); + +struct xb_softc { + device_t xb_dev; + struct disk xb_disk; /* disk params */ + struct bio_queue_head xb_bioq; /* sort queue */ + struct resource *xb_irq; + void *xb_resp_handler; + int xb_unit; + int xb_flags; +#define XB_OPEN (1<<0) /* drive is open (can't shut down) */ +}; + +/* Control whether runtime update of vbds is enabled. */ +#define ENABLE_VBD_UPDATE 1 + +#if ENABLE_VBD_UPDATE +static void vbd_update(void); +#else +static void vbd_update(void){}; +#endif + +#define BLKIF_STATE_CLOSED 0 +#define BLKIF_STATE_DISCONNECTED 1 +#define BLKIF_STATE_CONNECTED 2 + +static char *blkif_state_name[] = { + [BLKIF_STATE_CLOSED] = "closed", + [BLKIF_STATE_DISCONNECTED] = "disconnected", + [BLKIF_STATE_CONNECTED] = "connected", +}; + +static char * blkif_status_name[] = { + [BLKIF_INTERFACE_STATUS_CLOSED] = "closed", + [BLKIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", + [BLKIF_INTERFACE_STATUS_CONNECTED] = "connected", + [BLKIF_INTERFACE_STATUS_CHANGED] = "changed", +}; + +#define WPRINTK(fmt, args...) printk("[XEN] " fmt, ##args) + +static int blkif_handle; +static unsigned int blkif_state = BLKIF_STATE_CLOSED; +static unsigned int blkif_evtchn; +static unsigned int blkif_irq; + +static int blkif_control_rsp_valid; +static blkif_response_t blkif_control_rsp; + +static unsigned long xb_rec_ring_free; +blkif_request_t xb_rec_ring[BLKIF_RING_SIZE]; /* shadow recovery ring */ + +/* XXX move to xb_vbd.c when VBD update support is added */ +#define MAX_VBDS 64 +static vdisk_t xb_diskinfo[MAX_VBDS]; +static int xb_ndisks; + +#define XBD_SECTOR_SIZE 512 /* XXX: assume for now */ +#define XBD_SECTOR_SHFT 9 + +static unsigned int xb_kick_pending; + +static struct mtx blkif_io_lock; + +static blkif_ring_t *xb_blk_ring; +static BLKIF_RING_IDX xb_resp_cons; /* Response consumer for comms ring. */ +static BLKIF_RING_IDX xb_req_prod; /* Private request producer */ + +static int xb_recovery = 0; /* "Recovery in progress" flag. Protected + * by the blkif_io_lock */ + +/* We plug the I/O ring if the driver is suspended or if the ring is full. */ +#define BLKIF_RING_FULL (((xb_req_prod - xb_resp_cons) == BLKIF_RING_SIZE) || \ + (blkif_state != BLKIF_STATE_CONNECTED)) + +void blkif_completion(blkif_request_t *req); +void xb_response_intr(void *); + +/* XXX: This isn't supported in FreeBSD, so ignore it for now. */ +#define TASK_UNINTERRUPTIBLE 0 + +static inline int +GET_ID_FROM_FREELIST( void ) +{ + unsigned long free = xb_rec_ring_free; + + KASSERT(free <= BLKIF_RING_SIZE, ("free %lu > BLKIF_RING_SIZE", free)); + + xb_rec_ring_free = xb_rec_ring[free].id; + + xb_rec_ring[free].id = 0x0fffffee; /* debug */ + + return free; +} + +static inline void +ADD_ID_TO_FREELIST( unsigned long id ) +{ + xb_rec_ring[id].id = xb_rec_ring_free; + xb_rec_ring_free = id; +} + +static inline void translate_req_to_pfn(blkif_request_t *xreq, + blkif_request_t *req) +{ + int i; + + xreq->operation = req->operation; + xreq->nr_segments = req->nr_segments; + xreq->device = req->device; + /* preserve id */ + xreq->sector_number = req->sector_number; + + for ( i = 0; i < req->nr_segments; i++ ){ + xreq->frame_and_sects[i] = xpmap_mtop(req->frame_and_sects[i]); + } +} + +static inline void translate_req_to_mfn(blkif_request_t *xreq, + blkif_request_t *req) +{ + int i; + + xreq->operation = req->operation; + xreq->nr_segments = req->nr_segments; + xreq->device = req->device; + xreq->id = req->id; /* copy id (unlike above) */ + xreq->sector_number = req->sector_number; + + for ( i = 0; i < req->nr_segments; i++ ){ + xreq->frame_and_sects[i] = xpmap_ptom(req->frame_and_sects[i]); + } +} + + +static inline void flush_requests(void) +{ + xb_blk_ring->req_prod = xb_req_prod; + notify_via_evtchn(blkif_evtchn); +} + + +#if ENABLE_VBD_UPDATE +static void vbd_update() +{ + XENPRINTF(">\n"); + XENPRINTF("<\n"); +} +#endif /* ENABLE_VBD_UPDATE */ + +void +xb_response_intr(void *xsc) +{ + struct xb_softc *sc = NULL; + struct bio *bp; + blkif_response_t *bret; + BLKIF_RING_IDX i, rp; + unsigned long flags; + + if (blkif_state == BLKIF_STATE_CLOSED) + return; + + mtx_lock_irqsave(&blkif_io_lock, flags); + + if ( unlikely(blkif_state == BLKIF_STATE_CLOSED) || + unlikely(xb_recovery) ) { + mtx_unlock_irqrestore(&blkif_io_lock, flags); + return; + } + + rp = xb_blk_ring->resp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + /* sometimes we seem to lose i/o. stay in the interrupt handler while + * there is stuff to process: continually recheck the response producer. + */ + for ( i = xb_resp_cons; i != (rp = xb_blk_ring->resp_prod); i++ ) { + unsigned long id; + bret = &xb_blk_ring->ring[MASK_BLKIF_IDX(i)].resp; + + id = bret->id; + bp = (struct bio *)xb_rec_ring[id].id; + + blkif_completion(&xb_rec_ring[id]); + + ADD_ID_TO_FREELIST(id); /* overwrites req */ + + switch ( bret->operation ) { + case BLKIF_OP_READ: + /* had an unaligned buffer that needs to be copied */ + if (bp->bio_driver1) + bcopy(bp->bio_data, bp->bio_driver1, bp->bio_bcount); + case BLKIF_OP_WRITE: + + /* free the copy buffer */ + if (bp->bio_driver1) { + free(bp->bio_data, M_DEVBUF); + bp->bio_data = bp->bio_driver1; + bp->bio_driver1 = NULL; + } + + if ( unlikely(bret->status != BLKIF_RSP_OKAY) ) { + XENPRINTF("Bad return from blkdev data request: %x\n", + bret->status); + bp->bio_flags |= BIO_ERROR; + } + + sc = (struct xb_softc *)bp->bio_disk->d_drv1; + + if (bp->bio_flags & BIO_ERROR) + bp->bio_error = EIO; + else + bp->bio_resid = 0; + + biodone(bp); + break; + case BLKIF_OP_PROBE: + memcpy(&blkif_control_rsp, bret, sizeof(*bret)); + blkif_control_rsp_valid = 1; + break; + default: + panic("received invalid operation"); + break; + } + } + + xb_resp_cons = i; + + if (sc && xb_kick_pending) { + xb_kick_pending = FALSE; + xb_startio(sc); + } + + mtx_unlock_irqrestore(&blkif_io_lock, flags); +} + +static int +xb_open(struct disk *dp) +{ + struct xb_softc *sc = (struct xb_softc *)dp->d_drv1; + + if (sc == NULL) { + printk("xb%d: not found", sc->xb_unit); + return (ENXIO); + } + + /* block dev not active */ + if (blkif_state != BLKIF_STATE_CONNECTED) { + printk("xb%d: bad state: %dn", sc->xb_unit, blkif_state); + return(ENXIO); + } + + sc->xb_flags |= XB_OPEN; + return (0); +} + +static int +xb_close(struct disk *dp) +{ + struct xb_softc *sc = (struct xb_softc *)dp->d_drv1; + + if (sc == NULL) + return (ENXIO); + sc->xb_flags &= ~XB_OPEN; + return (0); +} + +static int +xb_ioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) +{ + struct xb_softc *sc = (struct xb_softc *)dp->d_drv1; + + TRACE_ENTER; + + if (sc == NULL) + return (ENXIO); + + return (ENOTTY); +} + +/* + * Dequeue buffers and place them in the shared communication ring. + * Return when no more requests can be accepted or all buffers have + * been queued. + * + * Signal XEN once the ring has been filled out. + */ +static void +xb_startio(struct xb_softc *sc) +{ + struct bio *bp; + unsigned long buffer_ma; + blkif_request_t *req; + int s, queued = 0; + unsigned long id; + unsigned int fsect, lsect; + + + if (unlikely(blkif_state != BLKIF_STATE_CONNECTED)) + return; + + s = splbio(); + + for (bp = bioq_first(&sc->xb_bioq); + bp && !BLKIF_RING_FULL; + xb_req_prod++, queued++, bp = bioq_first(&sc->xb_bioq)) { + + /* Check if the buffer is properly aligned */ + if ((vm_offset_t)bp->bio_data & PAGE_MASK) { + int align = (bp->bio_bcount < PAGE_SIZE/2) ? XBD_SECTOR_SIZE : + PAGE_SIZE; + caddr_t newbuf = malloc(bp->bio_bcount + align, M_DEVBUF, + M_WAITOK); + caddr_t alignbuf = (char *)roundup2((u_long)newbuf, align); + + /* save a copy of the current buffer */ + bp->bio_driver1 = bp->bio_data; + + /* Copy the data for a write */ + if (bp->bio_cmd == BIO_WRITE) + bcopy(bp->bio_data, alignbuf, bp->bio_bcount); + bp->bio_data = alignbuf; + } + + bioq_remove(&sc->xb_bioq, bp); + buffer_ma = vtomach(bp->bio_data); + fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT; + lsect = fsect + (bp->bio_bcount >> XBD_SECTOR_SHFT) - 1; + + KASSERT((buffer_ma & (XBD_SECTOR_SIZE-1)) == 0, + ("XEN buffer must be sector aligned")); + KASSERT(lsect <= 7, + ("XEN disk driver data cannot cross a page boundary")); + + buffer_ma &= ~PAGE_MASK; + + /* Fill out a communications ring structure. */ + req = &xb_blk_ring->ring[MASK_BLKIF_IDX(xb_req_prod)].req; + id = GET_ID_FROM_FREELIST(); + xb_rec_ring[id].id= (unsigned long)bp; + + req->id = id; + req->operation = (bp->bio_cmd == BIO_READ) ? BLKIF_OP_READ : + BLKIF_OP_WRITE; + + req->sector_number= (blkif_sector_t)bp->bio_pblkno; + req->device = xb_diskinfo[sc->xb_unit].device; + + req->nr_segments = 1; /* not doing scatter/gather since buffer + * chaining is not supported. + */ + /* + * upper bits represent the machine address of the buffer and the + * lower bits is the number of sectors to be read/written. + */ + req->frame_and_sects[0] = buffer_ma | (fsect << 3) | lsect; + + /* Keep a private copy so we can reissue requests when recovering. */ + translate_req_to_pfn( &xb_rec_ring[id], req); + + } + + if (BLKIF_RING_FULL) + xb_kick_pending = TRUE; + + if (queued != 0) + flush_requests(); + splx(s); +} + +/* + * Read/write routine for a buffer. Finds the proper unit, place it on + * the sortq and kick the controller. + */ +static void +xb_strategy(struct bio *bp) +{ + struct xb_softc *sc = (struct xb_softc *)bp->bio_disk->d_drv1; + int s; + + /* bogus disk? */ + if (sc == NULL) { + bp->bio_error = EINVAL; + bp->bio_flags |= BIO_ERROR; + goto bad; + } + + s = splbio(); + /* + * Place it in the queue of disk activities for this disk + */ + bioq_disksort(&sc->xb_bioq, bp); + splx(s); + + xb_startio(sc); + return; + + bad: + /* + * Correctly set the bio to indicate a failed tranfer. + */ + bp->bio_resid = bp->bio_bcount; + biodone(bp); + return; +} + + +static int +xb_create(int unit) +{ + struct xb_softc *sc; + int error = 0; + + sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK); + sc->xb_unit = unit; + + memset(&sc->xb_disk, 0, sizeof(sc->xb_disk)); + sc->xb_disk.d_unit = unit; + sc->xb_disk.d_open = xb_open; + sc->xb_disk.d_close = xb_close; + sc->xb_disk.d_ioctl = xb_ioctl; + sc->xb_disk.d_strategy = xb_strategy; + sc->xb_disk.d_name = "xbd"; + sc->xb_disk.d_drv1 = sc; + sc->xb_disk.d_sectorsize = XBD_SECTOR_SIZE; + sc->xb_disk.d_mediasize = xb_diskinfo[sc->xb_unit].capacity + << XBD_SECTOR_SHFT; +#if 0 + sc->xb_disk.d_maxsize = DFLTPHYS; +#else /* XXX: xen can't handle large single i/o requests */ + sc->xb_disk.d_maxsize = 4096; +#endif + + XENPRINTF("attaching device 0x%x unit %d capacity %llu\n", + xb_diskinfo[sc->xb_unit].device, sc->xb_unit, + sc->xb_disk.d_mediasize); + + disk_create(&sc->xb_disk, DISK_VERSION_00); + bioq_init(&sc->xb_bioq); + + return error; +} + +/* XXX move to xb_vbd.c when vbd update support is added */ +static void +xb_vbdinit(void) +{ + int i; + blkif_request_t req; + blkif_response_t rsp; + vdisk_t *buf; + + TRACE_ENTER; + + buf = (vdisk_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); + + /* Probe for disk information. */ + memset(&req, 0, sizeof(req)); + req.operation = BLKIF_OP_PROBE; + req.nr_segments = 1; + req.frame_and_sects[0] = vtomach(buf) | 7; + blkif_control_send(&req, &rsp); + + if ( rsp.status <= 0 ) { + printk("xb_identify: Could not identify disks (%d)\n", rsp.status); + free(buf, M_DEVBUF); + return; + } + + if ((xb_ndisks = rsp.status) > MAX_VBDS) + xb_ndisks = MAX_VBDS; + + memcpy(xb_diskinfo, buf, xb_ndisks * sizeof(vdisk_t)); + + for (i = 0; i < xb_ndisks; i++) + xb_create(i); + + free(buf, M_DEVBUF); +} + + +/***************************** COMMON CODE *******************************/ + +void +blkif_control_send(blkif_request_t *req, blkif_response_t *rsp) +{ + unsigned long flags, id; + + retry: + while ( (xb_req_prod - xb_resp_cons) == BLKIF_RING_SIZE ) { + tsleep( req, PWAIT | PCATCH, "blkif", hz); + } + + mtx_lock_irqsave(&blkif_io_lock, flags); + if ( (xb_req_prod - xb_resp_cons) == BLKIF_RING_SIZE ) + { + mtx_unlock_irqrestore(&blkif_io_lock, flags); + goto retry; + } + + xb_blk_ring->ring[MASK_BLKIF_IDX(xb_req_prod)].req = *req; + + id = GET_ID_FROM_FREELIST(); + xb_blk_ring->ring[MASK_BLKIF_IDX(xb_req_prod)].req.id = id; + xb_rec_ring[id].id = (unsigned long) req; + + translate_req_to_pfn( &xb_rec_ring[id], req ); + + xb_req_prod++; + flush_requests(); + + mtx_unlock_irqrestore(&blkif_io_lock, flags); + + while ( !blkif_control_rsp_valid ) + { + tsleep( &blkif_control_rsp_valid, PWAIT | PCATCH, "blkif", hz); + } + + memcpy(rsp, &blkif_control_rsp, sizeof(*rsp)); + blkif_control_rsp_valid = 0; +} + + +/* Send a driver status notification to the domain controller. */ +static void +send_driver_status(int ok) +{ + ctrl_msg_t cmsg = { + .type = CMSG_BLKIF_FE, + .subtype = CMSG_BLKIF_FE_DRIVER_STATUS, + .length = sizeof(blkif_fe_driver_status_t), + }; + blkif_fe_driver_status_t *msg = (void*)cmsg.msg; + + msg->status = (ok ? BLKIF_DRIVER_STATUS_UP : BLKIF_DRIVER_STATUS_DOWN); + + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); +} + +/* Tell the controller to bring up the interface. */ +static void +blkif_send_interface_connect(void) +{ + ctrl_msg_t cmsg = { + .type = CMSG_BLKIF_FE, + .subtype = CMSG_BLKIF_FE_INTERFACE_CONNECT, + .length = sizeof(blkif_fe_interface_connect_t), + }; + blkif_fe_interface_connect_t *msg = (void*)cmsg.msg; + + msg->handle = 0; + msg->shmem_frame = (vtomach(xb_blk_ring) >> PAGE_SHIFT); + + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); +} + +static void +blkif_free(void) +{ + + unsigned long flags; + + printk("[XEN] Recovering virtual block device driver\n"); + + /* Prevent new requests being issued until we fix things up. */ + mtx_lock_irqsave(&blkif_io_lock, flags); + xb_recovery = 1; + blkif_state = BLKIF_STATE_DISCONNECTED; + mtx_unlock_irqrestore(&blkif_io_lock, flags); + + /* Free resources associated with old device channel. */ + if (xb_blk_ring) { + free(xb_blk_ring, M_DEVBUF); + xb_blk_ring = NULL; + } + /* free_irq(blkif_irq, NULL);*/ + blkif_irq = 0; + + unbind_evtchn_from_irq(blkif_evtchn); + blkif_evtchn = 0; +} + +static void +blkif_close(void) +{ +} + +/* Move from CLOSED to DISCONNECTED state. */ +static void +blkif_disconnect(void) +{ + if (xb_blk_ring) free(xb_blk_ring, M_DEVBUF); + xb_blk_ring = (blkif_ring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); + xb_blk_ring->req_prod = xb_blk_ring->resp_prod = 0; + xb_resp_cons = xb_req_prod = 0; + blkif_state = BLKIF_STATE_DISCONNECTED; + blkif_send_interface_connect(); +} + +static void +blkif_reset(void) +{ + printk("[XEN] Recovering virtual block device driver\n"); + blkif_free(); + blkif_disconnect(); +} + +static void +blkif_recover(void) +{ + + int i; + + /* Hmm, requests might be re-ordered when we re-issue them. + * This will need to be fixed once we have barriers */ + + /* Stage 1 : Find active and move to safety. */ + for ( i = 0; i < BLKIF_RING_SIZE; i++ ) { + if ( xb_rec_ring[i].id >= KERNBASE ) { + translate_req_to_mfn( + &xb_blk_ring->ring[xb_req_prod].req, &xb_rec_ring[i]); + xb_req_prod++; + } + } + + printk("blkfront: recovered %d descriptors\n",xb_req_prod); + + /* Stage 2 : Set up shadow list. */ + for ( i = 0; i < xb_req_prod; i++ ) { + xb_rec_ring[i].id = xb_blk_ring->ring[i].req.id; + xb_blk_ring->ring[i].req.id = i; + translate_req_to_pfn(&xb_rec_ring[i], &xb_blk_ring->ring[i].req); + } + + /* Stage 3 : Set up free list. */ + for ( ; i < BLKIF_RING_SIZE; i++ ){ + xb_rec_ring[i].id = i+1; + } + xb_rec_ring_free = xb_req_prod; + xb_rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff; + + /* xb_blk_ring->req_prod will be set when we flush_requests().*/ + wmb(); + + /* Switch off recovery mode, using a memory barrier to ensure that + * it's seen before we flush requests - we don't want to miss any + * interrupts. */ + xb_recovery = 0; + wmb(); + + /* Kicks things back into life. */ + flush_requests(); + + /* Now safe to left other peope use interface. */ + blkif_state = BLKIF_STATE_CONNECTED; +} + +static void +blkif_connect(blkif_fe_interface_status_t *status) +{ + int err = 0; + + blkif_evtchn = status->evtchn; + blkif_irq = bind_evtchn_to_irq(blkif_evtchn); + + err = intr_add_handler("xbd", blkif_irq, + (driver_intr_t *)xb_response_intr, NULL, + INTR_TYPE_BIO | INTR_MPSAFE, NULL); + if(err){ + printk("[XEN] blkfront request_irq failed (err=%d)\n", err); + return; + } + + if ( xb_recovery ) { + blkif_recover(); + } else { + /* Probe for discs attached to the interface. */ + xb_vbdinit(); + + /* XXX: transition state after probe */ + blkif_state = BLKIF_STATE_CONNECTED; + } + + /* Kick pending requests. */ +#if 0 /* XXX: figure out sortq logic */ + mtx_lock_irq(&blkif_io_lock); + kick_pending_request_queues(); + mtx_unlock_irq(&blkif_io_lock); +#endif +} + +static void +unexpected(blkif_fe_interface_status_t *status) +{ + WPRINTK(" Unexpected blkif status %s in state %s\n", + blkif_status_name[status->status], + blkif_state_name[blkif_state]); +} + +static void +blkif_status(blkif_fe_interface_status_t *status) +{ + if (status->handle != blkif_handle) { + WPRINTK(" Invalid blkif: handle=%u", status->handle); + return; + } + + switch (status->status) { + + case BLKIF_INTERFACE_STATUS_CLOSED: + switch(blkif_state){ + case BLKIF_STATE_CLOSED: + unexpected(status); + break; + case BLKIF_STATE_DISCONNECTED: + case BLKIF_STATE_CONNECTED: + unexpected(status); + blkif_close(); + break; + } + break; + + case BLKIF_INTERFACE_STATUS_DISCONNECTED: + switch(blkif_state){ + case BLKIF_STATE_CLOSED: + blkif_disconnect(); + break; + case BLKIF_STATE_DISCONNECTED: + case BLKIF_STATE_CONNECTED: + unexpected(status); + blkif_reset(); + break; + } + break; + + case BLKIF_INTERFACE_STATUS_CONNECTED: + switch(blkif_state){ + case BLKIF_STATE_CLOSED: + unexpected(status); + blkif_disconnect(); + blkif_connect(status); + break; + case BLKIF_STATE_DISCONNECTED: + blkif_connect(status); + break; + case BLKIF_STATE_CONNECTED: + unexpected(status); + blkif_connect(status); + break; + } + break; + + case BLKIF_INTERFACE_STATUS_CHANGED: + switch(blkif_state){ + case BLKIF_STATE_CLOSED: + case BLKIF_STATE_DISCONNECTED: + unexpected(status); + break; + case BLKIF_STATE_CONNECTED: + vbd_update(); + break; + } + break; + + default: + WPRINTK("Invalid blkif status: %d\n", status->status); + break; + } +} + + +static void +blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) +{ + switch ( msg->subtype ) + { + case CMSG_BLKIF_FE_INTERFACE_STATUS: + if ( msg->length != sizeof(blkif_fe_interface_status_t) ) + goto parse_error; + blkif_status((blkif_fe_interface_status_t *) + &msg->msg[0]); + break; + default: + goto parse_error; + } + + ctrl_if_send_response(msg); + return; + + parse_error: + msg->length = 0; + ctrl_if_send_response(msg); +} + +static int +wait_for_blkif(void) +{ + int err = 0; + int i; + send_driver_status(1); + + /* + * We should read 'nr_interfaces' from response message and wait + * for notifications before proceeding. For now we assume that we + * will be notified of exactly one interface. + */ + for ( i=0; (blkif_state != BLKIF_STATE_CONNECTED) && (i < 10*hz); i++ ) + { + tsleep(&blkif_state, PWAIT | PCATCH, "blkif", hz); + } + + if (blkif_state != BLKIF_STATE_CONNECTED){ + printk("[XEN] Timeout connecting block device driver!\n"); + err = -ENOSYS; + } + return err; +} + + +static void +xb_init(void *unused) +{ + int i; + + printk("[XEN] Initialising virtual block device driver\n"); + + xb_rec_ring_free = 0; + for (i = 0; i < BLKIF_RING_SIZE; i++) { + xb_rec_ring[i].id = i+1; + } + xb_rec_ring[BLKIF_RING_SIZE-1].id = 0x0fffffff; + + (void)ctrl_if_register_receiver(CMSG_BLKIF_FE, blkif_ctrlif_rx, 0); + + wait_for_blkif(); +} + +#if 0 /* XXX not yet */ +void +blkdev_suspend(void) +{ +} + +void +blkdev_resume(void) +{ + send_driver_status(1); +} +#endif + +/* XXXXX THIS IS A TEMPORARY FUNCTION UNTIL WE GET GRANT TABLES */ + +void +blkif_completion(blkif_request_t *req) +{ + int i; + + switch ( req->operation ) + { + case BLKIF_OP_READ: + for ( i = 0; i < req->nr_segments; i++ ) + { + unsigned long pfn = req->frame_and_sects[i] >> PAGE_SHIFT; + unsigned long mfn = xen_phys_machine[pfn]; + xen_machphys_update(mfn, pfn); + } + break; + } + +} +MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_SPIN); +SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_ANY, xb_init, NULL) diff --git a/freebsd-5.3-xen-sparse/i386-xen/xen/char/console.c b/freebsd-5.3-xen-sparse/i386-xen/xen/char/console.c new file mode 100644 index 0000000000..7ea8e3eb4f --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/char/console.c @@ -0,0 +1,536 @@ +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "opt_ddb.h" +#ifdef DDB +#include +#endif + +static char driver_name[] = "xc"; +devclass_t xc_devclass; +static void xcstart (struct tty *); +static int xcparam (struct tty *, struct termios *); +static void xcstop (struct tty *, int); +static void xc_timeout(void *); +static void xencons_tx_flush_task_routine(void *,int ); +static void __xencons_tx_flush(void); +static void xencons_rx(ctrl_msg_t *msg,unsigned long id); +static boolean_t xcons_putc(int c); + +/* switch console so that shutdown can occur gracefully */ +static void xc_shutdown(void *arg, int howto); +static int xc_mute; + +void xcons_force_flush(void); + +static cn_probe_t xccnprobe; +static cn_init_t xccninit; +static cn_getc_t xccngetc; +static cn_putc_t xccnputc; +static cn_checkc_t xccncheckc; + +#define XC_POLLTIME (hz/10) + +CONS_DRIVER(xc, xccnprobe, xccninit, NULL, xccngetc, + xccncheckc, xccnputc, NULL); + +static int xen_console_up; +static boolean_t xc_tx_task_queued; +static boolean_t xc_start_needed; +static struct callout xc_callout; +struct mtx cn_mtx; + +#define RBUF_SIZE 1024 +#define RBUF_MASK(_i) ((_i)&(RBUF_SIZE-1)) +#define WBUF_SIZE 4096 +#define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1)) +static char wbuf[WBUF_SIZE]; +static char rbuf[RBUF_SIZE]; +static int rc, rp; +static int cnsl_evt_reg; +static unsigned int wc, wp; /* write_cons, write_prod */ +static struct task xencons_tx_flush_task = { {NULL},0,0,&xencons_tx_flush_task_routine,NULL }; + + +#define CDEV_MAJOR 12 +#define XCUNIT(x) (minor(x)) +#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN)) +#define CN_LOCK_INIT(x, _name) \ + mtx_init(&x, _name, _name, MTX_SPIN) +#define CN_LOCK(l, f) mtx_lock_irqsave(&(l), (f)) +#define CN_UNLOCK(l, f) mtx_unlock_irqrestore(&(l), (f)) +#define CN_LOCK_ASSERT(x) mtx_assert(&x, MA_OWNED) +#define CN_LOCK_DESTROY(x) mtx_destroy(&x) + + +static struct tty *xccons; + +struct xc_softc { + int xc_unit; + struct cdev *xc_dev; +}; + + +static d_open_t xcopen; +static d_close_t xcclose; +static d_ioctl_t xcioctl; + +static struct cdevsw xc_cdevsw = { + /* version */ D_VERSION_00, + /* maj */ CDEV_MAJOR, + /* flags */ D_TTY | D_NEEDGIANT, + /* name */ driver_name, + + /* open */ xcopen, + /* fdopen */ 0, + /* close */ xcclose, + /* read */ ttyread, + /* write */ ttywrite, + /* ioctl */ xcioctl, + /* poll */ ttypoll, + /* mmap */ 0, + /* strategy */ 0, + /* dump */ 0, + /* kqfilter */ ttykqfilter +}; + +static void +xccnprobe(struct consdev *cp) +{ + cp->cn_pri = CN_REMOTE; + cp->cn_tp = xccons; + sprintf(cp->cn_name, "%s0", driver_name); +} + + +static void +xccninit(struct consdev *cp) +{ + CN_LOCK_INIT(cn_mtx,"XCONS LOCK"); + +} +int +xccngetc(struct consdev *dev) +{ + int c; + if (xc_mute) + return 0; + do { + if ((c = xccncheckc(dev)) == -1) { + /* polling without sleeping in Xen doesn't work well. + * Sleeping gives other things like clock a chance to + * run + */ + tsleep(&cn_mtx, PWAIT | PCATCH, "console sleep", + XC_POLLTIME); + } + } while( c == -1 ); + return c; +} + +int +xccncheckc(struct consdev *dev) +{ + int ret = (xc_mute ? 0 : -1); + int flags; + CN_LOCK(cn_mtx, flags); + if ( (rp - rc) ){ + /* we need to return only one char */ + ret = (int)rbuf[RBUF_MASK(rc)]; + rc++; + } + CN_UNLOCK(cn_mtx, flags); + return(ret); +} + +static void +xccnputc(struct consdev *dev, int c) +{ + int flags; + CN_LOCK(cn_mtx, flags); + xcons_putc(c); + CN_UNLOCK(cn_mtx, flags); +} + +static boolean_t +xcons_putc(int c) +{ + int force_flush = xc_mute || +#ifdef DDB + db_active || +#endif + panicstr; /* we're not gonna recover, so force + * flush + */ + + if ( (wp-wc) < (WBUF_SIZE-1) ){ + if ( (wbuf[WBUF_MASK(wp++)] = c) == '\n' ) { + wbuf[WBUF_MASK(wp++)] = '\r'; + if (force_flush) + xcons_force_flush(); + } + } else if (force_flush) { + xcons_force_flush(); + + } + if (cnsl_evt_reg) + __xencons_tx_flush(); + + /* inform start path that we're pretty full */ + return ((wp - wc) >= WBUF_SIZE - 100) ? TRUE : FALSE; +} + +static void +xc_identify(driver_t *driver, device_t parent) +{ + device_t child; + child = BUS_ADD_CHILD(parent, 0, driver_name, 0); + device_set_driver(child, driver); + device_set_desc(child, "Xen Console"); +} + +static int +xc_probe(device_t dev) +{ + struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev); + + sc->xc_unit = device_get_unit(dev); + return (0); +} + +static int +xc_attach(device_t dev) +{ + struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev); + + sc->xc_dev = make_dev(&xc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "xc%r", 0); + xccons = ttymalloc(NULL); + + sc->xc_dev->si_drv1 = (void *)sc; + sc->xc_dev->si_tty = xccons; + + xccons->t_oproc = xcstart; + xccons->t_param = xcparam; + xccons->t_stop = xcstop; + xccons->t_dev = sc->xc_dev; + + callout_init(&xc_callout, 0); + + /* Ensure that we don't attach before the event channel is able to receive + * a registration. The XenBus code delays the probe/attach order until + * this has occurred. + */ + (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0); + cnsl_evt_reg = 1; + + callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, xccons); + + /* register handler to flush console on shutdown */ + if ((EVENTHANDLER_REGISTER(shutdown_post_sync, xc_shutdown, + NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) + printf("xencons: shutdown event registration failed!\n"); + + return (0); +} + +/* + * return 0 for all console input, force flush all output. + */ +static void +xc_shutdown(void *arg, int howto) +{ + xc_mute = 1; + xcons_force_flush(); + +} + +static void +xencons_rx(ctrl_msg_t *msg,unsigned long id) +{ + int i, flags; + struct tty *tp = xccons; + + CN_LOCK(cn_mtx, flags); + for ( i = 0; i < msg->length; i++ ) { + if ( xen_console_up ) + (*linesw[tp->t_line]->l_rint)(msg->msg[i], tp); + else + rbuf[RBUF_MASK(rp++)] = msg->msg[i]; + } + CN_UNLOCK(cn_mtx, flags); + msg->length = 0; + ctrl_if_send_response(msg); +} + +static void +__xencons_tx_flush(void) +{ + int sz, work_done = 0; + ctrl_msg_t msg; + + while ( wc != wp ) + { + sz = wp - wc; + if ( sz > sizeof(msg.msg) ) + sz = sizeof(msg.msg); + if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) ) + sz = WBUF_SIZE - WBUF_MASK(wc); + + msg.type = CMSG_CONSOLE; + msg.subtype = CMSG_CONSOLE_DATA; + msg.length = sz; + memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); + + if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ){ + wc += sz; + } + else if (xc_tx_task_queued) { + /* avoid the extra enqueue check if we know we're already queued */ + break; + } else if (ctrl_if_enqueue_space_callback(&xencons_tx_flush_task)) { + xc_tx_task_queued = TRUE; + break; + } + + work_done = 1; + } + + if ( work_done && xen_console_up ) + ttwakeup(xccons); +} +static void +xencons_tx_flush_task_routine(void * data, int arg) +{ + int flags; + CN_LOCK(cn_mtx, flags); + xc_tx_task_queued = FALSE; + __xencons_tx_flush(); + CN_UNLOCK(cn_mtx, flags); +} + +int +xcopen(struct cdev *dev, int flag, int mode, struct thread *td) +{ + struct xc_softc *sc; + int unit = XCUNIT(dev); + struct tty *tp; + int s, error; + + sc = (struct xc_softc *)device_get_softc( + devclass_get_device(xc_devclass, unit)); + if (sc == NULL) + return (ENXIO); + + tp = dev->si_tty; + s = spltty(); + if (!ISTTYOPEN(tp)) { + tp->t_state |= TS_CARR_ON; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG|CLOCAL; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + xcparam(tp, &tp->t_termios); + ttsetwater(tp); + } else if (tp->t_state & TS_XCLUDE && suser(td)) { + splx(s); + return (EBUSY); + } + splx(s); + + xen_console_up = 1; + + error = (*linesw[tp->t_line]->l_open)(dev, tp); + + return error; +} + +int +xcclose(struct cdev *dev, int flag, int mode, struct thread *td) +{ + struct tty *tp = dev->si_tty; + + if (tp == NULL) + return (0); + xen_console_up = 0; + + spltty(); + (*linesw[tp->t_line]->l_close)(tp, flag); + tty_close(tp); + spl0(); + return (0); +} + + +int +xcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) +{ + struct tty *tp = dev->si_tty; + int error; + + error = (*linesw[tp->t_line]->l_ioctl)(tp, cmd, data, flag, td); + if (error != ENOIOCTL) + return (error); + error = ttioctl(tp, cmd, data, flag); + if (error != ENOIOCTL) + return (error); + return (ENOTTY); +} + +static inline int +__xencons_put_char(int ch) +{ + char _ch = (char)ch; + if ( (wp - wc) == WBUF_SIZE ) + return 0; + wbuf[WBUF_MASK(wp++)] = _ch; + return 1; +} + + +static void +xcstart(struct tty *tp) +{ + int flags; + int s; + boolean_t cons_full = FALSE; + + s = spltty(); + CN_LOCK(cn_mtx, flags); + if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { + ttwwakeup(tp); + CN_UNLOCK(cn_mtx, flags); + return; + } + + tp->t_state |= TS_BUSY; + while (tp->t_outq.c_cc != 0 && !cons_full) + cons_full = xcons_putc(getc(&tp->t_outq)); + + /* if the console is close to full leave our state as busy */ + if (!cons_full) { + tp->t_state &= ~TS_BUSY; + ttwwakeup(tp); + } else { + /* let the timeout kick us in a bit */ + xc_start_needed = TRUE; + } + CN_UNLOCK(cn_mtx, flags); + splx(s); +} + +static void +xcstop(struct tty *tp, int flag) +{ + + if (tp->t_state & TS_BUSY) { + if ((tp->t_state & TS_TTSTOP) == 0) { + tp->t_state |= TS_FLUSH; + } + } +} + +static void +xc_timeout(void *v) +{ + struct tty *tp; + int c; + + tp = (struct tty *)v; + + while ((c = xccncheckc(NULL)) != -1) { + if (tp->t_state & TS_ISOPEN) { + (*linesw[tp->t_line]->l_rint)(c, tp); + } + } + + if (xc_start_needed) { + xc_start_needed = FALSE; + xcstart(tp); + } + + callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, tp); +} + +/* + * Set line parameters. + */ +int +xcparam(struct tty *tp, struct termios *t) +{ + tp->t_ispeed = t->c_ispeed; + tp->t_ospeed = t->c_ospeed; + tp->t_cflag = t->c_cflag; + return (0); +} + + +static device_method_t xc_methods[] = { + DEVMETHOD(device_identify, xc_identify), + DEVMETHOD(device_probe, xc_probe), + DEVMETHOD(device_attach, xc_attach), + {0, 0} +}; + +static driver_t xc_driver = { + driver_name, + xc_methods, + sizeof(struct xc_softc), +}; + +/*** Forcibly flush console data before dying. ***/ +void +xcons_force_flush(void) +{ + ctrl_msg_t msg; + int sz; + + /* + * We use dangerous control-interface functions that require a quiescent + * system and no interrupts. Try to ensure this with a global cli(). + */ + cli(); + + /* Spin until console data is flushed through to the domain controller. */ + while ( (wc != wp) && !ctrl_if_transmitter_empty() ) + { + /* Interrupts are disabled -- we must manually reap responses. */ + ctrl_if_discard_responses(); + + if ( (sz = wp - wc) == 0 ) + continue; + if ( sz > sizeof(msg.msg) ) + sz = sizeof(msg.msg); + if ( sz > (WBUF_SIZE - WBUF_MASK(wc)) ) + sz = WBUF_SIZE - WBUF_MASK(wc); + + msg.type = CMSG_CONSOLE; + msg.subtype = CMSG_CONSOLE_DATA; + msg.length = sz; + memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); + + if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) + wc += sz; + } +} + +DRIVER_MODULE(xc, xenbus, xc_driver, xc_devclass, 0, 0); diff --git a/freebsd-5.3-xen-sparse/i386-xen/xen/misc/evtchn_dev.c b/freebsd-5.3-xen-sparse/i386-xen/xen/misc/evtchn_dev.c new file mode 100644 index 0000000000..de379b6bf9 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/misc/evtchn_dev.c @@ -0,0 +1,410 @@ +/****************************************************************************** + * evtchn.c + * + * Xenolinux driver for receiving and demuxing event-channel signals. + * + * Copyright (c) 2004, K A Fraser + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +typedef struct evtchn_sotfc { + + struct selinfo ev_rsel; +} evtchn_softc_t; + + +#ifdef linuxcrap +/* NB. This must be shared amongst drivers if more things go in /dev/xen */ +static devfs_handle_t xen_dev_dir; +#endif + +/* Only one process may open /dev/xen/evtchn at any time. */ +static unsigned long evtchn_dev_inuse; + +/* Notification ring, accessed via /dev/xen/evtchn. */ +#define RING_SIZE 2048 /* 2048 16-bit entries */ +#define RING_MASK(_i) ((_i)&(RING_SIZE-1)) +static uint16_t *ring; +static unsigned int ring_cons, ring_prod, ring_overflow; + +/* Which ports is user-space bound to? */ +static uint32_t bound_ports[32]; + +/* Unique address for processes to sleep on */ +static void *evtchn_waddr = ˚ + +static struct mtx lock, upcall_lock; + +static d_read_t evtchn_read; +static d_write_t evtchn_write; +static d_ioctl_t evtchn_ioctl; +static d_poll_t evtchn_poll; +static d_open_t evtchn_open; +static d_close_t evtchn_close; + + +void +evtchn_device_upcall(int port) +{ + mtx_lock(&upcall_lock); + + mask_evtchn(port); + clear_evtchn(port); + + if ( ring != NULL ) { + if ( (ring_prod - ring_cons) < RING_SIZE ) { + ring[RING_MASK(ring_prod)] = (uint16_t)port; + if ( ring_cons == ring_prod++ ) { + wakeup(evtchn_waddr); + } + } + else { + ring_overflow = 1; + } + } + + mtx_unlock(&upcall_lock); +} + +static void +__evtchn_reset_buffer_ring(void) +{ + /* Initialise the ring to empty. Clear errors. */ + ring_cons = ring_prod = ring_overflow = 0; +} + +static int +evtchn_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + int rc; + unsigned int count, c, p, sst = 0, bytes1 = 0, bytes2 = 0; + count = uio->uio_resid; + + count &= ~1; /* even number of bytes */ + + if ( count == 0 ) + { + rc = 0; + goto out; + } + + if ( count > PAGE_SIZE ) + count = PAGE_SIZE; + + for ( ; ; ) { + if ( (c = ring_cons) != (p = ring_prod) ) + break; + + if ( ring_overflow ) { + rc = EFBIG; + goto out; + } + + if (sst != 0) { + rc = EINTR; + goto out; + } + + /* PCATCH == check for signals before and after sleeping + * PWAIT == priority of waiting on resource + */ + sst = tsleep(evtchn_waddr, PWAIT|PCATCH, "evchwt", 10); + } + + /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */ + if ( ((c ^ p) & RING_SIZE) != 0 ) { + bytes1 = (RING_SIZE - RING_MASK(c)) * sizeof(uint16_t); + bytes2 = RING_MASK(p) * sizeof(uint16_t); + } + else { + bytes1 = (p - c) * sizeof(uint16_t); + bytes2 = 0; + } + + /* Truncate chunks according to caller's maximum byte count. */ + if ( bytes1 > count ) { + bytes1 = count; + bytes2 = 0; + } + else if ( (bytes1 + bytes2) > count ) { + bytes2 = count - bytes1; + } + + if ( uiomove(&ring[RING_MASK(c)], bytes1, uio) || + ((bytes2 != 0) && uiomove(&ring[0], bytes2, uio))) + /* keeping this around as its replacement is not equivalent + * copyout(&ring[0], &buf[bytes1], bytes2) + */ + { + rc = EFAULT; + goto out; + } + + ring_cons += (bytes1 + bytes2) / sizeof(uint16_t); + + rc = bytes1 + bytes2; + + out: + + return rc; +} + +static int +evtchn_write(struct cdev *dev, struct uio *uio, int ioflag) +{ + int rc, i, count; + + count = uio->uio_resid; + + uint16_t *kbuf = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); + + + if ( kbuf == NULL ) + return ENOMEM; + + count &= ~1; /* even number of bytes */ + + if ( count == 0 ) { + rc = 0; + goto out; + } + + if ( count > PAGE_SIZE ) + count = PAGE_SIZE; + + if ( uiomove(kbuf, count, uio) != 0 ) { + rc = EFAULT; + goto out; + } + + mtx_lock_spin(&lock); + for ( i = 0; i < (count/2); i++ ) + if ( test_bit(kbuf[i], &bound_ports[0]) ) + unmask_evtchn(kbuf[i]); + mtx_unlock_spin(&lock); + + rc = count; + + out: + free(kbuf, M_DEVBUF); + return rc; +} + +static int +evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg, + int mode, struct thread *td __unused) +{ + int rc = 0; + + mtx_lock_spin(&lock); + + switch ( cmd ) + { + case EVTCHN_RESET: + __evtchn_reset_buffer_ring(); + break; + case EVTCHN_BIND: + if ( !synch_test_and_set_bit((int)arg, &bound_ports[0]) ) + unmask_evtchn((int)arg); + else + rc = EINVAL; + break; + case EVTCHN_UNBIND: + if ( synch_test_and_clear_bit((int)arg, &bound_ports[0]) ) + mask_evtchn((int)arg); + else + rc = EINVAL; + break; + default: + rc = ENOSYS; + break; + } + + mtx_unlock_spin(&lock); + + return rc; +} + +static int +evtchn_poll(struct cdev *dev, int poll_events, struct thread *td) +{ + + evtchn_softc_t *sc; + unsigned int mask = POLLOUT | POLLWRNORM; + + sc = dev->si_drv1; + + if ( ring_cons != ring_prod ) + mask |= POLLIN | POLLRDNORM; + else if ( ring_overflow ) + mask = POLLERR; + else + selrecord(td, &sc->ev_rsel); + + + return mask; +} + + +static int +evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td) +{ + uint16_t *_ring; + + if (flag & O_NONBLOCK) + return EBUSY; + + if ( synch_test_and_set_bit(0, &evtchn_dev_inuse) ) + return EBUSY; + + if ( (_ring = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK)) == NULL ) + return ENOMEM; + + mtx_lock_spin(&lock); + ring = _ring; + __evtchn_reset_buffer_ring(); + mtx_unlock_spin(&lock); + + + return 0; +} + +static int +evtchn_close(struct cdev *dev, int flag, int otyp, struct thread *td __unused) +{ + int i; + + mtx_lock_spin(&lock); + if (ring != NULL) { + free(ring, M_DEVBUF); + ring = NULL; + } + for ( i = 0; i < NR_EVENT_CHANNELS; i++ ) + if ( synch_test_and_clear_bit(i, &bound_ports[0]) ) + mask_evtchn(i); + mtx_unlock_spin(&lock); + + evtchn_dev_inuse = 0; + + return 0; +} + + + +/* XXX wild assed guess as to a safe major number */ +#define EVTCHN_MAJOR 140 + +static struct cdevsw evtchn_devsw = { + d_version: D_VERSION_00, + d_open: evtchn_open, + d_close: evtchn_close, + d_read: evtchn_read, + d_write: evtchn_write, + d_ioctl: evtchn_ioctl, + d_poll: evtchn_poll, + d_name: "evtchn", + d_maj: EVTCHN_MAJOR, + d_flags: 0, +}; + + +/* XXX - if this device is ever supposed to support use by more than one process + * this global static will have to go away + */ +static struct cdev *evtchn_dev; + + + +static int +evtchn_init(void *dummy __unused) +{ + /* XXX I believe we don't need these leaving them here for now until we + * have some semblance of it working + */ +#if 0 + devfs_handle_t symlink_handle; + int err, pos; + char link_dest[64]; +#endif + mtx_init(&upcall_lock, "evtchup", NULL, MTX_DEF); + + /* (DEVFS) create '/dev/misc/evtchn'. */ + evtchn_dev = make_dev(&evtchn_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "xen/evtchn"); + + mtx_init(&lock, "evch", NULL, MTX_SPIN | MTX_NOWITNESS); + + evtchn_dev->si_drv1 = malloc(sizeof(evtchn_softc_t), M_DEVBUF, M_WAITOK); + bzero(evtchn_dev->si_drv1, sizeof(evtchn_softc_t)); + + /* XXX I don't think we need any of this rubbish */ +#if 0 + if ( err != 0 ) + { + printk(KERN_ALERT "Could not register /dev/misc/evtchn\n"); + return err; + } + + /* (DEVFS) create directory '/dev/xen'. */ + xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL); + + /* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */ + pos = devfs_generate_path(evtchn_miscdev.devfs_handle, + &link_dest[3], + sizeof(link_dest) - 3); + if ( pos >= 0 ) + strncpy(&link_dest[pos], "../", 3); + /* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */ + (void)devfs_mk_symlink(xen_dev_dir, + "evtchn", + DEVFS_FL_DEFAULT, + &link_dest[pos], + &symlink_handle, + NULL); + + /* (DEVFS) automatically destroy the symlink with its destination. */ + devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle); +#endif + printk("Event-channel device installed.\n"); + + return 0; +} + + +SYSINIT(evtchn_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, evtchn_init, NULL); + + +#if 0 + +static void cleanup_module(void) +{ + destroy_dev(evtchn_dev); +; +} + +module_init(init_module); +module_exit(cleanup_module); +#endif diff --git a/freebsd-5.3-xen-sparse/i386-xen/xen/misc/npx.c b/freebsd-5.3-xen-sparse/i386-xen/xen/misc/npx.c new file mode 100644 index 0000000000..604aec78c1 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/misc/npx.c @@ -0,0 +1,1109 @@ +/*- + * Copyright (c) 1990 William Jolitz. + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)npx.c 7.2 (Berkeley) 5/12/91 + */ + +#include +__FBSDID("$FreeBSD: src/sys/i386/isa/npx.c,v 1.144 2003/11/03 21:53:38 jhb Exp $"); + +#include "opt_cpu.h" +#include "opt_debug_npx.h" +#include "opt_isa.h" +#include "opt_npx.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NPX_DEBUG +#include +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#ifdef PC98 +#include +#else +#include +#endif +#include +#ifdef DEV_ISA +#include +#endif + +#if !defined(CPU_ENABLE_SSE) && defined(I686_CPU) +#define CPU_ENABLE_SSE +#endif +#if defined(CPU_DISABLE_SSE) +#undef CPU_ENABLE_SSE +#endif + +/* + * 387 and 287 Numeric Coprocessor Extension (NPX) Driver. + */ + +/* Configuration flags. */ +#define NPX_DISABLE_I586_OPTIMIZED_BCOPY (1 << 0) +#define NPX_DISABLE_I586_OPTIMIZED_BZERO (1 << 1) +#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2) + +#if defined(__GNUC__) && !defined(lint) + +#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr))) +#define fnclex() __asm("fnclex") +#define fninit() __asm("fninit") +#define fnsave(addr) __asm __volatile("fnsave %0" : "=m" (*(addr))) +#define fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) +#define fp_divide_by_0() __asm("fldz; fld1; fdiv %st,%st(1); fnop") +#define frstor(addr) __asm("frstor %0" : : "m" (*(addr))) +#ifdef CPU_ENABLE_SSE +#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr))) +#define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr))) +#endif +#define start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \ + : : "n" (CR0_TS) : "ax") +#define stop_emulating() __asm("clts") + +#else /* not __GNUC__ */ + +void fldcw(caddr_t addr); +void fnclex(void); +void fninit(void); +void fnsave(caddr_t addr); +void fnstcw(caddr_t addr); +void fnstsw(caddr_t addr); +void fp_divide_by_0(void); +void frstor(caddr_t addr); +#ifdef CPU_ENABLE_SSE +void fxsave(caddr_t addr); +void fxrstor(caddr_t addr); +#endif +void start_emulating(void); +void stop_emulating(void); + +#endif /* __GNUC__ */ + +#ifdef CPU_ENABLE_SSE +#define GET_FPU_CW(thread) \ + (cpu_fxsr ? \ + (thread)->td_pcb->pcb_save.sv_xmm.sv_env.en_cw : \ + (thread)->td_pcb->pcb_save.sv_87.sv_env.en_cw) +#define GET_FPU_SW(thread) \ + (cpu_fxsr ? \ + (thread)->td_pcb->pcb_save.sv_xmm.sv_env.en_sw : \ + (thread)->td_pcb->pcb_save.sv_87.sv_env.en_sw) +#else /* CPU_ENABLE_SSE */ +#define GET_FPU_CW(thread) \ + (thread->td_pcb->pcb_save.sv_87.sv_env.en_cw) +#define GET_FPU_SW(thread) \ + (thread->td_pcb->pcb_save.sv_87.sv_env.en_sw) +#endif /* CPU_ENABLE_SSE */ + +typedef u_char bool_t; + +static void fpusave(union savefpu *); +static void fpurstor(union savefpu *); +static int npx_attach(device_t dev); +static void npx_identify(driver_t *driver, device_t parent); +#if 0 +static void npx_intr(void *); +#endif +static int npx_probe(device_t dev); +#ifdef I586_CPU_XXX +static long timezero(const char *funcname, + void (*func)(void *buf, size_t len)); +#endif /* I586_CPU */ + +int hw_float; /* XXX currently just alias for npx_exists */ + +SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint, + CTLFLAG_RD, &hw_float, 0, + "Floatingpoint instructions executed in hardware"); +#if 0 +static volatile u_int npx_intrs_while_probing; +#endif +static union savefpu npx_cleanstate; +static bool_t npx_cleanstate_ready; +static bool_t npx_ex16; +static bool_t npx_exists; +static bool_t npx_irq13; + +alias_for_inthand_t probetrap; +#if 0 +__asm(" \n\ + .text \n\ + .p2align 2,0x90 \n\ + .type " __XSTRING(CNAME(probetrap)) ",@function \n\ +" __XSTRING(CNAME(probetrap)) ": \n\ + ss \n\ + incl " __XSTRING(CNAME(npx_traps_while_probing)) " \n\ + fnclex \n\ + iret \n\ +"); +#endif +/* + * Identify routine. Create a connection point on our parent for probing. + */ +static void +npx_identify(driver, parent) + driver_t *driver; + device_t parent; +{ + device_t child; + + child = BUS_ADD_CHILD(parent, 0, "npx", 0); + if (child == NULL) + panic("npx_identify"); +} +#if 0 +/* + * Do minimal handling of npx interrupts to convert them to traps. + */ +static void +npx_intr(dummy) + void *dummy; +{ + struct thread *td; + + npx_intrs_while_probing++; + + /* + * The BUSY# latch must be cleared in all cases so that the next + * unmasked npx exception causes an interrupt. + */ +#ifdef PC98 + outb(0xf8, 0); +#else + outb(0xf0, 0); +#endif + + /* + * fpcurthread is normally non-null here. In that case, schedule an + * AST to finish the exception handling in the correct context + * (this interrupt may occur after the thread has entered the + * kernel via a syscall or an interrupt). Otherwise, the npx + * state of the thread that caused this interrupt must have been + * pushed to the thread's pcb, and clearing of the busy latch + * above has finished the (essentially null) handling of this + * interrupt. Control will eventually return to the instruction + * that caused it and it will repeat. We will eventually (usually + * soon) win the race to handle the interrupt properly. + */ + td = PCPU_GET(fpcurthread); + if (td != NULL) { + td->td_pcb->pcb_flags |= PCB_NPXTRAP; + mtx_lock_spin(&sched_lock); + td->td_flags |= TDF_ASTPENDING; + mtx_unlock_spin(&sched_lock); + } +} +#endif + +static int +npx_probe(device_t dev) +{ + + return 1; +} + +#if 0 +/* + * Probe routine. Initialize cr0 to give correct behaviour for [f]wait + * whether the device exists or not (XXX should be elsewhere). Set flags + * to tell npxattach() what to do. Modify device struct if npx doesn't + * need to use interrupts. Return 0 if device exists. + */ +static int +npx_probe(device_t dev) +{ + struct gate_descriptor save_idt_npxtrap; + struct resource *ioport_res, *irq_res; + void *irq_cookie; + int ioport_rid, irq_num, irq_rid; + u_short control; + u_short status; + + save_idt_npxtrap = idt[IDT_MF]; + setidt(IDT_MF, probetrap, SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + ioport_rid = 0; + ioport_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &ioport_rid, + IO_NPX, IO_NPX, IO_NPXSIZE, RF_ACTIVE); + if (ioport_res == NULL) + panic("npx: can't get ports"); +#ifdef PC98 + if (resource_int_value("npx", 0, "irq", &irq_num) != 0) + irq_num = 8; +#else + if (resource_int_value("npx", 0, "irq", &irq_num) != 0) + irq_num = 13; +#endif + irq_rid = 0; + irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, irq_num, + irq_num, 1, RF_ACTIVE); + if (irq_res == NULL) + panic("npx: can't get IRQ"); + if (bus_setup_intr(dev, irq_res, INTR_TYPE_MISC | INTR_FAST, npx_intr, + NULL, &irq_cookie) != 0) + panic("npx: can't create intr"); + + /* + * Partially reset the coprocessor, if any. Some BIOS's don't reset + * it after a warm boot. + */ +#ifdef PC98 + outb(0xf8,0); +#else + outb(0xf1, 0); /* full reset on some systems, NOP on others */ + outb(0xf0, 0); /* clear BUSY# latch */ +#endif + /* + * Prepare to trap all ESC (i.e., NPX) instructions and all WAIT + * instructions. We must set the CR0_MP bit and use the CR0_TS + * bit to control the trap, because setting the CR0_EM bit does + * not cause WAIT instructions to trap. It's important to trap + * WAIT instructions - otherwise the "wait" variants of no-wait + * control instructions would degenerate to the "no-wait" variants + * after FP context switches but work correctly otherwise. It's + * particularly important to trap WAITs when there is no NPX - + * otherwise the "wait" variants would always degenerate. + * + * Try setting CR0_NE to get correct error reporting on 486DX's. + * Setting it should fail or do nothing on lesser processors. + */ + load_cr0(rcr0() | CR0_MP | CR0_NE); + /* + * But don't trap while we're probing. + */ + stop_emulating(); + /* + * Finish resetting the coprocessor, if any. If there is an error + * pending, then we may get a bogus IRQ13, but npx_intr() will handle + * it OK. Bogus halts have never been observed, but we enabled + * IRQ13 and cleared the BUSY# latch early to handle them anyway. + */ + fninit(); + + device_set_desc(dev, "math processor"); + + /* + * Don't use fwait here because it might hang. + * Don't use fnop here because it usually hangs if there is no FPU. + */ + DELAY(1000); /* wait for any IRQ13 */ +#ifdef DIAGNOSTIC + if (npx_intrs_while_probing != 0) + printf("fninit caused %u bogus npx interrupt(s)\n", + npx_intrs_while_probing); + if (npx_traps_while_probing != 0) + printf("fninit caused %u bogus npx trap(s)\n", + npx_traps_while_probing); +#endif + /* + * Check for a status of mostly zero. + */ + status = 0x5a5a; + fnstsw(&status); + if ((status & 0xb8ff) == 0) { + /* + * Good, now check for a proper control word. + */ + control = 0x5a5a; + fnstcw(&control); + if ((control & 0x1f3f) == 0x033f) { + hw_float = npx_exists = 1; + /* + * We have an npx, now divide by 0 to see if exception + * 16 works. + */ + control &= ~(1 << 2); /* enable divide by 0 trap */ + fldcw(&control); +#ifdef FPU_ERROR_BROKEN + /* + * FPU error signal doesn't work on some CPU + * accelerator board. + */ + npx_ex16 = 1; + return (0); +#endif + npx_traps_while_probing = npx_intrs_while_probing = 0; + fp_divide_by_0(); + if (npx_traps_while_probing != 0) { + /* + * Good, exception 16 works. + */ + npx_ex16 = 1; + goto no_irq13; + } + if (npx_intrs_while_probing != 0) { + /* + * Bad, we are stuck with IRQ13. + */ + npx_irq13 = 1; + idt[IDT_MF] = save_idt_npxtrap; +#ifdef SMP + if (mp_ncpus > 1) + panic("npx0 cannot use IRQ 13 on an SMP system"); +#endif + return (0); + } + /* + * Worse, even IRQ13 is broken. Use emulator. + */ + } + } + /* + * Probe failed, but we want to get to npxattach to initialize the + * emulator and say that it has been installed. XXX handle devices + * that aren't really devices better. + */ +#ifdef SMP + if (mp_ncpus > 1) + panic("npx0 cannot be emulated on an SMP system"); +#endif + /* FALLTHROUGH */ +no_irq13: + idt[IDT_MF] = save_idt_npxtrap; + bus_teardown_intr(dev, irq_res, irq_cookie); + + /* + * XXX hack around brokenness of bus_teardown_intr(). If we left the + * irq active then we would get it instead of exception 16. + */ + { + struct intsrc *isrc; + + isrc = intr_lookup_source(irq_num); + isrc->is_pic->pic_disable_source(isrc); + } + + bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); + bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res); + return (0); +} +#endif + +/* + * Attach routine - announce which it is, and wire into system + */ +static int +npx_attach(device_t dev) +{ + int flags; + register_t s; + + if (resource_int_value("npx", 0, "flags", &flags) != 0) + flags = 0; + + if (flags) + device_printf(dev, "flags 0x%x ", flags); + if (npx_irq13) { + device_printf(dev, "using IRQ 13 interface\n"); + } else { + if (npx_ex16) + device_printf(dev, "INT 16 interface\n"); + else + device_printf(dev, "WARNING: no FPU!\n"); + } + npxinit(__INITIAL_NPXCW__); + + if (npx_cleanstate_ready == 0) { + s = intr_disable(); + stop_emulating(); + fpusave(&npx_cleanstate); + start_emulating(); + npx_cleanstate_ready = 1; + intr_restore(s); + } +#ifdef I586_CPU_XXX + if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists && + timezero("i586_bzero()", i586_bzero) < + timezero("bzero()", bzero) * 4 / 5) { + if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) + bcopy_vector = i586_bcopy; + if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO)) + bzero_vector = i586_bzero; + if (!(flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) { + copyin_vector = i586_copyin; + copyout_vector = i586_copyout; + } + } +#endif + + return (0); /* XXX unused */ +} + +/* + * Initialize floating point unit. + */ +void +npxinit(control) + u_short control; +{ + static union savefpu dummy; + register_t savecrit; + + if (!npx_exists) + return; + /* + * fninit has the same h/w bugs as fnsave. Use the detoxified + * fnsave to throw away any junk in the fpu. npxsave() initializes + * the fpu and sets fpcurthread = NULL as important side effects. + */ + savecrit = intr_disable(); + npxsave(&dummy); + stop_emulating(); +#ifdef CPU_ENABLE_SSE + /* XXX npxsave() doesn't actually initialize the fpu in the SSE case. */ + if (cpu_fxsr) + fninit(); +#endif + fldcw(&control); + start_emulating(); + intr_restore(savecrit); +} + +/* + * Free coprocessor (if we have it). + */ +void +npxexit(td) + struct thread *td; +{ + register_t savecrit; + + savecrit = intr_disable(); + if (curthread == PCPU_GET(fpcurthread)) + npxsave(&PCPU_GET(curpcb)->pcb_save); + intr_restore(savecrit); +#ifdef NPX_DEBUG + if (npx_exists) { + u_int masked_exceptions; + + masked_exceptions = GET_FPU_CW(td) & GET_FPU_SW(td) & 0x7f; + /* + * Log exceptions that would have trapped with the old + * control word (overflow, divide by 0, and invalid operand). + */ + if (masked_exceptions & 0x0d) + log(LOG_ERR, + "pid %d (%s) exited with masked floating point exceptions 0x%02x\n", + td->td_proc->p_pid, td->td_proc->p_comm, + masked_exceptions); + } +#endif +} + +int +npxformat() +{ + + if (!npx_exists) + return (_MC_FPFMT_NODEV); +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) + return (_MC_FPFMT_XMM); +#endif + return (_MC_FPFMT_387); +} + +/* + * The following mechanism is used to ensure that the FPE_... value + * that is passed as a trapcode to the signal handler of the user + * process does not have more than one bit set. + * + * Multiple bits may be set if the user process modifies the control + * word while a status word bit is already set. While this is a sign + * of bad coding, we have no choise than to narrow them down to one + * bit, since we must not send a trapcode that is not exactly one of + * the FPE_ macros. + * + * The mechanism has a static table with 127 entries. Each combination + * of the 7 FPU status word exception bits directly translates to a + * position in this table, where a single FPE_... value is stored. + * This FPE_... value stored there is considered the "most important" + * of the exception bits and will be sent as the signal code. The + * precedence of the bits is based upon Intel Document "Numerical + * Applications", Chapter "Special Computational Situations". + * + * The macro to choose one of these values does these steps: 1) Throw + * away status word bits that cannot be masked. 2) Throw away the bits + * currently masked in the control word, assuming the user isn't + * interested in them anymore. 3) Reinsert status word bit 7 (stack + * fault) if it is set, which cannot be masked but must be presered. + * 4) Use the remaining bits to point into the trapcode table. + * + * The 6 maskable bits in order of their preference, as stated in the + * above referenced Intel manual: + * 1 Invalid operation (FP_X_INV) + * 1a Stack underflow + * 1b Stack overflow + * 1c Operand of unsupported format + * 1d SNaN operand. + * 2 QNaN operand (not an exception, irrelavant here) + * 3 Any other invalid-operation not mentioned above or zero divide + * (FP_X_INV, FP_X_DZ) + * 4 Denormal operand (FP_X_DNML) + * 5 Numeric over/underflow (FP_X_OFL, FP_X_UFL) + * 6 Inexact result (FP_X_IMP) + */ +static char fpetable[128] = { + 0, + FPE_FLTINV, /* 1 - INV */ + FPE_FLTUND, /* 2 - DNML */ + FPE_FLTINV, /* 3 - INV | DNML */ + FPE_FLTDIV, /* 4 - DZ */ + FPE_FLTINV, /* 5 - INV | DZ */ + FPE_FLTDIV, /* 6 - DNML | DZ */ + FPE_FLTINV, /* 7 - INV | DNML | DZ */ + FPE_FLTOVF, /* 8 - OFL */ + FPE_FLTINV, /* 9 - INV | OFL */ + FPE_FLTUND, /* A - DNML | OFL */ + FPE_FLTINV, /* B - INV | DNML | OFL */ + FPE_FLTDIV, /* C - DZ | OFL */ + FPE_FLTINV, /* D - INV | DZ | OFL */ + FPE_FLTDIV, /* E - DNML | DZ | OFL */ + FPE_FLTINV, /* F - INV | DNML | DZ | OFL */ + FPE_FLTUND, /* 10 - UFL */ + FPE_FLTINV, /* 11 - INV | UFL */ + FPE_FLTUND, /* 12 - DNML | UFL */ + FPE_FLTINV, /* 13 - INV | DNML | UFL */ + FPE_FLTDIV, /* 14 - DZ | UFL */ + FPE_FLTINV, /* 15 - INV | DZ | UFL */ + FPE_FLTDIV, /* 16 - DNML | DZ | UFL */ + FPE_FLTINV, /* 17 - INV | DNML | DZ | UFL */ + FPE_FLTOVF, /* 18 - OFL | UFL */ + FPE_FLTINV, /* 19 - INV | OFL | UFL */ + FPE_FLTUND, /* 1A - DNML | OFL | UFL */ + FPE_FLTINV, /* 1B - INV | DNML | OFL | UFL */ + FPE_FLTDIV, /* 1C - DZ | OFL | UFL */ + FPE_FLTINV, /* 1D - INV | DZ | OFL | UFL */ + FPE_FLTDIV, /* 1E - DNML | DZ | OFL | UFL */ + FPE_FLTINV, /* 1F - INV | DNML | DZ | OFL | UFL */ + FPE_FLTRES, /* 20 - IMP */ + FPE_FLTINV, /* 21 - INV | IMP */ + FPE_FLTUND, /* 22 - DNML | IMP */ + FPE_FLTINV, /* 23 - INV | DNML | IMP */ + FPE_FLTDIV, /* 24 - DZ | IMP */ + FPE_FLTINV, /* 25 - INV | DZ | IMP */ + FPE_FLTDIV, /* 26 - DNML | DZ | IMP */ + FPE_FLTINV, /* 27 - INV | DNML | DZ | IMP */ + FPE_FLTOVF, /* 28 - OFL | IMP */ + FPE_FLTINV, /* 29 - INV | OFL | IMP */ + FPE_FLTUND, /* 2A - DNML | OFL | IMP */ + FPE_FLTINV, /* 2B - INV | DNML | OFL | IMP */ + FPE_FLTDIV, /* 2C - DZ | OFL | IMP */ + FPE_FLTINV, /* 2D - INV | DZ | OFL | IMP */ + FPE_FLTDIV, /* 2E - DNML | DZ | OFL | IMP */ + FPE_FLTINV, /* 2F - INV | DNML | DZ | OFL | IMP */ + FPE_FLTUND, /* 30 - UFL | IMP */ + FPE_FLTINV, /* 31 - INV | UFL | IMP */ + FPE_FLTUND, /* 32 - DNML | UFL | IMP */ + FPE_FLTINV, /* 33 - INV | DNML | UFL | IMP */ + FPE_FLTDIV, /* 34 - DZ | UFL | IMP */ + FPE_FLTINV, /* 35 - INV | DZ | UFL | IMP */ + FPE_FLTDIV, /* 36 - DNML | DZ | UFL | IMP */ + FPE_FLTINV, /* 37 - INV | DNML | DZ | UFL | IMP */ + FPE_FLTOVF, /* 38 - OFL | UFL | IMP */ + FPE_FLTINV, /* 39 - INV | OFL | UFL | IMP */ + FPE_FLTUND, /* 3A - DNML | OFL | UFL | IMP */ + FPE_FLTINV, /* 3B - INV | DNML | OFL | UFL | IMP */ + FPE_FLTDIV, /* 3C - DZ | OFL | UFL | IMP */ + FPE_FLTINV, /* 3D - INV | DZ | OFL | UFL | IMP */ + FPE_FLTDIV, /* 3E - DNML | DZ | OFL | UFL | IMP */ + FPE_FLTINV, /* 3F - INV | DNML | DZ | OFL | UFL | IMP */ + FPE_FLTSUB, /* 40 - STK */ + FPE_FLTSUB, /* 41 - INV | STK */ + FPE_FLTUND, /* 42 - DNML | STK */ + FPE_FLTSUB, /* 43 - INV | DNML | STK */ + FPE_FLTDIV, /* 44 - DZ | STK */ + FPE_FLTSUB, /* 45 - INV | DZ | STK */ + FPE_FLTDIV, /* 46 - DNML | DZ | STK */ + FPE_FLTSUB, /* 47 - INV | DNML | DZ | STK */ + FPE_FLTOVF, /* 48 - OFL | STK */ + FPE_FLTSUB, /* 49 - INV | OFL | STK */ + FPE_FLTUND, /* 4A - DNML | OFL | STK */ + FPE_FLTSUB, /* 4B - INV | DNML | OFL | STK */ + FPE_FLTDIV, /* 4C - DZ | OFL | STK */ + FPE_FLTSUB, /* 4D - INV | DZ | OFL | STK */ + FPE_FLTDIV, /* 4E - DNML | DZ | OFL | STK */ + FPE_FLTSUB, /* 4F - INV | DNML | DZ | OFL | STK */ + FPE_FLTUND, /* 50 - UFL | STK */ + FPE_FLTSUB, /* 51 - INV | UFL | STK */ + FPE_FLTUND, /* 52 - DNML | UFL | STK */ + FPE_FLTSUB, /* 53 - INV | DNML | UFL | STK */ + FPE_FLTDIV, /* 54 - DZ | UFL | STK */ + FPE_FLTSUB, /* 55 - INV | DZ | UFL | STK */ + FPE_FLTDIV, /* 56 - DNML | DZ | UFL | STK */ + FPE_FLTSUB, /* 57 - INV | DNML | DZ | UFL | STK */ + FPE_FLTOVF, /* 58 - OFL | UFL | STK */ + FPE_FLTSUB, /* 59 - INV | OFL | UFL | STK */ + FPE_FLTUND, /* 5A - DNML | OFL | UFL | STK */ + FPE_FLTSUB, /* 5B - INV | DNML | OFL | UFL | STK */ + FPE_FLTDIV, /* 5C - DZ | OFL | UFL | STK */ + FPE_FLTSUB, /* 5D - INV | DZ | OFL | UFL | STK */ + FPE_FLTDIV, /* 5E - DNML | DZ | OFL | UFL | STK */ + FPE_FLTSUB, /* 5F - INV | DNML | DZ | OFL | UFL | STK */ + FPE_FLTRES, /* 60 - IMP | STK */ + FPE_FLTSUB, /* 61 - INV | IMP | STK */ + FPE_FLTUND, /* 62 - DNML | IMP | STK */ + FPE_FLTSUB, /* 63 - INV | DNML | IMP | STK */ + FPE_FLTDIV, /* 64 - DZ | IMP | STK */ + FPE_FLTSUB, /* 65 - INV | DZ | IMP | STK */ + FPE_FLTDIV, /* 66 - DNML | DZ | IMP | STK */ + FPE_FLTSUB, /* 67 - INV | DNML | DZ | IMP | STK */ + FPE_FLTOVF, /* 68 - OFL | IMP | STK */ + FPE_FLTSUB, /* 69 - INV | OFL | IMP | STK */ + FPE_FLTUND, /* 6A - DNML | OFL | IMP | STK */ + FPE_FLTSUB, /* 6B - INV | DNML | OFL | IMP | STK */ + FPE_FLTDIV, /* 6C - DZ | OFL | IMP | STK */ + FPE_FLTSUB, /* 6D - INV | DZ | OFL | IMP | STK */ + FPE_FLTDIV, /* 6E - DNML | DZ | OFL | IMP | STK */ + FPE_FLTSUB, /* 6F - INV | DNML | DZ | OFL | IMP | STK */ + FPE_FLTUND, /* 70 - UFL | IMP | STK */ + FPE_FLTSUB, /* 71 - INV | UFL | IMP | STK */ + FPE_FLTUND, /* 72 - DNML | UFL | IMP | STK */ + FPE_FLTSUB, /* 73 - INV | DNML | UFL | IMP | STK */ + FPE_FLTDIV, /* 74 - DZ | UFL | IMP | STK */ + FPE_FLTSUB, /* 75 - INV | DZ | UFL | IMP | STK */ + FPE_FLTDIV, /* 76 - DNML | DZ | UFL | IMP | STK */ + FPE_FLTSUB, /* 77 - INV | DNML | DZ | UFL | IMP | STK */ + FPE_FLTOVF, /* 78 - OFL | UFL | IMP | STK */ + FPE_FLTSUB, /* 79 - INV | OFL | UFL | IMP | STK */ + FPE_FLTUND, /* 7A - DNML | OFL | UFL | IMP | STK */ + FPE_FLTSUB, /* 7B - INV | DNML | OFL | UFL | IMP | STK */ + FPE_FLTDIV, /* 7C - DZ | OFL | UFL | IMP | STK */ + FPE_FLTSUB, /* 7D - INV | DZ | OFL | UFL | IMP | STK */ + FPE_FLTDIV, /* 7E - DNML | DZ | OFL | UFL | IMP | STK */ + FPE_FLTSUB, /* 7F - INV | DNML | DZ | OFL | UFL | IMP | STK */ +}; + +/* + * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE. + * + * Clearing exceptions is necessary mainly to avoid IRQ13 bugs. We now + * depend on longjmp() restoring a usable state. Restoring the state + * or examining it might fail if we didn't clear exceptions. + * + * The error code chosen will be one of the FPE_... macros. It will be + * sent as the second argument to old BSD-style signal handlers and as + * "siginfo_t->si_code" (second argument) to SA_SIGINFO signal handlers. + * + * XXX the FP state is not preserved across signal handlers. So signal + * handlers cannot afford to do FP unless they preserve the state or + * longjmp() out. Both preserving the state and longjmp()ing may be + * destroyed by IRQ13 bugs. Clearing FP exceptions is not an acceptable + * solution for signals other than SIGFPE. + */ +int +npxtrap() +{ + register_t savecrit; + u_short control, status; + + if (!npx_exists) { + printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n", + PCPU_GET(fpcurthread), curthread, npx_exists); + panic("npxtrap from nowhere"); + } + savecrit = intr_disable(); + + /* + * Interrupt handling (for another interrupt) may have pushed the + * state to memory. Fetch the relevant parts of the state from + * wherever they are. + */ + if (PCPU_GET(fpcurthread) != curthread) { + control = GET_FPU_CW(curthread); + status = GET_FPU_SW(curthread); + } else { + fnstcw(&control); + fnstsw(&status); + } + + if (PCPU_GET(fpcurthread) == curthread) + fnclex(); + intr_restore(savecrit); + return (fpetable[status & ((~control & 0x3f) | 0x40)]); +} + +/* + * Implement device not available (DNA) exception + * + * It would be better to switch FP context here (if curthread != fpcurthread) + * and not necessarily for every context switch, but it is too hard to + * access foreign pcb's. + */ + +static int err_count = 0; + +int +npxdna() +{ + struct pcb *pcb; + register_t s; + u_short control; + + if (!npx_exists) + return (0); + if (PCPU_GET(fpcurthread) == curthread) { + printf("npxdna: fpcurthread == curthread %d times\n", + ++err_count); + stop_emulating(); + return (1); + } + if (PCPU_GET(fpcurthread) != NULL) { + printf("npxdna: fpcurthread = %p (%d), curthread = %p (%d)\n", + PCPU_GET(fpcurthread), + PCPU_GET(fpcurthread)->td_proc->p_pid, + curthread, curthread->td_proc->p_pid); + panic("npxdna"); + } + s = intr_disable(); + stop_emulating(); + /* + * Record new context early in case frstor causes an IRQ13. + */ + PCPU_SET(fpcurthread, curthread); + pcb = PCPU_GET(curpcb); + + if ((pcb->pcb_flags & PCB_NPXINITDONE) == 0) { + /* + * This is the first time this thread has used the FPU or + * the PCB doesn't contain a clean FPU state. Explicitly + * initialize the FPU and load the default control word. + */ + fninit(); + control = __INITIAL_NPXCW__; + fldcw(&control); + pcb->pcb_flags |= PCB_NPXINITDONE; + } else { + /* + * The following frstor may cause an IRQ13 when the state + * being restored has a pending error. The error will + * appear to have been triggered by the current (npx) user + * instruction even when that instruction is a no-wait + * instruction that should not trigger an error (e.g., + * fnclex). On at least one 486 system all of the no-wait + * instructions are broken the same as frstor, so our + * treatment does not amplify the breakage. On at least + * one 386/Cyrix 387 system, fnclex works correctly while + * frstor and fnsave are broken, so our treatment breaks + * fnclex if it is the first FPU instruction after a context + * switch. + */ + fpurstor(&pcb->pcb_save); + } + intr_restore(s); + + return (1); +} + +/* + * Wrapper for fnsave instruction, partly to handle hardware bugs. When npx + * exceptions are reported via IRQ13, spurious IRQ13's may be triggered by + * no-wait npx instructions. See the Intel application note AP-578 for + * details. This doesn't cause any additional complications here. IRQ13's + * are inherently asynchronous unless the CPU is frozen to deliver them -- + * one that started in userland may be delivered many instructions later, + * after the process has entered the kernel. It may even be delivered after + * the fnsave here completes. A spurious IRQ13 for the fnsave is handled in + * the same way as a very-late-arriving non-spurious IRQ13 from user mode: + * it is normally ignored at first because we set fpcurthread to NULL; it is + * normally retriggered in npxdna() after return to user mode. + * + * npxsave() must be called with interrupts disabled, so that it clears + * fpcurthread atomically with saving the state. We require callers to do the + * disabling, since most callers need to disable interrupts anyway to call + * npxsave() atomically with checking fpcurthread. + * + * A previous version of npxsave() went to great lengths to excecute fnsave + * with interrupts enabled in case executing it froze the CPU. This case + * can't happen, at least for Intel CPU/NPX's. Spurious IRQ13's don't imply + * spurious freezes. + */ +void +npxsave(addr) + union savefpu *addr; +{ + + stop_emulating(); + fpusave(addr); + + start_emulating(); + PCPU_SET(fpcurthread, NULL); + queue_multicall0(__HYPERVISOR_fpu_taskswitch); +} + +/* + * This should be called with interrupts disabled and only when the owning + * FPU thread is non-null. + */ +void +npxdrop() +{ + struct thread *td; + + td = PCPU_GET(fpcurthread); + PCPU_SET(fpcurthread, NULL); + td->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; + start_emulating(); +} + +/* + * Get the state of the FPU without dropping ownership (if possible). + * It returns the FPU ownership status. + */ +int +npxgetregs(td, addr) + struct thread *td; + union savefpu *addr; +{ + register_t s; + + if (!npx_exists) + return (_MC_FPOWNED_NONE); + + if ((td->td_pcb->pcb_flags & PCB_NPXINITDONE) == 0) { + if (npx_cleanstate_ready) + bcopy(&npx_cleanstate, addr, sizeof(npx_cleanstate)); + else + bzero(addr, sizeof(*addr)); + return (_MC_FPOWNED_NONE); + } + s = intr_disable(); + if (td == PCPU_GET(fpcurthread)) { + fpusave(addr); +#ifdef CPU_ENABLE_SSE + if (!cpu_fxsr) +#endif + /* + * fnsave initializes the FPU and destroys whatever + * context it contains. Make sure the FPU owner + * starts with a clean state next time. + */ + npxdrop(); + intr_restore(s); + return (_MC_FPOWNED_FPU); + } else { + intr_restore(s); + bcopy(&td->td_pcb->pcb_save, addr, sizeof(*addr)); + return (_MC_FPOWNED_PCB); + } +} + +/* + * Set the state of the FPU. + */ +void +npxsetregs(td, addr) + struct thread *td; + union savefpu *addr; +{ + register_t s; + + if (!npx_exists) + return; + + s = intr_disable(); + if (td == PCPU_GET(fpcurthread)) { + fpurstor(addr); + intr_restore(s); + } else { + intr_restore(s); + bcopy(addr, &td->td_pcb->pcb_save, sizeof(*addr)); + } + curthread->td_pcb->pcb_flags |= PCB_NPXINITDONE; +} + +static void +fpusave(addr) + union savefpu *addr; +{ + +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) + fxsave(addr); + else +#endif + fnsave(addr); +} + +static void +fpurstor(addr) + union savefpu *addr; +{ + +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) + fxrstor(addr); + else +#endif + frstor(addr); +} + +#ifdef I586_CPU_XXX +static long +timezero(funcname, func) + const char *funcname; + void (*func)(void *buf, size_t len); + +{ + void *buf; +#define BUFSIZE 1048576 + long usec; + struct timeval finish, start; + + buf = malloc(BUFSIZE, M_TEMP, M_NOWAIT); + if (buf == NULL) + return (BUFSIZE); + microtime(&start); + (*func)(buf, BUFSIZE); + microtime(&finish); + usec = 1000000 * (finish.tv_sec - start.tv_sec) + + finish.tv_usec - start.tv_usec; + if (usec <= 0) + usec = 1; + if (bootverbose) + printf("%s bandwidth = %u kBps\n", funcname, + (u_int32_t)(((BUFSIZE >> 10) * 1000000) / usec)); + free(buf, M_TEMP); + return (usec); +} +#endif /* I586_CPU */ + +static device_method_t npx_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, npx_identify), + DEVMETHOD(device_probe, npx_probe), + DEVMETHOD(device_attach, npx_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + { 0, 0 } +}; + +static driver_t npx_driver = { + "npx", + npx_methods, + 1, /* no softc */ +}; + +static devclass_t npx_devclass; +DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0); + +#ifdef DEV_ISA +/* + * We prefer to attach to the root nexus so that the usual case (exception 16) + * doesn't describe the processor as being `on isa'. + */ +DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0); + +/* + * This sucks up the legacy ISA support assignments from PNPBIOS/ACPI. + */ +static struct isa_pnp_id npxisa_ids[] = { + { 0x040cd041, "Legacy ISA coprocessor support" }, /* PNP0C04 */ + { 0 } +}; + +static int +npxisa_probe(device_t dev) +{ + int result; + if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, npxisa_ids)) <= 0) { + device_quiet(dev); + } + return(result); +} + +static int +npxisa_attach(device_t dev) +{ + return (0); +} + +static device_method_t npxisa_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, npxisa_probe), + DEVMETHOD(device_attach, npxisa_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + { 0, 0 } +}; + +static driver_t npxisa_driver = { + "npxisa", + npxisa_methods, + 1, /* no softc */ +}; + +static devclass_t npxisa_devclass; + +DRIVER_MODULE(npxisa, isa, npxisa_driver, npxisa_devclass, 0, 0); +#ifndef PC98 +DRIVER_MODULE(npxisa, acpi, npxisa_driver, npxisa_devclass, 0, 0); +#endif +#endif /* DEV_ISA */ diff --git a/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c b/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c new file mode 100644 index 0000000000..e25f218eb3 --- /dev/null +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/netfront/xn_netfront.c @@ -0,0 +1,1436 @@ +/* + * + * Copyright (c) 2004 Kip Macy + * All rights reserved. + * + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "opt_nfsroot.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include /* for DELAY */ +#include +#include +#include +#include + + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +struct xn_softc; +static void xn_txeof(struct xn_softc *); +static void xn_rxeof(struct xn_softc *); +static void xn_alloc_rx_buffers(struct xn_softc *); + +static void xn_tick_locked(struct xn_softc *); +static void xn_tick(void *); + +static void xn_intr(void *); +static void xn_start_locked(struct ifnet *); +static void xn_start(struct ifnet *); +static int xn_ioctl(struct ifnet *, u_long, caddr_t); +static void xn_ifinit_locked(struct xn_softc *); +static void xn_ifinit(void *); +static void xn_stop(struct xn_softc *); +#ifdef notyet +static void xn_watchdog(struct ifnet *); +#endif +/* Xenolinux helper functions */ +static void network_connect(struct xn_softc *, netif_fe_interface_status_t *); +static void create_netdev(int handle, struct xn_softc **); +static void netif_ctrlif_rx(ctrl_msg_t *,unsigned long); + +static void xn_free_rx_ring(struct xn_softc *); + +static void xn_free_tx_ring(struct xn_softc *); + + + +/* XXX: This isn't supported in FreeBSD, so ignore it for now. */ +#define TASK_UNINTERRUPTIBLE 0 +#define INVALID_P2M_ENTRY (~0UL) + +/* + * If the backend driver is pipelining transmit requests then we can be very + * aggressive in avoiding new-packet notifications -- only need to send a + * notification if there are no outstanding unreceived responses. + * If the backend may be buffering our transmit buffers for any reason then we + * are rather more conservative. + */ +#ifdef CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER +#define TX_TEST_IDX resp_prod /* aggressive: any outstanding responses? */ +#else +#define TX_TEST_IDX req_cons /* conservative: not seen all our requests? */ +#endif + +/* + * Mbuf pointers. We need these to keep track of the virtual addresses + * of our mbuf chains since we can only convert from virtual to physical, + * not the other way around. The size must track the free index arrays. + */ +struct xn_chain_data { + struct mbuf *xn_tx_chain[NETIF_TX_RING_SIZE+1]; + struct mbuf *xn_rx_chain[NETIF_RX_RING_SIZE+1]; +}; + +struct xn_softc { + struct arpcom arpcom; /* interface info */ + device_t xn_dev; + SLIST_ENTRY(xn_softc) xn_links; + struct mtx xn_mtx; + void *xn_intrhand; + struct resource *xn_res; + u_int8_t xn_ifno; /* interface number */ + struct xn_chain_data xn_cdata; /* mbufs */ + + netif_tx_interface_t *xn_tx_if; + netif_rx_interface_t *xn_rx_if; + + int xn_if_flags; + int xn_txcnt; + int xn_rxbufcnt; + struct callout xn_stat_ch; + unsigned int xn_irq; + unsigned int xn_evtchn; + + + /* What is the status of our connection to the remote backend? */ +#define BEST_CLOSED 0 +#define BEST_DISCONNECTED 1 +#define BEST_CONNECTED 2 + unsigned int xn_backend_state; + + /* Is this interface open or closed (down or up)? */ +#define UST_CLOSED 0 +#define UST_OPEN 1 + unsigned int xn_user_state; + + /* Receive-ring batched refills. */ +#define RX_MIN_TARGET 64 /* XXX: larger than linux. was causing packet + * loss at the default of 8. + */ +#define RX_MAX_TARGET NETIF_RX_RING_SIZE + int xn_rx_target; /* number to allocate */ + struct mbuf *xn_rx_batch; /* head of the batch queue */ + struct mbuf *xn_rx_batchtail; + int xn_rx_batchlen; /* how many queued */ + + int xn_rx_resp_cons; + int xn_tx_resp_cons; + unsigned short xn_rx_free_idxs[NETIF_RX_RING_SIZE+1]; + unsigned short xn_tx_free_idxs[NETIF_RX_RING_SIZE+1]; +}; + +static unsigned long xn_rx_pfns[NETIF_RX_RING_SIZE]; +static multicall_entry_t xn_rx_mcl[NETIF_RX_RING_SIZE+1]; +static mmu_update_t xn_rx_mmu[NETIF_RX_RING_SIZE]; + +static SLIST_HEAD(, xn_softc) xn_dev_list = + SLIST_HEAD_INITIALIZER(xn_dev_list); + +#define XN_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->xn_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define XN_LOCK(_sc) mtx_lock(&(_sc)->xn_mtx) +#define XN_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->xn_mtx, MA_OWNED) +#define XN_UNLOCK(_sc) mtx_unlock(&(_sc)->xn_mtx) +#define XN_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->xn_mtx) + +/* Access macros for acquiring freeing slots in xn_free_{tx,rx}_idxs[]. */ +#define ADD_ID_TO_FREELIST(_list, _id) \ + (_list)[(_id)] = (_list)[0]; \ + (_list)[0] = (_id); +#define GET_ID_FROM_FREELIST(_list) \ + ({ unsigned short _id = (_list)[0]; \ + (_list)[0] = (_list)[_id]; \ + (unsigned short)_id; }) +#define FREELIST_EMPTY(_list, _maxid) \ + ((_list)[0] == (_maxid+1)) + +static char *status_name[] = { + [NETIF_INTERFACE_STATUS_CLOSED] = "closed", + [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", + [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", + [NETIF_INTERFACE_STATUS_CHANGED] = "changed", +}; + +static char *be_state_name[] = { + [BEST_CLOSED] = "closed", + [BEST_DISCONNECTED] = "disconnected", + [BEST_CONNECTED] = "connected", +}; + +#define IPRINTK(fmt, args...) \ + printk("[XEN] " fmt, ##args) +#define WPRINTK(fmt, args...) \ + printk("[XEN] " fmt, ##args) + +static struct xn_softc * +find_sc_by_handle(unsigned int handle) +{ + struct xn_softc *sc; + SLIST_FOREACH(sc, &xn_dev_list, xn_links) + { + if ( sc->xn_ifno == handle ) + return sc; + } + return NULL; +} + +/** Network interface info. */ +struct netif_ctrl { + /** Number of interfaces. */ + int interface_n; + /** Number of connected interfaces. */ + int connected_n; + /** Error code. */ + int err; + int up; +}; + +static struct netif_ctrl netctrl; + +static void +netctrl_init(void) +{ + /* + * netctrl is already in bss, why are we setting it? + */ + memset(&netctrl, 0, sizeof(netctrl)); + netctrl.up = NETIF_DRIVER_STATUS_DOWN; +} + +/** Get or set a network interface error. + */ +static int +netctrl_err(int err) +{ + if ( (err < 0) && !netctrl.err ) + netctrl.err = err; + return netctrl.err; +} + +/** Test if all network interfaces are connected. + * + * @return 1 if all connected, 0 if not, negative error code otherwise + */ +static int +netctrl_connected(void) +{ + int ok; + + if (netctrl.err) + ok = netctrl.err; + else if (netctrl.up == NETIF_DRIVER_STATUS_UP) + ok = (netctrl.connected_n == netctrl.interface_n); + else + ok = 0; + + return ok; +} + +/** Count the connected network interfaces. + * + * @return connected count + */ +static int +netctrl_connected_count(void) +{ + + struct xn_softc *sc; + unsigned int connected; + + connected = 0; + + SLIST_FOREACH(sc, &xn_dev_list, xn_links) + { + if ( sc->xn_backend_state == BEST_CONNECTED ) + connected++; + } + + netctrl.connected_n = connected; + XENPRINTF("> connected_n=%d interface_n=%d\n", + netctrl.connected_n, netctrl.interface_n); + return connected; +} + +static __inline struct mbuf* +makembuf (struct mbuf *buf) +{ + struct mbuf *m = NULL; + + MGETHDR (m, M_DONTWAIT, MT_DATA); + + if (! m) + return 0; + + M_MOVE_PKTHDR(m, buf); + + MCLGET (m, M_DONTWAIT); + + m->m_pkthdr.len = buf->m_pkthdr.len; + m->m_len = buf->m_len; + m_copydata(buf, 0, buf->m_pkthdr.len, mtod(m,caddr_t) ); + m->m_ext.ext_args = (vm_paddr_t *)vtophys(mtod(m,caddr_t)); + + return m; +} + + + +static void +xn_free_rx_ring(struct xn_softc *sc) +{ +#if 0 + int i; + + for (i = 0; i < NETIF_RX_RING_SIZE; i++) { + if (sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(i)] != NULL) { + m_freem(sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(i)]); + sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(i)] = NULL; + } + } + + sc->xn_rx_resp_cons = 0; + sc->xn_rx_if->req_prod = 0; + sc->xn_rx_if->event = sc->xn_rx_resp_cons ; +#endif +} + +static void +xn_free_tx_ring(struct xn_softc *sc) +{ +#if 0 + int i; + + for (i = 0; i < NETIF_TX_RING_SIZE; i++) { + if (sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(i)] != NULL) { + m_freem(sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(i)]); + sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(i)] = NULL; + } + } + + return; +#endif +} + +static void +xn_alloc_rx_buffers(struct xn_softc *sc) +{ + unsigned short id; + struct mbuf *m_new, *next; + int i, batch_target; + NETIF_RING_IDX req_prod = sc->xn_rx_if->req_prod; + + if (unlikely(sc->xn_backend_state != BEST_CONNECTED) ) + return; + + /* + * Allocate skbuffs greedily, even though we batch updates to the + * receive ring. This creates a less bursty demand on the memory allocator, + * so should reduce the chance of failed allocation requests both for + * ourself and for other kernel subsystems. + */ + batch_target = sc->xn_rx_target - (req_prod - sc->xn_rx_resp_cons); + for ( i = sc->xn_rx_batchlen; i < batch_target; i++, sc->xn_rx_batchlen++) { + MGETHDR(m_new, M_DONTWAIT, MT_DATA); + if (m_new == NULL) + break; + + MCLGET(m_new, M_DONTWAIT); + if (!(m_new->m_flags & M_EXT)) { + m_freem(m_new); + break; + } + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + + /* queue the mbufs allocated */ + if (!sc->xn_rx_batch) + sc->xn_rx_batch = m_new; + + if (sc->xn_rx_batchtail) + sc->xn_rx_batchtail->m_next = m_new; + sc->xn_rx_batchtail = m_new; + } + + /* Is the batch large enough to be worthwhile? */ + if ( i < (sc->xn_rx_target/2) ) + return; + + for (i = 0, m_new = sc->xn_rx_batch; m_new; + i++, sc->xn_rx_batchlen--, m_new = next) { + + next = m_new->m_next; + m_new->m_next = NULL; + + m_new->m_ext.ext_args = (vm_paddr_t *)vtophys(m_new->m_ext.ext_buf); + + id = GET_ID_FROM_FREELIST(sc->xn_rx_free_idxs); + KASSERT(id != 0, ("alloc_rx_buffers: found free receive index of 0\n")); + sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(id)] = m_new; + + sc->xn_rx_if->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id; + + xn_rx_pfns[i] = vtomach(mtod(m_new,vm_offset_t)) >> PAGE_SHIFT; + + /* Remove this page from pseudo phys map before passing back to Xen. */ + xen_phys_machine[((unsigned long)m_new->m_ext.ext_args >> PAGE_SHIFT)] + = INVALID_P2M_ENTRY; + + xn_rx_mcl[i].op = __HYPERVISOR_update_va_mapping; + xn_rx_mcl[i].args[0] = (unsigned long)mtod(m_new,vm_offset_t) + >> PAGE_SHIFT; + xn_rx_mcl[i].args[1] = 0; + xn_rx_mcl[i].args[2] = 0; + + } + + KASSERT(i, ("no mbufs processed")); /* should have returned earlier */ + KASSERT(sc->xn_rx_batchlen == 0, ("not all mbufs processed")); + sc->xn_rx_batch = sc->xn_rx_batchtail = NULL; + + /* + * We may have allocated buffers which have entries outstanding + in the page * update queue -- make sure we flush those first! */ + PT_UPDATES_FLUSH(); + + /* After all PTEs have been zapped we blow away stale TLB entries. */ + xn_rx_mcl[i-1].args[2] = UVMF_FLUSH_TLB; + + /* Give away a batch of pages. */ + xn_rx_mcl[i].op = __HYPERVISOR_dom_mem_op; + xn_rx_mcl[i].args[0] = (unsigned long) MEMOP_decrease_reservation; + xn_rx_mcl[i].args[1] = (unsigned long)xn_rx_pfns; + xn_rx_mcl[i].args[2] = (unsigned long)i; + xn_rx_mcl[i].args[3] = 0; + xn_rx_mcl[i].args[4] = DOMID_SELF; + + /* Zap PTEs and give away pages in one big multicall. */ + (void)HYPERVISOR_multicall(xn_rx_mcl, i+1); + + /* Check return status of HYPERVISOR_dom_mem_op(). */ + if ( xn_rx_mcl[i].args[5] != i ) + panic("Unable to reduce memory reservation\n"); + + /* Above is a suitable barrier to ensure backend will see requests. */ + sc->xn_rx_if->req_prod = req_prod + i; + + /* Adjust our floating fill target if we risked running out of buffers. */ + if ( ((req_prod - sc->xn_rx_if->resp_prod) < (sc->xn_rx_target / 4)) && + ((sc->xn_rx_target *= 2) > RX_MAX_TARGET) ) + sc->xn_rx_target = RX_MAX_TARGET; +} + +static void +xn_rxeof(struct xn_softc *sc) +{ + struct ifnet *ifp; + netif_rx_response_t *rx; + NETIF_RING_IDX i, rp; + mmu_update_t *mmu = xn_rx_mmu; + multicall_entry_t *mcl = xn_rx_mcl; + struct mbuf *tail_mbuf = NULL, *head_mbuf = NULL, *m, *next; + + XN_LOCK_ASSERT(sc); + if (sc->xn_backend_state != BEST_CONNECTED) + return; + + ifp = &sc->arpcom.ac_if; + + rp = sc->xn_rx_if->resp_prod; + rmb(); /* Ensure we see queued responses up to 'rp'. */ + + for (i = sc->xn_rx_resp_cons; i != rp; i++) { + + rx = &sc->xn_rx_if->ring[MASK_NETIF_RX_IDX(i)].resp; + KASSERT(rx->id != 0, ("xn_rxeof: found free receive index of 0\n")); + + /* + * An error here is very odd. Usually indicates a backend bug, + * low-memory condition, or that we didn't have reservation headroom. + * Whatever - print an error and queue the id again straight away. + */ + if (unlikely(rx->status <= 0)) { + printk("bad buffer on RX ring!(%d)\n", rx->status); + sc->xn_rx_if->ring[MASK_NETIF_RX_IDX(sc->xn_rx_if->req_prod)].req.id + = rx->id; + wmb(); + sc->xn_rx_if->req_prod++; + continue; + } + + m = (struct mbuf *) + sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(rx->id)]; + if (m->m_next) + panic("mbuf is already part of a valid mbuf chain"); + ADD_ID_TO_FREELIST(sc->xn_rx_free_idxs, rx->id); + + m->m_data += (rx->addr & PAGE_MASK); + m->m_pkthdr.len = m->m_len = rx->status; + m->m_pkthdr.rcvif = ifp; + + /* Remap the page. */ + mmu->ptr = (rx->addr & ~PAGE_MASK) | MMU_MACHPHYS_UPDATE; + mmu->val = (unsigned long)m->m_ext.ext_args >> PAGE_SHIFT; + mmu++; + mcl->op = __HYPERVISOR_update_va_mapping; + mcl->args[0] = (unsigned long)m->m_data >> PAGE_SHIFT; + mcl->args[1] = (rx->addr & ~PAGE_MASK) | PG_KERNEL; + mcl->args[2] = 0; + mcl++; + + xen_phys_machine[((unsigned long)m->m_ext.ext_args >> PAGE_SHIFT)] = + (rx->addr >> PAGE_SHIFT); + + if (unlikely(!head_mbuf)) + head_mbuf = m; + + if (tail_mbuf) + tail_mbuf->m_next = m; + tail_mbuf = m; + + sc->xn_cdata.xn_rx_chain[MASK_NETIF_RX_IDX(rx->id)] = NULL; + sc->xn_rxbufcnt++; + } + + /* Do all the remapping work, and M->P updates, in one big hypercall. */ + if (likely((mcl - xn_rx_mcl) != 0)) { + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)xn_rx_mmu; + mcl->args[1] = mmu - xn_rx_mmu; + mcl->args[2] = 0; + mcl++; + (void)HYPERVISOR_multicall(xn_rx_mcl, mcl - xn_rx_mcl); + } + + + /* + * Process all the mbufs after the remapping is complete. + * Break the mbuf chain first though. + */ + for (m = head_mbuf; m; m = next) { + next = m->m_next; + m->m_next = NULL; + + ifp->if_ipackets++; + + XN_UNLOCK(sc); + + /* Pass it up. */ + (*ifp->if_input)(ifp, m); + XN_LOCK(sc); + } + + sc->xn_rx_resp_cons = i; + + /* If we get a callback with very few responses, reduce fill target. */ + /* NB. Note exponential increase, linear decrease. */ + if (((sc->xn_rx_if->req_prod - sc->xn_rx_if->resp_prod) > + ((3*sc->xn_rx_target) / 4)) && (--sc->xn_rx_target < RX_MIN_TARGET)) + sc->xn_rx_target = RX_MIN_TARGET; + + xn_alloc_rx_buffers(sc); + + sc->xn_rx_if->event = i + 1; +} + +static void +xn_txeof(struct xn_softc *sc) +{ + NETIF_RING_IDX i, prod; + unsigned short id; + struct ifnet *ifp; + struct mbuf *m; + + XN_LOCK_ASSERT(sc); + + if (sc->xn_backend_state != BEST_CONNECTED) + return; + + ifp = &sc->arpcom.ac_if; + ifp->if_timer = 0; + + do { + prod = sc->xn_tx_if->resp_prod; + + for (i = sc->xn_tx_resp_cons; i != prod; i++) { + id = sc->xn_tx_if->ring[MASK_NETIF_TX_IDX(i)].resp.id; + m = sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(id)]; + + KASSERT(m != NULL, ("mbuf not found in xn_tx_chain")); + M_ASSERTVALID(m); + + m_freem(m); + sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(id)] = NULL; + ADD_ID_TO_FREELIST(sc->xn_tx_free_idxs, id); + sc->xn_txcnt--; + } + sc->xn_tx_resp_cons = prod; + + /* + * Set a new event, then check for race with update of tx_cons. Note + * that it is essential to schedule a callback, no matter how few + * buffers are pending. Even if there is space in the transmit ring, + * higher layers may be blocked because too much data is outstanding: + * in such cases notification from Xen is likely to be the only kick + * that we'll get. + */ + sc->xn_tx_if->event = + prod + ((sc->xn_tx_if->req_prod - prod) >> 1) + 1; + + mb(); + + } while (prod != sc->xn_tx_if->resp_prod); +} + +static void +xn_intr(void *xsc) +{ + struct xn_softc *sc = xsc; + struct ifnet *ifp = &sc->arpcom.ac_if; + + XN_LOCK(sc); + + /* sometimes we seem to lose packets. stay in the interrupt handler while + * there is stuff to process: continually recheck the response producer. + */ + do { + xn_txeof(sc); + + if (sc->xn_rx_resp_cons != sc->xn_rx_if->resp_prod && + sc->xn_user_state == UST_OPEN) + xn_rxeof(sc); + + if (ifp->if_flags & IFF_RUNNING && ifp->if_snd.ifq_head != NULL) + xn_start_locked(ifp); + } while (sc->xn_rx_resp_cons != sc->xn_rx_if->resp_prod && + sc->xn_user_state == UST_OPEN); + + XN_UNLOCK(sc); + return; +} + +static void +xn_tick_locked(struct xn_softc *sc) +{ + XN_LOCK_ASSERT(sc); + callout_reset(&sc->xn_stat_ch, hz, xn_tick, sc); + + /* XXX placeholder for printing debug information */ + +} + + +static void +xn_tick(void *xsc) +{ + struct xn_softc *sc; + + sc = xsc; + XN_LOCK(sc); + xn_tick_locked(sc); + XN_UNLOCK(sc); + +} +static void +xn_start_locked(struct ifnet *ifp) +{ + unsigned short id; + struct mbuf *m_head, *new_m; + struct xn_softc *sc = ifp->if_softc; + netif_tx_request_t *tx; + NETIF_RING_IDX i, start; + + if (sc->xn_backend_state != BEST_CONNECTED) + return; + + for (i = start = sc->xn_tx_if->req_prod; TRUE; i++, sc->xn_txcnt++) { + + IF_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + break; + + if (FREELIST_EMPTY(sc->xn_tx_free_idxs, NETIF_TX_RING_SIZE)) { + IF_PREPEND(&ifp->if_snd, m_head); + ifp->if_flags |= IFF_OACTIVE; + break; + } + + i = sc->xn_tx_if->req_prod; + + id = GET_ID_FROM_FREELIST(sc->xn_tx_free_idxs); + + /* + * Start packing the mbufs in this chain into + * the fragment pointers. Stop when we run out + * of fragments or hit the end of the mbuf chain. + */ + new_m = makembuf(m_head); + tx = &(sc->xn_tx_if->ring[MASK_NETIF_TX_IDX(i)].req); + tx->id = id; + tx->size = new_m->m_pkthdr.len; + new_m->m_next = NULL; + new_m->m_nextpkt = NULL; + + m_freem(m_head); + tx->addr = vtomach(mtod(new_m, vm_offset_t)); + + sc->xn_cdata.xn_tx_chain[MASK_NETIF_TX_IDX(id)] = new_m; + BPF_MTAP(ifp, new_m); + } + + sc->xn_tx_if->req_prod = i; + xn_txeof(sc); + + /* Only notify Xen if we really have to. */ + if (sc->xn_tx_if->TX_TEST_IDX == start) + notify_via_evtchn(sc->xn_evtchn); + return; +} + +static void +xn_start(struct ifnet *ifp) +{ + struct xn_softc *sc; + sc = ifp->if_softc; + XN_LOCK(sc); + xn_start_locked(ifp); + XN_UNLOCK(sc); +} + + + +/* equivalent of network_open() in Linux */ +static void +xn_ifinit_locked(struct xn_softc *sc) +{ + struct ifnet *ifp; + + XN_LOCK_ASSERT(sc); + + ifp = &sc->arpcom.ac_if; + + if (ifp->if_flags & IFF_RUNNING) + return; + + xn_stop(sc); + + sc->xn_user_state = UST_OPEN; + + xn_alloc_rx_buffers(sc); + sc->xn_rx_if->event = sc->xn_rx_resp_cons + 1; + + ifp->if_flags |= IFF_RUNNING; + ifp->if_flags &= ~IFF_OACTIVE; + + callout_reset(&sc->xn_stat_ch, hz, xn_tick, sc); + +} + + +static void +xn_ifinit(void *xsc) +{ + struct xn_softc *sc = xsc; + + XN_LOCK(sc); + xn_ifinit_locked(sc); + XN_UNLOCK(sc); + +} + + +static int +xn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct xn_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; + int mask, error = 0; + switch(cmd) { + case SIOCSIFMTU: + /* XXX can we alter the MTU on a VN ?*/ +#ifdef notyet + if (ifr->ifr_mtu > XN_JUMBO_MTU) + error = EINVAL; + else +#endif + { + ifp->if_mtu = ifr->ifr_mtu; + ifp->if_flags &= ~IFF_RUNNING; + xn_ifinit(sc); + } + break; + case SIOCSIFFLAGS: + XN_LOCK(sc); + if (ifp->if_flags & IFF_UP) { + /* + * If only the state of the PROMISC flag changed, + * then just use the 'set promisc mode' command + * instead of reinitializing the entire NIC. Doing + * a full re-init means reloading the firmware and + * waiting for it to start up, which may take a + * second or two. + */ +#ifdef notyet + /* No promiscuous mode with Xen */ + if (ifp->if_flags & IFF_RUNNING && + ifp->if_flags & IFF_PROMISC && + !(sc->xn_if_flags & IFF_PROMISC)) { + XN_SETBIT(sc, XN_RX_MODE, + XN_RXMODE_RX_PROMISC); + } else if (ifp->if_flags & IFF_RUNNING && + !(ifp->if_flags & IFF_PROMISC) && + sc->xn_if_flags & IFF_PROMISC) { + XN_CLRBIT(sc, XN_RX_MODE, + XN_RXMODE_RX_PROMISC); + } else +#endif + xn_ifinit_locked(sc); + } else { + if (ifp->if_flags & IFF_RUNNING) { + xn_stop(sc); + } + } + sc->xn_if_flags = ifp->if_flags; + XN_UNLOCK(sc); + error = 0; + break; + case SIOCSIFCAP: + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if (mask & IFCAP_HWCSUM) { + if (IFCAP_HWCSUM & ifp->if_capenable) + ifp->if_capenable &= ~IFCAP_HWCSUM; + else + ifp->if_capenable |= IFCAP_HWCSUM; + } + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: +#ifdef notyet + if (ifp->if_flags & IFF_RUNNING) { + XN_LOCK(sc); + xn_setmulti(sc); + XN_UNLOCK(sc); + error = 0; + } +#endif + /* FALLTHROUGH */ + case SIOCSIFMEDIA: + case SIOCGIFMEDIA: + error = EINVAL; + break; + default: + error = ether_ioctl(ifp, cmd, data); + } + + return (error); +} + +static void +xn_stop(struct xn_softc *sc) +{ + struct ifnet *ifp; + + XN_LOCK_ASSERT(sc); + + ifp = &sc->arpcom.ac_if; + + callout_stop(&sc->xn_stat_ch); + + xn_free_rx_ring(sc); + xn_free_tx_ring(sc); + + ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); +} + +/* START of Xenolinux helper functions adapted to FreeBSD */ +static void +network_connect(struct xn_softc *sc, netif_fe_interface_status_t *status) +{ + struct ifnet *ifp; + int i, requeue_idx; + netif_tx_request_t *tx; + + XN_LOCK(sc); + + ifp = &sc->arpcom.ac_if; + /* first time through, setup the ifp info */ + if (ifp->if_softc == NULL) { + ifp->if_softc = sc; + if_initname(ifp, "xn", sc->xn_ifno); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + ifp->if_ioctl = xn_ioctl; + ifp->if_output = ether_output; + ifp->if_start = xn_start; +#ifdef notyet + ifp->if_watchdog = xn_watchdog; +#endif + ifp->if_init = xn_ifinit; + ifp->if_mtu = ETHERMTU; + ifp->if_snd.ifq_maxlen = NETIF_TX_RING_SIZE - 1; + +#ifdef notyet + ifp->if_hwassist = XN_CSUM_FEATURES; + ifp->if_capabilities = IFCAP_HWCSUM; + ifp->if_capenable = ifp->if_capabilities; +#endif + + ether_ifattach(ifp, sc->arpcom.ac_enaddr); + callout_init(&sc->xn_stat_ch, CALLOUT_MPSAFE); + } + + /* Recovery procedure: */ + + /* Step 1: Reinitialise variables. */ + sc->xn_rx_resp_cons = sc->xn_tx_resp_cons = 0; + sc->xn_rxbufcnt = sc->xn_txcnt = 0; + sc->xn_rx_if->event = sc->xn_tx_if->event = 1; + + /* Step 2: Rebuild the RX and TX ring contents. + * NB. We could just free the queued TX packets now but we hope + * that sending them out might do some good. We have to rebuild + * the RX ring because some of our pages are currently flipped out + * so we can't just free the RX skbs. + */ + + /* Rebuild the TX buffer freelist and the TX ring itself. + * NB. This reorders packets. We could keep more private state + * to avoid this but maybe it doesn't matter so much given the + * interface has been down. + */ + for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ) + { + if (sc->xn_cdata.xn_tx_chain[i] != NULL) + { + struct mbuf *m = sc->xn_cdata.xn_tx_chain[i]; + + tx = &sc->xn_tx_if->ring[requeue_idx++].req; + + tx->id = i; + tx->addr = vtomach(mtod(m, vm_offset_t)); + tx->size = m->m_pkthdr.len; + sc->xn_txcnt++; + } + } + wmb(); + sc->xn_tx_if->req_prod = requeue_idx; + + /* Rebuild the RX buffer freelist and the RX ring itself. */ + for ( requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++ ) + if (sc->xn_cdata.xn_rx_chain[i] != NULL) + sc->xn_rx_if->ring[requeue_idx++].req.id = i; + wmb(); + sc->xn_rx_if->req_prod = requeue_idx; + + printk("[XEN] Netfront recovered tx=%d rxfree=%d\n", + sc->xn_tx_if->req_prod,sc->xn_rx_if->req_prod); + + + /* Step 3: All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver + * domain a kick because we've probably just requeued some + * packets. + */ + sc->xn_backend_state = BEST_CONNECTED; + wmb(); + notify_via_evtchn(status->evtchn); + xn_txeof(sc); + + XN_UNLOCK(sc); +} + + +static void +vif_show(struct xn_softc *sc) +{ +#if DEBUG + if (sc) { + IPRINTK("\n", + sc->xn_ifno, + be_state_name[sc->xn_backend_state], + sc->xn_user_state ? "open" : "closed", + sc->xn_evtchn, + sc->xn_irq, + sc->xn_tx_if, + sc->xn_rx_if); + } else { + IPRINTK("\n"); + } +#endif +} + +/* Send a connect message to xend to tell it to bring up the interface. */ +static void +send_interface_connect(struct xn_softc *sc) +{ + ctrl_msg_t cmsg = { + .type = CMSG_NETIF_FE, + .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT, + .length = sizeof(netif_fe_interface_connect_t), + }; + netif_fe_interface_connect_t *msg = (void*)cmsg.msg; + + vif_show(sc); + msg->handle = sc->xn_ifno; + msg->tx_shmem_frame = (vtomach(sc->xn_tx_if) >> PAGE_SHIFT); + msg->rx_shmem_frame = (vtomach(sc->xn_rx_if) >> PAGE_SHIFT); + + ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); +} + +/* Send a driver status notification to the domain controller. */ +static int +send_driver_status(int ok) +{ + int err = 0; + ctrl_msg_t cmsg = { + .type = CMSG_NETIF_FE, + .subtype = CMSG_NETIF_FE_DRIVER_STATUS, + .length = sizeof(netif_fe_driver_status_t), + }; + netif_fe_driver_status_t *msg = (void*)cmsg.msg; + + msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN); + err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); + return err; +} + +/* Stop network device and free tx/rx queues and irq. + */ +static void +vif_release(struct xn_softc *sc) +{ + /* Stop old i/f to prevent errors whilst we rebuild the state. */ + XN_LOCK(sc); + /* sc->xn_backend_state = BEST_DISCONNECTED; */ + XN_UNLOCK(sc); + + /* Free resources. */ + if(sc->xn_tx_if != NULL) { + unbind_evtchn_from_irq(sc->xn_evtchn); + free(sc->xn_tx_if, M_DEVBUF); + free(sc->xn_rx_if, M_DEVBUF); + sc->xn_irq = 0; + sc->xn_evtchn = 0; + sc->xn_tx_if = NULL; + sc->xn_rx_if = NULL; + } +} + +/* Release vif resources and close it down completely. + */ +static void +vif_close(struct xn_softc *sc) +{ + vif_show(sc); + WPRINTK("Unexpected netif-CLOSED message in state %s\n", + be_state_name[sc->xn_backend_state]); + vif_release(sc); + sc->xn_backend_state = BEST_CLOSED; + /* todo: take dev down and free. */ + vif_show(sc); +} + +/* Move the vif into disconnected state. + * Allocates tx/rx pages. + * Sends connect message to xend. + */ +static void +vif_disconnect(struct xn_softc *sc) +{ + if (sc->xn_tx_if) free(sc->xn_tx_if, M_DEVBUF); + if (sc->xn_rx_if) free(sc->xn_rx_if, M_DEVBUF); + + // Before this sc->xn_tx_if and sc->xn_rx_if had better be null. + sc->xn_tx_if = (netif_tx_interface_t *)malloc(PAGE_SIZE,M_DEVBUF,M_WAITOK); + sc->xn_rx_if = (netif_rx_interface_t *)malloc(PAGE_SIZE,M_DEVBUF,M_WAITOK); + memset(sc->xn_tx_if, 0, PAGE_SIZE); + memset(sc->xn_rx_if, 0, PAGE_SIZE); + sc->xn_backend_state = BEST_DISCONNECTED; + send_interface_connect(sc); + vif_show(sc); +} + +/* Begin interface recovery. + * + * NB. Whilst we're recovering, we turn the carrier state off. We + * take measures to ensure that this device isn't used for + * anything. We also stop the queue for this device. Various + * different approaches (e.g. continuing to buffer packets) have + * been tested but don't appear to improve the overall impact on + * TCP connections. + * + * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery + * is initiated by a special "RESET" message - disconnect could + * just mean we're not allowed to use this interface any more. + */ +static void +vif_reset(struct xn_softc *sc) +{ + IPRINTK("Attempting to reconnect network interface: handle=%u\n", + sc->xn_ifno); + vif_release(sc); + vif_disconnect(sc); + vif_show(sc); +} + +/* Move the vif into connected state. + * Sets the mac and event channel from the message. + * Binds the irq to the event channel. + */ +static void +vif_connect( + struct xn_softc *sc, netif_fe_interface_status_t *status) +{ + memcpy(sc->arpcom.ac_enaddr, status->mac, ETHER_ADDR_LEN); + network_connect(sc, status); + + sc->xn_evtchn = status->evtchn; + sc->xn_irq = bind_evtchn_to_irq(sc->xn_evtchn); + + (void)intr_add_handler("xn", sc->xn_irq, (driver_intr_t *)xn_intr, sc, + INTR_TYPE_NET | INTR_MPSAFE, &sc->xn_intrhand); + netctrl_connected_count(); + /* vif_wake(dev); Not needed for FreeBSD */ + vif_show(sc); +} + +/** Create a network device. + * @param handle device handle + */ +static void +create_netdev(int handle, struct xn_softc **sc) +{ + int i; + + *sc = (struct xn_softc *)malloc(sizeof(**sc), M_DEVBUF, M_WAITOK); + memset(*sc, 0, sizeof(struct xn_softc)); + + (*sc)->xn_backend_state = BEST_CLOSED; + (*sc)->xn_user_state = UST_CLOSED; + (*sc)->xn_ifno = handle; + + XN_LOCK_INIT(*sc, "xnetif"); + (*sc)->xn_rx_target = RX_MIN_TARGET; + + /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ + for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ ) + (*sc)->xn_tx_free_idxs[i] = (i+1); + for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ ) + (*sc)->xn_rx_free_idxs[i] = (i+1); + + SLIST_INSERT_HEAD(&xn_dev_list, *sc, xn_links); +} + +/* Get the target interface for a status message. + * Creates the interface when it makes sense. + * The returned interface may be null when there is no error. + * + * @param status status message + * @param sc return parameter for interface state + * @return 0 on success, error code otherwise + */ +static int +target_vif(netif_fe_interface_status_t *status, struct xn_softc **sc) +{ + int err = 0; + + XENPRINTF("> handle=%d\n", status->handle); + if ( status->handle < 0 ) + { + err = -EINVAL; + goto exit; + } + + if ( (*sc = find_sc_by_handle(status->handle)) != NULL ) + goto exit; + + if ( status->status == NETIF_INTERFACE_STATUS_CLOSED ) + goto exit; + if ( status->status == NETIF_INTERFACE_STATUS_CHANGED ) + goto exit; + + /* It's a new interface in a good state - create it. */ + XENPRINTF("> create device...\n"); + create_netdev(status->handle, sc); + netctrl.interface_n++; + +exit: + return err; +} + +/* Handle an interface status message. */ +static void +netif_interface_status(netif_fe_interface_status_t *status) +{ + int err = 0; + struct xn_softc *sc = NULL; + + XENPRINTF("> status=%s handle=%d\n", + status_name[status->status], status->handle); + + if ( (err = target_vif(status, &sc)) != 0 ) + { + WPRINTK("Invalid netif: handle=%u\n", status->handle); + return; + } + + if ( sc == NULL ) + { + XENPRINTF("> no vif\n"); + return; + } + + vif_show(sc); + + switch ( status->status ) + { + case NETIF_INTERFACE_STATUS_CLOSED: + switch ( sc->xn_backend_state ) + { + case BEST_CLOSED: + case BEST_DISCONNECTED: + case BEST_CONNECTED: + vif_close(sc); + break; + } + break; + + case NETIF_INTERFACE_STATUS_DISCONNECTED: + switch ( sc->xn_backend_state ) + { + case BEST_CLOSED: + vif_disconnect(sc); + break; + case BEST_DISCONNECTED: + case BEST_CONNECTED: + vif_reset(sc); + break; + } + break; + + case NETIF_INTERFACE_STATUS_CONNECTED: + switch ( sc->xn_backend_state ) + { + case BEST_CLOSED: + WPRINTK("Unexpected netif status %s in state %s\n", + status_name[status->status], + be_state_name[sc->xn_backend_state]); + vif_disconnect(sc); + vif_connect(sc, status); + break; + case BEST_DISCONNECTED: + vif_connect(sc, status); + break; + } + break; + + case NETIF_INTERFACE_STATUS_CHANGED: + /* + * The domain controller is notifying us that a device has been + * added or removed. + */ + break; + + default: + WPRINTK("Invalid netif status code %d\n", status->status); + break; + } + vif_show(sc); +} + +/* + * Initialize the network control interface. + */ +static void +netif_driver_status(netif_fe_driver_status_t *status) +{ + XENPRINTF("> status=%d\n", status->status); + netctrl.up = status->status; + //netctrl.interface_n = status->max_handle; + //netctrl.connected_n = 0; + netctrl_connected_count(); +} + +/* Receive handler for control messages. */ +static void +netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) +{ + + switch ( msg->subtype ) + { + case CMSG_NETIF_FE_INTERFACE_STATUS: + if ( msg->length != sizeof(netif_fe_interface_status_t) ) + goto error; + netif_interface_status((netif_fe_interface_status_t *) + &msg->msg[0]); + break; + + case CMSG_NETIF_FE_DRIVER_STATUS: + if ( msg->length != sizeof(netif_fe_driver_status_t) ) + goto error; + netif_driver_status((netif_fe_driver_status_t *) + &msg->msg[0]); + break; + + error: + default: + msg->length = 0; + break; + } + + ctrl_if_send_response(msg); +} + +#if 1 +/* Wait for all interfaces to be connected. + * + * This works OK, but we'd like to use the probing mode (see below). + */ +static int probe_interfaces(void) +{ + int err = 0, conn = 0; + int wait_i, wait_n = 100; + + for ( wait_i = 0; wait_i < wait_n; wait_i++) + { + XENPRINTF("> wait_i=%d\n", wait_i); + conn = netctrl_connected(); + if(conn) break; + tsleep(&xn_dev_list, PWAIT | PCATCH, "netif", hz); + } + + XENPRINTF("> wait finished...\n"); + if ( conn <= 0 ) + { + err = netctrl_err(-ENETDOWN); + WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); + } + + XENPRINTF("< err=%d\n", err); + + return err; +} +#else +/* Probe for interfaces until no more are found. + * + * This is the mode we'd like to use, but at the moment it panics the kernel. +*/ +static int +probe_interfaces(void) +{ + int err = 0; + int wait_i, wait_n = 100; + ctrl_msg_t cmsg = { + .type = CMSG_NETIF_FE, + .subtype = CMSG_NETIF_FE_INTERFACE_STATUS, + .length = sizeof(netif_fe_interface_status_t), + }; + netif_fe_interface_status_t msg = {}; + ctrl_msg_t rmsg = {}; + netif_fe_interface_status_t *reply = (void*)rmsg.msg; + int state = TASK_UNINTERRUPTIBLE; + uint32_t query = -1; + + + netctrl.interface_n = 0; + for ( wait_i = 0; wait_i < wait_n; wait_i++ ) + { + XENPRINTF("> wait_i=%d query=%d\n", wait_i, query); + msg.handle = query; + memcpy(cmsg.msg, &msg, sizeof(msg)); + XENPRINTF("> set_current_state...\n"); + set_current_state(state); + XENPRINTF("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); + XENPRINTF("> sending...\n"); + err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state); + XENPRINTF("> err=%d\n", err); + if(err) goto exit; + XENPRINTF("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); + if((int)reply->handle < 0){ + // No more interfaces. + break; + } + query = -reply->handle - 2; + XENPRINTF(">netif_interface_status ...\n"); + netif_interface_status(reply); + } + + exit: + if ( err ) + { + err = netctrl_err(-ENETDOWN); + WPRINTK("Connecting virtual network interfaces failed: err=%d\n", err); + } + + XENPRINTF("< err=%d\n", err); + return err; +} + +#endif + +static void +xn_init(void *unused) +{ + + int err = 0; + + netctrl_init(); + (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, + CALLBACK_IN_BLOCKING_CONTEXT); + + send_driver_status(1); + err = probe_interfaces(); + + if (err) + ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); +} + +SYSINIT(xndev, SI_SUB_PSEUDO, SI_ORDER_ANY, xn_init, NULL) diff --git a/freebsd-5.3-xen-sparse/kern/kern_fork.c b/freebsd-5.3-xen-sparse/kern/kern_fork.c new file mode 100644 index 0000000000..4b38ee45b6 --- /dev/null +++ b/freebsd-5.3-xen-sparse/kern/kern_fork.c @@ -0,0 +1,846 @@ +/* + * Copyright (c) 1982, 1986, 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 + */ + +#include +__FBSDID("$FreeBSD: src/sys/kern/kern_fork.c,v 1.234.2.4 2004/09/18 04:11:35 julian Exp $"); + +#include "opt_ktrace.h" +#include "opt_mac.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef _SYS_SYSPROTO_H_ +struct fork_args { + int dummy; +}; +#endif + +static int forksleep; /* Place for fork1() to sleep on. */ + +/* + * MPSAFE + */ +/* ARGSUSED */ +int +fork(td, uap) + struct thread *td; + struct fork_args *uap; +{ + int error; + struct proc *p2; + + error = fork1(td, RFFDG | RFPROC, 0, &p2); + if (error == 0) { + td->td_retval[0] = p2->p_pid; + td->td_retval[1] = 0; + } + return (error); +} + +/* + * MPSAFE + */ +/* ARGSUSED */ +int +vfork(td, uap) + struct thread *td; + struct vfork_args *uap; +{ + int error; + struct proc *p2; + + error = fork1(td, RFFDG | RFPROC /* | RFPPWAIT | RFMEM */, 0, &p2); + if (error == 0) { + td->td_retval[0] = p2->p_pid; + td->td_retval[1] = 0; + } + return (error); +} + +/* + * MPSAFE + */ +int +rfork(td, uap) + struct thread *td; + struct rfork_args *uap; +{ + struct proc *p2; + int error; + + /* Don't allow kernel-only flags. */ + if ((uap->flags & RFKERNELONLY) != 0) + return (EINVAL); + + error = fork1(td, uap->flags, 0, &p2); + if (error == 0) { + td->td_retval[0] = p2 ? p2->p_pid : 0; + td->td_retval[1] = 0; + } + return (error); +} + +int nprocs = 1; /* process 0 */ +int lastpid = 0; +SYSCTL_INT(_kern, OID_AUTO, lastpid, CTLFLAG_RD, &lastpid, 0, + "Last used PID"); + +/* + * Random component to lastpid generation. We mix in a random factor to make + * it a little harder to predict. We sanity check the modulus value to avoid + * doing it in critical paths. Don't let it be too small or we pointlessly + * waste randomness entropy, and don't let it be impossibly large. Using a + * modulus that is too big causes a LOT more process table scans and slows + * down fork processing as the pidchecked caching is defeated. + */ +static int randompid = 0; + +static int +sysctl_kern_randompid(SYSCTL_HANDLER_ARGS) +{ + int error, pid; + + error = sysctl_wire_old_buffer(req, sizeof(int)); + if (error != 0) + return(error); + sx_xlock(&allproc_lock); + pid = randompid; + error = sysctl_handle_int(oidp, &pid, 0, req); + if (error == 0 && req->newptr != NULL) { + if (pid < 0 || pid > PID_MAX - 100) /* out of range */ + pid = PID_MAX - 100; + else if (pid < 2) /* NOP */ + pid = 0; + else if (pid < 100) /* Make it reasonable */ + pid = 100; + randompid = pid; + } + sx_xunlock(&allproc_lock); + return (error); +} + +SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW, + 0, 0, sysctl_kern_randompid, "I", "Random PID modulus"); + +int +fork1(td, flags, pages, procp) + struct thread *td; + int flags; + int pages; + struct proc **procp; +{ + struct proc *p1, *p2, *pptr; + uid_t uid; + struct proc *newproc; + int ok, trypid; + static int curfail, pidchecked = 0; + static struct timeval lastfail; + struct filedesc *fd; + struct filedesc_to_leader *fdtol; + struct thread *td2; + struct ksegrp *kg2; + struct sigacts *newsigacts; + int error; + + /* Can't copy and clear. */ + if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) + return (EINVAL); + + p1 = td->td_proc; + + /* + * Here we don't create a new process, but we divorce + * certain parts of a process from itself. + */ + if ((flags & RFPROC) == 0) { + mtx_lock(&Giant); + vm_forkproc(td, NULL, NULL, flags); + mtx_unlock(&Giant); + + /* + * Close all file descriptors. + */ + if (flags & RFCFDG) { + struct filedesc *fdtmp; + FILEDESC_LOCK(td->td_proc->p_fd); + fdtmp = fdinit(td->td_proc->p_fd); + FILEDESC_UNLOCK(td->td_proc->p_fd); + fdfree(td); + p1->p_fd = fdtmp; + } + + /* + * Unshare file descriptors (from parent). + */ + if (flags & RFFDG) { + FILEDESC_LOCK(p1->p_fd); + if (p1->p_fd->fd_refcnt > 1) { + struct filedesc *newfd; + + newfd = fdcopy(td->td_proc->p_fd); + FILEDESC_UNLOCK(p1->p_fd); + fdfree(td); + p1->p_fd = newfd; + } else + FILEDESC_UNLOCK(p1->p_fd); + } + *procp = NULL; + return (0); + } + + /* + * Note 1:1 allows for forking with one thread coming out on the + * other side with the expectation that the process is about to + * exec. + */ + if (p1->p_flag & P_HADTHREADS) { + /* + * Idle the other threads for a second. + * Since the user space is copied, it must remain stable. + * In addition, all threads (from the user perspective) + * need to either be suspended or in the kernel, + * where they will try restart in the parent and will + * be aborted in the child. + */ + PROC_LOCK(p1); + if (thread_single(SINGLE_NO_EXIT)) { + /* Abort. Someone else is single threading before us. */ + PROC_UNLOCK(p1); + return (ERESTART); + } + PROC_UNLOCK(p1); + /* + * All other activity in this process + * is now suspended at the user boundary, + * (or other safe places if we think of any). + */ + } + + /* Allocate new proc. */ + newproc = uma_zalloc(proc_zone, M_WAITOK); +#ifdef MAC + mac_init_proc(newproc); +#endif + knlist_init(&newproc->p_klist, &newproc->p_mtx); + + /* We have to lock the process tree while we look for a pid. */ + sx_slock(&proctree_lock); + + /* + * Although process entries are dynamically created, we still keep + * a global limit on the maximum number we will create. Don't allow + * a nonprivileged user to use the last ten processes; don't let root + * exceed the limit. The variable nprocs is the current number of + * processes, maxproc is the limit. + */ + sx_xlock(&allproc_lock); + uid = td->td_ucred->cr_ruid; + if ((nprocs >= maxproc - 10 && + suser_cred(td->td_ucred, SUSER_RUID) != 0) || + nprocs >= maxproc) { + error = EAGAIN; + goto fail; + } + + /* + * Increment the count of procs running with this uid. Don't allow + * a nonprivileged user to exceed their current limit. + */ + PROC_LOCK(p1); + ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, + (uid != 0) ? lim_cur(p1, RLIMIT_NPROC) : 0); + PROC_UNLOCK(p1); + if (!ok) { + error = EAGAIN; + goto fail; + } + + /* + * Increment the nprocs resource before blocking can occur. There + * are hard-limits as to the number of processes that can run. + */ + nprocs++; + + /* + * Find an unused process ID. We remember a range of unused IDs + * ready to use (from lastpid+1 through pidchecked-1). + * + * If RFHIGHPID is set (used during system boot), do not allocate + * low-numbered pids. + */ + trypid = lastpid + 1; + if (flags & RFHIGHPID) { + if (trypid < 10) + trypid = 10; + } else { + if (randompid) + trypid += arc4random() % randompid; + } +retry: + /* + * If the process ID prototype has wrapped around, + * restart somewhat above 0, as the low-numbered procs + * tend to include daemons that don't exit. + */ + if (trypid >= PID_MAX) { + trypid = trypid % PID_MAX; + if (trypid < 100) + trypid += 100; + pidchecked = 0; + } + if (trypid >= pidchecked) { + int doingzomb = 0; + + pidchecked = PID_MAX; + /* + * Scan the active and zombie procs to check whether this pid + * is in use. Remember the lowest pid that's greater + * than trypid, so we can avoid checking for a while. + */ + p2 = LIST_FIRST(&allproc); +again: + for (; p2 != NULL; p2 = LIST_NEXT(p2, p_list)) { + PROC_LOCK(p2); + while (p2->p_pid == trypid || + (p2->p_pgrp != NULL && + (p2->p_pgrp->pg_id == trypid || + (p2->p_session != NULL && + p2->p_session->s_sid == trypid)))) { + trypid++; + if (trypid >= pidchecked) { + PROC_UNLOCK(p2); + goto retry; + } + } + if (p2->p_pid > trypid && pidchecked > p2->p_pid) + pidchecked = p2->p_pid; + if (p2->p_pgrp != NULL) { + if (p2->p_pgrp->pg_id > trypid && + pidchecked > p2->p_pgrp->pg_id) + pidchecked = p2->p_pgrp->pg_id; + if (p2->p_session != NULL && + p2->p_session->s_sid > trypid && + pidchecked > p2->p_session->s_sid) + pidchecked = p2->p_session->s_sid; + } + PROC_UNLOCK(p2); + } + if (!doingzomb) { + doingzomb = 1; + p2 = LIST_FIRST(&zombproc); + goto again; + } + } + sx_sunlock(&proctree_lock); + + /* + * RFHIGHPID does not mess with the lastpid counter during boot. + */ + if (flags & RFHIGHPID) + pidchecked = 0; + else + lastpid = trypid; + + p2 = newproc; + p2->p_state = PRS_NEW; /* protect against others */ + p2->p_pid = trypid; + LIST_INSERT_HEAD(&allproc, p2, p_list); + LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); + sx_xunlock(&allproc_lock); + + /* + * Malloc things while we don't hold any locks. + */ + if (flags & RFSIGSHARE) + newsigacts = NULL; + else + newsigacts = sigacts_alloc(); + + /* + * Copy filedesc. + */ + if (flags & RFCFDG) { + FILEDESC_LOCK(td->td_proc->p_fd); + fd = fdinit(td->td_proc->p_fd); + FILEDESC_UNLOCK(td->td_proc->p_fd); + fdtol = NULL; + } else if (flags & RFFDG) { + FILEDESC_LOCK(p1->p_fd); + fd = fdcopy(td->td_proc->p_fd); + FILEDESC_UNLOCK(p1->p_fd); + fdtol = NULL; + } else { + fd = fdshare(p1->p_fd); + if (p1->p_fdtol == NULL) + p1->p_fdtol = + filedesc_to_leader_alloc(NULL, + NULL, + p1->p_leader); + if ((flags & RFTHREAD) != 0) { + /* + * Shared file descriptor table and + * shared process leaders. + */ + fdtol = p1->p_fdtol; + FILEDESC_LOCK(p1->p_fd); + fdtol->fdl_refcount++; + FILEDESC_UNLOCK(p1->p_fd); + } else { + /* + * Shared file descriptor table, and + * different process leaders + */ + fdtol = filedesc_to_leader_alloc(p1->p_fdtol, + p1->p_fd, + p2); + } + } + /* + * Make a proc table entry for the new process. + * Start by zeroing the section of proc that is zero-initialized, + * then copy the section that is copied directly from the parent. + */ + td2 = FIRST_THREAD_IN_PROC(p2); + kg2 = FIRST_KSEGRP_IN_PROC(p2); + + /* Allocate and switch to an alternate kstack if specified. */ + if (pages != 0) + vm_thread_new_altkstack(td2, pages); + + PROC_LOCK(p2); + PROC_LOCK(p1); + +#define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) + + bzero(&p2->p_startzero, + (unsigned) RANGEOF(struct proc, p_startzero, p_endzero)); + bzero(&td2->td_startzero, + (unsigned) RANGEOF(struct thread, td_startzero, td_endzero)); + bzero(&kg2->kg_startzero, + (unsigned) RANGEOF(struct ksegrp, kg_startzero, kg_endzero)); + + bcopy(&p1->p_startcopy, &p2->p_startcopy, + (unsigned) RANGEOF(struct proc, p_startcopy, p_endcopy)); + bcopy(&td->td_startcopy, &td2->td_startcopy, + (unsigned) RANGEOF(struct thread, td_startcopy, td_endcopy)); + bcopy(&td->td_ksegrp->kg_startcopy, &kg2->kg_startcopy, + (unsigned) RANGEOF(struct ksegrp, kg_startcopy, kg_endcopy)); +#undef RANGEOF + + td2->td_sigstk = td->td_sigstk; + + /* + * Duplicate sub-structures as needed. + * Increase reference counts on shared objects. + * The p_stats substruct is set in vm_forkproc. + */ + p2->p_flag = 0; + if (p1->p_flag & P_PROFIL) + startprofclock(p2); + mtx_lock_spin(&sched_lock); + p2->p_sflag = PS_INMEM; + /* + * Allow the scheduler to adjust the priority of the child and + * parent while we hold the sched_lock. + */ + sched_fork(td, td2); + + mtx_unlock_spin(&sched_lock); + p2->p_ucred = crhold(td->td_ucred); + td2->td_ucred = crhold(p2->p_ucred); /* XXXKSE */ + + pargs_hold(p2->p_args); + + if (flags & RFSIGSHARE) { + p2->p_sigacts = sigacts_hold(p1->p_sigacts); + } else { + sigacts_copy(newsigacts, p1->p_sigacts); + p2->p_sigacts = newsigacts; + } + if (flags & RFLINUXTHPN) + p2->p_sigparent = SIGUSR1; + else + p2->p_sigparent = SIGCHLD; + + p2->p_textvp = p1->p_textvp; + p2->p_fd = fd; + p2->p_fdtol = fdtol; + + /* + * p_limit is copy-on-write. Bump its refcount. + */ + p2->p_limit = lim_hold(p1->p_limit); + PROC_UNLOCK(p1); + PROC_UNLOCK(p2); + + /* Bump references to the text vnode (for procfs) */ + if (p2->p_textvp) + vref(p2->p_textvp); + + /* + * Set up linkage for kernel based threading. + */ + if ((flags & RFTHREAD) != 0) { + mtx_lock(&ppeers_lock); + p2->p_peers = p1->p_peers; + p1->p_peers = p2; + p2->p_leader = p1->p_leader; + mtx_unlock(&ppeers_lock); + PROC_LOCK(p1->p_leader); + if ((p1->p_leader->p_flag & P_WEXIT) != 0) { + PROC_UNLOCK(p1->p_leader); + /* + * The task leader is exiting, so process p1 is + * going to be killed shortly. Since p1 obviously + * isn't dead yet, we know that the leader is either + * sending SIGKILL's to all the processes in this + * task or is sleeping waiting for all the peers to + * exit. We let p1 complete the fork, but we need + * to go ahead and kill the new process p2 since + * the task leader may not get a chance to send + * SIGKILL to it. We leave it on the list so that + * the task leader will wait for this new process + * to commit suicide. + */ + PROC_LOCK(p2); + psignal(p2, SIGKILL); + PROC_UNLOCK(p2); + } else + PROC_UNLOCK(p1->p_leader); + } else { + p2->p_peers = NULL; + p2->p_leader = p2; + } + + sx_xlock(&proctree_lock); + PGRP_LOCK(p1->p_pgrp); + PROC_LOCK(p2); + PROC_LOCK(p1); + + /* + * Preserve some more flags in subprocess. P_PROFIL has already + * been preserved. + */ + p2->p_flag |= p1->p_flag & P_SUGID; + td2->td_pflags |= td->td_pflags & TDP_ALTSTACK; + SESS_LOCK(p1->p_session); + if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT) + p2->p_flag |= P_CONTROLT; + SESS_UNLOCK(p1->p_session); + if (flags & RFPPWAIT) + p2->p_flag |= P_PPWAIT; + + p2->p_pgrp = p1->p_pgrp; + LIST_INSERT_AFTER(p1, p2, p_pglist); + PGRP_UNLOCK(p1->p_pgrp); + LIST_INIT(&p2->p_children); + + callout_init(&p2->p_itcallout, CALLOUT_MPSAFE); + +#ifdef KTRACE + /* + * Copy traceflag and tracefile if enabled. + */ + mtx_lock(&ktrace_mtx); + KASSERT(p2->p_tracevp == NULL, ("new process has a ktrace vnode")); + if (p1->p_traceflag & KTRFAC_INHERIT) { + p2->p_traceflag = p1->p_traceflag; + if ((p2->p_tracevp = p1->p_tracevp) != NULL) { + VREF(p2->p_tracevp); + KASSERT(p1->p_tracecred != NULL, + ("ktrace vnode with no cred")); + p2->p_tracecred = crhold(p1->p_tracecred); + } + } + mtx_unlock(&ktrace_mtx); +#endif + + /* + * If PF_FORK is set, the child process inherits the + * procfs ioctl flags from its parent. + */ + if (p1->p_pfsflags & PF_FORK) { + p2->p_stops = p1->p_stops; + p2->p_pfsflags = p1->p_pfsflags; + } + + /* + * This begins the section where we must prevent the parent + * from being swapped. + */ + _PHOLD(p1); + PROC_UNLOCK(p1); + + /* + * Attach the new process to its parent. + * + * If RFNOWAIT is set, the newly created process becomes a child + * of init. This effectively disassociates the child from the + * parent. + */ + if (flags & RFNOWAIT) + pptr = initproc; + else + pptr = p1; + p2->p_pptr = pptr; + LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling); + sx_xunlock(&proctree_lock); + + /* Inform accounting that we have forked. */ + p2->p_acflag = AFORK; + PROC_UNLOCK(p2); + + /* + * Finish creating the child process. It will return via a different + * execution path later. (ie: directly into user mode) + */ + mtx_lock(&Giant); + vm_forkproc(td, p2, td2, flags); + + if (flags == (RFFDG | RFPROC)) { + cnt.v_forks++; + cnt.v_forkpages += p2->p_vmspace->vm_dsize + + p2->p_vmspace->vm_ssize; + } else if (flags == (RFFDG | RFPROC | RFPPWAIT | RFMEM)) { + cnt.v_vforks++; + cnt.v_vforkpages += p2->p_vmspace->vm_dsize + + p2->p_vmspace->vm_ssize; + } else if (p1 == &proc0) { + cnt.v_kthreads++; + cnt.v_kthreadpages += p2->p_vmspace->vm_dsize + + p2->p_vmspace->vm_ssize; + } else { + cnt.v_rforks++; + cnt.v_rforkpages += p2->p_vmspace->vm_dsize + + p2->p_vmspace->vm_ssize; + } + mtx_unlock(&Giant); + + /* + * Both processes are set up, now check if any loadable modules want + * to adjust anything. + * What if they have an error? XXX + */ + EVENTHANDLER_INVOKE(process_fork, p1, p2, flags); + + /* + * Set the child start time and mark the process as being complete. + */ + microuptime(&p2->p_stats->p_start); + mtx_lock_spin(&sched_lock); + p2->p_state = PRS_NORMAL; + + /* + * If RFSTOPPED not requested, make child runnable and add to + * run queue. + */ + if ((flags & RFSTOPPED) == 0) { + TD_SET_CAN_RUN(td2); + setrunqueue(td2, SRQ_BORING); + } + mtx_unlock_spin(&sched_lock); + + /* + * Now can be swapped. + */ + PROC_LOCK(p1); + _PRELE(p1); + + /* + * Tell any interested parties about the new process. + */ + KNOTE_LOCKED(&p1->p_klist, NOTE_FORK | p2->p_pid); + + PROC_UNLOCK(p1); + + /* + * Preserve synchronization semantics of vfork. If waiting for + * child to exec or exit, set P_PPWAIT on child, and sleep on our + * proc (in case of exit). + */ + PROC_LOCK(p2); + while (p2->p_flag & P_PPWAIT) + msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); + PROC_UNLOCK(p2); + + /* + * If other threads are waiting, let them continue now. + */ + if (p1->p_flag & P_HADTHREADS) { + PROC_LOCK(p1); + thread_single_end(); + PROC_UNLOCK(p1); + } + + /* + * Return child proc pointer to parent. + */ + *procp = p2; + return (0); +fail: + sx_sunlock(&proctree_lock); + if (ppsratecheck(&lastfail, &curfail, 1)) + printf("maxproc limit exceeded by uid %i, please see tuning(7) and login.conf(5).\n", + uid); + sx_xunlock(&allproc_lock); +#ifdef MAC + mac_destroy_proc(newproc); +#endif + uma_zfree(proc_zone, newproc); + if (p1->p_flag & P_HADTHREADS) { + PROC_LOCK(p1); + thread_single_end(); + PROC_UNLOCK(p1); + } + tsleep(&forksleep, PUSER, "fork", hz / 2); + return (error); +} + +/* + * Handle the return of a child process from fork1(). This function + * is called from the MD fork_trampoline() entry point. + */ +void +fork_exit(callout, arg, frame) + void (*callout)(void *, struct trapframe *); + void *arg; + struct trapframe *frame; +{ + struct proc *p; + struct thread *td; + + /* + * Finish setting up thread glue so that it begins execution in a + * non-nested critical section with sched_lock held but not recursed. + */ + td = curthread; + p = td->td_proc; + td->td_oncpu = PCPU_GET(cpuid); + KASSERT(p->p_state == PRS_NORMAL, ("executing process is still new")); + + sched_lock.mtx_lock = (uintptr_t)td; + mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); + cpu_critical_fork_exit(); + CTR4(KTR_PROC, "fork_exit: new thread %p (kse %p, pid %d, %s)", + td, td->td_sched, p->p_pid, p->p_comm); + + /* + * Processes normally resume in mi_switch() after being + * cpu_switch()'ed to, but when children start up they arrive here + * instead, so we must do much the same things as mi_switch() would. + */ + + if ((td = PCPU_GET(deadthread))) { + PCPU_SET(deadthread, NULL); + thread_stash(td); + } + td = curthread; + mtx_unlock_spin(&sched_lock); + + /* + * cpu_set_fork_handler intercepts this function call to + * have this call a non-return function to stay in kernel mode. + * initproc has its own fork handler, but it does return. + */ + KASSERT(callout != NULL, ("NULL callout in fork_exit")); + callout(arg, frame); + + /* + * Check if a kernel thread misbehaved and returned from its main + * function. + */ + PROC_LOCK(p); + if (p->p_flag & P_KTHREAD) { + PROC_UNLOCK(p); + printf("Kernel thread \"%s\" (pid %d) exited prematurely.\n", + p->p_comm, p->p_pid); + kthread_exit(0); + } + PROC_UNLOCK(p); + mtx_assert(&Giant, MA_NOTOWNED); +} + +/* + * Simplified back end of syscall(), used when returning from fork() + * directly into user mode. Giant is not held on entry, and must not + * be held on return. This function is passed in to fork_exit() as the + * first parameter and is called when returning to a new userland process. + */ +void +fork_return(td, frame) + struct thread *td; + struct trapframe *frame; +{ + + userret(td, frame, 0); +#ifdef KTRACE + if (KTRPOINT(td, KTR_SYSRET)) + ktrsysret(SYS_fork, 0, 0); +#endif + mtx_assert(&Giant, MA_NOTOWNED); +} diff --git a/freebsd-5.3-xen-sparse/mkbuildtree b/freebsd-5.3-xen-sparse/mkbuildtree new file mode 100644 index 0000000000..ce4c91d431 --- /dev/null +++ b/freebsd-5.3-xen-sparse/mkbuildtree @@ -0,0 +1,119 @@ +#!/bin/bash + +# mkbuildtree +# +# Creates symbolic links in for the sparse tree +# in the current directory. + +# Script to determine the relative path between two directories. +# Copyright (c) D. J. Hawkey Jr. 2002 +# Fixed for Xen project by K. Fraser in 2003. +abs_to_rel () +{ + local CWD SRCPATH + + if [ "$1" != "/" -a "${1##*[^/]}" = "/" ]; then + SRCPATH=${1%?} + else + SRCPATH=$1 + fi + if [ "$2" != "/" -a "${2##*[^/]}" = "/" ]; then + DESTPATH=${2%?} + else + DESTPATH=$2 + fi + + CWD=$PWD + [ "${1%%[^/]*}" != "/" ] && cd $1 && SRCPATH=$PWD + [ "${2%%[^/]*}" != "/" ] && cd $2 && DESTPATH=$PWD + [ "$CWD" != "$PWD" ] && cd $CWD + + BASEPATH=$SRCPATH + + [ "$SRCPATH" = "$DESTPATH" ] && DESTPATH="." && return + [ "$SRCPATH" = "/" ] && DESTPATH=${DESTPATH#?} && return + + while [ "$BASEPATH/" != "${DESTPATH%${DESTPATH#$BASEPATH/}}" ]; do + BASEPATH=${BASEPATH%/*} + done + + SRCPATH=${SRCPATH#$BASEPATH} + DESTPATH=${DESTPATH#$BASEPATH} + DESTPATH=${DESTPATH#?} + while [ -n "$SRCPATH" ]; do + SRCPATH=${SRCPATH%/*} + DESTPATH="../$DESTPATH" + done + + [ -z "$BASEPATH" ] && BASEPATH="/" + [ "${DESTPATH##*[^/]}" = "/" ] && DESTPATH=${DESTPATH%?} +} + +# relative_lndir +# Creates a tree of symlinks in the current working directory that mirror +# real files in . should be relative to the current +# working directory. Symlinks in are ignored. Source-control files +# are ignored. +relative_lndir () +{ + local SYMLINK_DIR REAL_DIR pref i j + SYMLINK_DIR=$PWD + REAL_DIR=$1 + ( + cd $REAL_DIR + for i in `find . -type d | grep -v SCCS`; do + [ -d $SYMLINK_DIR/$i ] || mkdir -p $SYMLINK_DIR/$i + ( + cd $i + pref=`echo $i | sed -e 's#/[^/]*#../#g' -e 's#^\.##'` + for j in `find . -type f -o -type l -maxdepth 1`; do + ln -sf ${pref}${REAL_DIR}/$i/$j ${SYMLINK_DIR}/$i/$j + done + ) + done + ) +} + +[ "$1" == "" ] && { echo "Syntax: $0 "; exit 1; } + +# Get absolute path to the destination directory +pushd . >/dev/null +cd ${1} +AD=$PWD +popd >/dev/null + +# Get absolute path to the source directory +AS=`pwd` + +# Get name of sparse directory +SDN=$(basename $AS) + +# Get path to source, relative to destination +abs_to_rel ${AD} ${AS} +RS=$DESTPATH + +# Remove old copies of files and directories at the destination +for i in `find sys -type f -o -type l` ; do rm -f ${AD}/${i#./} ; done + +# We now work from the destination directory +cd ${AD} + +# Remove old symlinks +find sys -type l | while read f +do + case $(readlink $f) in + */$SDN/*) + rm -f $f + ;; + esac +done + +if [ -f ${AD}/BUILDING ]; then + # Create symlinks of files and directories which exist in the sparse source + (cd sys && relative_lndir ../${RS}/sys) +else + # Create symlinks of files and directories which exist in the sparse source + relative_lndir ${RS} + rm -f mkbuildtree +fi + diff --git a/freebsd-5.3-xen-sparse/xenfbsd_kernel_build b/freebsd-5.3-xen-sparse/xenfbsd_kernel_build new file mode 100644 index 0000000000..dc2c927c06 --- /dev/null +++ b/freebsd-5.3-xen-sparse/xenfbsd_kernel_build @@ -0,0 +1,7 @@ +#!/bin/csh -f +cd i386-xen/conf +config XENCONF +cd ../compile/XENCONF +make kernel-clean +ln -s ../../include/xen-public/io/ring.h +make kernel-depend; make -j4 kernel From 608a4b13c97af585af5e6132e84df9a853781605 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Mon, 21 Mar 2005 08:21:45 +0000 Subject: [PATCH 167/199] bitkeeper revision 1.1159.272.4 (423e841947gMngP1oyDbc6vVjSMbqg) Make freebsd build scripts executable. Signed-off-by: ian@xensource.com --- freebsd-5.3-xen-sparse/fbsdxensetup | 0 freebsd-5.3-xen-sparse/mkbuildtree | 0 freebsd-5.3-xen-sparse/xenfbsd_kernel_build | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 freebsd-5.3-xen-sparse/fbsdxensetup mode change 100644 => 100755 freebsd-5.3-xen-sparse/mkbuildtree mode change 100644 => 100755 freebsd-5.3-xen-sparse/xenfbsd_kernel_build diff --git a/freebsd-5.3-xen-sparse/fbsdxensetup b/freebsd-5.3-xen-sparse/fbsdxensetup old mode 100644 new mode 100755 diff --git a/freebsd-5.3-xen-sparse/mkbuildtree b/freebsd-5.3-xen-sparse/mkbuildtree old mode 100644 new mode 100755 diff --git a/freebsd-5.3-xen-sparse/xenfbsd_kernel_build b/freebsd-5.3-xen-sparse/xenfbsd_kernel_build old mode 100644 new mode 100755 From dec435003fd10fc92b1dc4c1fbdf3e3e0a130501 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 21 Mar 2005 09:51:50 +0000 Subject: [PATCH 168/199] bitkeeper revision 1.1159.273.4 (423e9936-Gs_rM0rC9UWa8TA2293kA) Fix floppy driver on Xen -- vmalloc/vfree are unsafe because of the context that the fd_dma functions may get called from. Signed-off-by: Keir Fraser --- .../include/asm-xen/asm-i386/floppy.h | 119 ++++-------------- 1 file changed, 22 insertions(+), 97 deletions(-) diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h index ff838f21fb..2d5dd220ad 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/floppy.h @@ -28,10 +28,14 @@ #define fd_enable_irq() enable_irq(FLOPPY_IRQ) #define fd_disable_irq() disable_irq(FLOPPY_IRQ) #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) -#define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA) -#define fd_dma_mem_alloc(size) vdma_mem_alloc(size) -#define fd_dma_mem_free(addr, size) vdma_mem_free(addr, size) +#define fd_get_dma_residue() (virtual_dma_count + virtual_dma_residue) #define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) +/* + * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from + * softirq context via motor_off_callback. A generic bug we happen to trigger. + */ +#define fd_dma_mem_alloc(size) __get_free_pages(GFP_KERNEL, get_order(size)) +#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size)) static int virtual_dma_count; static int virtual_dma_residue; @@ -42,99 +46,36 @@ static int doing_pdma; static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs) { register unsigned char st; + register int lcount; + register char *lptr; -#undef TRACE_FLPY_INT -#define NO_FLOPPY_ASSEMBLER - -#ifdef TRACE_FLPY_INT - static int calls=0; - static int bytes=0; - static int dma_wait=0; -#endif if (!doing_pdma) return floppy_interrupt(irq, dev_id, regs); -#ifdef TRACE_FLPY_INT - if(!calls) - bytes = virtual_dma_count; -#endif - -#ifndef NO_FLOPPY_ASSEMBLER - __asm__ ( - "testl %1,%1" - "je 3f" -"1: inb %w4,%b0" - "andb $160,%b0" - "cmpb $160,%b0" - "jne 2f" - "incw %w4" - "testl %3,%3" - "jne 4f" - "inb %w4,%b0" - "movb %0,(%2)" - "jmp 5f" -"4: movb (%2),%0" - "outb %b0,%w4" -"5: decw %w4" - "outb %0,$0x80" - "decl %1" - "incl %2" - "testl %1,%1" - "jne 1b" -"3: inb %w4,%b0" -"2: " - : "=a" ((char) st), - "=c" ((long) virtual_dma_count), - "=S" ((long) virtual_dma_addr) - : "b" ((long) virtual_dma_mode), - "d" ((short) virtual_dma_port+4), - "1" ((long) virtual_dma_count), - "2" ((long) virtual_dma_addr)); -#else - { - register int lcount; - register char *lptr; - - st = 1; - for(lcount=virtual_dma_count, lptr=virtual_dma_addr; - lcount; lcount--, lptr++) { - st=inb(virtual_dma_port+4) & 0xa0 ; - if(st != 0xa0) - break; - if(virtual_dma_mode) - outb_p(*lptr, virtual_dma_port+5); - else - *lptr = inb_p(virtual_dma_port+5); - } - virtual_dma_count = lcount; - virtual_dma_addr = lptr; - st = inb(virtual_dma_port+4); + st = 1; + for(lcount=virtual_dma_count, lptr=virtual_dma_addr; + lcount; lcount--, lptr++) { + st=inb(virtual_dma_port+4) & 0xa0 ; + if(st != 0xa0) + break; + if(virtual_dma_mode) + outb_p(*lptr, virtual_dma_port+5); + else + *lptr = inb_p(virtual_dma_port+5); } -#endif + virtual_dma_count = lcount; + virtual_dma_addr = lptr; + st = inb(virtual_dma_port+4); -#ifdef TRACE_FLPY_INT - calls++; -#endif if(st == 0x20) return IRQ_HANDLED; if(!(st & 0x20)) { virtual_dma_residue += virtual_dma_count; virtual_dma_count=0; -#ifdef TRACE_FLPY_INT - printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", - virtual_dma_count, virtual_dma_residue, calls, bytes, - dma_wait); - calls = 0; - dma_wait=0; -#endif doing_pdma = 0; floppy_interrupt(irq, dev_id, regs); return IRQ_HANDLED; } -#ifdef TRACE_FLPY_INT - if(!virtual_dma_count) - dma_wait++; -#endif return IRQ_HANDLED; } @@ -145,28 +86,12 @@ static void fd_disable_dma(void) virtual_dma_count=0; } -static int vdma_get_dma_residue(unsigned int dummy) -{ - return virtual_dma_count + virtual_dma_residue; -} - static int fd_request_irq(void) { return request_irq(FLOPPY_IRQ, floppy_hardint,SA_INTERRUPT, "floppy", NULL); } -static unsigned long vdma_mem_alloc(unsigned long size) -{ - return (unsigned long) vmalloc(size); - -} - -static void vdma_mem_free(unsigned long addr, unsigned long size) -{ - vfree((void *)addr); -} - static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) { doing_pdma = 1; From b9aefb2dd74e17762f3ead534f40669b91c36fb2 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Mon, 21 Mar 2005 16:33:03 +0000 Subject: [PATCH 169/199] bitkeeper revision 1.1159.258.63 (423ef73fgHxWB39GjIH7wq4Q4o6-3Q) Change to choose a free vnc display based on netstat. Signed-off-by: Mike Wray --- tools/python/xen/xm/create.py | 44 ++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 5d45732dff..d36c89af7b 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -82,11 +82,12 @@ gopts.opt('console_autoconnect', short='c', fn=set_true, default=0, use="Connect to the console after the domain is created.") -gopts.opt('vnc', val='DISPLAY', - fn=set_int, default=None, +gopts.var('vnc', val='no|yes', + fn=set_bool, default=None, use="""Spawn a vncviewer listening for a vnc server in the domain. The address of the vncviewer is passed to the domain on the kernel command line using 'VNC_SERVER=:'. The port used by vnc is 5500 + DISPLAY. + A display value with a free port is chosen if possible. """) gopts.var('name', val='NAME', @@ -430,18 +431,49 @@ def get_host_addr(): addr = socket.gethostbyname(host) return addr +VNC_BASE_PORT = 5500 + +def choose_vnc_display(): + """Try to choose a free vnc display. + """ + def netstat_local_ports(): + """Run netstat to get a list of the local ports in use. + """ + l = os.popen("netstat -nat").readlines() + r = [] + # Skip 2 lines of header. + for x in l[2:]: + # Local port is field 3. + y = x.split()[3] + # Field is addr:port, split off the port. + y = y.split(':')[1] + r.append(int(y)) + return r + + ports = netstat_local_ports() + for d in range(1, 100): + port = VNC_BASE_PORT + d + if port in ports: continue + return d + return None + def spawn_vnc(display): os.system("vncviewer -listen %d &" % display) - return 5500 + display + return VNC_BASE_PORT + display def preprocess_vnc(opts, vals): """If vnc was specified, spawn a vncviewer in listen mode and pass its address to the domain on the kernel command line. """ - if vals.vnc is None: return - vnc_host = get_host_addr() - vnc_port = spawn_vnc(vals.vnc) + if not vals.vnc: return + vnc_display = choose_vnc_display() + if not vnc_display: + opts.warn("No free vnc display") + return + print 'VNC=', vnc_display + vnc_port = spawn_vnc(vnc_display) if vnc_port > 0: + vnc_host = get_host_addr() vnc = 'VNC_VIEWER=%s:%d' % (vnc_host, vnc_port) vals.extra = vnc + ' ' + vals.extra From d46869e28adebf88db7e77324d61c49d68b290bd Mon Sep 17 00:00:00 2001 From: "vh249@arcadians.cl.cam.ac.uk" Date: Mon, 21 Mar 2005 16:35:25 +0000 Subject: [PATCH 170/199] bitkeeper revision 1.1159.272.6 (423ef7cda7Kpa_XoIQvmnA23rDLP2Q) remove some bogus test while removing device Signed-off-by: Vincent Hanquez --- linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c index f9265e74ec..8dce5bd8ce 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c @@ -365,7 +365,7 @@ static int xlvbd_init_device(vdisk_t *xd) */ static int xlvbd_remove_device(int dev16) { - int i, rc = 0, minor = MINOR(dev16); + int i, rc = 0; struct gendisk *gd; struct block_device *bd; struct xlbd_disk_info *di; @@ -393,7 +393,6 @@ static int xlvbd_remove_device(int dev16) goto out; } - BUG_ON(minor != gd->first_minor); /* The VBD is mapped to an entire unit. */ invalidate_partition(gd, 0); From 2594f8caadbfba211eb5246a55f3d2a02c708989 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 22 Mar 2005 11:35:53 +0000 Subject: [PATCH 171/199] bitkeeper revision 1.1159.272.7 (42400319uaziODdhs_qBb3aaQuxIEg) Back-port the AGP patch that has been checked into the 2.6-mm tree by Andrew Morton. Signed-off-by: Keir Fraser --- .rootkeys | 1 + .../include/asm-xen/asm-i386/agp.h | 37 ++ patches/linux-2.6.11/agpgart.patch | 340 +++++++++++------- 3 files changed, 241 insertions(+), 137 deletions(-) create mode 100644 linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/agp.h diff --git a/.rootkeys b/.rootkeys index f45a92a1ab..178d51fbef 100644 --- a/.rootkeys +++ b/.rootkeys @@ -281,6 +281,7 @@ 4108f5c1ppFXVpQzCOAZ6xXYubsjKA linux-2.6.11-xen-sparse/drivers/xen/privcmd/Makefile 3e5a4e65IUfzzMu2kZFlGEB8-rpTaA linux-2.6.11-xen-sparse/drivers/xen/privcmd/privcmd.c 412f47e4RKD-R5IS5gEXvcT8L4v8gA linux-2.6.11-xen-sparse/include/asm-generic/pgtable.h +42400318xlBIV46qyxLTaDepPLNyhg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/agp.h 40f56239YAjS52QG2FIAQpHDZAdGHg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/desc.h 4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h 40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/fixmap.h diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/agp.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/agp.h new file mode 100644 index 0000000000..138986300a --- /dev/null +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/agp.h @@ -0,0 +1,37 @@ +#ifndef AGP_H +#define AGP_H 1 + +#include +#include +#include + +/* + * Functions to keep the agpgart mappings coherent with the MMU. + * The GART gives the CPU a physical alias of pages in memory. The alias region is + * mapped uncacheable. Make sure there are no conflicting mappings + * with different cachability attributes for the same page. This avoids + * data corruption on some CPUs. + */ + +int map_page_into_agp(struct page *page); +int unmap_page_from_agp(struct page *page); +#define flush_agp_mappings() global_flush_tlb() + +/* Could use CLFLUSH here if the cpu supports it. But then it would + need to be called for each cacheline of the whole page so it may not be + worth it. Would need a page for it. */ +#define flush_agp_cache() wbinvd() + +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) phys_to_machine(x) +#define gart_to_phys(x) machine_to_phys(x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) ({ \ + char *_t; dma_addr_t _d; \ + _t = dma_alloc_coherent(NULL,PAGE_SIZE<<(order),&_d,GFP_KERNEL); \ + _t; }) +#define free_gatt_pages(table, order) \ + dma_free_coherent(NULL,PAGE_SIZE<<(order),(table),virt_to_bus(table)) + +#endif diff --git a/patches/linux-2.6.11/agpgart.patch b/patches/linux-2.6.11/agpgart.patch index 4335ddb3cf..87dded22d4 100644 --- a/patches/linux-2.6.11/agpgart.patch +++ b/patches/linux-2.6.11/agpgart.patch @@ -1,371 +1,437 @@ -diff -rup pristine-linux-2.6.11/drivers/char/agp/ali-agp.c linux-2.6.11/drivers/char/agp/ali-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/ali-agp.c 2005-03-02 07:38:13.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/ali-agp.c 2005-03-11 00:35:21.320192760 +0000 -@@ -150,7 +150,7 @@ static void *m1541_alloc_page(void) +--- linux-2.6.11/drivers/char/agp/agp.h 2005-03-02 07:38:07 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/agp.h 2005-03-22 11:14:02 +00:00 +@@ -272,6 +272,8 @@ + #define AGP_GENERIC_SIZES_ENTRIES 11 + extern struct aper_size_info_16 agp3_generic_sizes[]; + ++#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) ++#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) + + extern int agp_off; + extern int agp_try_unsupported_boot; +--- linux-2.6.11/drivers/char/agp/ali-agp.c 2005-03-02 07:38:13 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/ali-agp.c 2005-03-22 11:14:56 +00:00 +@@ -150,7 +150,7 @@ pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); -+ virt_to_bus(addr)) | ALI_CACHE_FLUSH_EN )); ++ virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); return addr; } -@@ -174,7 +174,7 @@ static void m1541_destroy_page(void * ad +@@ -174,7 +174,7 @@ pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); -+ virt_to_bus(addr)) | ALI_CACHE_FLUSH_EN)); ++ virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); agp_generic_destroy_page(addr); } -diff -rup pristine-linux-2.6.11/drivers/char/agp/amd-k7-agp.c linux-2.6.11/drivers/char/agp/amd-k7-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/amd-k7-agp.c 2005-03-02 07:38:33.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/amd-k7-agp.c 2005-03-11 00:35:21.321192788 +0000 -@@ -43,7 +43,7 @@ static int amd_create_page_map(struct am +--- linux-2.6.11/drivers/char/agp/amd-k7-agp.c 2005-03-02 07:38:33 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/amd-k7-agp.c 2005-03-22 11:14:56 +00:00 +@@ -43,7 +43,7 @@ SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), -+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real), ++ page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); -@@ -154,7 +154,7 @@ static int amd_create_gatt_table(void) +@@ -154,7 +154,7 @@ agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); -+ agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); ++ agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its -@@ -167,7 +167,7 @@ static int amd_create_gatt_table(void) +@@ -167,7 +167,7 @@ /* Calculate the agp offset */ for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, -+ writel(virt_to_bus(amd_irongate_private.gatt_pages[i]->real) | 1, ++ writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } -diff -rup pristine-linux-2.6.11/drivers/char/agp/amd64-agp.c linux-2.6.11/drivers/char/agp/amd64-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/amd64-agp.c 2005-03-02 07:38:13.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/amd64-agp.c 2005-03-11 00:35:21.322192816 +0000 -@@ -218,7 +218,7 @@ static struct aper_size_info_32 amd_8151 +--- linux-2.6.11/drivers/char/agp/amd64-agp.c 2005-03-02 07:38:13 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/amd64-agp.c 2005-03-22 11:14:56 +00:00 +@@ -218,7 +218,7 @@ static int amd_8151_configure(void) { - unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); -+ unsigned long gatt_bus = virt_to_bus(agp_bridge->gatt_table_real); ++ unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); /* Configure AGP regs in each x86-64 host bridge. */ for_each_nb() { -@@ -590,7 +590,7 @@ static void __devexit agp_amd64_remove(s +@@ -590,7 +590,7 @@ { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - release_mem_region(virt_to_phys(bridge->gatt_table_real), -+ release_mem_region(virt_to_bus(bridge->gatt_table_real), ++ release_mem_region(virt_to_gart(bridge->gatt_table_real), amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); -diff -rup pristine-linux-2.6.11/drivers/char/agp/ati-agp.c linux-2.6.11/drivers/char/agp/ati-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/ati-agp.c 2005-03-02 07:38:13.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/ati-agp.c 2005-03-11 00:41:25.848450763 +0000 -@@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_ +--- linux-2.6.11/drivers/char/agp/ati-agp.c 2005-03-02 07:38:13 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/ati-agp.c 2005-03-22 11:14:56 +00:00 +@@ -61,7 +61,7 @@ SetPageReserved(virt_to_page(page_map->real)); err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), -+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real), ++ page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL || err) { ClearPageReserved(virt_to_page(page_map->real)); -diff -rup pristine-linux-2.6.11/drivers/char/agp/backend.c linux-2.6.11/drivers/char/agp/backend.c ---- pristine-linux-2.6.11/drivers/char/agp/backend.c 2005-03-02 07:38:13.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/backend.c 2005-03-11 00:35:21.323192844 +0000 -@@ -142,7 +142,7 @@ static int agp_backend_initialize(struct +--- linux-2.6.11/drivers/char/agp/backend.c 2005-03-02 07:38:13 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/backend.c 2005-03-22 11:14:56 +00:00 +@@ -142,7 +142,7 @@ return -ENOMEM; } - bridge->scratch_page_real = virt_to_phys(addr); -+ bridge->scratch_page_real = virt_to_bus(addr); ++ bridge->scratch_page_real = virt_to_gart(addr); bridge->scratch_page = bridge->driver->mask_memory(bridge->scratch_page_real, 0); } -@@ -186,7 +186,7 @@ static int agp_backend_initialize(struct +@@ -186,7 +186,7 @@ err_out: if (bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); -+ bus_to_virt(bridge->scratch_page_real)); ++ gart_to_virt(bridge->scratch_page_real)); if (got_gatt) bridge->driver->free_gatt_table(); if (got_keylist) { -@@ -211,7 +211,7 @@ static void agp_backend_cleanup(struct a +@@ -211,7 +211,7 @@ if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - phys_to_virt(bridge->scratch_page_real)); -+ bus_to_virt(bridge->scratch_page_real)); ++ gart_to_virt(bridge->scratch_page_real)); } /* XXX Kludge alert: agpgart isn't ready for multiple bridges yet */ -diff -rup pristine-linux-2.6.11/drivers/char/agp/efficeon-agp.c linux-2.6.11/drivers/char/agp/efficeon-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/efficeon-agp.c 2005-03-02 07:37:30.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/efficeon-agp.c 2005-03-11 00:35:21.324192872 +0000 -@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(vo +--- linux-2.6.11/drivers/char/agp/efficeon-agp.c 2005-03-02 07:37:30 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/efficeon-agp.c 2005-03-22 11:15:17 +00:00 +@@ -219,7 +219,7 @@ efficeon_private.l1_table[index] = page; - value = __pa(page) | pati | present | index; -+ value = virt_to_bus(page) | pati | present | index; ++ value = virt_to_gart(page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); -diff -rup pristine-linux-2.6.11/drivers/char/agp/generic.c linux-2.6.11/drivers/char/agp/generic.c ---- pristine-linux-2.6.11/drivers/char/agp/generic.c 2005-03-02 07:37:55.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/generic.c 2005-03-11 00:44:53.858248651 +0000 -@@ -151,7 +151,7 @@ void agp_free_memory(struct agp_memory * +--- linux-2.6.11/drivers/char/agp/generic.c 2005-03-02 07:37:55 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/generic.c 2005-03-22 11:17:37 +00:00 +@@ -151,7 +151,7 @@ } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i])); -+ agp_bridge->driver->agp_destroy_page(bus_to_virt(curr->memory[i])); ++ agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); } } agp_free_key(curr->key); -@@ -204,7 +204,7 @@ struct agp_memory *agp_allocate_memory(s +@@ -204,7 +204,7 @@ agp_free_memory(new); return NULL; } - new->memory[i] = virt_to_phys(addr); -+ new->memory[i] = virt_to_bus(addr); ++ new->memory[i] = virt_to_gart(addr); new->page_count++; } -@@ -659,6 +659,7 @@ int agp_generic_create_gatt_table(void) - int i; - void *temp; - struct page *page; -+ dma_addr_t dma; - - /* The generic routines can't handle 2 level gatt's */ - if (agp_bridge->driver->size_type == LVL2_APER_SIZE) -@@ -697,8 +698,10 @@ int agp_generic_create_gatt_table(void) +@@ -697,8 +697,7 @@ break; } - table = (char *) __get_free_pages(GFP_KERNEL, - page_order); -+ table = dma_alloc_coherent( -+ &agp_bridge->dev->dev, -+ PAGE_SIZE << page_order, &dma, -+ GFP_KERNEL); ++ table = alloc_gatt_pages(page_order); if (table == NULL) { i++; -@@ -729,7 +732,9 @@ int agp_generic_create_gatt_table(void) +@@ -729,7 +728,7 @@ size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; - table = (char *) __get_free_pages(GFP_KERNEL, page_order); -+ table = dma_alloc_coherent( -+ &agp_bridge->dev->dev, -+ PAGE_SIZE << page_order, &dma, GFP_KERNEL); ++ table = alloc_gatt_pages(page_order); } if (table == NULL) -@@ -744,7 +749,7 @@ int agp_generic_create_gatt_table(void) +@@ -744,7 +743,7 @@ agp_gatt_table = (void *)table; agp_bridge->driver->cache_flush(); - agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table), -+ agp_bridge->gatt_table = ioremap_nocache(virt_to_bus(table), ++ agp_bridge->gatt_table = ioremap_nocache(virt_to_gart(table), (PAGE_SIZE * (1 << page_order))); agp_bridge->driver->cache_flush(); -@@ -752,11 +757,12 @@ int agp_generic_create_gatt_table(void) +@@ -752,11 +751,11 @@ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) table, page_order); -+ dma_free_coherent(&agp_bridge->dev->dev, PAGE_SIZE<gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real); -+ agp_bridge->gatt_bus_addr = virt_to_bus(table); ++ agp_bridge->gatt_bus_addr = virt_to_gart(agp_bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) { -@@ -810,7 +816,8 @@ int agp_generic_free_gatt_table(void) +@@ -810,7 +809,7 @@ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_pages((unsigned long) agp_bridge->gatt_table_real, page_order); -+ dma_free_coherent(&agp_bridge->dev->dev, PAGE_SIZE<gatt_table_real, agp_bridge->gatt_bus_addr); ++ free_gatt_pages(agp_bridge->gatt_table_real, page_order); agp_gatt_table = NULL; agp_bridge->gatt_table = NULL; -diff -rup pristine-linux-2.6.11/drivers/char/agp/hp-agp.c linux-2.6.11/drivers/char/agp/hp-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/hp-agp.c 2005-03-02 07:38:19.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/hp-agp.c 2005-03-11 00:47:41.424653508 +0000 -@@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void +--- linux-2.6.11/drivers/char/agp/hp-agp.c 2005-03-02 07:38:19 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/hp-agp.c 2005-03-22 11:14:56 +00:00 +@@ -110,7 +110,7 @@ hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; - hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); -+ hp->io_pdir = bus_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); ++ hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { -@@ -248,7 +248,7 @@ hp_zx1_configure (void) +@@ -248,7 +248,7 @@ agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); if (hp->io_pdir_owner) { - writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); -+ writel(virt_to_bus(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); ++ writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); readl(hp->ioc_regs+HP_ZX1_TCNFG); -diff -rup pristine-linux-2.6.11/drivers/char/agp/i460-agp.c linux-2.6.11/drivers/char/agp/i460-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/i460-agp.c 2005-03-02 07:38:10.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/i460-agp.c 2005-03-11 00:35:21.327192957 +0000 -@@ -371,7 +371,7 @@ static int i460_alloc_large_page (struct +--- linux-2.6.11/drivers/char/agp/i460-agp.c 2005-03-02 07:38:10 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/i460-agp.c 2005-03-22 11:14:56 +00:00 +@@ -371,7 +371,7 @@ } memset(lp->alloced_map, 0, map_size); - lp->paddr = virt_to_phys(lpage); -+ lp->paddr = virt_to_bus(lpage); ++ lp->paddr = virt_to_gart(lpage); lp->refcount = 0; atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; -@@ -382,7 +382,7 @@ static void i460_free_large_page (struct +@@ -382,7 +382,7 @@ kfree(lp->alloced_map); lp->alloced_map = NULL; - free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); -+ free_pages((unsigned long) bus_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); ++ free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } -diff -rup pristine-linux-2.6.11/drivers/char/agp/intel-agp.c linux-2.6.11/drivers/char/agp/intel-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/intel-agp.c 2005-03-02 07:38:09.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/intel-agp.c 2005-03-11 00:35:21.328192985 +0000 -@@ -285,7 +285,7 @@ static struct agp_memory *alloc_agpphysm +--- linux-2.6.11/drivers/char/agp/intel-agp.c 2005-03-02 07:38:09 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/intel-agp.c 2005-03-22 11:14:56 +00:00 +@@ -285,7 +285,7 @@ if (new == NULL) return NULL; - new->memory[0] = virt_to_phys(addr); -+ new->memory[0] = virt_to_bus(addr); ++ new->memory[0] = virt_to_gart(addr); if (pg_count == 4) { /* kludge to get 4 physical pages for ARGB cursor */ new->memory[1] = new->memory[0] + PAGE_SIZE; -@@ -328,10 +328,10 @@ static void intel_i810_free_by_type(stru +@@ -328,10 +328,10 @@ agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { if (curr->page_count == 4) - i8xx_destroy_pages(phys_to_virt(curr->memory[0])); -+ i8xx_destroy_pages(bus_to_virt(curr->memory[0])); ++ i8xx_destroy_pages(gart_to_virt(curr->memory[0])); else agp_bridge->driver->agp_destroy_page( - phys_to_virt(curr->memory[0])); -+ bus_to_virt(curr->memory[0])); ++ gart_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); -diff -rup pristine-linux-2.6.11/drivers/char/agp/intel-mch-agp.c linux-2.6.11/drivers/char/agp/intel-mch-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/intel-mch-agp.c 2005-03-02 07:37:48.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/intel-mch-agp.c 2005-03-11 00:49:37.713063638 +0000 -@@ -51,7 +51,7 @@ static struct agp_memory *alloc_agpphysm +--- linux-2.6.11/drivers/char/agp/intel-mch-agp.c 2005-03-02 07:37:48 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/intel-mch-agp.c 2005-03-22 11:14:56 +00:00 +@@ -51,7 +51,7 @@ if (new == NULL) return NULL; - new->memory[0] = virt_to_phys(addr); -+ new->memory[0] = virt_to_bus(addr); ++ new->memory[0] = virt_to_gart(addr); new->page_count = 1; new->num_scratch_pages = 1; new->type = AGP_PHYS_MEMORY; -@@ -63,7 +63,7 @@ static void intel_i810_free_by_type(stru +@@ -63,7 +63,7 @@ { agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { - agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0])); -+ agp_bridge->driver->agp_destroy_page(bus_to_virt(curr->memory[0])); ++ agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); -diff -rup pristine-linux-2.6.11/drivers/char/agp/sworks-agp.c linux-2.6.11/drivers/char/agp/sworks-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/sworks-agp.c 2005-03-02 07:38:37.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/sworks-agp.c 2005-03-11 00:35:21.330193041 +0000 -@@ -51,7 +51,7 @@ static int serverworks_create_page_map(s +--- linux-2.6.11/drivers/char/agp/sworks-agp.c 2005-03-02 07:38:37 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/sworks-agp.c 2005-03-22 11:14:56 +00:00 +@@ -51,7 +51,7 @@ } SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), -+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real), ++ page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); -@@ -162,7 +162,7 @@ static int serverworks_create_gatt_table +@@ -162,7 +162,7 @@ /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); - writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); -+ writel(virt_to_bus(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); ++ writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); } retval = serverworks_create_gatt_pages(value->num_entries / 1024); -@@ -174,7 +174,7 @@ static int serverworks_create_gatt_table +@@ -174,7 +174,7 @@ agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); -+ agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); ++ agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its -@@ -187,7 +187,7 @@ static int serverworks_create_gatt_table +@@ -187,7 +187,7 @@ /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++) - writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); -+ writel(virt_to_bus(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); ++ writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); return 0; } -diff -rup pristine-linux-2.6.11/drivers/char/agp/uninorth-agp.c linux-2.6.11/drivers/char/agp/uninorth-agp.c ---- pristine-linux-2.6.11/drivers/char/agp/uninorth-agp.c 2005-03-02 07:38:09.000000000 +0000 -+++ linux-2.6.11/drivers/char/agp/uninorth-agp.c 2005-03-11 00:35:21.330193041 +0000 -@@ -200,7 +200,7 @@ static int uninorth_create_gatt_table(vo +--- linux-2.6.11/drivers/char/agp/uninorth-agp.c 2005-03-02 07:38:09 +00:00 ++++ linux-2.6.11-agp/drivers/char/agp/uninorth-agp.c 2005-03-22 11:14:56 +00:00 +@@ -200,7 +200,7 @@ agp_bridge->gatt_table_real = (u32 *) table; agp_bridge->gatt_table = (u32 *)table; - agp_bridge->gatt_bus_addr = virt_to_phys(table); -+ agp_bridge->gatt_bus_addr = virt_to_bus(table); ++ agp_bridge->gatt_bus_addr = virt_to_gart(table); for (i = 0; i < num_entries; i++) { agp_bridge->gatt_table[i] = -diff -rup pristine-linux-2.6.11/include/asm-i386/agp.h linux-2.6.11/include/asm-i386/agp.h ---- pristine-linux-2.6.11/include/asm-i386/agp.h 2005-03-02 07:37:31.000000000 +0000 -+++ linux-2.6.11/include/asm-i386/agp.h 2005-03-11 00:35:21.331193069 +0000 -@@ -3,6 +3,7 @@ - - #include - #include -+#include - - /* - * Functions to keep the agpgart mappings coherent with the MMU. -@@ -19,6 +20,6 @@ int unmap_page_from_agp(struct page *pag - /* Could use CLFLUSH here if the cpu supports it. But then it would - need to be called for each cacheline of the whole page so it may not be - worth it. Would need a page for it. */ --#define flush_agp_cache() asm volatile("wbinvd":::"memory") -+#define flush_agp_cache() wbinvd() +--- linux-2.6.11/include/asm-alpha/agp.h 2005-03-02 07:37:39 +00:00 ++++ linux-2.6.11-agp/include/asm-alpha/agp.h 2005-03-22 11:18:34 +00:00 +@@ -10,4 +10,14 @@ + #define flush_agp_mappings() + #define flush_agp_cache() mb() ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ + #endif +--- linux-2.6.11/include/asm-i386/agp.h 2005-03-02 07:37:31 +00:00 ++++ linux-2.6.11-agp/include/asm-i386/agp.h 2005-03-22 11:18:39 +00:00 +@@ -21,4 +21,14 @@ + worth it. Would need a page for it. */ + #define flush_agp_cache() asm volatile("wbinvd":::"memory") + ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ + #endif +--- linux-2.6.11/include/asm-ia64/agp.h 2005-03-02 07:38:09 +00:00 ++++ linux-2.6.11-agp/include/asm-ia64/agp.h 2005-03-22 11:18:45 +00:00 +@@ -18,4 +18,14 @@ + #define flush_agp_mappings() /* nothing */ + #define flush_agp_cache() mb() + ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ + #endif /* _ASM_IA64_AGP_H */ +--- linux-2.6.11/include/asm-ppc/agp.h 2005-03-02 07:38:08 +00:00 ++++ linux-2.6.11-agp/include/asm-ppc/agp.h 2005-03-22 11:18:52 +00:00 +@@ -10,4 +10,14 @@ + #define flush_agp_mappings() + #define flush_agp_cache() mb() + ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ + #endif +--- linux-2.6.11/include/asm-sparc64/agp.h 2005-03-02 07:37:48 +00:00 ++++ linux-2.6.11-agp/include/asm-sparc64/agp.h 2005-03-22 11:18:59 +00:00 +@@ -8,4 +8,14 @@ + #define flush_agp_mappings() + #define flush_agp_cache() mb() + ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ + #endif +--- linux-2.6.11/include/asm-x86_64/agp.h 2005-03-02 07:37:30 +00:00 ++++ linux-2.6.11-agp/include/asm-x86_64/agp.h 2005-03-22 11:18:22 +00:00 +@@ -19,4 +19,14 @@ + worth it. Would need a page for it. */ + #define flush_agp_cache() asm volatile("wbinvd":::"memory") + ++/* Convert a physical address to an address suitable for the GART. */ ++#define phys_to_gart(x) (x) ++#define gart_to_phys(x) (x) ++ ++/* GATT allocation. Returns/accepts GATT kernel virtual address. */ ++#define alloc_gatt_pages(order) \ ++ ((char *)__get_free_pages(GFP_KERNEL, (order))) ++#define free_gatt_pages(table, order) \ ++ free_pages((unsigned long)(table), (order)) ++ #endif From 16ca18af9004f25512a33bf60e131bfe2a6dac1a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 22 Mar 2005 19:26:37 +0000 Subject: [PATCH 172/199] bitkeeper revision 1.1159.272.8 (4240716dixo5jLBihZPvbRrP21dn4g) Schedule page scrubbing for dead domains off the per-cpu periodic ticker. We take 10% of busy cpus and all of idle cpu time. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 3 ++ xen/common/page_alloc.c | 93 +++++++++++++++++++++++++++++++++------ xen/common/schedule.c | 2 + xen/include/xen/mm.h | 13 ++++++ xen/include/xen/softirq.h | 3 +- 5 files changed, 99 insertions(+), 15 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 9c81c9c718..812d14c506 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -69,7 +69,10 @@ static __attribute_used__ void idle_loop(void) { irq_stat[cpu].idle_timestamp = jiffies; while ( !softirq_pending(cpu) ) + { + page_scrub_schedule_work(); default_idle(); + } do_softirq(); } } diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index d8ac2d4ca0..8637b8cea5 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include /* @@ -551,7 +552,6 @@ void free_domheap_pages(struct pfn_info *pg, unsigned int order) { int i, drop_dom_ref; struct domain *d = pg->u.inuse.domain; - void *p; ASSERT(!in_irq()); @@ -579,18 +579,6 @@ void free_domheap_pages(struct pfn_info *pg, unsigned int order) pg[i].tlbflush_timestamp = tlbflush_current_time(); pg[i].u.free.cpu_mask = 1 << d->processor; list_del(&pg[i].list); - - /* - * Normally we expect a domain to clear pages before freeing them, - * if it cares about the secrecy of their contents. However, after - * a domain has died we assume responsibility for erasure. - */ - if ( unlikely(test_bit(DF_DYING, &d->flags)) ) - { - p = map_domain_mem(page_to_phys(&pg[i])); - clear_page(p); - unmap_domain_mem(p); - } } d->tot_pages -= 1 << order; @@ -598,7 +586,24 @@ void free_domheap_pages(struct pfn_info *pg, unsigned int order) spin_unlock_recursive(&d->page_alloc_lock); - free_heap_pages(MEMZONE_DOM, pg, order); + if ( likely(!test_bit(DF_DYING, &d->flags)) ) + { + free_heap_pages(MEMZONE_DOM, pg, order); + } + else + { + /* + * Normally we expect a domain to clear pages before freeing them, + * if it cares about the secrecy of their contents. However, after + * a domain has died we assume responsibility for erasure. + */ + for ( i = 0; i < (1 << order); i++ ) + { + spin_lock(&page_scrub_lock); + list_add(&pg[i].list, &page_scrub_list); + spin_unlock(&page_scrub_lock); + } + } } else { @@ -616,3 +621,63 @@ unsigned long avail_domheap_pages(void) { return avail[MEMZONE_DOM]; } + + + +/************************* + * PAGE SCRUBBING + */ + +static spinlock_t page_scrub_lock; +struct list_head page_scrub_list; + +static void page_scrub_softirq(void) +{ + struct list_head *ent; + struct pfn_info *pg; + void *p; + int i; + s_time_t start = NOW(); + + /* Aim to do 1ms of work (ten percent of a 10ms jiffy). */ + do { + spin_lock(&page_scrub_lock); + + if ( unlikely((ent = page_scrub_list.next) == &page_scrub_list) ) + { + spin_unlock(&page_scrub_lock); + return; + } + + /* Peel up to 16 pages from the list. */ + for ( i = 0; i < 16; i++ ) + if ( (ent = ent->next) == &page_scrub_list ) + break; + + /* Remove peeled pages from the list. */ + ent->next->prev = &page_scrub_list; + page_scrub_list.next = ent->next; + + spin_unlock(&page_scrub_lock); + + /* Working backwards, scrub each page in turn. */ + while ( ent != &page_scrub_list ) + { + pg = list_entry(ent, struct pfn_info, list); + ent = ent->prev; + p = map_domain_mem(page_to_phys(pg)); + clear_page(p); + unmap_domain_mem(p); + free_heap_pages(MEMZONE_DOM, pg, 0); + } + } while ( (NOW() - start) < MILLISECS(1) ); +} + +static __init int page_scrub_init(void) +{ + spin_lock_init(&page_scrub_lock); + INIT_LIST_HEAD(&page_scrub_list); + open_softirq(PAGE_SCRUB_SOFTIRQ, page_scrub_softirq); + return 0; +} +__initcall(page_scrub_init); diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 62f764e9d9..d16c2192f4 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -437,6 +437,8 @@ static void t_timer_fn(unsigned long unused) if ( !is_idle_task(d) && update_dom_time(d) ) send_guest_virq(d, VIRQ_TIMER); + page_scrub_schedule_work(); + t_timer[d->processor].expires = NOW() + MILLISECS(10); add_ac_timer(&t_timer[d->processor]); } diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 12242ca491..33ce8ac603 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -2,6 +2,10 @@ #ifndef __XEN_MM_H__ #define __XEN_MM_H__ +#include +#include +#include + struct domain; struct pfn_info; @@ -34,6 +38,15 @@ unsigned long avail_domheap_pages(void); #define alloc_domheap_page(_d) (alloc_domheap_pages(_d,0)) #define free_domheap_page(_p) (free_domheap_pages(_p,0)) +/* Automatic page scrubbing for dead domains. */ +extern spinlock_t page_scrub_lock; +extern struct list_head page_scrub_list; +#define page_scrub_schedule_work() \ + do { \ + if ( !list_empty(&page_scrub_list) ) \ + raise_softirq(PAGE_SCRUB_SOFTIRQ); \ + } while ( 0 ) + #include #endif /* __XEN_MM_H__ */ diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h index 6180dae775..a538540247 100644 --- a/xen/include/xen/softirq.h +++ b/xen/include/xen/softirq.h @@ -7,7 +7,8 @@ #define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2 #define KEYPRESS_SOFTIRQ 3 #define NMI_SOFTIRQ 4 -#define NR_SOFTIRQS 5 +#define PAGE_SCRUB_SOFTIRQ 5 +#define NR_SOFTIRQS 6 #ifndef __ASSEMBLY__ From 74f81dd1a5e3cfe3efb1dfc01177313be2dd5882 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 23 Mar 2005 09:07:45 +0000 Subject: [PATCH 173/199] bitkeeper revision 1.1159.272.9 (424131e1AxW6hgsgUY2M3meFO0k4MQ) libxc reacts to memory allocation delay because memory is on the scrub list. Signed-off-by: Keir Fraser --- tools/libxc/xc_private.h | 12 +++++++++++- xen/common/domain.c | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index c05ae491d9..a48156000a 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -72,7 +72,7 @@ static inline int do_xen_hypercall(int xc_handle, static inline int do_dom0_op(int xc_handle, dom0_op_t *op) { - int ret = -1; + int ret = -1, retries = 0; privcmd_hypercall_t hypercall; op->interface_version = DOM0_INTERFACE_VERSION; @@ -86,8 +86,18 @@ static inline int do_dom0_op(int xc_handle, dom0_op_t *op) goto out1; } + again: if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { + if ( (errno == EAGAIN) && (retries++ < 10) ) + { + /* + * This was added for memory allocation, where we can get EAGAIN + * if memory is unavailable because it is on the scrub list. + */ + sleep(1); + goto again; + } if ( errno == EACCES ) fprintf(stderr, "Dom0 operation failed -- need to" " rebuild the user-space tool set?\n"); diff --git a/xen/common/domain.c b/xen/common/domain.c index fa07f2baf9..30b0677fbb 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -197,7 +197,7 @@ unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes) if ( unlikely((page = alloc_domheap_page(d)) == NULL) ) { domain_relinquish_memory(d); - return -ENOMEM; + return list_empty(&page_scrub_list) ? -ENOMEM : -EAGAIN; } /* Initialise the machine-to-phys mapping for this page. */ From d535ea243e5e92f51b0e099a6754d6bb9c82c36b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 24 Mar 2005 17:26:29 +0000 Subject: [PATCH 174/199] bitkeeper revision 1.1159.272.10 (4242f845cpppoqILZOUsc9BDNxlTUA) Set a block timeout at least a jiffy ahead, to have same behaviour as native Linux. Signed-off-by: Keir Fraser --- linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c index 5d09ae6a0a..bf8e8f9d90 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/time.c @@ -673,6 +673,7 @@ int set_timeout_timer(void) { u64 alarm = 0; int ret = 0; + unsigned long j; /* * This is safe against long blocking (since calculations are @@ -681,7 +682,10 @@ int set_timeout_timer(void) * would first get locked out. It is safe against normal * updates of jiffies since interrupts are off. */ - alarm = __jiffies_to_st(next_timer_interrupt()); + j = next_timer_interrupt(); + if (j < (jiffies + 1)) + j = jiffies + 1; + alarm = __jiffies_to_st(j); /* Failure is pretty bad, but we'd best soldier on. */ if ( HYPERVISOR_set_timer_op(alarm) != 0 ) From 3aca223127966196f412ddeba3736c2f2beeecf1 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Thu, 24 Mar 2005 21:24:38 +0000 Subject: [PATCH 175/199] bitkeeper revision 1.1159.258.64 (42433016pzi5kr8wggkPTZcHlxXCpg) Back out changes to netif backend messaging to set vifname. Try using 'ip link' instead. Signed-off-by: Mike Wray --- .../drivers/xen/netback/interface.c | 6 +----- tools/python/xen/lowlevel/xu/xu.c | 2 -- tools/python/xen/xend/Vifctl.py | 13 +++++++++++++ tools/python/xen/xend/server/netif.py | 9 +++++++-- xen/include/public/io/domain_controller.h | 5 ++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c index f54dd0ad9c..1d1a5923c4 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/netback/interface.c @@ -121,11 +121,7 @@ void netif_create(netif_be_create_t *create) netif_t **pnetif, *netif; char name[IFNAMSIZ] = {}; - if(create->vifname[0] == '\0'){ - snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); - } else { - snprintf(name, IFNAMSIZ - 1, "%s", create->vifname); - } + snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); dev = alloc_netdev(sizeof(netif_t), name, ether_setup); if ( dev == NULL ) { diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index 3f32cadc34..2c3ee6b33f 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -480,7 +480,6 @@ static PyObject *xu_message_get_payload(PyObject *self, PyObject *args) C2P(netif_be_create_t, domid, Int, Long); C2P(netif_be_create_t, netif_handle, Int, Long); C2P(netif_be_create_t, status, Int, Long); - C2P(netif_be_create_t, vifname, String, String); return dict; case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): C2P(netif_be_destroy_t, domid, Int, Long); @@ -648,7 +647,6 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args) P2C(netif_be_create_t, mac[3], u8); P2C(netif_be_create_t, mac[4], u8); P2C(netif_be_create_t, mac[5], u8); - P2CSTRING(netif_be_create_t, vifname); break; case TYPE(CMSG_NETIF_BE, CMSG_NETIF_BE_DESTROY): P2C(netif_be_destroy_t, domid, u32); diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index 86f68db0b4..bfc750315a 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -37,6 +37,19 @@ def network(op, script=None, bridge=None, antispoof=None): args = ' '.join(args) os.system(script + ' ' + args) +def set_vif_name(vif_old, vif_new): + if vif_old == vif_new: + vif = view_new + if os.system("ip link show %s" % vif_old) == 0: + os.system("ip link set %s down" % vif_old) + os.system("ip link set %s name %s" % (vif_old, vif_new)) + os.system("ip link set %s up" % vif_new) + if os.system("ip link show %s" % vif_new) == 0: + vif = vif_new + else: + vif = vif_old + return vif + def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]): """Call a vif control script. Xend calls this when bringing vifs up or down. diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 5afb3df388..5d3ef5a18d 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -134,7 +134,7 @@ class NetDev(controller.SplitDev): self.vifname = sxp.child_value(config, 'vifname') if self.vifname is None: - self.vifname = "vif%d.%d" % (self.controller.dom, self.vif) + self.vifname = self.default_vifname() if len(self.vifname) > 15: raise XendError('invalid vifname: too long: ' + self.vifname) mac = self._get_config_mac(config) @@ -217,6 +217,9 @@ class NetDev(controller.SplitDev): """ return self.vifname + def default_vifname(self): + return "vif%d.%d" % (self.controller.dom, self.vif) + def get_mac(self): """Get the MAC address as a string. """ @@ -248,6 +251,8 @@ class NetDev(controller.SplitDev): @param op: operation name (up, down) @param vmname: vmname """ + if op == 'up': + Vifctl.set_vif_name(self.default_vifname(), self.vifname) Vifctl.vifctl(op, **self.vifctl_params(vmname=vmname)) vnet = XendVnet.instance().vnet_of_bridge(self.bridge) if vnet: @@ -276,7 +281,7 @@ class NetDev(controller.SplitDev): { 'domid' : self.controller.dom, 'netif_handle' : self.vif, 'mac' : self.mac, - 'vifname' : self.vifname + #'vifname' : self.vifname }) self.getBackendInterface().writeRequest(msg, response=d) return d diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index b42510d688..c3494e34ca 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -466,10 +466,9 @@ typedef struct { u32 netif_handle; /* 4: Domain-specific interface handle. */ u8 mac[6]; /* 8 */ u16 __pad1; /* 14 */ - char vifname[16]; /* 16 */ /* OUT */ - u32 status; /* 32 */ -} PACKED netif_be_create_t; /* 36 bytes */ + u32 status; /* 16 */ +} PACKED netif_be_create_t; /* 20 bytes */ /* * CMSG_NETIF_BE_DESTROY: From 971b02507e29fa75c276566244b0c820c447d6f2 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Thu, 24 Mar 2005 21:51:46 +0000 Subject: [PATCH 176/199] bitkeeper revision 1.1159.272.11 (42433672q27Zpx5yJpmpyepHVywt3Q) Only include files of the TARGET_ARCH arch in TAGS file. Signed-off-by: Christian Limpach --- xen/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/Makefile b/xen/Makefile index 7593e017fa..0455b26807 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -105,7 +105,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s .PHONY: default debug install dist clean delete-unfresh-files TAGS -SUBDIRS = arch common drivers +SUBDIRS = arch/$(TARGET_ARCH) common drivers TAGS: ( find include/asm-$(TARGET_ARCH) -name '*.h'; \ find include -type d \( -name "asm-*" -o -name config \) -prune -o \ From 521752c0b7885d58344ef2ec7bfa2463005fcc70 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk[iap10]" Date: Fri, 25 Mar 2005 11:41:40 +0000 Subject: [PATCH 177/199] bitkeeper revision 1.1159.258.67 (4243f8f4bOCvwTNPuva3gzEiuhWgSw) fix to xend --- tools/python/xen/xend/Vifctl.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index bfc750315a..fe33ecbc71 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -39,7 +39,8 @@ def network(op, script=None, bridge=None, antispoof=None): def set_vif_name(vif_old, vif_new): if vif_old == vif_new: - vif = view_new + vif = vif_new + return vif if os.system("ip link show %s" % vif_old) == 0: os.system("ip link set %s down" % vif_old) os.system("ip link set %s name %s" % (vif_old, vif_new)) From f050756e4101d4cb510dc395afe4cffff781acc3 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Fri, 25 Mar 2005 13:33:38 +0000 Subject: [PATCH 178/199] bitkeeper revision 1.1159.272.12 (42441332UkmiN7Ka9ysrPj9ZtPvXZg) Fix cleanup path for active writable pagetable. Reconnect page so that it gets cleaned up correctly. Signed-off-by: Christian Limpach --- xen/arch/x86/memory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 3961b37a89..6fb64a31fa 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1765,6 +1765,11 @@ void ptwr_flush(const int which) (ENTRIES_PER_L1_PAGETABLE - i) * sizeof(l1_pgentry_t)); unmap_domain_mem(pl1e); ptwr_info[cpu].ptinfo[which].l1va = 0; + if ( (which == PTWR_PT_ACTIVE) && likely(!d->mm.shadow_mode) ) + { + pl2e = &linear_l2_table[ptwr_info[cpu].ptinfo[which].l2_idx]; + *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); + } domain_crash(); } From 68a40bb5ec51d9befdb5bfad9d578cf1b368582b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 25 Mar 2005 23:01:33 +0000 Subject: [PATCH 179/199] bitkeeper revision 1.1159.258.69 (4244984dfA_QIQFHRNZRU9hNBMo-lw) ifdef fix. --- xen/arch/x86/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 06b0acf44a..eef9c16100 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -136,7 +136,7 @@ static unsigned long __init calibrate_tsc(void) diff = end - start; -#if defined(_i386__) +#if defined(__i386__) /* If quotient doesn't fit in 32 bits then we return error (zero). */ if ( diff & ~0xffffffffULL ) return 0; From f9774e8f732bd5e92bdf1014d88c28a2f059e065 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 25 Mar 2005 23:36:25 +0000 Subject: [PATCH 180/199] bitkeeper revision 1.1159.258.70 (4244a079wh98lZeg0t3eZdAEyBTNPQ) Tools makefile cleanup and fix for parallel build. Signed-off-by: Jerone Young Signed-off-by: Keir Fraser --- tools/Makefile | 60 ++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index c582a014d0..0308c7512f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,32 +1,34 @@ +XEN_ROOT = ../ +include $(XEN_ROOT)/tools/Rules.mk -all: +SUBDIRS := +SUBDIRS += libxutil +SUBDIRS += libxc +SUBDIRS += misc +SUBDIRS += examples +SUBDIRS += xentrace +SUBDIRS += python +SUBDIRS += xfrd + +.PHONY: all install clean check check_clean + +all: check + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + +install: check + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + +clean: check_clean + @set -e; for subdir in $(SUBDIRS); do \ + $(MAKE) -C $$subdir $@; \ + done + +check: $(MAKE) -C check - $(MAKE) -C libxutil - $(MAKE) -C libxc - $(MAKE) -C misc - $(MAKE) -C examples - $(MAKE) -C xentrace - $(MAKE) -C python - $(MAKE) -C xfrd - -install: - $(MAKE) -C check - $(MAKE) -C libxutil install - $(MAKE) -C libxc install - $(MAKE) -C misc install - $(MAKE) -C examples install - $(MAKE) -C xentrace install - $(MAKE) -C python install - $(MAKE) -C xfrd install - $(MAKE) -C sv install - -clean build: - $(MAKE) -C check $@ - $(MAKE) -C libxutil $@ - $(MAKE) -C libxc $@ - $(MAKE) -C misc $@ - $(MAKE) -C examples $@ - $(MAKE) -C xentrace $@ - $(MAKE) -C python $@ - $(MAKE) -C xfrd $@ +check_clean: + $(MAKE) -C check clean From b30aadd3f032274c3a46350f1f55f20c7b11a756 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Sat, 26 Mar 2005 01:12:37 +0000 Subject: [PATCH 181/199] bitkeeper revision 1.1159.275.1 (4244b7056FS2uC4AapFJtHCNgoKPFg) No direct entry to __enter_scheduler allowed. Must always pass through softirq handler. Also domain_crash() now returns and defers descheduling from local CPU: old behaviour is still provided by domain_crash_synchronous(). Signed-off-by: Keir Fraser Signed-off-by: Christian Limpach --- xen/arch/x86/domain.c | 3 ++- xen/arch/x86/memory.c | 44 +++++++------------------------------ xen/arch/x86/shadow.c | 16 +++++++++----- xen/arch/x86/traps.c | 4 ++-- xen/arch/x86/x86_32/entry.S | 10 ++++----- xen/common/domain.c | 26 ++++++++++++---------- xen/common/schedule.c | 5 +++-- xen/include/xen/sched.h | 15 ++++++++++--- 8 files changed, 57 insertions(+), 66 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 812d14c506..d47910233a 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -82,7 +82,8 @@ void startup_cpu_idle_loop(void) /* Just some sanity to ensure that the scheduler is set up okay. */ ASSERT(current->id == IDLE_DOMAIN_ID); domain_unpause_by_systemcontroller(current); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); + do_softirq(); /* * Declares CPU setup done to the boot processor. diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 6fb64a31fa..4c91d7374b 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -1686,7 +1686,7 @@ void ptwr_flush(const int which) MEM_LOG("ptwr: Could not read pte at %p\n", ptep); /* * Really a bug. We could read this PTE during the initial fault, - * and pagetables can't have changed meantime. XXX Multi-CPU guests? + * and pagetables can't have changed meantime. */ BUG(); } @@ -1713,7 +1713,7 @@ void ptwr_flush(const int which) MEM_LOG("ptwr: Could not update pte at %p\n", ptep); /* * Really a bug. We could write this PTE during the initial fault, - * and pagetables can't have changed meantime. XXX Multi-CPU guests? + * and pagetables can't have changed meantime. */ BUG(); } @@ -1771,6 +1771,7 @@ void ptwr_flush(const int which) *pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT); } domain_crash(); + return; } if ( unlikely(sl1e != NULL) ) @@ -1834,13 +1835,17 @@ int ptwr_do_page_fault(unsigned long addr) /* Get the L2 index at which this L1 p.t. is always mapped. */ l2_idx = page->u.inuse.type_info & PGT_va_mask; if ( unlikely(l2_idx >= PGT_va_unknown) ) + { domain_crash(); /* Urk! This L1 is mapped in multiple L2 slots! */ + return 0; + } l2_idx >>= PGT_va_shift; if ( l2_idx == (addr >> L2_PAGETABLE_SHIFT) ) { MEM_LOG("PTWR failure! Pagetable maps itself at %08lx\n", addr); domain_crash(); + return 0; } /* @@ -1908,6 +1913,7 @@ int ptwr_do_page_fault(unsigned long addr) unmap_domain_mem(ptwr_info[cpu].ptinfo[which].pl1e); ptwr_info[cpu].ptinfo[which].l1va = 0; domain_crash(); + return 0; } return EXCRET_fault_fixed; @@ -1938,40 +1944,6 @@ __initcall(ptwr_init); #ifndef NDEBUG -void ptwr_status(void) -{ - unsigned long pte, *ptep, pfn; - struct pfn_info *page; - int cpu = smp_processor_id(); - - ptep = (unsigned long *)&linear_pg_table - [ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va>>PAGE_SHIFT]; - - if ( __get_user(pte, ptep) ) { - MEM_LOG("ptwr: Could not read pte at %p\n", ptep); - domain_crash(); - } - - pfn = pte >> PAGE_SHIFT; - page = &frame_table[pfn]; - printk("need to alloc l1 page %p\n", page); - /* make pt page writable */ - printk("need to make read-only l1-page at %p is %08lx\n", - ptep, pte); - - if ( ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va == 0 ) - return; - - if ( __get_user(pte, (unsigned long *) - ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va) ) { - MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *) - ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va); - domain_crash(); - } - pfn = pte >> PAGE_SHIFT; - page = &frame_table[pfn]; -} - void audit_domain(struct domain *d) { int ttot=0, ctot=0, io_mappings=0, lowmem_mappings=0; diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 01d67d43ad..465563fb8f 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -580,15 +580,13 @@ int shadow_fault(unsigned long va, long error_code) &linear_pg_table[va >> PAGE_SHIFT])) ) { SH_VVLOG("shadow_fault - EXIT: read gpte faulted" ); - shadow_unlock(m); - return 0; + goto fail; } if ( unlikely(!(gpte & _PAGE_PRESENT)) ) { SH_VVLOG("shadow_fault - EXIT: gpte not present (%lx)",gpte ); - shadow_unlock(m); - return 0; + goto fail; } /* Write fault? */ @@ -598,8 +596,7 @@ int shadow_fault(unsigned long va, long error_code) { /* Write fault on a read-only mapping. */ SH_VVLOG("shadow_fault - EXIT: wr fault on RO page (%lx)", gpte); - shadow_unlock(m); - return 0; + goto fail; } l1pte_write_fault(m, &gpte, &spte); @@ -616,7 +613,10 @@ int shadow_fault(unsigned long va, long error_code) /* XXX Watch out for read-only L2 entries! (not used in Linux). */ if ( unlikely(__put_user(gpte, (unsigned long *) &linear_pg_table[va >> PAGE_SHIFT])) ) + { domain_crash(); + goto fail; + } /* * Update of shadow PTE can fail because the L1 p.t. is not shadowed, @@ -637,6 +637,10 @@ int shadow_fault(unsigned long va, long error_code) check_pagetable(m, current->mm.pagetable, "post-sf"); return EXCRET_fault_fixed; + + fail: + shadow_unlock(m); + return 0; } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 8e965c5f60..df68d420fc 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -654,8 +654,6 @@ asmlinkage int do_debug(struct xen_regs *regs) struct domain *d = current; struct trap_bounce *tb = &d->thread.trap_bounce; - DEBUGGER_trap_entry(TRAP_debug, regs); - __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); /* Mask out spurious debug traps due to lazy DR7 setting */ @@ -666,6 +664,8 @@ asmlinkage int do_debug(struct xen_regs *regs) goto out; } + DEBUGGER_trap_entry(TRAP_debug, regs); + if ( !GUEST_FAULT(regs) ) { /* Clear TF just for absolute sanity. */ diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index aaf6caccef..b155938310 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -112,7 +112,7 @@ DBLFLT1:GET_CURRENT(%ebx) jmp test_all_events DBLFIX1:GET_CURRENT(%ebx) testb $TF_failsafe_return,DOMAIN_thread_flags(%ebx) - jnz domain_crash # cannot reenter failsafe code + jnz domain_crash_synchronous # cannot reenter failsafe code orb $TF_failsafe_return,DOMAIN_thread_flags(%ebx) jmp test_all_events # will return via failsafe code .previous @@ -330,7 +330,7 @@ DBLFLT2:jmp process_guest_exception_and_events .long FLT23,FIX7 , FLT24,FIX7 , FLT25,FIX7 , FLT26,FIX7 , FLT27,FIX7 .previous .section __ex_table,"a" - .long DBLFLT2,domain_crash + .long DBLFLT2,domain_crash_synchronous .previous ALIGN @@ -620,9 +620,9 @@ VFLT3: movl %gs:(%esi),%eax jmp test_all_events .section __ex_table,"a" - .long VFLT1,domain_crash - .long VFLT2,domain_crash - .long VFLT3,domain_crash + .long VFLT1,domain_crash_synchronous + .long VFLT2,domain_crash_synchronous + .long VFLT3,domain_crash_synchronous .previous .data diff --git a/xen/common/domain.c b/xen/common/domain.c index 30b0677fbb..90e893899a 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -146,8 +147,15 @@ void domain_crash(void) send_guest_virq(dom0, VIRQ_DOM_EXC); - __enter_scheduler(); - BUG(); + raise_softirq(SCHEDULE_SOFTIRQ); +} + + +void domain_crash_synchronous(void) +{ + domain_crash(); + for ( ; ; ) + do_softirq(); } void domain_shutdown(u8 reason) @@ -169,18 +177,14 @@ void domain_shutdown(u8 reason) } } - if ( reason == SHUTDOWN_crash ) - { - domain_crash(); - BUG(); - } - - current->shutdown_code = reason; - set_bit(DF_SHUTDOWN, ¤t->flags); + if ( (current->shutdown_code = reason) == SHUTDOWN_crash ) + set_bit(DF_CRASHED, ¤t->flags); + else + set_bit(DF_SHUTDOWN, ¤t->flags); send_guest_virq(dom0, VIRQ_DOM_EXC); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); } unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index d16c2192f4..9756b18512 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -79,7 +79,8 @@ static struct scheduler *schedulers[] = { NULL }; -/* Operations for the current scheduler. */ +static void __enter_scheduler(void); + static struct scheduler ops; #define SCHED_OP(fn, ...) \ @@ -310,7 +311,7 @@ long sched_adjdom(struct sched_adjdom_cmd *cmd) * - deschedule the current domain (scheduler independent). * - pick a new domain (scheduler dependent). */ -void __enter_scheduler(void) +static void __enter_scheduler(void) { struct domain *prev = current, *next = NULL; int cpu = prev->processor; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 254169cd9f..8f5345375b 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -184,9 +184,20 @@ struct domain *find_domain_by_id(domid_t dom); struct domain *find_last_domain(void); extern void domain_destruct(struct domain *d); extern void domain_kill(struct domain *d); -extern void domain_crash(void); extern void domain_shutdown(u8 reason); +/* + * Mark current domain as crashed. This function returns: the domain is not + * synchronously descheduled from any processor. + */ +extern void domain_crash(void); + +/* + * Mark current domain as crashed and synchronously deschedule from the local + * processor. This function never returns. + */ +extern void domain_crash_synchronous(void) __attribute__((noreturn)); + void new_thread(struct domain *d, unsigned long start_pc, unsigned long start_stack, @@ -207,8 +218,6 @@ void init_idle_task(void); void domain_wake(struct domain *d); void domain_sleep(struct domain *d); -void __enter_scheduler(void); - extern void switch_to(struct domain *prev, struct domain *next); From cc49e1c47b26664aa56eafc0ce2eded78ea479ab Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 28 Mar 2005 17:51:38 +0000 Subject: [PATCH 182/199] bitkeeper revision 1.1159.258.72 (4248442au44vPuBRKPCu7xAuIZfS3Q) Upgrade MTRR support to that from Linux 2.6.11. Signed-off-by: Keir Fraser --- xen/arch/x86/mtrr/generic.c | 22 +++++++++++++++++----- xen/arch/x86/mtrr/main.c | 24 +++++++++--------------- xen/arch/x86/smpboot.c | 11 ----------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/xen/arch/x86/mtrr/generic.c b/xen/arch/x86/mtrr/generic.c index 8da0c5b43c..56c59107a1 100644 --- a/xen/arch/x86/mtrr/generic.c +++ b/xen/arch/x86/mtrr/generic.c @@ -8,7 +8,6 @@ #include #include #include -//#include #include "mtrr.h" struct mtrr_state { @@ -232,6 +231,13 @@ static unsigned long cr4 = 0; static u32 deftype_lo, deftype_hi; static spinlock_t set_atomicity_lock = SPIN_LOCK_UNLOCKED; +/* + * Since we are disabling the cache don't allow any interrupts - they + * would run extremely slow and would only increase the pain. The caller must + * ensure that local interrupts are disabled and are reenabled after post_set() + * has been called. + */ + static void prepare_set(void) { unsigned long cr0; @@ -239,18 +245,18 @@ static void prepare_set(void) /* Note that this is not ideal, since the cache is only flushed/disabled for this CPU while the MTRRs are changed, but changing this requires more invasive changes to the way the kernel boots */ + spin_lock(&set_atomicity_lock); /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ cr0 = read_cr0() | 0x40000000; /* set CD flag */ - wbinvd(); write_cr0(cr0); wbinvd(); /* Save value of CR4 and clear Page Global Enable (bit 7) */ if ( cpu_has_pge ) { cr4 = read_cr4(); - write_cr4(cr4 & (unsigned char) ~(1 << 7)); + write_cr4(cr4 & ~X86_CR4_PGE); } /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ @@ -265,8 +271,7 @@ static void prepare_set(void) static void post_set(void) { - /* Flush caches and TLBs */ - wbinvd(); + /* Flush TLBs (no need to flush caches - they are disabled) */ __flush_tlb(); /* Intel (P6) standard MTRRs */ @@ -284,13 +289,16 @@ static void post_set(void) static void generic_set_all(void) { unsigned long mask, count; + unsigned long flags; + local_irq_save(flags); prepare_set(); /* Actually set the state */ mask = set_mtrr_state(deftype_lo,deftype_hi); post_set(); + local_irq_restore(flags); /* Use the atomic bitops to update the global mask */ for (count = 0; count < sizeof mask * 8; ++count) { @@ -313,6 +321,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, [RETURNS] Nothing. */ { + unsigned long flags; + + local_irq_save(flags); prepare_set(); if (size == 0) { @@ -327,6 +338,7 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, } post_set(); + local_irq_restore(flags); } int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type) diff --git a/xen/arch/x86/mtrr/main.c b/xen/arch/x86/mtrr/main.c index bd1ae5d054..b0f7396f6b 100644 --- a/xen/arch/x86/mtrr/main.c +++ b/xen/arch/x86/mtrr/main.c @@ -167,10 +167,8 @@ static void ipi_handler(void *info) local_irq_save(flags); atomic_dec(&data->count); - while(!atomic_read(&data->gate)) { + while(!atomic_read(&data->gate)) cpu_relax(); - barrier(); - } /* The master has cleared me to execute */ if (data->smp_reg != ~0U) @@ -180,10 +178,9 @@ static void ipi_handler(void *info) mtrr_if->set_all(); atomic_dec(&data->count); - while(atomic_read(&data->gate)) { + while(atomic_read(&data->gate)) cpu_relax(); - barrier(); - } + atomic_dec(&data->count); local_irq_restore(flags); } @@ -248,10 +245,9 @@ static void set_mtrr(unsigned int reg, unsigned long base, local_irq_save(flags); - while(atomic_read(&data.count)) { + while(atomic_read(&data.count)) cpu_relax(); - barrier(); - } + /* ok, reset count and toggle gate */ atomic_set(&data.count, num_booting_cpus() - 1); atomic_set(&data.gate,1); @@ -268,10 +264,9 @@ static void set_mtrr(unsigned int reg, unsigned long base, mtrr_if->set(reg,base,size,type); /* wait for the others */ - while(atomic_read(&data.count)) { + while(atomic_read(&data.count)) cpu_relax(); - barrier(); - } + atomic_set(&data.count, num_booting_cpus() - 1); atomic_set(&data.gate,0); @@ -279,10 +274,9 @@ static void set_mtrr(unsigned int reg, unsigned long base, * Wait here for everyone to have seen the gate change * So we're the last ones to touch 'data' */ - while(atomic_read(&data.count)) { + while(atomic_read(&data.count)) cpu_relax(); - barrier(); - } + local_irq_restore(flags); } diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 991b5c577a..f5aacca063 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -351,13 +351,6 @@ void __init smp_callin(void) __sti(); -#ifdef CONFIG_MTRR - /* - * Must be done before calibration delay is computed - */ - mtrr_init_secondary_cpu (); -#endif - Dprintk("Stack at about %p\n",&cpuid); /* @@ -771,10 +764,6 @@ void __init smp_boot_cpus(void) { int apicid, bit; -#ifdef CONFIG_MTRR - /* Must be done before other processors booted */ - mtrr_init_boot_cpu (); -#endif /* Initialize the logical to physical CPU number mapping */ init_cpu_to_apicid(); From 0d3c526e866e6160f4bc5a9b8e75c85ead8719ce Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 28 Mar 2005 21:15:47 +0000 Subject: [PATCH 183/199] bitkeeper revision 1.1159.258.73 (424874035MwIUi8jFNCdaLfnJCrWig) Fix cpu_relax/rep_nop to include a compiler barrier. This is needed for SMP booting with gcc 4.0, for example. Signed-off-by: Keir Fraser --- xen/arch/x86/memory.c | 5 +---- xen/arch/x86/setup.c | 3 --- xen/arch/x86/smp.c | 10 ++-------- xen/arch/x86/smpboot.c | 2 +- xen/common/schedule.c | 3 --- xen/include/asm-x86/processor.h | 4 ++-- 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 4c91d7374b..e82f5aa8c8 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -904,10 +904,7 @@ int get_page_type(struct pfn_info *page, u32 type) { /* Someone else is updating validation of this page. Wait... */ while ( (y = page->u.inuse.type_info) == x ) - { - rep_nop(); - barrier(); - } + cpu_relax(); goto again; } } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 6ef530c4e6..1de2e2d71d 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -452,10 +452,7 @@ static void __init start_of_day(void) smp_threads_ready = 1; smp_commence(); /* Tell other CPUs that state of the world is stable. */ while ( wait_init_idle != 0 ) - { cpu_relax(); - barrier(); - } #endif watchdog_on = 1; diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c index 65b126c1e9..120acaef00 100644 --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -239,10 +239,7 @@ void flush_tlb_mask(unsigned long mask) flush_cpumask = mask; send_IPI_mask(mask, INVALIDATE_TLB_VECTOR); while ( flush_cpumask != 0 ) - { - rep_nop(); - barrier(); - } + cpu_relax(); spin_unlock(&flush_lock); } @@ -260,10 +257,7 @@ void new_tlbflush_clock_period(void) flush_cpumask = ((1 << smp_num_cpus) - 1) & ~(1 << smp_processor_id()); send_IPI_allbutself(INVALIDATE_TLB_VECTOR); while ( flush_cpumask != 0 ) - { - rep_nop(); - barrier(); - } + cpu_relax(); spin_unlock(&flush_lock); } diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index f5aacca063..e3e152bb49 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -396,7 +396,7 @@ void __init start_secondary(void) smp_callin(); while (!atomic_read(&smp_commenced)) - rep_nop(); + cpu_relax(); /* * At this point, boot CPU has fully initialised the IDT. It is diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 9756b18512..0470f9ee17 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -166,10 +166,7 @@ void domain_sleep(struct domain *d) /* Synchronous. */ while ( test_bit(DF_RUNNING, &d->flags) && !domain_runnable(d) ) - { - smp_mb(); cpu_relax(); - } } void domain_wake(struct domain *d) diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index e3446aaeae..00b3259f98 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -571,10 +571,10 @@ struct extended_sigtable { /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ static inline void rep_nop(void) { - __asm__ __volatile__("rep;nop"); + __asm__ __volatile__ ( "rep;nop" : : : "memory" ); } -#define cpu_relax() rep_nop() +#define cpu_relax() rep_nop() /* Prefetch instructions for Pentium III and AMD Athlon */ #ifdef CONFIG_MPENTIUMIII From 5daacba8059a5f77d126b900abda24048229b8a5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 28 Mar 2005 21:45:46 +0000 Subject: [PATCH 184/199] bitkeeper revision 1.1159.258.74 (42487b0a9j3H5ye852jyPD3Lg6GPaw) Add a tags target to the Xen Makefile. Signed-off-by: Rik van Riel Signed-off-by: Keir Fraser --- BitKeeper/etc/ignore | 2 ++ xen/Makefile | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore index 0b96e34b39..f772e7094f 100644 --- a/BitKeeper/etc/ignore +++ b/BitKeeper/etc/ignore @@ -70,6 +70,8 @@ tools/vnetd/vnetd tools/web-shutdown.tap tools/xentrace/xentrace tools/xfrd/xfrd +xen/tags +xen/TAGS xen/arch/x86/asm-offsets.s xen/arch/x86/boot/mkelf32 xen/drivers/pci/classlist.h diff --git a/xen/Makefile b/xen/Makefile index 0455b26807..b36ed9a43e 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -103,7 +103,7 @@ include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s echo ""; \ echo "#endif") <$< >$@ -.PHONY: default debug install dist clean delete-unfresh-files TAGS +.PHONY: default debug install dist clean delete-unfresh-files TAGS tags SUBDIRS = arch/$(TARGET_ARCH) common drivers TAGS: @@ -111,5 +111,10 @@ TAGS: find include -type d \( -name "asm-*" -o -name config \) -prune -o \ -name '*.h' -print; \ find $(SUBDIRS) -name '*.[ch]' ) | grep -v /SCCS/ | etags - +tags: + ( find include/asm-$(TARGET_ARCH) -name '*.h'; \ + find include -type d \( -name "asm-*" -o -name config \) -prune -o \ + -name '*.h' -print; \ + find $(SUBDIRS) -name '*.[chS]' ) | grep -v /SCCS/ | xargs ctags MAP: nm $(TARGET) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map From ec90dc4bb93baaa44c7b0f92a425a8d586d8b2ab Mon Sep 17 00:00:00 2001 From: "mwilli2@equilibrium.research" Date: Tue, 29 Mar 2005 00:57:29 +0000 Subject: [PATCH 185/199] bitkeeper revision 1.1159.276.1 (4248a7f9-4Jb7VaVyStfIWsk_XitsQ) Make sysrq work. Signed-off-by: --- linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c | 2 +- tools/python/xen/lowlevel/xu/xu.c | 3 +++ xen/include/public/io/domain_controller.h | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c index 07aae9d0c6..d732070fe4 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c @@ -242,7 +242,7 @@ static void shutdown_handler(ctrl_msg_t *msg, unsigned long id) else if ( (pending_sysrq == -1) && (msg->subtype == CMSG_SHUTDOWN_SYSRQ) ) { - pending_sysrq = msg->msg[0]; + pending_sysrq = ((shutdown_sysrq_t *)&msg->msg[0])->key; schedule_work(&sysrq_work); } else diff --git a/tools/python/xen/lowlevel/xu/xu.c b/tools/python/xen/lowlevel/xu/xu.c index 2c3ee6b33f..79c18795c9 100644 --- a/tools/python/xen/lowlevel/xu/xu.c +++ b/tools/python/xen/lowlevel/xu/xu.c @@ -671,6 +671,9 @@ static PyObject *xu_message_new(PyObject *self, PyObject *args) P2C(mem_request_t, target, u32); P2C(mem_request_t, status, u32); break; + case TYPE(CMSG_SHUTDOWN, CMSG_SHUTDOWN_SYSRQ): + P2C(shutdown_sysrq_t, key, char); + break; } if ( dict_items_parsed != PyDict_Size(payload) ) diff --git a/xen/include/public/io/domain_controller.h b/xen/include/public/io/domain_controller.h index c3494e34ca..58652a530e 100644 --- a/xen/include/public/io/domain_controller.h +++ b/xen/include/public/io/domain_controller.h @@ -545,6 +545,10 @@ typedef struct { /* SHUTDOWN_suspend. */ #define CMSG_SHUTDOWN_SYSRQ 3 +typedef struct { + char key; /* 0: sysrq key */ + char __pad[3]; /* 1: */ +} PACKED shutdown_sysrq_t; /* 4 bytes */ /****************************************************************************** * MEMORY CONTROLS From 2dc5f21f49c2bbb19823b228ba00a599d6976cc5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 29 Mar 2005 08:05:47 +0000 Subject: [PATCH 186/199] bitkeeper revision 1.1159.258.76 (42490c5b3SVISdc-fROkhmb0BdgCvA) Use fwrite() to write variable string in xfrd, to make it 64-bit safe. Signed-off-by: Jerone Young Signed-off-by: Keir Fraser --- tools/xfrd/xen_domain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/xfrd/xen_domain.c b/tools/xfrd/xen_domain.c index 64567900b4..8b666777a7 100644 --- a/tools/xfrd/xen_domain.c +++ b/tools/xfrd/xen_domain.c @@ -177,7 +177,9 @@ static CURL *curlinit(void){ /** Curl debug function. */ int curldebug(CURL *curl, curl_infotype ty, char *buf, size_t buf_n, void *data){ - printf("%*s\n", buf_n, buf); + // printf("%*s\n", buf_n, buf); /* Does not compile correctly on non 32bit platforms */ + fwrite(data, buf_n, 1, stdout); + printf("\n"); return 0; } From da70133553b1f3d128c8524eb7de8f1b3c37feaa Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 30 Mar 2005 09:59:54 +0000 Subject: [PATCH 187/199] bitkeeper revision 1.1159.258.77 (424a789awnI9QtGxkwnLulWuRuSRxA) Rationalise blkdev settings in frontend drivers. Signed-off-by: Keir Fraser --- .../arch/xen/drivers/blkif/frontend/vbd.c | 15 ++++------ .../drivers/xen/blkfront/block.h | 2 -- .../drivers/xen/blkfront/vbd.c | 30 +++++-------------- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c index 81a873e4e0..d3f43f9426 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c +++ b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c @@ -169,14 +169,14 @@ static int xlvbd_init_device(vdisk_t *xd) blksize_size[major] = xlide_blksize_size; hardsect_size[major] = xlide_hardsect_size; max_sectors[major] = xlide_max_sectors; - read_ahead[major] = 8; /* from drivers/ide/ide-probe.c */ + read_ahead[major] = 8; } else if ( is_scsi ) { blksize_size[major] = xlscsi_blksize_size; hardsect_size[major] = xlscsi_hardsect_size; max_sectors[major] = xlscsi_max_sectors; - read_ahead[major] = 0; /* XXX 8; -- guessing */ + read_ahead[major] = 8; } else { @@ -529,20 +529,17 @@ int xlvbd_init(void) /* Initialize the global arrays. */ for ( i = 0; i < 256; i++ ) { - /* from the generic ide code (drivers/ide/ide-probe.c, etc) */ xlide_blksize_size[i] = 1024; xlide_hardsect_size[i] = 512; - xlide_max_sectors[i] = 128; /* 'hwif->rqsize' if we knew it */ + xlide_max_sectors[i] = 512; - /* from the generic scsi disk code (drivers/scsi/sd.c) */ - xlscsi_blksize_size[i] = 1024; /* XXX 512; */ + xlscsi_blksize_size[i] = 1024; xlscsi_hardsect_size[i] = 512; - xlscsi_max_sectors[i] = 128*8; /* XXX 128; */ + xlscsi_max_sectors[i] = 512; - /* we don't really know what to set these too since it depends */ xlvbd_blksize_size[i] = 512; xlvbd_hardsect_size[i] = 512; - xlvbd_max_sectors[i] = 128; + xlvbd_max_sectors[i] = 512; } vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h index 9d9bb03db6..b7fff75956 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/block.h @@ -66,8 +66,6 @@ struct xlbd_type_info { int partn_shift; int partn_per_major; int devs_per_major; - int hardsect_size; - int max_sectors; char *devname; char *diskname; }; diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c index 8dce5bd8ce..d7b6aa6aa1 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c @@ -33,9 +33,9 @@ #include /* - * For convenience we distinguish between ide, scsi and 'other' (i.e. - * potentially combinations of the two) in the naming scheme and in a few - * other places (like default readahead, etc). + * For convenience we distinguish between ide, scsi and 'other' (i.e., + * potentially combinations of the two) in the naming scheme and in a few other + * places. */ #define NUM_IDE_MAJORS 10 @@ -45,10 +45,6 @@ static struct xlbd_type_info xlbd_ide_type = { .partn_shift = 6, .partn_per_major = 2, - // XXXcl todo blksize_size[major] = 1024; - .hardsect_size = 512, - .max_sectors = 128, /* 'hwif->rqsize' if we knew it */ - // XXXcl todo read_ahead[major] = 8; /* from drivers/ide/ide-probe.c */ .devname = "ide", .diskname = "hd", }; @@ -56,10 +52,6 @@ static struct xlbd_type_info xlbd_ide_type = { static struct xlbd_type_info xlbd_scsi_type = { .partn_shift = 4, .partn_per_major = 16, - // XXXcl todo blksize_size[major] = 1024; /* XXX 512; */ - .hardsect_size = 512, - .max_sectors = 128*8, /* XXX 128; */ - // XXXcl todo read_ahead[major] = 0; /* XXX 8; -- guessing */ .devname = "sd", .diskname = "sd", }; @@ -67,10 +59,6 @@ static struct xlbd_type_info xlbd_scsi_type = { static struct xlbd_type_info xlbd_vbd_type = { .partn_shift = 4, .partn_per_major = 16, - // XXXcl todo blksize_size[major] = 512; - .hardsect_size = 512, - .max_sectors = 128, - // XXXcl todo read_ahead[major] = 8; .devname = "xvd", .diskname = "xvd", }; @@ -245,17 +233,13 @@ static struct gendisk *xlvbd_get_gendisk(struct xlbd_major_info *mi, elevator_init(xlbd_blk_queue, "noop"); /* - * Turn off barking 'headactive' mode. We dequeue - * buffer heads as soon as we pass them to back-end - * driver. + * Turn off barking 'headactive' mode. We dequeue buffer heads as soon + * as we pass them to back-end driver. */ blk_queue_headactive(xlbd_blk_queue, 0); - /* Hard sector size and max sectors impersonate the equiv. hardware. */ - blk_queue_hardsect_size( - xlbd_blk_queue, mi->type->hardsect_size); - blk_queue_max_sectors( - xlbd_blk_queue, mi->type->max_sectors); + blk_queue_hardsect_size(xlbd_blk_queue, 512); + blk_queue_max_sectors(xlbd_blk_queue, 512); /* Each segment in a request is up to an aligned page in size. */ blk_queue_segment_boundary(xlbd_blk_queue, PAGE_SIZE - 1); From 2af6d121f022c88cc659c5c6ffeaa062ebaa8c4b Mon Sep 17 00:00:00 2001 From: "jrb44@plym.cl.cam.ac.uk" Date: Wed, 30 Mar 2005 14:08:05 +0000 Subject: [PATCH 188/199] bitkeeper revision 1.1159.258.78 (424ab2c5j7eJJls3kgj8UgYPektTwQ) Updated mailing lists details in documentation. Signed-off-by: James Bulpin --- BitKeeper/etc/logging_ok | 1 + docs/src/interface.tex | 20 +++++++++++--------- docs/src/user.tex | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index e671b4583f..dd518ad6c9 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -25,6 +25,7 @@ iap10@nidd.cl.cam.ac.uk iap10@pb007.cl.cam.ac.uk iap10@striker.cl.cam.ac.uk iap10@tetris.cl.cam.ac.uk +jrb44@plym.cl.cam.ac.uk jws22@gauntlet.cl.cam.ac.uk jws@cairnwell.research kaf24@camelot.eng.3leafnetworks.com diff --git a/docs/src/interface.tex b/docs/src/interface.tex index c018ad37ba..f9e3efc907 100644 --- a/docs/src/interface.tex +++ b/docs/src/interface.tex @@ -601,22 +601,24 @@ documentation. \section{Mailing lists} -There are currently three official Xen mailing lists: +There are currently four official Xen mailing lists: \begin{description} -\item[xen-devel@lists.sourceforge.net] Used for development +\item[xen-devel@lists.xensource.com] Used for development +discussions and bug reports. Subscribe at: \\ +{\small {\tt http://lists.xensource.com/xen-devel}} +\item[xen-users@lists.xensource.com] Used for installation and usage discussions and requests for help. Subscribe at: \\ -{\small {\tt http://lists.sourceforge.net/mailman/listinfo/xen-devel}} -\item[xen-announce@lists.sourceforge.net] Used for announcements only. +{\small {\tt http://lists.xensource.com/xen-users}} +\item[xen-announce@lists.xensource.com] Used for announcements only. Subscribe at: \\ -{\small {\tt http://lists.sourceforge.net/mailman/listinfo/xen-announce}} -\item[xen-changelog@lists.sourceforge.net] Changelog feed +{\small {\tt http://lists.xensource.com/xen-announce}} +\item[xen-changelog@lists.xensource.com] Changelog feed from the unstable and 2.0 trees - developer oriented. Subscribe at: \\ -{\small {\tt http://lists.sourceforge.net/mailman/listinfo/xen-changelog}} +{\small {\tt http://lists.xensource.com/xen-changelog}} \end{description} -Of these, xen-devel is the most active; it is currently used for -both developer and user-related discussions. +Of these, xen-devel is the most active. diff --git a/docs/src/user.tex b/docs/src/user.tex index 0e2c040ed6..0f758954d7 100644 --- a/docs/src/user.tex +++ b/docs/src/user.tex @@ -1850,23 +1850,23 @@ documentation (including the lateset version of the FAQ). \section{Mailing Lists} -There are currently three official Xen mailing lists: +There are currently four official Xen mailing lists: \begin{description} -\item[xen-devel@lists.sourceforge.net] Used for development +\item[xen-devel@lists.xensource.com] Used for development +discussions and bug reports. Subscribe at: \\ +{\small {\tt http://lists.xensource.com/xen-devel}} +\item[xen-users@lists.xensource.com] Used for installation and usage discussions and requests for help. Subscribe at: \\ -\path{http://lists.sourceforge.net/mailman/listinfo/xen-devel} -\item[xen-announce@lists.sourceforge.net] Used for announcements only. +{\small {\tt http://lists.xensource.com/xen-users}} +\item[xen-announce@lists.xensource.com] Used for announcements only. Subscribe at: \\ -\path{http://lists.sourceforge.net/mailman/listinfo/xen-announce} -\item[xen-changelog@lists.sourceforge.net] Changelog feed +{\small {\tt http://lists.xensource.com/xen-announce}} +\item[xen-changelog@lists.xensource.com] Changelog feed from the unstable and 2.0 trees - developer oriented. Subscribe at: \\ -\path{http://lists.sourceforge.net/mailman/listinfo/xen-changelog} +{\small {\tt http://lists.xensource.com/xen-changelog}} \end{description} -Although there is no specific user support list, the developers try to -assist users who post on xen-devel. As the bulk of traffic on this -list increases, a dedicated user support list may be introduced. \appendix From 34d67da366bf14b8b3996c60a542da6ebc42c8c0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 07:53:30 +0000 Subject: [PATCH 189/199] bitkeeper revision 1.1159.277.1 (424bac7axeGTzSf5qEZA1c6OXWqlIg) Remove unused extern decl. of page_scrub_lock. Signed-off-by: Keir Fraser --- xen/include/xen/mm.h | 1 - 1 file changed, 1 deletion(-) diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 33ce8ac603..807987045f 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -39,7 +39,6 @@ unsigned long avail_domheap_pages(void); #define free_domheap_page(_p) (free_domheap_pages(_p,0)) /* Automatic page scrubbing for dead domains. */ -extern spinlock_t page_scrub_lock; extern struct list_head page_scrub_list; #define page_scrub_schedule_work() \ do { \ From cb666ced1a8d9b0e3e1c18ffeb82e37a6b949b16 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 08:04:01 +0000 Subject: [PATCH 190/199] bitkeeper revision 1.1159.258.80 (424baef1fEkcfSfQH4BQ1MHHtsEiYQ) Fix memset arg ordering. --- tools/libxutil/sys_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxutil/sys_net.c b/tools/libxutil/sys_net.c index 94da58d63e..41436019b5 100644 --- a/tools/libxutil/sys_net.c +++ b/tools/libxutil/sys_net.c @@ -310,7 +310,7 @@ char *mac_ntoa(const unsigned char *mac){ static char buf[MAC_LENGTH + 1]; int buf_n = sizeof(buf); - memset(buf, buf_n, 0); + memset(buf, 0, buf_n); snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); From 8d4adc5120b277c11aff999beb6d2b2c0d8a5862 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 08:52:16 +0000 Subject: [PATCH 191/199] bitkeeper revision 1.1159.258.81 (424bba4091aV1FuNksY_4w_z4Tvr3g) Backport of Jens blkdev performance patch. I accidentally applied it first to unstable. --- .../drivers/xen/blkback/blkback.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c index 6d201022d2..1f117e21dd 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c @@ -481,7 +481,6 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) for ( i = 0; i < nr_psegs; i++ ) { struct bio *bio; - struct bio_vec *bv; bio = bio_alloc(GFP_ATOMIC, 1); if ( unlikely(bio == NULL) ) @@ -494,17 +493,14 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) bio->bi_private = pending_req; bio->bi_end_io = end_block_io_op; bio->bi_sector = phys_seg[i].sector_number; - bio->bi_rw = operation; - bv = bio_iovec_idx(bio, 0); - bv->bv_page = virt_to_page(MMAP_VADDR(pending_idx, i)); - bv->bv_len = phys_seg[i].nr_sects << 9; - bv->bv_offset = phys_seg[i].buffer & ~PAGE_MASK; + bio_add_page( + bio, + virt_to_page(MMAP_VADDR(pending_idx, i)), + phys_seg[i].nr_sects << 9, + phys_seg[i].buffer & ~PAGE_MASK); - bio->bi_size = bv->bv_len; - bio->bi_vcnt++; - - submit_bio(operation, bio); + submit_bio(operation | (1 << BIO_RW_SYNC), bio); } #endif From ba77d5acc9b67b0ca90e91d35603e8a902610db4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 09:55:59 +0000 Subject: [PATCH 192/199] bitkeeper revision 1.1159.258.82 (424bc92fEcWwZjH-px6jvpApRHiBmQ) fix the broken xen build --- xen/common/page_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 8637b8cea5..b143eba8bc 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -41,6 +41,9 @@ string_param("badpage", opt_badpage); #define round_pgdown(_p) ((_p)&PAGE_MASK) #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) +static spinlock_t page_scrub_lock; +struct list_head page_scrub_list; + /********************* * ALLOCATION BITMAP * One bit per page of memory. Bit set => page is allocated. @@ -628,9 +631,6 @@ unsigned long avail_domheap_pages(void) * PAGE SCRUBBING */ -static spinlock_t page_scrub_lock; -struct list_head page_scrub_list; - static void page_scrub_softirq(void) { struct list_head *ent; From a2628ee068073f93f8965b17f00e3c77b5647587 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 15:43:57 +0000 Subject: [PATCH 193/199] bitkeeper revision 1.1159.258.83 (424c1abd7LgWMiaskLEEAAX7ffdkXQ) Backport of batched request_queue unplugging in blkback driver. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 31 +++++++++++++++++-- .../drivers/xen/blkback/common.h | 2 ++ .../drivers/xen/blkback/vbd.c | 8 ++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c index 1f117e21dd..9fb789216c 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c @@ -66,6 +66,19 @@ static PEND_RING_IDX pending_prod, pending_cons; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) static kmem_cache_t *buffer_head_cachep; +#else +static request_queue_t *plugged_queue; +void bdev_put(struct block_device *bdev) +{ + request_queue_t *q = plugged_queue; + /* We might be giving up last reference to plugged queue. Flush if so. */ + if ( (q != NULL) && + (q == bdev_get_queue(bdev)) && + (cmpxchg(&plugged_queue, q, NULL) == q) ) + blk_run_queue(q); + /* It's now safe to drop the block device. */ + blkdev_put(bdev); +} #endif static int do_block_io_op(blkif_t *blkif, int max_to_do); @@ -176,9 +189,15 @@ static int blkio_schedule(void *arg) blkif_put(blkif); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) /* Push the batch through to disc. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) run_task_queue(&tq_disk); +#else + if ( plugged_queue != NULL ) + { + blk_run_queue(plugged_queue); + plugged_queue = NULL; + } #endif } } @@ -481,6 +500,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) for ( i = 0; i < nr_psegs; i++ ) { struct bio *bio; + request_queue_t *q; bio = bio_alloc(GFP_ATOMIC, 1); if ( unlikely(bio == NULL) ) @@ -500,7 +520,14 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) phys_seg[i].nr_sects << 9, phys_seg[i].buffer & ~PAGE_MASK); - submit_bio(operation | (1 << BIO_RW_SYNC), bio); + if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue ) + { + if ( plugged_queue != NULL ) + blk_run_queue(plugged_queue); + plugged_queue = q; + } + + submit_bio(operation, bio); } #endif diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h index 4a12ca8fe9..8f8a521702 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h @@ -30,8 +30,10 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) typedef struct rb_root rb_root_t; typedef struct rb_node rb_node_t; +extern void bdev_put(struct block_device *bdev); #else struct block_device; +#define bdev_put(_b) ((void)0) #endif typedef struct blkif_st { diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c index 1aa5acf0c9..639b8fc5d5 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c @@ -150,7 +150,7 @@ void vbd_grow(blkif_be_vbd_grow_t *grow) { DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device); grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND; - blkdev_put(x->bdev); + bdev_put(x->bdev); goto out; } @@ -255,7 +255,7 @@ void vbd_shrink(blkif_be_vbd_shrink_t *shrink) *px = x->next; /* ATOMIC: no need for vbd_lock. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - blkdev_put(x->bdev); + bdev_put(x->bdev); #endif kfree(x); @@ -307,7 +307,7 @@ void vbd_destroy(blkif_be_vbd_destroy_t *destroy) { t = x->next; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - blkdev_put(x->bdev); + bdev_put(x->bdev); #endif kfree(x); x = t; @@ -335,7 +335,7 @@ void destroy_all_vbds(blkif_t *blkif) { t = x->next; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - blkdev_put(x->bdev); + bdev_put(x->bdev); #endif kfree(x); x = t; From b4d3bc3dbbdf4c4a81b4bf16cf080404d20333b9 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 21:22:05 +0000 Subject: [PATCH 194/199] bitkeeper revision 1.1159.278.1 (424c69fdsFkm7FZ7SYMwK1Y6v6p1Og) Make default CPU placement of domains a bit smarter on systems with hyperthreading: only dom0 gets to use hyperthreading by default, we effectively ignore it on all other CPUs by allocating domains to the same hyperthread. If you don't like this, use 'xm pincpu' to change it. [note: we probably need to make pincpu more expressive, providing a list of CPUs that the domain can be scheduled on.] Signed-off-by: ian@xensource.com --- xen/common/dom0_ops.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index e5b9f1d1e7..3af35e39e0 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -161,7 +161,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_CREATEDOMAIN: { struct domain *d; - unsigned int pro = 0; + unsigned int pro; domid_t dom; dom = op->u.createdomain.domain; @@ -178,16 +178,22 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { /* Do an initial placement. Pick the least-populated CPU. */ struct domain *d; - unsigned int i, cnt[NR_CPUS] = { 0 }; + unsigned int i, ht, cnt[NR_CPUS] = { 0 }; read_lock(&domlist_lock); for_each_domain ( d ) cnt[d->processor]++; read_unlock(&domlist_lock); - for ( i = 0; i < smp_num_cpus; i++ ) - if ( cnt[i] < cnt[pro] ) - pro = i; + /* If we're on a HT system, we only use the first HT for dom0, + other domains will all share the second HT of each CPU. + Since dom0 is on CPU 0, we favour high numbered CPUs in + the event of a tie */ + ht = opt_noht ? 1 : ht_per_core; + pro = ht-1; + for ( i = pro; i < smp_num_cpus; i += ht ) + if ( cnt[i] <= cnt[pro] ) + pro = i; } else pro = op->u.createdomain.cpu % smp_num_cpus; From 6120ae1e358a0c5e63b7e3ee72c2257a29adf733 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 31 Mar 2005 21:51:48 +0000 Subject: [PATCH 195/199] bitkeeper revision 1.1159.279.1 (424c70f4QCqyymdEdrsWpGJWoWos9A) Fix queue unplugging in blkback driver. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 16 +++++----------- .../drivers/xen/blkback/common.h | 2 -- .../drivers/xen/blkback/vbd.c | 3 +++ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c index 9fb789216c..be250a4bf3 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c @@ -68,16 +68,10 @@ static PEND_RING_IDX pending_prod, pending_cons; static kmem_cache_t *buffer_head_cachep; #else static request_queue_t *plugged_queue; -void bdev_put(struct block_device *bdev) +static inline void bdev_flush_queue(request_queue_t *q) { - request_queue_t *q = plugged_queue; - /* We might be giving up last reference to plugged queue. Flush if so. */ - if ( (q != NULL) && - (q == bdev_get_queue(bdev)) && - (cmpxchg(&plugged_queue, q, NULL) == q) ) - blk_run_queue(q); - /* It's now safe to drop the block device. */ - blkdev_put(bdev); + if ( q->unplug_fn != NULL ) + q->unplug_fn(q); } #endif @@ -195,7 +189,7 @@ static int blkio_schedule(void *arg) #else if ( plugged_queue != NULL ) { - blk_run_queue(plugged_queue); + bdev_flush_queue(plugged_queue); plugged_queue = NULL; } #endif @@ -523,7 +517,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue ) { if ( plugged_queue != NULL ) - blk_run_queue(plugged_queue); + bdev_flush_queue(plugged_queue); plugged_queue = q; } diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h index 8f8a521702..4a12ca8fe9 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/common.h @@ -30,10 +30,8 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) typedef struct rb_root rb_root_t; typedef struct rb_node rb_node_t; -extern void bdev_put(struct block_device *bdev); #else struct block_device; -#define bdev_put(_b) ((void)0) #endif typedef struct blkif_st { diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c index 639b8fc5d5..90d194680b 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/vbd.c @@ -14,6 +14,9 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static dev_t vbd_map_devnum(blkif_pdev_t); +#define bdev_put(_b) blkdev_put(_b) +#else +#define bdev_put(_b) ((void)0) #endif void vbd_create(blkif_be_vbd_create_t *create) From 0dbd0848995e81208a08cb18e1c636081c5ab90f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 1 Apr 2005 07:59:40 +0000 Subject: [PATCH 196/199] bitkeeper revision 1.1159.258.86 (424cff6c82IPl2w_FuJj_0tdGUdFiw) Correctly account for our reference to plugged_queue in blkback. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c index be250a4bf3..375377b138 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkback/blkback.c @@ -68,10 +68,16 @@ static PEND_RING_IDX pending_prod, pending_cons; static kmem_cache_t *buffer_head_cachep; #else static request_queue_t *plugged_queue; -static inline void bdev_flush_queue(request_queue_t *q) +static inline void flush_plugged_queue(void) { - if ( q->unplug_fn != NULL ) - q->unplug_fn(q); + request_queue_t *q = plugged_queue; + if ( q != NULL ) + { + if ( q->unplug_fn != NULL ) + q->unplug_fn(q); + blk_put_queue(q); + plugged_queue = NULL; + } } #endif @@ -187,11 +193,7 @@ static int blkio_schedule(void *arg) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) run_task_queue(&tq_disk); #else - if ( plugged_queue != NULL ) - { - bdev_flush_queue(plugged_queue); - plugged_queue = NULL; - } + flush_plugged_queue(); #endif } } @@ -516,8 +518,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue ) { - if ( plugged_queue != NULL ) - bdev_flush_queue(plugged_queue); + flush_plugged_queue(); + blk_get_queue(q); plugged_queue = q; } From 9ef012c70bf1fbee48c849c11ed417a366e2367c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 1 Apr 2005 17:44:25 +0000 Subject: [PATCH 197/199] bitkeeper revision 1.1159.258.87 (424d8879K9lhGxxSZd9bVE9LZZ2YDw) Fix page scrubbing when fewer than 16 pages remain in the scrub list. Signed-off-by: Keir Fraser --- xen/common/page_alloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index b143eba8bc..dc5b70c843 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -651,8 +651,11 @@ static void page_scrub_softirq(void) /* Peel up to 16 pages from the list. */ for ( i = 0; i < 16; i++ ) - if ( (ent = ent->next) == &page_scrub_list ) + { + if ( ent->next == &page_scrub_list ) break; + ent = ent->next; + } /* Remove peeled pages from the list. */ ent->next->prev = &page_scrub_list; From 859492d2216cd8fe9924018d5bc738b78603627d Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk[cl349]" Date: Sat, 2 Apr 2005 21:21:29 +0000 Subject: [PATCH 198/199] bitkeeper revision 1.1159.258.88 (424f0cd9Oldi24NGanGDdr82_K9qpQ) From: YAMAMOTO Takashi Add support to domain0 builder to load a (Net)BSD symtab for domain0. Signed-off-by: Christian Limpach --- xen/arch/x86/domain.c | 8 +++- xen/common/elf.c | 100 ++++++++++++++++++++++++++++++++++++++++ xen/include/xen/elf.h | 1 + xen/include/xen/sched.h | 5 ++ 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index d47910233a..aeb2b0c547 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -667,6 +667,9 @@ int construct_dom0(struct domain *p, if ( rc != 0 ) return rc; + if (dsi.load_bsd_symtab) + loadelfsymtab(image_start, 0, &dsi); + /* Set up domain options */ if ( dsi.use_writable_pagetables ) vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); @@ -684,7 +687,7 @@ int construct_dom0(struct domain *p, * read-only). We have a pair of simultaneous equations in two unknowns, * which we solve by exhaustive search. */ - vinitrd_start = round_pgup(dsi.v_kernend); + vinitrd_start = round_pgup(dsi.v_end); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); @@ -884,6 +887,9 @@ int construct_dom0(struct domain *p, /* Copy the OS image. */ (void)loadelfimage(image_start); + if (dsi.load_bsd_symtab) + loadelfsymtab(image_start, 1, &dsi); + /* Copy the initial ramdisk. */ if ( initrd_len != 0 ) memcpy((void *)vinitrd_start, initrd_start, initrd_len); diff --git a/xen/common/elf.c b/xen/common/elf.c index 8241d96520..7feb9095db 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -125,12 +125,18 @@ int parseelfimage(char *elfbase, if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL ) dsi->use_writable_pagetables = 1; + + if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) + dsi->load_bsd_symtab = 1; + } dsi->v_kernstart = kernstart; dsi->v_kernend = kernend; dsi->v_kernentry = ehdr->e_entry; + dsi->v_end = dsi->v_kernend; + return 0; } @@ -155,3 +161,97 @@ int loadelfimage(char *elfbase) return 0; } + +#define ELFROUND (ELFSIZE / 8) + +int loadelfsymtab(char *elfbase, int doload, struct domain_setup_info *dsi) +{ + Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr; + Elf_Shdr *shdr; + unsigned long maxva, symva; + char *p; + int h, i; + + maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1); + symva = maxva; + maxva += sizeof(int); + dsi->symtab_addr = maxva; + dsi->symtab_len = 0; + maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr); + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + if (doload) { + p = (void *)symva; + + shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); + memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr)); + } else { + shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff); + p = NULL; /* XXX: gcc */ + } + + for ( h = 0; h < ehdr->e_shnum; h++ ) + { + if ( shdr[h].sh_type == SHT_STRTAB ) + { + /* Look for a strtab @i linked to symtab @h. */ + for ( i = 0; i < ehdr->e_shnum; i++ ) + if ( (shdr[i].sh_type == SHT_SYMTAB) && + (shdr[i].sh_link == h) ) + break; + /* Skip symtab @h if we found no corresponding strtab @i. */ + if ( i == ehdr->e_shnum ) + { + if (doload) { + shdr[h].sh_offset = 0; + } + continue; + } + } + + if ( (shdr[h].sh_type == SHT_STRTAB) || + (shdr[h].sh_type == SHT_SYMTAB) ) + { + if (doload) { + memcpy((void *)maxva, elfbase + shdr[h].sh_offset, + shdr[h].sh_size); + + /* Mangled to be based on ELF header location. */ + shdr[h].sh_offset = maxva - dsi->symtab_addr; + + } + dsi->symtab_len += shdr[h].sh_size; + maxva += shdr[h].sh_size; + maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1); + } + + if (doload) { + shdr[h].sh_name = 0; /* Name is NULL. */ + } + } + + if ( dsi->symtab_len == 0 ) + { + dsi->symtab_addr = 0; + goto out; + } + + if (doload) { + *(int *)p = maxva - dsi->symtab_addr; + sym_ehdr = (Elf_Ehdr *)(p + sizeof(int)); + memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr)); + sym_ehdr->e_phoff = 0; + sym_ehdr->e_shoff = sizeof(Elf_Ehdr); + sym_ehdr->e_phentsize = 0; + sym_ehdr->e_phnum = 0; + sym_ehdr->e_shstrndx = SHN_UNDEF; + } + +#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) /* XXX */ + + dsi->symtab_len = maxva - dsi->symtab_addr; + dsi->v_end = round_pgup(maxva); + + out: + + return 0; +} diff --git a/xen/include/xen/elf.h b/xen/include/xen/elf.h index f63daa6fc6..3a62173b1e 100644 --- a/xen/include/xen/elf.h +++ b/xen/include/xen/elf.h @@ -526,6 +526,7 @@ typedef struct { struct domain_setup_info; extern int loadelfimage(char *); +extern int loadelfsymtab(char *, int, struct domain_setup_info *); extern int parseelfimage(char *, unsigned long, struct domain_setup_info *); #endif /* __XEN_ELF_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 8f5345375b..4b7e7080c8 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -119,11 +119,16 @@ struct domain struct domain_setup_info { unsigned long v_start; + unsigned long v_end; unsigned long v_kernstart; unsigned long v_kernend; unsigned long v_kernentry; unsigned int use_writable_pagetables; + unsigned int load_bsd_symtab; + + unsigned long symtab_addr; + unsigned long symtab_len; }; #include /* for KERNEL_DS */ From fbe22bd546a8adad1d1bcbb49ab69ed6a3fda95b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 5 Apr 2005 08:04:19 +0000 Subject: [PATCH 199/199] bitkeeper revision 1.1159.258.89 (42524683eHdxgb97Ju0emhDCWjpCDA) Reduce severity of TLS warning. Signed-off-by: Keir Fraser --- linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c index 01fe5df942..1b2aeea60d 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/fixup.c @@ -58,10 +58,8 @@ __LINKAGE void do_fixup_4gb_segment(struct pt_regs *regs, long error_code) DP("***************************************************************"); DP("** WARNING: Currently emulating unsupported memory accesses **"); DP("** in /lib/tls libraries. The emulation is very **"); - DP("** slow, and may not work correctly with all **"); - DP("** programs (e.g., some may 'Segmentation fault'). **"); - DP("** TO ENSURE FULL PERFORMANCE AND CORRECT FUNCTION, **"); - DP("** YOU MUST EXECUTE THE FOLLOWING AS ROOT: **"); + DP("** slow. To ensure full performance you should **"); + DP("** execute the following as root: **"); DP("** mv /lib/tls /lib/tls.disabled **"); DP("***************************************************************"); DP("***************************************************************");