[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merge.
# HG changeset patch # User adsharma@xxxxxxxxxxxxxxxxxxxx # Node ID 112d44270733c583e9c2506732299baceff7753a # Parent e2025593f702880de0cd6cb1958a72b5b6250d31 # Parent b4b3f6be5226adfb127bc32fd5cca27f2ed473f7 Merge. diff -r e2025593f702 -r 112d44270733 extras/mini-os/include/hypervisor.h --- a/extras/mini-os/include/hypervisor.h Wed Aug 24 23:16:52 2005 +++ b/extras/mini-os/include/hypervisor.h Thu Aug 25 18:18:47 2005 @@ -80,16 +80,42 @@ 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), - _a1 (req), _a2 (count), _a3 (success_count) : "memory" ); - - return ret; -} + int *success_count, + domid_t domid) +{ + int ret; + unsigned long ign1, ign2, ign3, ign4; + + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) + : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), + "3" (success_count), "4" (domid) + : "memory" ); + + return ret; +} + + +static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, + int count, + int *success_count, + domid_t domid) +{ + int ret; + unsigned long ign1, ign2, ign3, ign4; + + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) + : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count), + "3" (success_count), "4" (domid) + : "memory" ); + + return ret; +} + + static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) { diff -r e2025593f702 -r 112d44270733 extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Wed Aug 24 23:16:52 2005 +++ b/extras/mini-os/include/mm.h Thu Aug 25 18:18:47 2005 @@ -43,13 +43,27 @@ #define PADDR_MASK ((1UL << PADDR_BITS)-1) #define VADDR_MASK ((1UL << VADDR_BITS)-1) -#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT) +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT) + +#endif + + + +#ifdef __i386__ + +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 22 + +#define L1_PAGETABLE_ENTRIES 1024 +#define L2_PAGETABLE_ENTRIES 1024 +#endif /* Given a virtual address, get an entry offset into a page table. */ #define l1_table_offset(_a) \ (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) #define l2_table_offset(_a) \ (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +#ifdef __x86_64__ #define l3_table_offset(_a) \ (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) #define l4_table_offset(_a) \ @@ -67,13 +81,16 @@ #define _PAGE_PSE 0x080UL #define _PAGE_GLOBAL 0x100UL -#define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED) +#define L2_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_USER) + +#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT) +#define PAGE_SHIFT L1_PAGETABLE_SHIFT #define PAGE_MASK (~(PAGE_SIZE-1)) -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT) +#define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT) +#define PFN_PHYS(x) ((x) << L1_PAGETABLE_SHIFT) /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) @@ -83,14 +100,14 @@ #define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) static __inline__ unsigned long phys_to_machine(unsigned long phys) { - unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT); - machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); + unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT); + machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK); return machine; } static __inline__ unsigned long machine_to_phys(unsigned long machine) { - unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT); - phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); + unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT); + phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK); return phys; } @@ -105,7 +122,10 @@ #define __va to_virt #define __pa to_phys +#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt))) + void init_mm(void); unsigned long alloc_pages(int order); +int is_mfn_mapped(unsigned long mfn); #endif /* _MM_H_ */ diff -r e2025593f702 -r 112d44270733 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Wed Aug 24 23:16:52 2005 +++ b/extras/mini-os/kernel.c Thu Aug 25 18:18:47 2005 @@ -133,7 +133,7 @@ for ( ; ; ) { // HYPERVISOR_yield(); - block(1); + block(100); i++; } } diff -r e2025593f702 -r 112d44270733 extras/mini-os/mm.c --- a/extras/mini-os/mm.c Wed Aug 24 23:16:52 2005 +++ b/extras/mini-os/mm.c Thu Aug 25 18:18:47 2005 @@ -5,9 +5,9 @@ * * File: mm.c * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: + * Changes: Grzegorz Milos * - * Date: Aug 2003 + * Date: Aug 2003, chages Aug 2005 * * Environment: Xen Minimal OS * Description: memory management related functions @@ -41,86 +41,18 @@ #include <types.h> #include <lib.h> + +#ifdef MM_DEBUG +#define DEBUG(_f, _a...) \ + printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a) +#else +#define DEBUG(_f, _a...) ((void)0) +#endif + unsigned long *phys_to_machine_mapping; extern char *stack; extern char _text, _etext, _edata, _end; -static void init_page_allocator(unsigned long min, unsigned long max); - -void init_mm(void) -{ - - unsigned long start_pfn, max_pfn, max_free_pfn; - - unsigned long *pgd = (unsigned long *)start_info.pt_base; - - printk("MM: Init\n"); - - printk(" _text: %p\n", &_text); - printk(" _etext: %p\n", &_etext); - printk(" _edata: %p\n", &_edata); - printk(" stack start: %p\n", &stack); - printk(" _end: %p\n", &_end); - - /* set up minimal memory infos */ - start_pfn = PFN_UP(to_phys(&_end)); - max_pfn = start_info.nr_pages; - - printk(" start_pfn: %lx\n", start_pfn); - printk(" max_pfn: %lx\n", max_pfn); - - /* - * we know where free tables start (start_pfn) and how many we - * have (max_pfn). - * - * Currently the hypervisor stores page tables it providesin the - * high region of the this memory range. - * - * next we work out how far down this goes (max_free_pfn) - * - * XXX this assumes the hypervisor provided page tables to be in - * the upper region of our initial memory. I don't know if this - * is always true. - */ - - max_free_pfn = PFN_DOWN(to_phys(pgd)); -#ifdef __i386__ - { - unsigned long *pgd = (unsigned long *)start_info.pt_base; - unsigned long pte; - int i; - printk(" pgd(pa(pgd)): %lx(%lx)", (u_long)pgd, to_phys(pgd)); - - for ( i = 0; i < (HYPERVISOR_VIRT_START>>22); i++ ) - { - unsigned long pgde = *pgd++; - if ( !(pgde & 1) ) continue; - pte = machine_to_phys(pgde & PAGE_MASK); - printk(" PT(%x): %lx(%lx)", i, (u_long)to_virt(pte), pte); - if (PFN_DOWN(pte) <= max_free_pfn) - max_free_pfn = PFN_DOWN(pte); - } - } - max_free_pfn--; - printk(" max_free_pfn: %lx\n", max_free_pfn); - - /* - * now we can initialise the page allocator - */ - printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n", - (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), - (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn)); - init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn)); -#endif - - - /* Now initialise the physical->machine mapping table. */ - - - printk("MM: done\n"); - - -} /********************* * ALLOCATION BITMAP @@ -213,6 +145,59 @@ #define round_pgdown(_p) ((_p)&PAGE_MASK) #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) + +#ifdef MM_DEBUG +/* + * Prints allocation[0/1] for @nr_pages, starting at @start + * address (virtual). + */ +static void print_allocation(void *start, int nr_pages) +{ + unsigned long pfn_start = virt_to_pfn(start); + int count; + for(count = 0; count < nr_pages; count++) + if(allocated_in_map(pfn_start + count)) printk("1"); + else printk("0"); + + printk("\n"); +} + +/* + * Prints chunks (making them with letters) for @nr_pages starting + * at @start (virtual). + */ +static void print_chunks(void *start, int nr_pages) +{ + char chunks[1001], current='A'; + int order, count; + chunk_head_t *head; + unsigned long pfn_start = virt_to_pfn(start); + + memset(chunks, (int)'_', 1000); + if(nr_pages > 1000) + { + DEBUG("Can only pring 1000 pages. Increase buffer size."); + } + + for(order=0; order < FREELIST_SIZE; order++) + { + head = free_head[order]; + while(!FREELIST_EMPTY(head)) + { + for(count = 0; count < 1<< head->level; count++) + { + if(count + virt_to_pfn(head) - pfn_start < 1000) + chunks[count + virt_to_pfn(head) - pfn_start] = current; + } + head = head->next; + current++; + } + } + chunks[nr_pages] = '\0'; + printk("%s\n", chunks); +} +#endif + /* @@ -328,3 +313,198 @@ return 0; } +void free_pages(void *pointer, int order) +{ + chunk_head_t *freed_ch, *to_merge_ch; + chunk_tail_t *freed_ct; + unsigned long mask; + + /* First free the chunk */ + map_free(virt_to_pfn(pointer), 1 << order); + + /* Create free chunk */ + freed_ch = (chunk_head_t *)pointer; + freed_ct = (chunk_tail_t *)((char *)pointer + (1<<(order + PAGE_SHIFT)))-1; + + /* Now, possibly we can conseal chunks together */ + while(order < FREELIST_SIZE) + { + mask = 1 << (order + PAGE_SHIFT); + if((unsigned long)freed_ch & mask) + { + to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask); + if(allocated_in_map(virt_to_pfn(to_merge_ch)) || + to_merge_ch->level != order) + break; + + /* Merge with predecessor */ + freed_ch = to_merge_ch; + } + else + { + to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask); + if(allocated_in_map(virt_to_pfn(to_merge_ch)) || + to_merge_ch->level != order) + break; + + /* Merge with successor */ + freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask); + } + + /* We are commited to merging, unlink the chunk */ + *(to_merge_ch->pprev) = to_merge_ch->next; + to_merge_ch->next->pprev = to_merge_ch->pprev; + + order++; + } + + /* Link the new chunk */ + freed_ch->level = order; + freed_ch->next = free_head[order]; + freed_ch->pprev = &free_head[order]; + freed_ct->level = order; + + freed_ch->next->pprev = &freed_ch->next; + free_head[order] = freed_ch; + +} +void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) +{ + unsigned long pfn_to_map, pt_frame; + unsigned long mach_ptd, max_mach_ptd; + int count; + unsigned long mach_pte, virt_pte; + unsigned long *ptd = (unsigned long *)start_info.pt_base; + mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; + struct mmuext_op pin_request; + + /* Firstly work out what is the first pfn that is not yet in page tables + NB. Assuming that builder fills whole pt_frames (which it does at the + moment) + */ + pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES; + DEBUG("start_pfn=%ld, first pfn_to_map %ld, max_pfn=%ld", + *start_pfn, pfn_to_map, *max_pfn); + + /* Machine address of page table directory */ + mach_ptd = phys_to_machine(to_phys(start_info.pt_base)); + mach_ptd += sizeof(void *) * + l2_table_offset((unsigned long)to_virt(PFN_PHYS(pfn_to_map))); + + max_mach_ptd = sizeof(void *) * + l2_table_offset((unsigned long)to_virt(PFN_PHYS(*max_pfn))); + + /* Check that we are not trying to access Xen region */ + if(max_mach_ptd > sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START)) + { + printk("WARNING: mini-os will not use all the memory supplied\n"); + max_mach_ptd = sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START); + *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE); + } + max_mach_ptd += phys_to_machine(to_phys(start_info.pt_base)); + DEBUG("Max_mach_ptd 0x%lx", max_mach_ptd); + + pt_frame = *start_pfn; + /* Should not happen - no empty, mapped pages */ + if(pt_frame >= pfn_to_map) + { + printk("ERROR: Not even a single empty, mapped page\n"); + *(int*)0=0; + } + + while(mach_ptd < max_mach_ptd) + { + /* Correct protection needs to be set for the new page table frame */ + virt_pte = (unsigned long)to_virt(PFN_PHYS(pt_frame)); + mach_pte = ptd[l2_table_offset(virt_pte)] & ~(PAGE_SIZE-1); + mach_pte += sizeof(void *) * l1_table_offset(virt_pte); + DEBUG("New page table page: pfn=0x%lx, mfn=0x%lx, virt_pte=0x%lx, " + "mach_pte=0x%lx", pt_frame, pfn_to_mfn(pt_frame), + virt_pte, mach_pte); + + /* Update the entry */ + mmu_updates[0].ptr = mach_pte; + mmu_updates[0].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT | + (L1_PROT & ~_PAGE_RW); + if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) + { + printk("PTE for new page table page could not be updated\n"); + *(int*)0=0; + } + + /* Pin the page to provide correct protection */ + pin_request.cmd = MMUEXT_PIN_L1_TABLE; + pin_request.mfn = pfn_to_mfn(pt_frame); + if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0) + { + printk("ERROR: pinning failed\n"); + *(int*)0=0; + } + + /* Now fill the new page table page with entries. + Update the page directory as well. */ + count = 0; + mmu_updates[count].ptr = mach_ptd; + mmu_updates[count].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT | + L2_PROT; + count++; + mach_ptd += sizeof(void *); + mach_pte = phys_to_machine(PFN_PHYS(pt_frame++)); + + for(;count <= L1_PAGETABLE_ENTRIES && pfn_to_map <= *max_pfn; count++) + { + mmu_updates[count].ptr = mach_pte; + mmu_updates[count].val = + pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT; + if(count == 1) DEBUG("mach_pte 0x%lx", mach_pte); + mach_pte += sizeof(void *); + } + if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0) + { + printk("ERROR: mmu_update failed\n"); + *(int*)0=0; + } + (*start_pfn)++; + } + + *start_pfn = pt_frame; +} + +void init_mm(void) +{ + + unsigned long start_pfn, max_pfn; + + printk("MM: Init\n"); + + printk(" _text: %p\n", &_text); + printk(" _etext: %p\n", &_etext); + printk(" _edata: %p\n", &_edata); + printk(" stack start: %p\n", &stack); + printk(" _end: %p\n", &_end); + + /* set up minimal memory infos */ + phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; + + /* First page follows page table pages and 3 more pages (store page etc) */ + start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3; + max_pfn = start_info.nr_pages; + + printk(" start_pfn: %lx\n", start_pfn); + printk(" max_pfn: %lx\n", max_pfn); + + + build_pagetable(&start_pfn, &max_pfn); + +#ifdef __i386__ + /* + * now we can initialise the page allocator + */ + printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n", + (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), + (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn)); + init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn)); +#endif + + printk("MM: done\n"); +} diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c Thu Aug 25 18:18:47 2005 @@ -19,11 +19,13 @@ #include "cpu.h" +#ifndef CONFIG_XEN DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]); EXPORT_PER_CPU_SYMBOL(cpu_gdt_table); DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); +#endif static int cachesize_override __initdata = -1; static int disable_x86_fxsr __initdata = 0; diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c Thu Aug 25 18:18:47 2005 @@ -131,15 +131,7 @@ */ void __init smp_alloc_memory(void) { -#if 1 - int cpu; - - for (cpu = 1; cpu < NR_CPUS; cpu++) { - cpu_gdt_descr[cpu].address = (unsigned long) - alloc_bootmem_low_pages(PAGE_SIZE); - /* XXX free unused pages later */ - } -#else +#if 0 trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); /* * Has to be in very low memory so we can execute @@ -861,8 +853,8 @@ atomic_set(&init_deasserted, 0); #if 1 - if (cpu_gdt_descr[0].size > PAGE_SIZE) - BUG(); + cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL); + BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; printk("GDT: copying %d bytes from %lx to %lx\n", cpu_gdt_descr[0].size, cpu_gdt_descr[0].address, diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c Thu Aug 25 18:18:47 2005 @@ -871,6 +871,7 @@ } } +#ifndef CONFIG_XEN fastcall void setup_x86_bogus_stack(unsigned char * stk) { unsigned long *switch16_ptr, *switch32_ptr; @@ -915,6 +916,7 @@ memcpy(stack32, stack16, len); return stack32; } +#endif /* * 'math_state_restore()' saves the current math information in the diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Thu Aug 25 18:18:47 2005 @@ -34,9 +34,11 @@ EXPORT_SYMBOL(gnttab_grant_foreign_access); +EXPORT_SYMBOL(gnttab_end_foreign_access_ref); EXPORT_SYMBOL(gnttab_end_foreign_access); EXPORT_SYMBOL(gnttab_query_foreign_access); EXPORT_SYMBOL(gnttab_grant_foreign_transfer); +EXPORT_SYMBOL(gnttab_end_foreign_transfer_ref); EXPORT_SYMBOL(gnttab_end_foreign_transfer); EXPORT_SYMBOL(gnttab_alloc_grant_references); EXPORT_SYMBOL(gnttab_free_grant_references); @@ -160,7 +162,7 @@ } void -gnttab_end_foreign_access(grant_ref_t ref, int readonly) +gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) { u16 flags, nflags; @@ -170,7 +172,12 @@ printk(KERN_ALERT "WARNING: g.e. still in use!\n"); } while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags ); - +} + +void +gnttab_end_foreign_access(grant_ref_t ref, int readonly) +{ + gnttab_end_foreign_access_ref(ref, readonly); put_free_entry(ref); } @@ -201,20 +208,13 @@ } unsigned long -gnttab_end_foreign_transfer(grant_ref_t ref) +gnttab_end_foreign_transfer_ref(grant_ref_t ref) { unsigned long frame = 0; u16 flags; flags = shared[ref].flags; -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - /* - * But can't flags == (GTF_accept_transfer | GTF_transfer_completed) - * if gnttab_donate executes without interruption??? - */ -#else - ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed)); -#endif + /* * If a transfer is committed then wait for the frame address to appear. * Otherwise invalidate the grant entry against future use. @@ -224,8 +224,14 @@ while ( unlikely((frame = shared[ref].frame) == 0) ) cpu_relax(); + return frame; +} + +unsigned long +gnttab_end_foreign_transfer(grant_ref_t ref) +{ + unsigned long frame = gnttab_end_foreign_transfer_ref(ref); put_free_entry(ref); - return frame; } diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/kernel/reboot.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Thu Aug 25 18:18:47 2005 @@ -128,14 +128,6 @@ /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ /* XXX SMH: yes it would :-( */ - -#ifdef CONFIG_XEN_NETDEV_FRONTEND - extern void netif_suspend(void); - extern void netif_resume(void); -#else -#define netif_suspend() do{}while(0) -#define netif_resume() do{}while(0) -#endif #ifdef CONFIG_XEN_USB_FRONTEND extern void usbif_resume(); @@ -218,8 +210,6 @@ kmem_cache_shrink(pgd_cache); #endif - netif_suspend(); - time_suspend(); #ifdef CONFIG_SMP @@ -276,8 +266,6 @@ #endif time_resume(); - - netif_resume(); usbif_resume(); diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c Thu Aug 25 18:18:47 2005 @@ -5,6 +5,8 @@ #include <linux/string.h> #include <asm/io.h> #include <asm/processor.h> + +#ifndef CONFIG_XEN /* Simple VGA output */ @@ -59,7 +61,6 @@ .index = -1, }; -#ifndef CONFIG_XEN /* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ static int early_serial_base = 0x3f8; /* ttyS0 */ @@ -148,7 +149,8 @@ outb((divisor >> 8) & 0xff, early_serial_base + DLH); outb(c & ~DLAB, early_serial_base + LCR); } -#else + +#else /* CONFIG_XEN */ static void early_serial_write(struct console *con, const char *s, unsigned count) @@ -167,6 +169,13 @@ static __init void early_serial_init(char *s) { } + +/* + * No early VGA console on Xen, as we do not have convenient ISA-space + * mappings. Someone should fix this for domain 0. For now, use fake serial. + */ +#define early_vga_console early_serial_console + #endif static struct console early_serial_console = { diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Thu Aug 25 18:18:47 2005 @@ -206,11 +206,13 @@ .quad 0,0,0 /* three TLS descriptors */ .quad 0 /* unused now? __KERNEL16_CS - 16bit PM for S3 wakeup. */ -gdt_end: +gdt_end: +#if 0 /* asm/segment.h:GDT_ENTRIES must match this */ /* This should be a multiple of the cache line size */ /* GDTs of other CPUs: */ .fill (GDT_SIZE * NR_CPUS) - (gdt_end - cpu_gdt_table) +#endif .org 0x8000 ENTRY(empty_zero_page) diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Thu Aug 25 18:18:47 2005 @@ -536,48 +536,7 @@ } #endif -#ifdef CONFIG_XEN -#define reserve_ebda_region() void(0) - -static void __init print_memory_map(char *who) -{ - int i; - - for (i = 0; i < e820.nr_map; i++) { - early_printk(" %s: %016Lx - %016Lx ", who, - e820.map[i].addr, - e820.map[i].addr + e820.map[i].size); - switch (e820.map[i].type) { - case E820_RAM: early_printk("(usable)\n"); - break; - case E820_RESERVED: - early_printk("(reserved)\n"); - break; - case E820_ACPI: - early_printk("(ACPI data)\n"); - break; - case E820_NVS: - early_printk("(ACPI NVS)\n"); - break; - default: early_printk("type %u\n", e820.map[i].type); - break; - } - } -} - -void __init smp_alloc_memory(void) -{ - int cpu; - - for (cpu = 1; cpu < NR_CPUS; cpu++) { - cpu_gdt_descr[cpu].address = (unsigned long) - alloc_bootmem_low_pages(PAGE_SIZE); - /* XXX free unused pages later */ - } -} - - -#else +#ifndef CONFIG_XEN #define EBDA_ADDR_POINTER 0x40E static void __init reserve_ebda_region(void) { @@ -628,7 +587,6 @@ VMASST_TYPE_writable_pagetables); ARCH_SETUP - print_memory_map(machine_specific_memory_setup()); #else ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); drive_info = DRIVE_INFO; @@ -743,9 +701,6 @@ initrd_start = 0; } } -#endif -#ifdef CONFIG_SMP - smp_alloc_memory(); #endif #else /* CONFIG_XEN */ #ifdef CONFIG_BLK_DEV_INITRD diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c Thu Aug 25 18:18:47 2005 @@ -286,10 +286,10 @@ memcpy(me->thread.tls_array, cpu_gdt_table[cpu], GDT_ENTRY_TLS_ENTRIES * 8); #else - memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN], + memcpy(me->thread.tls_array, &get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN], GDT_ENTRY_TLS_ENTRIES * 8); - cpu_gdt_init(&cpu_gdt_descr[cpu]); + cpu_gdt_init(&cpu_gdt_descr[cpu]); #endif /* diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c Thu Aug 25 18:18:47 2005 @@ -739,8 +739,8 @@ atomic_set(&init_deasserted, 0); #ifdef CONFIG_XEN - if (cpu_gdt_descr[0].size > PAGE_SIZE) - BUG(); + cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL); + BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; memcpy((void *)cpu_gdt_descr[cpu].address, (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size); @@ -798,6 +798,8 @@ ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; boot_error = HYPERVISOR_boot_vcpu(cpu, &ctxt); + if (boot_error) + printk("boot error: %ld\n", boot_error); if (!boot_error) { /* diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Thu Aug 25 18:18:47 2005 @@ -536,70 +536,38 @@ round_up(ptes * 8, PAGE_SIZE); } -static void xen_copy_pt(void) -{ - unsigned long va = __START_KERNEL_map; - unsigned long addr, *pte_page; +void __init xen_init_pt(void) +{ + unsigned long addr, *page; int i; - pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned long *page = (unsigned long *) init_level4_pgt; - - addr = (unsigned long) page[pgd_index(va)]; + + for (i = 0; i < NR_CPUS; i++) + per_cpu(cur_pgd, i) = init_mm.pgd; + + memset((void *)init_level4_pgt, 0, PAGE_SIZE); + memset((void *)level3_kernel_pgt, 0, PAGE_SIZE); + memset((void *)level2_kernel_pgt, 0, PAGE_SIZE); + + /* Find the initial pte page that was built for us. */ + page = (unsigned long *)xen_start_info.pt_base; + addr = page[pgd_index(__START_KERNEL_map)]; addr_to_page(addr, page); - - pud = (pud_t *) &page[pud_index(va)]; - addr = page[pud_index(va)]; + addr = page[pud_index(__START_KERNEL_map)]; addr_to_page(addr, page); - level3_kernel_pgt[pud_index(va)] = - __pud(__pa_symbol(level2_kernel_pgt) | _KERNPG_TABLE | _PAGE_USER); - - for (;;) { - pmd = (pmd_t *) &page[pmd_index(va)]; - if (pmd_present(*pmd)) { - level2_kernel_pgt[pmd_index(va)] = *pmd; - /* - * if pmd is valid, check pte. - */ - addr = page[pmd_index(va)]; - addr_to_page(addr, pte_page); - - for (i = 0; i < PTRS_PER_PTE; i++) { - pte = (pte_t *) &pte_page[pte_index(va)]; - if (pte_present(*pte)) - va += PAGE_SIZE; - else - break; - } - - } else - break; - } - + /* Construct mapping of initial pte page in our own directories. */ init_level4_pgt[pgd_index(__START_KERNEL_map)] = mk_kernel_pgd(__pa_symbol(level3_kernel_pgt)); -} - -void __init xen_init_pt(void) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - per_cpu(cur_pgd, i) = init_mm.pgd; - - memcpy((void *)init_level4_pgt, - (void *)xen_start_info.pt_base, PAGE_SIZE); - - memset((void *)level3_kernel_pgt, 0, PAGE_SIZE); - memset((void *)level2_kernel_pgt, 0, PAGE_SIZE); - - xen_copy_pt(); + level3_kernel_pgt[pud_index(__START_KERNEL_map)] = + __pud(__pa_symbol(level2_kernel_pgt) | + _KERNPG_TABLE | _PAGE_USER); + memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE); make_page_readonly(init_level4_pgt); + make_page_readonly(init_level4_user_pgt); make_page_readonly(level3_kernel_pgt); + make_page_readonly(level3_user_pgt); make_page_readonly(level2_kernel_pgt); - make_page_readonly(init_level4_user_pgt); - make_page_readonly(level3_user_pgt); /* for vsyscall stuff */ xen_pgd_pin(__pa_symbol(init_level4_pgt)); xen_pgd_pin(__pa_symbol(init_level4_user_pgt)); @@ -609,7 +577,6 @@ set_pgd((pgd_t *)(init_level4_user_pgt + 511), mk_kernel_pgd(__pa_symbol(level3_user_pgt))); - } /* @@ -617,69 +584,58 @@ * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the * mapping for early initialization. */ - -#define MIN_INIT_SIZE 0x800000 static unsigned long current_size, extended_size; void __init extend_init_mapping(void) { unsigned long va = __START_KERNEL_map; - unsigned long addr, *pte_page; - - unsigned long phys; + unsigned long phys, addr, *pte_page; pmd_t *pmd; pte_t *pte, new_pte; unsigned long *page = (unsigned long *) init_level4_pgt; int i; - addr = (unsigned long) page[pgd_index(va)]; + addr = page[pgd_index(va)]; addr_to_page(addr, page); - addr = page[pud_index(va)]; addr_to_page(addr, page); for (;;) { + pmd = (pmd_t *)&page[pmd_index(va)]; + if (!pmd_present(*pmd)) + break; + addr = page[pmd_index(va)]; + addr_to_page(addr, pte_page); + for (i = 0; i < PTRS_PER_PTE; i++) { + pte = (pte_t *) &pte_page[pte_index(va)]; + if (!pte_present(*pte)) + break; + va += PAGE_SIZE; + current_size += PAGE_SIZE; + } + } + + while (va < __START_KERNEL_map + current_size + tables_space) { pmd = (pmd_t *) &page[pmd_index(va)]; - if (pmd_present(*pmd)) { - /* - * if pmd is valid, check pte. - */ - addr = page[pmd_index(va)]; - addr_to_page(addr, pte_page); - - for (i = 0; i < PTRS_PER_PTE; i++) { - pte = (pte_t *) &pte_page[pte_index(va)]; - - if (pte_present(*pte)) { - va += PAGE_SIZE; - current_size += PAGE_SIZE; - } else - break; - } - - } else - break; - } - - for (; va < __START_KERNEL_map + current_size + tables_space; ) { - pmd = (pmd_t *) &page[pmd_index(va)]; - - if (pmd_none(*pmd)) { - pte_page = (unsigned long *) alloc_static_page(&phys); - make_page_readonly(pte_page); - xen_pte_pin(phys); - set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); - - for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) { - new_pte = pfn_pte((va - __START_KERNEL_map) >> PAGE_SHIFT, - __pgprot(_KERNPG_TABLE | _PAGE_USER)); - - pte = (pte_t *) &pte_page[pte_index(va)]; - xen_l1_entry_update(pte, new_pte); - extended_size += PAGE_SIZE; - } - } - } + if (!pmd_none(*pmd)) + continue; + pte_page = (unsigned long *) alloc_static_page(&phys); + make_page_readonly(pte_page); + xen_pte_pin(phys); + set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); + for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) { + new_pte = pfn_pte( + (va - __START_KERNEL_map) >> PAGE_SHIFT, + __pgprot(_KERNPG_TABLE | _PAGE_USER)); + pte = (pte_t *)&pte_page[pte_index(va)]; + xen_l1_entry_update(pte, new_pte); + extended_size += PAGE_SIZE; + } + } + + /* Kill mapping of low 1MB. */ + for (va = __START_KERNEL_map; va < (unsigned long)&_text; va += PAGE_SIZE) + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); } @@ -719,10 +675,6 @@ table_end<<PAGE_SHIFT); start_pfn = ((current_size + extended_size) >> PAGE_SHIFT); - - /* - * TBD: Need to calculate at runtime - */ __flush_tlb_all(); init_mapping_done = 1; diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Thu Aug 25 18:18:47 2005 @@ -57,26 +57,26 @@ /* Front end tells us frame. */ static void frontend_changed(struct xenbus_watch *watch, const char *node) { - unsigned long sharedmfn; + unsigned long ring_ref; unsigned int evtchn; int err; struct backend_info *be = container_of(watch, struct backend_info, watch); /* If other end is gone, delete ourself. */ - if (!xenbus_exists(be->frontpath, "")) { + if (node && !xenbus_exists(be->frontpath, "")) { xenbus_rm(be->dev->nodename, ""); device_unregister(&be->dev->dev); return; } - if (be->blkif->status == CONNECTED) - return; - - err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn, + if (be->blkif == NULL || be->blkif->status == CONNECTED) + return; + + err = xenbus_gather(be->frontpath, "ring-ref", "%lu", &ring_ref, "event-channel", "%u", &evtchn, NULL); if (err) { xenbus_dev_error(be->dev, err, - "reading %s/grant-id and event-channel", + "reading %s/ring-ref and event-channel", be->frontpath); return; } @@ -113,11 +113,10 @@ } /* Map the shared frame, irq etc. */ - err = blkif_map(be->blkif, sharedmfn, evtchn); - if (err) { - xenbus_dev_error(be->dev, err, - "mapping shared-frame %lu port %u", - sharedmfn, evtchn); + err = blkif_map(be->blkif, ring_ref, evtchn); + if (err) { + xenbus_dev_error(be->dev, err, "mapping ring-ref %lu port %u", + ring_ref, evtchn); goto abort; } @@ -139,133 +138,125 @@ { int err; char *p; - char *frontend; long int handle, pdev; struct backend_info *be = container_of(watch, struct backend_info, backend_watch); struct xenbus_device *dev = be->dev; + + err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); + if (XENBUS_EXIST_ERR(err)) + return; + if (err < 0) { + xenbus_dev_error(dev, err, "reading physical-device"); + return; + } + if (be->pdev && be->pdev != pdev) { + printk(KERN_WARNING + "changing physical-device not supported\n"); + return; + } + be->pdev = pdev; + + /* If there's a read-only node, we're read only. */ + p = xenbus_read(dev->nodename, "read-only", NULL); + if (!IS_ERR(p)) { + be->readonly = 1; + kfree(p); + } + + if (be->blkif == NULL) { + /* Front end dir is a number, which is used as the handle. */ + p = strrchr(be->frontpath, '/') + 1; + handle = simple_strtoul(p, NULL, 0); + + be->blkif = alloc_blkif(be->frontend_id); + if (IS_ERR(be->blkif)) { + err = PTR_ERR(be->blkif); + be->blkif = NULL; + xenbus_dev_error(dev, err, "creating block interface"); + return; + } + + err = vbd_create(be->blkif, handle, be->pdev, be->readonly); + if (err) { + xenbus_dev_error(dev, err, "creating vbd structure"); + return; + } + + /* Pass in NULL node to skip exist test. */ + frontend_changed(&be->watch, NULL); + } +} + +static int blkback_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + struct backend_info *be; + char *frontend; + int err; + + be = kmalloc(sizeof(*be), GFP_KERNEL); + if (!be) { + xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); + return -ENOMEM; + } + memset(be, 0, sizeof(*be)); frontend = NULL; err = xenbus_gather(dev->nodename, "frontend-id", "%li", &be->frontend_id, "frontend", NULL, &frontend, NULL); - if (XENBUS_EXIST_ERR(err) || - strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { + if (XENBUS_EXIST_ERR(err)) + goto free_be; + if (err < 0) { + xenbus_dev_error(dev, err, + "reading %s/frontend or frontend-id", + dev->nodename); + goto free_be; + } + if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { /* If we can't get a frontend path and a frontend-id, * then our bus-id is no longer valid and we need to * destroy the backend device. */ - goto device_fail; - } - if (err < 0) { - xenbus_dev_error(dev, err, - "reading %s/frontend or frontend-id", - dev->nodename); - goto device_fail; - } - - if (!be->frontpath || strcmp(frontend, be->frontpath)) { - if (be->watch.node) - unregister_xenbus_watch(&be->watch); - if (be->frontpath) - kfree(be->frontpath); - be->frontpath = frontend; - frontend = NULL; - be->watch.node = be->frontpath; - be->watch.callback = frontend_changed; - err = register_xenbus_watch(&be->watch); - if (err) { - be->watch.node = NULL; - xenbus_dev_error(dev, err, - "adding frontend watch on %s", - be->frontpath); - goto device_fail; - } - } - - err = xenbus_scanf(dev->nodename, "physical-device", "%li", &pdev); - if (XENBUS_EXIST_ERR(err)) - goto out; - if (err < 0) { - xenbus_dev_error(dev, err, "reading physical-device"); - goto device_fail; - } - if (be->pdev && be->pdev != pdev) { - printk(KERN_WARNING - "changing physical-device not supported\n"); - goto device_fail; - } - be->pdev = pdev; - - /* If there's a read-only node, we're read only. */ - p = xenbus_read(dev->nodename, "read-only", NULL); - if (!IS_ERR(p)) { - be->readonly = 1; - kfree(p); - } - - if (be->blkif == NULL) { - /* Front end dir is a number, which is used as the handle. */ - p = strrchr(be->frontpath, '/') + 1; - handle = simple_strtoul(p, NULL, 0); - - be->blkif = alloc_blkif(be->frontend_id); - if (IS_ERR(be->blkif)) { - err = PTR_ERR(be->blkif); - be->blkif = NULL; - xenbus_dev_error(dev, err, "creating block interface"); - goto device_fail; - } - - err = vbd_create(be->blkif, handle, be->pdev, be->readonly); - if (err) { - xenbus_dev_error(dev, err, "creating vbd structure"); - goto device_fail; - } - - frontend_changed(&be->watch, be->frontpath); - } - - out: - if (frontend) - kfree(frontend); - return; - - device_fail: - device_unregister(&be->dev->dev); - goto out; -} - -static int blkback_probe(struct xenbus_device *dev, - const struct xenbus_device_id *id) -{ - struct backend_info *be; - int err; - - be = kmalloc(sizeof(*be), GFP_KERNEL); - if (!be) { - xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); - return -ENOMEM; - } - - memset(be, 0, sizeof(*be)); + err = -ENOENT; + goto free_be; + } be->dev = dev; be->backend_watch.node = dev->nodename; be->backend_watch.callback = backend_changed; err = register_xenbus_watch(&be->backend_watch); if (err) { + be->backend_watch.node = NULL; xenbus_dev_error(dev, err, "adding backend watch on %s", dev->nodename); goto free_be; } + be->frontpath = frontend; + be->watch.node = be->frontpath; + be->watch.callback = frontend_changed; + err = register_xenbus_watch(&be->watch); + if (err) { + be->watch.node = NULL; + xenbus_dev_error(dev, err, + "adding frontend watch on %s", + be->frontpath); + goto free_be; + } + dev->data = be; backend_changed(&be->backend_watch, dev->nodename); - return err; + return 0; + free_be: + if (be->backend_watch.node) + unregister_xenbus_watch(&be->backend_watch); + if (frontend) + kfree(frontend); kfree(be); return err; } diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Thu Aug 25 18:18:47 2005 @@ -1084,7 +1084,8 @@ "sector-size", "%lu", §or_size, NULL); if (err) { - xenbus_dev_error(info->xbdev, err, "reading backend fields"); + xenbus_dev_error(info->xbdev, err, + "reading backend fields at %s", watch->node); return; } @@ -1123,12 +1124,12 @@ xenbus_dev_error(dev, err, "granting access to ring page"); return err; } - info->grant_id = err; + info->ring_ref = err; op.u.alloc_unbound.dom = info->backend_id; err = HYPERVISOR_event_channel_op(&op); if (err) { - gnttab_end_foreign_access(info->grant_id, 0); + gnttab_end_foreign_access(info->ring_ref, 0); free_page((unsigned long)info->ring.sring); info->ring.sring = 0; xenbus_dev_error(dev, err, "allocating event channel"); @@ -1176,9 +1177,9 @@ goto destroy_blkring; } - err = xenbus_printf(dev->nodename, "grant-id","%u", info->grant_id); + err = xenbus_printf(dev->nodename, "ring-ref","%u", info->ring_ref); if (err) { - message = "writing grant-id"; + message = "writing ring-ref"; goto abort_transaction; } err = xenbus_printf(dev->nodename, diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/blkfront/block.h --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/block.h Thu Aug 25 18:18:47 2005 @@ -112,7 +112,7 @@ int connected; char *backend; int backend_id; - int grant_id; + int ring_ref; blkif_front_ring_t ring; unsigned int evtchn; struct xlbd_major_info *mi; diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Thu Aug 25 18:18:47 2005 @@ -240,7 +240,11 @@ #endif /*** Useful function for console debugging -- goes straight to Xen. ***/ +#ifdef CONFIG_XEN_PRIVILEGED_GUEST asmlinkage int xprintk(const char *fmt, ...) +#else +asmlinkage int xprintk(const char *fmt, ...) +#endif { va_list args; int printk_len; diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/Makefile Thu Aug 25 18:18:47 2005 @@ -1,2 +1,2 @@ -obj-y := netback.o control.o interface.o loopback.o +obj-y := netback.o xenbus.o interface.o loopback.o diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/common.h --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Thu Aug 25 18:18:47 2005 @@ -59,6 +59,7 @@ grant_ref_t rx_shmem_ref; #endif unsigned int evtchn; + unsigned int remote_evtchn; /* The shared rings and indexes. */ netif_tx_interface_t *tx; @@ -82,36 +83,30 @@ /* Miscellaneous private stuff. */ enum { DISCONNECTED, DISCONNECTING, CONNECTED } status; int active; - /* - * DISCONNECT response is deferred until pending requests are ack'ed. - * We therefore need to store the id from the original request. - */ - u8 disconnect_rspid; - struct netif_st *hash_next; struct list_head list; /* scheduling list */ atomic_t refcnt; struct net_device *dev; struct net_device_stats stats; - struct work_struct work; + struct work_struct free_work; } netif_t; -void netif_create(netif_be_create_t *create); -void netif_destroy(netif_be_destroy_t *destroy); -void netif_creditlimit(netif_be_creditlimit_t *creditlimit); -void netif_connect(netif_be_connect_t *connect); -int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id); -void netif_disconnect_complete(netif_t *netif); -netif_t *netif_find_by_handle(domid_t domid, unsigned int handle); +void netif_creditlimit(netif_t *netif); +int netif_disconnect(netif_t *netif); + +netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]); +void free_netif_callback(netif_t *netif); +int netif_map(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn); + #define netif_get(_b) (atomic_inc(&(_b)->refcnt)) #define netif_put(_b) \ do { \ if ( atomic_dec_and_test(&(_b)->refcnt) ) \ - netif_disconnect_complete(_b); \ + free_netif_callback(_b); \ } while (0) -void netif_interface_init(void); -void netif_ctrlif_init(void); +void netif_xenbus_init(void); void netif_schedule_work(netif_t *netif); void netif_deschedule_work(netif_t *netif); diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Aug 25 18:18:47 2005 @@ -9,24 +9,6 @@ #include "common.h" #include <linux/rtnetlink.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#endif - -#define NETIF_HASHSZ 1024 -#define NETIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(NETIF_HASHSZ-1)) - -static netif_t *netif_hash[NETIF_HASHSZ]; - -netif_t *netif_find_by_handle(domid_t domid, unsigned int handle) -{ - netif_t *netif = netif_hash[NETIF_HASH(domid, handle)]; - while ( (netif != NULL) && - ((netif->domid != domid) || (netif->handle != handle)) ) - netif = netif->hash_next; - return netif; -} - static void __netif_up(netif_t *netif) { struct net_device *dev = netif->dev; @@ -51,7 +33,7 @@ static int net_open(struct net_device *dev) { netif_t *netif = netdev_priv(dev); - if ( netif->status == CONNECTED ) + if (netif->status == CONNECTED) __netif_up(netif); netif_start_queue(dev); return 0; @@ -61,92 +43,23 @@ { netif_t *netif = netdev_priv(dev); netif_stop_queue(dev); - if ( netif->status == CONNECTED ) + if (netif->status == CONNECTED) __netif_down(netif); return 0; } -static void __netif_disconnect_complete(void *arg) -{ - netif_t *netif = (netif_t *)arg; - ctrl_msg_t cmsg; - netif_be_disconnect_t disc; -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) - struct gnttab_unmap_grant_ref op; -#endif - - /* - * These can't be done in netif_disconnect() because at that point there - * may be outstanding requests in the network stack whose asynchronous - * responses must still be notified to the remote driver. - */ - -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - op.host_addr = netif->tx_shmem_vaddr; - op.handle = netif->tx_shmem_handle; - op.dev_bus_addr = 0; - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); -#endif - -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - op.host_addr = netif->rx_shmem_vaddr; - op.handle = netif->rx_shmem_handle; - op.dev_bus_addr = 0; - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); -#endif - - - vfree(netif->tx); /* Frees netif->rx as well. */ - - /* Construct the deferred response message. */ - cmsg.type = CMSG_NETIF_BE; - cmsg.subtype = CMSG_NETIF_BE_DISCONNECT; - cmsg.id = netif->disconnect_rspid; - cmsg.length = sizeof(netif_be_disconnect_t); - disc.domid = netif->domid; - disc.netif_handle = netif->handle; - disc.status = NETIF_BE_STATUS_OKAY; - memcpy(cmsg.msg, &disc, sizeof(disc)); - - /* - * Make sure message is constructed /before/ status change, because - * after the status change the 'netif' structure could be deallocated at - * any time. Also make sure we send the response /after/ status change, - * as otherwise a subsequent CONNECT request could spuriously fail if - * another CPU doesn't see the status change yet. - */ - mb(); - if ( netif->status != DISCONNECTING ) - BUG(); - netif->status = DISCONNECTED; - mb(); - - /* Send the successful response. */ - ctrl_if_send_response(&cmsg); -} - -void netif_disconnect_complete(netif_t *netif) -{ - INIT_WORK(&netif->work, __netif_disconnect_complete, (void *)netif); - schedule_work(&netif->work); -} - -void netif_create(netif_be_create_t *create) -{ - int err = 0; - domid_t domid = create->domid; - unsigned int handle = create->netif_handle; +netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) +{ + int err = 0, i; struct net_device *dev; - netif_t **pnetif, *netif; - char name[IFNAMSIZ] = {}; + netif_t *netif; + char name[IFNAMSIZ] = {}; snprintf(name, IFNAMSIZ - 1, "vif%u.%u", domid, handle); dev = alloc_netdev(sizeof(netif_t), name, ether_setup); - if ( dev == NULL ) - { + if (dev == NULL) { DPRINTK("Could not create netif: out of memory\n"); - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - return; + return NULL; } netif = netdev_priv(dev); @@ -161,19 +74,6 @@ netif->credit_usec = 0UL; init_timer(&netif->credit_timeout); - pnetif = &netif_hash[NETIF_HASH(domid, handle)]; - while ( *pnetif != NULL ) - { - if ( ((*pnetif)->domid == domid) && ((*pnetif)->handle == handle) ) - { - DPRINTK("Could not create netif: already exists\n"); - create->status = NETIF_BE_STATUS_INTERFACE_EXISTS; - free_netdev(dev); - return; - } - pnetif = &(*pnetif)->hash_next; - } - dev->hard_start_xmit = netif_be_start_xmit; dev->get_stats = netif_be_get_stats; dev->open = net_open; @@ -183,10 +83,10 @@ /* Disable queuing. */ dev->tx_queue_len = 0; - if ( (create->be_mac[0] == 0) && (create->be_mac[1] == 0) && - (create->be_mac[2] == 0) && (create->be_mac[3] == 0) && - (create->be_mac[4] == 0) && (create->be_mac[5] == 0) ) - { + for (i = 0; i < ETH_ALEN; i++) + if (be_mac[i] != 0) + break; + if (i == ETH_ALEN) { /* * Initialise a dummy MAC address. We choose the numerically largest * non-broadcast address to prevent the address getting stolen by an @@ -194,87 +94,200 @@ */ memset(dev->dev_addr, 0xFF, ETH_ALEN); dev->dev_addr[0] &= ~0x01; - } - else - { - memcpy(dev->dev_addr, create->be_mac, ETH_ALEN); - } - - memcpy(netif->fe_dev_addr, create->mac, ETH_ALEN); + } else + memcpy(dev->dev_addr, be_mac, ETH_ALEN); rtnl_lock(); err = register_netdevice(dev); rtnl_unlock(); - - if ( err != 0 ) - { + if (err) { DPRINTK("Could not register new net device %s: err=%d\n", dev->name, err); - create->status = NETIF_BE_STATUS_OUT_OF_MEMORY; free_netdev(dev); - return; - } - - netif->hash_next = *pnetif; - *pnetif = netif; + return NULL; + } DPRINTK("Successfully created netif\n"); - create->status = NETIF_BE_STATUS_OKAY; -} - -void netif_destroy(netif_be_destroy_t *destroy) -{ - domid_t domid = destroy->domid; - unsigned int handle = destroy->netif_handle; - netif_t **pnetif, *netif; - - pnetif = &netif_hash[NETIF_HASH(domid, handle)]; - while ( (netif = *pnetif) != NULL ) + return netif; +} + +static int map_frontend_page(netif_t *netif, unsigned long localaddr, + unsigned long tx_ring_ref, unsigned long rx_ring_ref) +{ +#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) + pgprot_t prot = __pgprot(_KERNPG_TABLE); + int err; +#endif +#if defined(CONFIG_XEN_NETDEV_GRANT_TX) { - if ( (netif->domid == domid) && (netif->handle == handle) ) - { - if ( netif->status != DISCONNECTED ) - goto still_connected; - goto destroy; + struct gnttab_map_grant_ref op; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr; + op.flags = GNTMAP_host_map; + op.ref = tx_ring_ref; + op.dom = netif->domid; + + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Grant table operation failure !\n"); + return op.handle; } - pnetif = &netif->hash_next; - } - - destroy->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - - still_connected: - destroy->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; - return; - - destroy: - *pnetif = netif->hash_next; + + netif->tx_shmem_ref = tx_ring_ref; + netif->tx_shmem_handle = op.handle; + netif->tx_shmem_vaddr = localaddr; + } +#else + err = direct_remap_area_pages(&init_mm, localaddr, + tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE, + prot, netif->domid); + if (err) + return err; +#endif + +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) + { + struct gnttab_map_grant_ref op; + + /* Map: Use the Grant table reference */ + op.host_addr = localaddr + PAGE_SIZE; + op.flags = GNTMAP_host_map; + op.ref = rx_ring_ref; + op.dom = netif->domid; + + BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) ); + if (op.handle < 0) { + DPRINTK(" Grant table operation failure !\n"); + return op.handle; + } + + netif->rx_shmem_ref = rx_ring_ref; + netif->rx_shmem_handle = op.handle; + netif->rx_shmem_vaddr = localaddr + PAGE_SIZE; + } +#else + err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE, + rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE, + prot, netif->domid); + if (err) + return err; +#endif + + return 0; +} + +static void unmap_frontend_page(netif_t *netif) +{ +#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX) + struct gnttab_unmap_grant_ref op; +#endif + +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + op.host_addr = netif->tx_shmem_vaddr; + op.handle = netif->tx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); +#endif + +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + op.host_addr = netif->rx_shmem_vaddr; + op.handle = netif->rx_shmem_handle; + op.dev_bus_addr = 0; + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); +#endif +} + +int netif_map(netif_t *netif, unsigned long tx_ring_ref, + unsigned long rx_ring_ref, unsigned int evtchn) +{ + struct vm_struct *vma; + evtchn_op_t op = { .cmd = EVTCHNOP_bind_interdomain }; + int err; + + vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP); + if (vma == NULL) + return -ENOMEM; + + err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref, + rx_ring_ref); + if (err) { + vfree(vma->addr); + return err; + } + + op.u.bind_interdomain.dom1 = DOMID_SELF; + op.u.bind_interdomain.dom2 = netif->domid; + op.u.bind_interdomain.port1 = 0; + op.u.bind_interdomain.port2 = evtchn; + err = HYPERVISOR_event_channel_op(&op); + if (err) { + unmap_frontend_page(netif); + vfree(vma->addr); + return err; + } + + netif->evtchn = op.u.bind_interdomain.port1; + netif->remote_evtchn = evtchn; + + netif->tx = (netif_tx_interface_t *)vma->addr; + netif->rx = (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); + netif->tx->resp_prod = netif->rx->resp_prod = 0; + netif_get(netif); + wmb(); /* Other CPUs see new state before interface is started. */ + + rtnl_lock(); + netif->status = CONNECTED; + wmb(); + if (netif_running(netif->dev)) + __netif_up(netif); + rtnl_unlock(); + + return 0; +} + +static void free_netif(void *arg) +{ + evtchn_op_t op = { .cmd = EVTCHNOP_close }; + netif_t *netif = (netif_t *)arg; + + /* + * These can't be done in netif_disconnect() because at that point there + * may be outstanding requests in the network stack whose asynchronous + * responses must still be notified to the remote driver. + */ + + op.u.close.port = netif->evtchn; + op.u.close.dom = DOMID_SELF; + HYPERVISOR_event_channel_op(&op); + op.u.close.port = netif->remote_evtchn; + op.u.close.dom = netif->domid; + HYPERVISOR_event_channel_op(&op); + unregister_netdev(netif->dev); + + if (netif->tx) { + unmap_frontend_page(netif); + vfree(netif->tx); /* Frees netif->rx as well. */ + } + free_netdev(netif->dev); - destroy->status = NETIF_BE_STATUS_OKAY; -} - -void netif_creditlimit(netif_be_creditlimit_t *creditlimit) -{ - domid_t domid = creditlimit->domid; - unsigned int handle = creditlimit->netif_handle; - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { - DPRINTK("netif_creditlimit attempted for non-existent netif" - " (%u,%u)\n", creditlimit->domid, creditlimit->netif_handle); - creditlimit->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - +} + +void free_netif_callback(netif_t *netif) +{ + INIT_WORK(&netif->free_work, free_netif, (void *)netif); + schedule_work(&netif->free_work); +} + +void netif_creditlimit(netif_t *netif) +{ +#if 0 /* Set the credit limit (reset remaining credit to new limit). */ netif->credit_bytes = netif->remaining_credit = creditlimit->credit_bytes; netif->credit_usec = creditlimit->period_usec; - if ( netif->status == CONNECTED ) - { + if (netif->status == CONNECTED) { /* * Schedule work so that any packets waiting under previous credit * limit are dealt with (acts like a replenishment point). @@ -282,184 +295,22 @@ netif->credit_timeout.expires = jiffies; netif_schedule_work(netif); } - - creditlimit->status = NETIF_BE_STATUS_OKAY; -} - -void netif_connect(netif_be_connect_t *connect) -{ - domid_t domid = connect->domid; - unsigned int handle = connect->netif_handle; - unsigned int evtchn = connect->evtchn; - unsigned long tx_shmem_frame = connect->tx_shmem_frame; - unsigned long rx_shmem_frame = connect->rx_shmem_frame; - struct vm_struct *vma; -#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX) - pgprot_t prot = __pgprot(_KERNPG_TABLE); - int error; -#endif - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) { - DPRINTK("netif_connect attempted for non-existent netif (%u,%u)\n", - connect->domid, connect->netif_handle); - connect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return; - } - - if ( netif->status != DISCONNECTED ) { - connect->status = NETIF_BE_STATUS_INTERFACE_CONNECTED; - return; - } - - if ( (vma = get_vm_area(2*PAGE_SIZE, VM_IOREMAP)) == NULL ) { - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - return; - } - - -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) - { - struct gnttab_map_grant_ref op; - int tx_ref = connect->tx_shmem_ref; - - /* Map: Use the Grant table reference */ - op.host_addr = VMALLOC_VMADDR(vma->addr); - op.flags = GNTMAP_host_map; - op.ref = tx_ref; - op.dom = domid; - - if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || - (op.handle < 0)) { - DPRINTK(" Grant table operation failure !\n"); - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; - vfree(vma->addr); - return; - } - - netif->tx_shmem_ref = tx_ref; - netif->tx_shmem_handle = op.handle; - netif->tx_shmem_vaddr = VMALLOC_VMADDR(vma->addr); - } - - -#else - error = direct_remap_area_pages(&init_mm, - VMALLOC_VMADDR(vma->addr), - tx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, - prot, domid); - if ( error != 0 ) - { - if ( error == -ENOMEM ) - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - else if ( error == -EFAULT ) - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; - else - connect->status = NETIF_BE_STATUS_ERROR; - vfree(vma->addr); - return; - } -#endif - - -#if defined(CONFIG_XEN_NETDEV_GRANT_RX) - { - struct gnttab_map_grant_ref op; - int rx_ref = connect->rx_shmem_ref; - - - /* Map: Use the Grant table reference */ - op.host_addr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; - op.flags = GNTMAP_host_map; - op.ref = rx_ref; - op.dom = domid; - - if ((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) < 0) || - (op.handle < 0)) { - DPRINTK(" Grant table operation failure !\n"); - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; - vfree(vma->addr); - return; - } - - netif->rx_shmem_ref = rx_ref; - netif->rx_shmem_handle = handle; - netif->rx_shmem_vaddr = VMALLOC_VMADDR(vma->addr) + PAGE_SIZE; - } -#else - error = direct_remap_area_pages(&init_mm, - VMALLOC_VMADDR(vma->addr) + PAGE_SIZE, - rx_shmem_frame<<PAGE_SHIFT, PAGE_SIZE, - prot, domid); - if ( error != 0 ) - { - if ( error == -ENOMEM ) - connect->status = NETIF_BE_STATUS_OUT_OF_MEMORY; - else if ( error == -EFAULT ) - connect->status = NETIF_BE_STATUS_MAPPING_ERROR; - else - connect->status = NETIF_BE_STATUS_ERROR; - vfree(vma->addr); - return; - } - -#endif - - netif->evtchn = evtchn; - netif->tx_shmem_frame = tx_shmem_frame; - netif->rx_shmem_frame = rx_shmem_frame; - netif->tx = - (netif_tx_interface_t *)vma->addr; - netif->rx = - (netif_rx_interface_t *)((char *)vma->addr + PAGE_SIZE); - netif->tx->resp_prod = netif->rx->resp_prod = 0; - netif_get(netif); - wmb(); /* Other CPUs see new state before interface is started. */ - - rtnl_lock(); - netif->status = CONNECTED; - wmb(); - if ( netif_running(netif->dev) ) - __netif_up(netif); - rtnl_unlock(); - - connect->status = NETIF_BE_STATUS_OKAY; -} - -int netif_disconnect(netif_be_disconnect_t *disconnect, u8 rsp_id) -{ - domid_t domid = disconnect->domid; - unsigned int handle = disconnect->netif_handle; - netif_t *netif; - - netif = netif_find_by_handle(domid, handle); - if ( unlikely(netif == NULL) ) - { - DPRINTK("netif_disconnect attempted for non-existent netif" - " (%u,%u)\n", disconnect->domid, disconnect->netif_handle); - disconnect->status = NETIF_BE_STATUS_INTERFACE_NOT_FOUND; - return 1; /* Caller will send response error message. */ - } - - if ( netif->status == CONNECTED ) - { +#endif +} + +int netif_disconnect(netif_t *netif) +{ + + if (netif->status == CONNECTED) { rtnl_lock(); netif->status = DISCONNECTING; - netif->disconnect_rspid = rsp_id; wmb(); - if ( netif_running(netif->dev) ) + if (netif_running(netif->dev)) __netif_down(netif); rtnl_unlock(); netif_put(netif); return 0; /* Caller should not send response message. */ } - disconnect->status = NETIF_BE_STATUS_OKAY; return 1; } - -void netif_interface_init(void) -{ - memset(netif_hash, 0, sizeof(netif_hash)); -} diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Aug 25 18:18:47 2005 @@ -13,10 +13,6 @@ #include "common.h" #include <asm-xen/balloon.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#include <linux/delay.h> -#endif - #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) #include <asm-xen/xen-public/grant_table.h> #include <asm-xen/gnttab.h> @@ -153,11 +149,7 @@ static inline int is_xen_skb(struct sk_buff *skb) { extern kmem_cache_t *skbuff_cachep; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; -#else - kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->list.next; -#endif return (cp == skbuff_cachep); } @@ -642,11 +634,7 @@ netif->credit_timeout.expires = next_credit; netif->credit_timeout.data = (unsigned long)netif; netif->credit_timeout.function = tx_credit_callback; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) add_timer_on(&netif->credit_timeout, smp_processor_id()); -#else - add_timer(&netif->credit_timeout); -#endif break; } } @@ -966,8 +954,6 @@ net_timer.data = 0; net_timer.function = net_alarm; - netif_interface_init(); - page = balloon_alloc_empty_page_range(MAX_PENDING_REQS); BUG_ON(page == NULL); mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); @@ -987,7 +973,7 @@ spin_lock_init(&net_schedule_list_lock); INIT_LIST_HEAD(&net_schedule_list); - netif_ctrlif_init(); + netif_xenbus_init(); (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), netif_be_dbg, SA_SHIRQ, diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Thu Aug 25 18:18:47 2005 @@ -48,7 +48,7 @@ #include <asm/io.h> #include <asm/uaccess.h> #include <asm-xen/evtchn.h> -#include <asm-xen/ctrl_if.h> +#include <asm-xen/xenbus.h> #include <asm-xen/xen-public/io/netif.h> #include <asm-xen/balloon.h> #include <asm/page.h> @@ -112,9 +112,13 @@ #endif #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) -static domid_t rdomid = 0; #define GRANT_INVALID_REF (0xFFFF) #endif + +#define NETIF_STATE_DISCONNECTED 0 +#define NETIF_STATE_CONNECTED 1 + +static unsigned int netif_state = NETIF_STATE_DISCONNECTED; static void network_tx_buf_gc(struct net_device *dev); static void network_alloc_rx_buffers(struct net_device *dev); @@ -133,12 +137,11 @@ #define xennet_proc_delif(d) ((void)0) #endif -static struct list_head dev_list; - +#define netfront_info net_private struct net_private { struct list_head list; - struct net_device *dev; + struct net_device *netdev; struct net_device_stats stats; NETIF_RING_IDX rx_resp_cons, tx_resp_cons; @@ -176,6 +179,14 @@ */ struct sk_buff *tx_skbs[NETIF_TX_RING_SIZE+1]; struct sk_buff *rx_skbs[NETIF_RX_RING_SIZE+1]; + + struct xenbus_device *xbdev; + char *backend; + int backend_id; + struct xenbus_watch watch; + int tx_ring_ref; + int rx_ring_ref; + u8 mac[ETH_ALEN]; }; /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ @@ -187,20 +198,14 @@ (_list)[0] = (_list)[_id]; \ (unsigned short)_id; }) -static char *status_name[] = { - [NETIF_INTERFACE_STATUS_CLOSED] = "closed", - [NETIF_INTERFACE_STATUS_DISCONNECTED] = "disconnected", - [NETIF_INTERFACE_STATUS_CONNECTED] = "connected", - [NETIF_INTERFACE_STATUS_CHANGED] = "changed", -}; - +#ifdef DEBUG static char *be_state_name[] = { [BEST_CLOSED] = "closed", [BEST_DISCONNECTED] = "disconnected", [BEST_CONNECTED] = "connected", }; - -#define DEBUG +#endif + #ifdef DEBUG #define DPRINTK(fmt, args...) \ printk(KERN_ALERT "xen_net (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args) @@ -211,89 +216,6 @@ printk(KERN_INFO "xen_net: " fmt, ##args) #define WPRINTK(fmt, args...) \ printk(KERN_WARNING "xen_net: " fmt, ##args) - -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) { - np = list_entry(ent, struct net_private, list); - if (np->handle == handle) - return np->dev; - } - 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) -{ - 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 list_head *ent; - struct net_private *np; - unsigned int connected; - - connected = 0; - - list_for_each(ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - if (np->backend_state == BEST_CONNECTED) - connected++; - } - - netctrl.connected_n = connected; - DPRINTK("> connected_n=%d interface_n=%d\n", - netctrl.connected_n, netctrl.interface_n); - return connected; -} /** Send a packet on a net device to encourage switches to learn the * MAC. We send a fake ARP request. @@ -364,7 +286,7 @@ "still in use by backend domain.\n"); goto out; } - gnttab_end_foreign_access(grant_tx_ref[id], GNTMAP_readonly); + gnttab_end_foreign_access_ref(grant_tx_ref[id], GNTMAP_readonly); gnttab_release_grant_reference(&gref_tx_head, grant_tx_ref[id]); grant_tx_ref[id] = GRANT_INVALID_REF; #endif @@ -448,7 +370,7 @@ BUG(); } grant_rx_ref[id] = ref; - gnttab_grant_foreign_transfer_ref(ref, rdomid, + gnttab_grant_foreign_transfer_ref(ref, np->backend_id, virt_to_mfn(skb->head)); np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.gref = ref; #endif @@ -544,7 +466,7 @@ BUG(); } mfn = virt_to_mfn(skb->data); - gnttab_grant_foreign_access_ref(ref, rdomid, mfn, GNTMAP_readonly); + gnttab_grant_foreign_access_ref(ref, np->backend_id, mfn, GNTMAP_readonly); tx->addr = ref << PAGE_SHIFT; grant_tx_ref[id] = ref; #else @@ -650,7 +572,7 @@ #ifdef CONFIG_XEN_NETDEV_GRANT_RX ref = grant_rx_ref[rx->id]; grant_rx_ref[rx->id] = GRANT_INVALID_REF; - mfn = gnttab_end_foreign_transfer(ref); + mfn = gnttab_end_foreign_transfer_ref(ref); gnttab_release_grant_reference(&gref_rx_head, ref); #endif @@ -809,7 +731,7 @@ { struct net_private *np = netdev_priv(dev); np->user_state = UST_CLOSED; - netif_stop_queue(np->dev); + netif_stop_queue(np->netdev); return 0; } @@ -821,8 +743,7 @@ } -static void network_connect(struct net_device *dev, - netif_fe_interface_status_t *status) +static void network_connect(struct net_device *dev) { struct net_private *np; int i, requeue_idx; @@ -890,7 +811,7 @@ */ np->backend_state = BEST_CONNECTED; wmb(); - notify_via_evtchn(status->evtchn); + notify_via_evtchn(np->evtchn); network_tx_buf_gc(dev); if (np->user_state == UST_OPEN) @@ -900,148 +821,21 @@ spin_unlock_irq(&np->tx_lock); } -static void vif_show(struct net_private *np) +static void show_device(struct net_private *np) { #ifdef DEBUG - if (np) { - IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", - np->handle, - be_state_name[np->backend_state], - np->user_state ? "open" : "closed", - np->evtchn, - np->tx, - np->rx); - } else { - IPRINTK("<vif NULL>\n"); - } -#endif -} - -/* Send a connect message to xend to tell it to bring up the interface. */ -static void send_interface_connect(struct net_private *np) -{ - int err; - 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; - - msg->handle = np->handle; - msg->tx_shmem_frame = virt_to_mfn(np->tx); -#ifdef CONFIG_XEN_NETDEV_GRANT_TX - err = gnttab_grant_foreign_access(rdomid, msg->tx_shmem_frame, 0); - if (err < 0) { - printk(KERN_ALERT "#### netfront can't grant access to tx_shmem\n"); - BUG(); - } - msg->tx_shmem_ref = err; -#endif - - msg->rx_shmem_frame = virt_to_mfn(np->rx); -#ifdef CONFIG_XEN_NETDEV_GRANT_RX - err = gnttab_grant_foreign_access(rdomid, msg->rx_shmem_frame, 0); - if (err < 0) { - printk(KERN_ALERT "#### netfront can't grant access to rx_shmem\n"); - BUG(); - } - msg->rx_shmem_ref = err; -#endif - - 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 net_private *np) -{ - /* Stop old i/f to prevent errors whilst we rebuild the state. */ - spin_lock_irq(&np->tx_lock); - spin_lock(&np->rx_lock); - netif_stop_queue(np->dev); - /* np->backend_state = BEST_DISCONNECTED; */ - spin_unlock(&np->rx_lock); - spin_unlock_irq(&np->tx_lock); - - /* Free resources. */ - if ( np->tx != NULL ) - { - unbind_evtchn_from_irqhandler(np->evtchn, np->dev); - free_page((unsigned long)np->tx); - free_page((unsigned long)np->rx); - np->evtchn = 0; - np->tx = NULL; - np->rx = NULL; - } -} - -/* Release vif resources and close it down completely. - */ -static void vif_close(struct net_private *np) -{ - WPRINTK("Unexpected netif-CLOSED message in state %s\n", - be_state_name[np->backend_state]); - vif_release(np); - np->backend_state = BEST_CLOSED; - /* todo: take dev down and free. */ - vif_show(np); -} - -/* Move the vif into disconnected state. - * Allocates tx/rx pages. - * Sends connect message to xend. - */ -static void vif_disconnect(struct net_private *np) -{ - if(np->tx) free_page((unsigned long)np->tx); - if(np->rx) free_page((unsigned long)np->rx); - // Before this np->tx and np->rx had better be null. - np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); - np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); - memset(np->tx, 0, PAGE_SIZE); - memset(np->rx, 0, PAGE_SIZE); - np->backend_state = BEST_DISCONNECTED; - send_interface_connect(np); - vif_show(np); -} - -/* 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 net_private *np) -{ - IPRINTK("Attempting to reconnect network interface: handle=%u\n", - np->handle); - vif_release(np); - vif_disconnect(np); - vif_show(np); + if (np) { + IPRINTK("<vif handle=%u %s(%s) evtchn=%u tx=%p rx=%p>\n", + np->handle, + be_state_name[np->backend_state], + np->user_state ? "open" : "closed", + np->evtchn, + np->tx, + np->rx); + } else { + IPRINTK("<vif NULL>\n"); + } +#endif } /* Move the vif into connected state. @@ -1049,26 +843,22 @@ * Binds the irq to the event channel. */ 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); - network_connect(dev, status); - np->evtchn = status->evtchn; -#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) - rdomid = status->domid; -#endif - (void)bind_evtchn_to_irqhandler( - np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); - netctrl_connected_count(); - (void)send_fake_arp(dev); - vif_show(np); +connect_device(struct net_private *np, unsigned int evtchn) +{ + struct net_device *dev = np->netdev; + memcpy(dev->dev_addr, np->mac, ETH_ALEN); + np->evtchn = evtchn; + network_connect(dev); + (void)bind_evtchn_to_irqhandler( + np->evtchn, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); + (void)send_fake_arp(dev); + show_device(np); } static struct ethtool_ops network_ethtool_ops = { - .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, }; /** Create a network device. @@ -1076,22 +866,24 @@ * @param val return parameter for created device * @return 0 on success, error code otherwise */ -static int create_netdev(int handle, struct net_device **val) +static int create_netdev(int handle, struct xenbus_device *dev, + struct net_device **val) { int i, err = 0; - struct net_device *dev = NULL; + struct net_device *netdev = NULL; struct net_private *np = NULL; - if ((dev = alloc_etherdev(sizeof(struct net_private))) == NULL) { + if ((netdev = alloc_etherdev(sizeof(struct net_private))) == NULL) { printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__); err = -ENOMEM; goto exit; } - np = netdev_priv(dev); + np = netdev_priv(netdev); np->backend_state = BEST_CLOSED; np->user_state = UST_CLOSED; np->handle = handle; + np->xbdev = dev; spin_lock_init(&np->tx_lock); spin_lock_init(&np->rx_lock); @@ -1115,268 +907,53 @@ #endif } - dev->open = network_open; - dev->hard_start_xmit = network_start_xmit; - dev->stop = network_close; - dev->get_stats = network_get_stats; - dev->poll = netif_poll; - dev->weight = 64; - dev->features = NETIF_F_IP_CSUM; - - SET_ETHTOOL_OPS(dev, &network_ethtool_ops); - - if ((err = register_netdev(dev)) != 0) { + netdev->open = network_open; + netdev->hard_start_xmit = network_start_xmit; + netdev->stop = network_close; + netdev->get_stats = network_get_stats; + netdev->poll = netif_poll; + netdev->weight = 64; + netdev->features = NETIF_F_IP_CSUM; + + SET_ETHTOOL_OPS(netdev, &network_ethtool_ops); + + if ((err = register_netdev(netdev)) != 0) { printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); goto exit; } - if ((err = xennet_proc_addif(dev)) != 0) { - unregister_netdev(dev); + if ((err = xennet_proc_addif(netdev)) != 0) { + unregister_netdev(netdev); goto exit; } - np->dev = dev; - list_add(&np->list, &dev_list); + np->netdev = netdev; exit: - if ((err != 0) && (dev != NULL)) - kfree(dev); + if ((err != 0) && (netdev != NULL)) + kfree(netdev); else if (val != NULL) - *val = dev; + *val = netdev; return err; } -/* 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 np return parameter for interface state - * @return 0 on success, error code otherwise - */ -static int -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) { - err = -EINVAL; - goto exit; - } - - if ((dev = find_dev_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. */ - DPRINTK("> create device...\n"); - if ((err = create_netdev(status->handle, &dev)) != 0) - goto exit; - - netctrl.interface_n++; - - exit: - if (np != NULL) - *np = ((dev && !err) ? netdev_priv(dev) : NULL); - DPRINTK("< err=%d\n", err); - return err; -} - -/* Handle an interface status message. */ -static void netif_interface_status(netif_fe_interface_status_t *status) -{ - int err = 0; - struct net_private *np = NULL; - - DPRINTK("> status=%s handle=%d\n", - status_name[status->status], status->handle); - - if ((err = target_vif(status, &np)) != 0) { - WPRINTK("Invalid netif: handle=%u\n", status->handle); - return; - } - - if (np == NULL) { - DPRINTK("> no vif\n"); - return; - } - - switch (status->status) { - case NETIF_INTERFACE_STATUS_CLOSED: - switch (np->backend_state) { - case BEST_CLOSED: - case BEST_DISCONNECTED: - case BEST_CONNECTED: - vif_close(np); - break; - } - break; - - case NETIF_INTERFACE_STATUS_DISCONNECTED: - switch (np->backend_state) { - case BEST_CLOSED: - vif_disconnect(np); - break; - case BEST_DISCONNECTED: - case BEST_CONNECTED: - vif_reset(np); - break; - } - break; - - case NETIF_INTERFACE_STATUS_CONNECTED: - switch (np->backend_state) { - case BEST_CLOSED: - WPRINTK("Unexpected netif status %s in state %s\n", - status_name[status->status], - be_state_name[np->backend_state]); - vif_disconnect(np); - vif_connect(np, status); - break; - case BEST_DISCONNECTED: - vif_connect(np, 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(np); -} - -/* - * Initialize the network control interface. - */ -static void netif_driver_status(netif_fe_driver_status_t *status) -{ - netctrl.up = status->status; - 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: - netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]); - break; - - case CMSG_NETIF_FE_DRIVER_STATUS: - netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]); - break; - - 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; - - DPRINTK(">\n"); - - for (wait_i = 0; wait_i < wait_n; wait_i++) { - DPRINTK("> wait_i=%d\n", wait_i); - conn = netctrl_connected(); - if(conn) break; - DPRINTK("> schedule_timeout...\n"); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(10); - } - - DPRINTK("> wait finished...\n"); - if (conn <= 0) { - err = netctrl_err(-ENETDOWN); - WPRINTK("Failed to connect all virtual interfaces: err=%d\n", err); - } - - DPRINTK("< 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; - u32 query = -1; - - DPRINTK(">\n"); - - netctrl.interface_n = 0; - 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)); - DPRINTK("> set_current_state...\n"); - set_current_state(state); - DPRINTK("> rmsg=%p msg=%p, reply=%p\n", &rmsg, rmsg.msg, reply); - DPRINTK("> sending...\n"); - err = ctrl_if_send_message_and_get_response(&cmsg, &rmsg, state); - 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) { - // No more interfaces. - break; - } - query = -reply->handle - 2; - DPRINTK(">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); - } - - DPRINTK("< err=%d\n", err); - return err; -} - -#endif +static int destroy_netdev(struct net_device *netdev) +{ + struct net_private *np = NULL; + +#ifdef CONFIG_PROC_FS + xennet_proc_delif(netdev); +#endif + + unregister_netdev(netdev); + + np = netdev_priv(netdev); + list_del(&np->list); + + kfree(netdev); + + return 0; +} /* * We use this notifier to send out a fake ARP reply to reset switches and @@ -1387,19 +964,11 @@ { 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) - goto out; - - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - if (np->dev == dev) - (void)send_fake_arp(dev); - } + + /* UP event and is it one of our devices? */ + if (event == NETDEV_UP && dev->open == network_open) + (void)send_fake_arp(dev); - out: return NOTIFY_DONE; } @@ -1409,67 +978,310 @@ .priority = 0 }; -static int __init netif_init(void) -{ - int err = 0; - - if (xen_start_info.flags & SIF_INITDOMAIN) - return 0; +static struct xenbus_device_id netfront_ids[] = { + { "vif" }, + { "" } +}; + +static void watch_for_status(struct xenbus_watch *watch, const char *node) +{ +} + +static int setup_device(struct xenbus_device *dev, struct netfront_info *info) +{ + evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound }; + int err; + #ifdef CONFIG_XEN_NETDEV_GRANT_TX - /* A grant for every ring slot */ - if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, - &gref_tx_head) < 0) { - printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); - return 1; - } - printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); + info->tx_ring_ref = GRANT_INVALID_REF; #endif #ifdef CONFIG_XEN_NETDEV_GRANT_RX - /* A grant for every ring slot */ - if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE, - &gref_rx_head) < 0) { - printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); - return 1; - } - printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); -#endif - - if ((err = xennet_proc_init()) != 0) - return err; - - IPRINTK("Initialising virtual ethernet driver.\n"); - INIT_LIST_HEAD(&dev_list); - (void)register_inetaddr_notifier(¬ifier_inetdev); - 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); - - DPRINTK("< err=%d\n", err); - return err; -} - -static void netif_exit(void) -{ + info->rx_ring_ref = GRANT_INVALID_REF; +#endif + + info->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL); + if (info->tx == 0) { + err = -ENOMEM; + xenbus_dev_error(dev, err, "allocating tx ring page"); + goto out; + } + info->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL); + if (info->rx == 0) { + err = -ENOMEM; + xenbus_dev_error(dev, err, "allocating rx ring page"); + goto out; + } + memset(info->tx, 0, PAGE_SIZE); + memset(info->rx, 0, PAGE_SIZE); + info->backend_state = BEST_DISCONNECTED; + #ifdef CONFIG_XEN_NETDEV_GRANT_TX - gnttab_free_grant_references(gref_tx_head); -#endif + err = gnttab_grant_foreign_access(info->backend_id, + virt_to_mfn(info->tx), 0); + if (err < 0) { + xenbus_dev_error(dev, err, "granting access to tx ring page"); + goto out; + } + info->tx_ring_ref = err; +#else + info->tx_ring_ref = virt_to_mfn(info->tx); +#endif + #ifdef CONFIG_XEN_NETDEV_GRANT_RX - gnttab_free_grant_references(gref_rx_head); -#endif -} - -static void vif_suspend(struct net_private *np) -{ + err = gnttab_grant_foreign_access(info->backend_id, + virt_to_mfn(info->rx), 0); + if (err < 0) { + xenbus_dev_error(dev, err, "granting access to rx ring page"); + goto out; + } + info->rx_ring_ref = err; +#else + info->rx_ring_ref = virt_to_mfn(info->rx); +#endif + + op.u.alloc_unbound.dom = info->backend_id; + err = HYPERVISOR_event_channel_op(&op); + if (err) { + xenbus_dev_error(dev, err, "allocating event channel"); + goto out; + } + connect_device(info, op.u.alloc_unbound.port); + return 0; + + out: + if (info->tx) + free_page((unsigned long)info->tx); + info->tx = 0; + if (info->rx) + free_page((unsigned long)info->rx); + info->rx = 0; +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + if (info->tx_ring_ref != GRANT_INVALID_REF) + gnttab_end_foreign_access(info->tx_ring_ref, 0); + info->tx_ring_ref = GRANT_INVALID_REF; +#endif +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + if (info->rx_ring_ref != GRANT_INVALID_REF) + gnttab_end_foreign_access(info->rx_ring_ref, 0); + info->rx_ring_ref = GRANT_INVALID_REF; +#endif + return err; +} + +static void netif_free(struct netfront_info *info) +{ + if (info->tx) + free_page((unsigned long)info->tx); + info->tx = 0; + if (info->rx) + free_page((unsigned long)info->rx); + info->rx = 0; +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + if (info->tx_ring_ref != GRANT_INVALID_REF) + gnttab_end_foreign_access(info->tx_ring_ref, 0); + info->tx_ring_ref = GRANT_INVALID_REF; +#endif +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + if (info->rx_ring_ref != GRANT_INVALID_REF) + gnttab_end_foreign_access(info->rx_ring_ref, 0); + info->rx_ring_ref = GRANT_INVALID_REF; +#endif + unbind_evtchn_from_irqhandler(info->evtchn, info->netdev); + info->evtchn = 0; +} + +/* Stop network device and free tx/rx queues and irq. + */ +static void shutdown_device(struct net_private *np) +{ + /* Stop old i/f to prevent errors whilst we rebuild the state. */ + spin_lock_irq(&np->tx_lock); + spin_lock(&np->rx_lock); + netif_stop_queue(np->netdev); + /* np->backend_state = BEST_DISCONNECTED; */ + spin_unlock(&np->rx_lock); + spin_unlock_irq(&np->tx_lock); + + /* Free resources. */ + netif_free(np); +} + +/* Common code used when first setting up, and when resuming. */ +static int talk_to_backend(struct xenbus_device *dev, + struct netfront_info *info) +{ + char *backend, *mac, *e, *s; + const char *message; + int err, i; + + backend = NULL; + err = xenbus_gather(dev->nodename, + "backend-id", "%i", &info->backend_id, + "backend", NULL, &backend, + NULL); + if (XENBUS_EXIST_ERR(err)) + goto out; + if (backend && strlen(backend) == 0) { + err = -ENOENT; + goto out; + } + if (err < 0) { + xenbus_dev_error(dev, err, "reading %s/backend or backend-id", + dev->nodename); + goto out; + } + + mac = xenbus_read(dev->nodename, "mac", NULL); + if (IS_ERR(mac)) { + err = PTR_ERR(mac); + xenbus_dev_error(dev, err, "reading %s/mac", + dev->nodename); + goto out; + } + s = mac; + for (i = 0; i < ETH_ALEN; i++) { + info->mac[i] = simple_strtoul(s, &e, 16); + if (s == e || (e[0] != ':' && e[0] != 0)) { + kfree(mac); + err = -ENOENT; + xenbus_dev_error(dev, err, "parsing %s/mac", + dev->nodename); + goto out; + } + s = &e[1]; + } + kfree(mac); + + /* Create shared ring, alloc event channel. */ + err = setup_device(dev, info); + if (err) { + xenbus_dev_error(dev, err, "setting up ring"); + goto out; + } + + err = xenbus_transaction_start(dev->nodename); + if (err) { + xenbus_dev_error(dev, err, "starting transaction"); + goto destroy_ring; + } + + err = xenbus_printf(dev->nodename, "tx-ring-ref","%u", + info->tx_ring_ref); + if (err) { + message = "writing tx ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(dev->nodename, "rx-ring-ref","%u", + info->rx_ring_ref); + if (err) { + message = "writing rx ring-ref"; + goto abort_transaction; + } + err = xenbus_printf(dev->nodename, + "event-channel", "%u", info->evtchn); + if (err) { + message = "writing event-channel"; + goto abort_transaction; + } + + info->backend = backend; + backend = NULL; + + info->watch.node = info->backend; + info->watch.callback = watch_for_status; + err = register_xenbus_watch(&info->watch); + if (err) { + message = "registering watch on backend"; + goto abort_transaction; + } + + err = xenbus_transaction_end(0); + if (err) { + xenbus_dev_error(dev, err, "completing transaction"); + goto destroy_ring; + } + + netif_state = NETIF_STATE_CONNECTED; + + out: + if (backend) + kfree(backend); + return err; + + abort_transaction: + xenbus_transaction_end(1); + /* Have to do this *outside* transaction. */ + xenbus_dev_error(dev, err, "%s", message); + destroy_ring: + shutdown_device(info); + goto out; +} + +/* Setup supplies the backend dir, virtual device. + + We place an event channel and shared frame entries. + We watch backend to wait if it's ok. */ +static int netfront_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + int err; + struct net_device *netdev; + struct netfront_info *info; + unsigned int handle; + + err = xenbus_scanf(dev->nodename, "handle", "%u", &handle); + if (XENBUS_EXIST_ERR(err)) + return err; + if (err < 0) { + xenbus_dev_error(dev, err, "reading handle"); + return err; + } + + err = create_netdev(handle, dev, &netdev); + if (err) { + xenbus_dev_error(dev, err, "creating netdev"); + return err; + } + + info = netdev_priv(netdev); + err = talk_to_backend(dev, info); + if (err) { + destroy_netdev(netdev); + return err; + } + + /* Call once in case entries already there. */ + watch_for_status(&info->watch, info->watch.node); + + return 0; +} + +static int netfront_remove(struct xenbus_device *dev) +{ + struct netfront_info *info = dev->data; + + if (info->backend) + unregister_xenbus_watch(&info->watch); + + netif_free(info); + + kfree(info->backend); + kfree(info); + + return 0; +} + +static int netfront_suspend(struct xenbus_device *dev) +{ + struct net_private *np = dev->data; /* Avoid having tx/rx stuff happen until we're ready. */ - unbind_evtchn_from_irqhandler(np->evtchn, np->dev); -} - -static void vif_resume(struct net_private *np) -{ + unbind_evtchn_from_irqhandler(np->evtchn, np->netdev); + return 0; +} + +static int netfront_resume(struct xenbus_device *dev) +{ + struct net_private *np = dev->data; /* * Connect regardless of whether IFF_UP flag set. * Stop bad things from happening until we're back up. @@ -1478,29 +1290,96 @@ memset(np->tx, 0, PAGE_SIZE); memset(np->rx, 0, PAGE_SIZE); - send_interface_connect(np); -} - -void netif_suspend(void) -{ - struct list_head *ent; - struct net_private *np; - - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - vif_suspend(np); - } -} - -void netif_resume(void) -{ - struct list_head *ent; - struct net_private *np; - - list_for_each (ent, &dev_list) { - np = list_entry(ent, struct net_private, list); - vif_resume(np); - } + // send_interface_connect(np); + return 0; +} + +static struct xenbus_driver netfront = { + .name = "vif", + .owner = THIS_MODULE, + .ids = netfront_ids, + .probe = netfront_probe, + .remove = netfront_remove, + .resume = netfront_resume, + .suspend = netfront_suspend, +}; + +static void __init init_net_xenbus(void) +{ + xenbus_register_device(&netfront); +} + +static int wait_for_netif(void) +{ + int err = 0; + int i; + + /* + * We should figure out how many and which devices we need to + * proceed and only wait for those. For now, continue once the + * first device is around. + */ + for ( i=0; netif_state != NETIF_STATE_CONNECTED && (i < 10*HZ); i++ ) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + } + + if (netif_state != NETIF_STATE_CONNECTED) { + WPRINTK("Timeout connecting to device!\n"); + err = -ENOSYS; + } + return err; +} + +static int __init netif_init(void) +{ + int err = 0; + + if (xen_start_info.flags & SIF_INITDOMAIN) + return 0; + +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + /* A grant for every ring slot */ + if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE, + &gref_tx_head) < 0) { + printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); + return 1; + } + printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n"); +#endif +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + /* A grant for every ring slot */ + if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE, + &gref_rx_head) < 0) { + printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); + return 1; + } + printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n"); +#endif + + if ((err = xennet_proc_init()) != 0) + return err; + + IPRINTK("Initialising virtual ethernet driver.\n"); + + (void)register_inetaddr_notifier(¬ifier_inetdev); + + init_net_xenbus(); + + wait_for_netif(); + + return err; +} + +static void netif_exit(void) +{ +#ifdef CONFIG_XEN_NETDEV_GRANT_TX + gnttab_free_grant_references(gref_tx_head); +#endif +#ifdef CONFIG_XEN_NETDEV_GRANT_RX + gnttab_free_grant_references(gref_rx_head); +#endif } #ifdef CONFIG_PROC_FS diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h Thu Aug 25 18:18:47 2005 @@ -65,8 +65,26 @@ extern unsigned int *phys_to_machine_mapping; #define pfn_to_mfn(pfn) \ ((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL) -#define mfn_to_pfn(mfn) \ -((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)]) +static inline unsigned long mfn_to_pfn(unsigned long mfn) +{ + unsigned int pfn; + + /* + * The array access can fail (e.g., device space beyond end of RAM). + * In such cases it doesn't matter what we return (we return garbage), + * but we must handle the fault without crashing! + */ + asm ( + "1: movl %1,%0\n" + "2:\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b,2b\n" + ".previous" + : "=r" (pfn) : "m" (machine_to_phys_mapping[mfn]) ); + + return (unsigned long)pfn; +} /* Definitions for machine and pseudophysical addresses. */ #ifdef CONFIG_X86_PAE diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h Thu Aug 25 18:18:47 2005 @@ -67,8 +67,26 @@ extern u32 *phys_to_machine_mapping; #define pfn_to_mfn(pfn) \ ((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL) -#define mfn_to_pfn(mfn) \ -((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)]) +static inline unsigned long mfn_to_pfn(unsigned long mfn) +{ + unsigned int pfn; + + /* + * The array access can fail (e.g., device space beyond end of RAM). + * In such cases it doesn't matter what we return (we return garbage), + * but we must handle the fault without crashing! + */ + asm ( + "1: movl %1,%k0\n" + "2:\n" + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 1b,2b\n" + ".previous" + : "=r" (pfn) : "m" (machine_to_phys_mapping[mfn]) ); + + return (unsigned long)pfn; +} /* Definitions for machine and pseudophysical addresses. */ typedef unsigned long paddr_t; diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/include/asm-xen/gnttab.h --- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h Thu Aug 25 18:18:47 2005 @@ -30,10 +30,12 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly); +void gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); void gnttab_end_foreign_access(grant_ref_t ref, int readonly); int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn); +unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref); unsigned long gnttab_end_foreign_transfer(grant_ref_t ref); int gnttab_query_foreign_access(grant_ref_t ref); diff -r e2025593f702 -r 112d44270733 tools/blktap/blktaplib.h --- a/tools/blktap/blktaplib.h Wed Aug 24 23:16:52 2005 +++ b/tools/blktap/blktaplib.h Thu Aug 25 18:18:47 2005 @@ -7,7 +7,7 @@ #ifndef __BLKTAPLIB_H__ #define __BLKTAPLIB_H__ -#include <xc.h> +#include <xenctrl.h> #include <sys/user.h> #include <xen/xen.h> #include <xen/io/blkif.h> diff -r e2025593f702 -r 112d44270733 tools/blktap/parallax/block-async.h --- a/tools/blktap/parallax/block-async.h Wed Aug 24 23:16:52 2005 +++ b/tools/blktap/parallax/block-async.h Thu Aug 25 18:18:47 2005 @@ -7,7 +7,7 @@ #define _BLOCKASYNC_H_ #include <assert.h> -#include <xc.h> +#include <xenctrl.h> #include "vdi.h" struct io_ret diff -r e2025593f702 -r 112d44270733 tools/blktap/parallax/blockstore.h --- a/tools/blktap/parallax/blockstore.h Wed Aug 24 23:16:52 2005 +++ b/tools/blktap/parallax/blockstore.h Thu Aug 25 18:18:47 2005 @@ -10,7 +10,7 @@ #define __BLOCKSTORE_H__ #include <netinet/in.h> -#include <xc.h> +#include <xenctrl.h> #define BLOCK_SIZE 4096 #define BLOCK_SHIFT 12 diff -r e2025593f702 -r 112d44270733 tools/console/Makefile --- a/tools/console/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/console/Makefile Thu Aug 25 18:18:47 2005 @@ -26,11 +26,11 @@ xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c)) $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \ - -lxc -lxenstore + -lxenctrl -lxenstore xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c)) $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \ - -lxc -lxenstore + -lxenctrl -lxenstore install: $(BIN) $(INSTALL_DIR) -p $(DESTDIR)/$(DAEMON_INSTALL_DIR) diff -r e2025593f702 -r 112d44270733 tools/console/client/main.c --- a/tools/console/client/main.c Wed Aug 24 23:16:52 2005 +++ b/tools/console/client/main.c Thu Aug 25 18:18:47 2005 @@ -36,7 +36,7 @@ #include <errno.h> #include <pty.h> -#include "xc.h" +#include "xenctrl.h" #include "xs.h" #define ESCAPE_CHARACTER 0x1d diff -r e2025593f702 -r 112d44270733 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Wed Aug 24 23:16:52 2005 +++ b/tools/console/daemon/io.c Thu Aug 25 18:18:47 2005 @@ -23,7 +23,7 @@ #include "utils.h" #include "io.h" -#include "xc.h" +#include "xenctrl.h" #include "xs.h" #include "xen/io/domain_controller.h" #include "xcs_proto.h" diff -r e2025593f702 -r 112d44270733 tools/console/daemon/main.c --- a/tools/console/daemon/main.c Wed Aug 24 23:16:52 2005 +++ b/tools/console/daemon/main.c Thu Aug 25 18:18:47 2005 @@ -25,7 +25,7 @@ #include <unistd.h> #include <sys/types.h> -#include "xc.h" +#include "xenctrl.h" #include "xen/io/domain_controller.h" #include "xcs_proto.h" diff -r e2025593f702 -r 112d44270733 tools/console/daemon/utils.c --- a/tools/console/daemon/utils.c Wed Aug 24 23:16:52 2005 +++ b/tools/console/daemon/utils.c Thu Aug 25 18:18:47 2005 @@ -33,7 +33,7 @@ #include <sys/un.h> #include <string.h> -#include "xc.h" +#include "xenctrl.h" #include "xen/io/domain_controller.h" #include "xcs_proto.h" diff -r e2025593f702 -r 112d44270733 tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Thu Aug 25 18:18:47 2005 @@ -35,7 +35,7 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> -#include <xc.h> +#include <xenctrl.h> #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */ long (*myptrace)(enum __ptrace_request, pid_t, long, long); int (*myxcwait)(int domain, int *status, int options) ; diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/Makefile --- a/tools/debugger/libxendebug/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/libxendebug/Makefile Thu Aug 25 18:18:47 2005 @@ -20,7 +20,7 @@ CFLAGS += -Wp,-MD,.$(@F).d DEPS = .*.d -LDFLAGS += -L$(XEN_ROOT)/tools/libxc -lxc +LDFLAGS += -L$(XEN_ROOT)/tools/libxc -lxenctrl LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/xendebug.c --- a/tools/debugger/libxendebug/xendebug.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/libxendebug/xendebug.c Thu Aug 25 18:18:47 2005 @@ -12,7 +12,7 @@ #include <string.h> #include <errno.h> #include <sys/mman.h> -#include <xc.h> +#include <xenctrl.h> #include "list.h" #if defined(__i386__) diff -r e2025593f702 -r 112d44270733 tools/debugger/libxendebug/xendebug.h --- a/tools/debugger/libxendebug/xendebug.h Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/libxendebug/xendebug.h Thu Aug 25 18:18:47 2005 @@ -9,7 +9,7 @@ #ifndef _XENDEBUG_H_DEFINED #define _XENDEBUG_H_DEFINED -#include <xc.h> +#include <xenctrl.h> int xendebug_attach(int xc_handle, u32 domid, diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_domain.c --- a/tools/debugger/pdb/pdb_caml_domain.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_caml_domain.c Thu Aug 25 18:18:47 2005 @@ -6,7 +6,7 @@ * PDB's OCaml interface library for debugging domains */ -#include <xc.h> +#include <xenctrl.h> #include <xendebug.h> #include <errno.h> #include <stdio.h> diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_evtchn.c --- a/tools/debugger/pdb/pdb_caml_evtchn.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_caml_evtchn.c Thu Aug 25 18:18:47 2005 @@ -6,7 +6,7 @@ * PDB's OCaml interface library for event channels */ -#include <xc.h> +#include <xenctrl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_process.c --- a/tools/debugger/pdb/pdb_caml_process.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_caml_process.c Thu Aug 25 18:18:47 2005 @@ -15,7 +15,7 @@ #include <caml/memory.h> #include <caml/mlvalues.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/xen.h> #include <xen/io/domain_controller.h> #include <xen/linux/privcmd.h> diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_xc.c --- a/tools/debugger/pdb/pdb_caml_xc.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_caml_xc.c Thu Aug 25 18:18:47 2005 @@ -6,7 +6,7 @@ * PDB's OCaml interface library for debugging domains */ -#include <xc.h> +#include <xenctrl.h> #include <xendebug.h> #include <errno.h> #include <stdio.h> diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_caml_xcs.c --- a/tools/debugger/pdb/pdb_caml_xcs.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_caml_xcs.c Thu Aug 25 18:18:47 2005 @@ -17,7 +17,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <errno.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/xen.h> #include <xen/io/domain_controller.h> diff -r e2025593f702 -r 112d44270733 tools/debugger/pdb/pdb_xen.c --- a/tools/debugger/pdb/pdb_xen.c Wed Aug 24 23:16:52 2005 +++ b/tools/debugger/pdb/pdb_xen.c Thu Aug 25 18:18:47 2005 @@ -7,7 +7,7 @@ * PDB interface library for accessing Xen */ -#include <xc.h> +#include <xenctrl.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> diff -r e2025593f702 -r 112d44270733 tools/examples/Makefile --- a/tools/examples/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/examples/Makefile Thu Aug 25 18:18:47 2005 @@ -24,10 +24,14 @@ XEN_BOOT_DIR = /usr/lib/xen/boot XEN_BOOT = mem-map.sxp +XEN_HOTPLUG_DIR = /etc/hotplug.d/xen-backend +XEN_HOTPLUG_SCRIPTS = backend.hotplug + all: build: -install: all install-initd install-configs install-scripts install-boot +install: all install-initd install-configs install-scripts install-boot \ + install-hotplug install-initd: [ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d @@ -60,4 +64,12 @@ $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_BOOT_DIR); \ done +install-hotplug: + [ -d $(DESTDIR)$(XEN_HOTPLUG_DIR) ] || \ + $(INSTALL_DIR) $(DESTDIR)$(XEN_HOTPLUG_DIR) + for i in $(XEN_HOTPLUG_SCRIPTS); \ + do [ -a $(DESTDIR)$(XEN_HOTPLUG_DIR)/$$i ] || \ + $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_HOTPLUG_DIR); \ + done + clean: diff -r e2025593f702 -r 112d44270733 tools/examples/README --- a/tools/examples/README Wed Aug 24 23:16:52 2005 +++ b/tools/examples/README Thu Aug 25 18:18:47 2005 @@ -9,9 +9,20 @@ send it (preferably with a little summary to go in this file) to <xen-devel@xxxxxxxxxxxxxxxxxxxxx> so we can add it to this directory. +block-enbd - binds/unbinds network block devices +block-file - binds/unbinds file to loopback device +mem-map.sxp - memory map xend configuration file. network - default network setup script called by xend at startup. +network-route - default xen network start/stop script. +network-nat - default xen network start/stop script when using NAT. vif-bridge - default virtual network interface setup script. +vif-route - default xen virtual network start/stop script +vif-nat - configures vif in routed-nat mode. xend-config.sxp - default xend configuration file. xmexample1 - example configuration script for 'xm create'. xmexample2 - a more complex configuration script for 'xm create'. +xmexample3 - an advanced configuration script for 'xm create' + that utilizes the vmid. +xmexample.vmx - a configuration script for creating a vmx domain with + 'xm create'. diff -r e2025593f702 -r 112d44270733 tools/examples/vif-bridge --- a/tools/examples/vif-bridge Wed Aug 24 23:16:52 2005 +++ b/tools/examples/vif-bridge Thu Aug 25 18:18:47 2005 @@ -74,8 +74,10 @@ exit fi -# Add/remove vif to/from bridge. -brctl ${brcmd} ${bridge} ${vif} +# Add vif to bridge. vifs are auto-removed from bridge. +if [ "${brcmd}" == "addif" ] ; then + brctl ${brcmd} ${bridge} ${vif} +fi ifconfig ${vif} $OP if [ ${ip} ] ; then diff -r e2025593f702 -r 112d44270733 tools/firmware/acpi/acpi2_0.h --- a/tools/firmware/acpi/acpi2_0.h Wed Aug 24 23:16:52 2005 +++ b/tools/firmware/acpi/acpi2_0.h Thu Aug 25 18:18:47 2005 @@ -18,7 +18,7 @@ #ifndef _ACPI_2_0_H_ #define _ACPI_2_0_H_ -#include "xc.h" // for u8, u16, u32, u64 definition +#include "xenctrl.h" // for u8, u16, u32, u64 definition #pragma pack (1) diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/i8254.c --- a/tools/ioemu/hw/i8254.c Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/hw/i8254.c Thu Aug 25 18:18:47 2005 @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" -#include "xc.h" +#include "xenctrl.h" #include <io/ioreq.h> //#define DEBUG_PIT diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/i8259.c --- a/tools/ioemu/hw/i8259.c Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/hw/i8259.c Thu Aug 25 18:18:47 2005 @@ -22,7 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" -#include "xc.h" +#include "xenctrl.h" #include <io/ioreq.h> /* debug PIC */ diff -r e2025593f702 -r 112d44270733 tools/ioemu/hw/ioapic.h --- a/tools/ioemu/hw/ioapic.h Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/hw/ioapic.h Thu Aug 25 18:18:47 2005 @@ -26,7 +26,7 @@ #ifndef __IOAPIC_H #define __IOAPIC_H -#include "xc.h" +#include "xenctrl.h" #include <io/ioreq.h> #include <io/vmx_vlapic.h> diff -r e2025593f702 -r 112d44270733 tools/ioemu/target-i386-dm/Makefile --- a/tools/ioemu/target-i386-dm/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/target-i386-dm/Makefile Thu Aug 25 18:18:47 2005 @@ -188,7 +188,7 @@ ######################################################### DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DAPIC_SUPPORT -LIBS+=-lm -L../../libxc -lxc +LIBS+=-lm -L../../libxc -lxenctrl ifndef CONFIG_USER_ONLY LIBS+=-lz endif diff -r e2025593f702 -r 112d44270733 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/target-i386-dm/helper2.c Thu Aug 25 18:18:47 2005 @@ -47,7 +47,7 @@ #include <fcntl.h> #include <sys/ioctl.h> -#include "xc.h" +#include "xenctrl.h" #include <io/ioreq.h> #include "cpu.h" diff -r e2025593f702 -r 112d44270733 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Wed Aug 24 23:16:52 2005 +++ b/tools/ioemu/vl.c Thu Aug 25 18:18:47 2005 @@ -72,7 +72,7 @@ #endif #endif /* CONFIG_SDL */ -#include "xc.h" +#include "xenctrl.h" #include "exec-all.h" //#define DO_TB_FLUSH diff -r e2025593f702 -r 112d44270733 tools/libxc/Makefile --- a/tools/libxc/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/Makefile Thu Aug 25 18:18:47 2005 @@ -12,28 +12,32 @@ XEN_ROOT = ../.. include $(XEN_ROOT)/tools/Rules.mk -SRCS := -SRCS += xc_sedf.c -SRCS += xc_bvtsched.c -SRCS += xc_core.c -SRCS += xc_domain.c -SRCS += xc_evtchn.c -SRCS += xc_gnttab.c -SRCS += xc_load_bin.c -SRCS += xc_load_elf.c -SRCS += xc_linux_build.c -SRCS += xc_misc.c -SRCS += xc_physdev.c -SRCS += xc_private.c +SRCS := +BUILD_SRCS := +SRCS += xc_bvtsched.c +SRCS += xc_core.c +SRCS += xc_domain.c +SRCS += xc_evtchn.c +SRCS += xc_gnttab.c +SRCS += xc_misc.c +SRCS += xc_physdev.c +SRCS += xc_private.c +SRCS += xc_sedf.c + ifeq ($(XEN_TARGET_ARCH),ia64) -SRCS += xc_ia64_stubs.c +BUILD_SRCS += xc_ia64_stubs.c else -SRCS += xc_load_aout9.c -SRCS += xc_linux_restore.c -SRCS += xc_linux_save.c -SRCS += xc_vmx_build.c -SRCS += xc_ptrace.c -SRCS += xc_ptrace_core.c +SRCS += xc_ptrace.c +SRCS += xc_ptrace_core.c + +BUILD_SRCS := xc_load_aout9.c +BUILD_SRCS += xc_load_bin.c +BUILD_SRCS += xc_load_elf.c +BUILD_SRCS += xc_linux_build.c +BUILD_SRCS += xc_linux_restore.c +BUILD_SRCS += xc_linux_save.c +BUILD_SRCS += xc_vmx_build.c +BUILD_SRCS += xg_private.c endif CFLAGS += -Wall @@ -43,13 +47,20 @@ CFLAGS += $(INCLUDES) -I. # Get gcc to generate the dependencies for us. CFLAGS += -Wp,-MD,.$(@F).d +LDFLAGS += -L. DEPS = .*.d LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) -LIB := libxc.a libxc-pic.a -LIB += libxc.so libxc.so.$(MAJOR) libxc.so.$(MAJOR).$(MINOR) +LIB_BUILD_OBJS := $(patsubst %.c,%.o,$(BUILD_SRCS)) +PIC_BUILD_OBJS := $(patsubst %.c,%.opic,$(BUILD_SRCS)) + +LIB := libxenctrl.a +LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR) + +LIB += libxenguest.a +LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR) all: build build: check-for-zlib mk-symlinks @@ -77,11 +88,16 @@ install: build [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR) [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include - $(INSTALL_PROG) libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) - $(INSTALL_DATA) libxc.a $(DESTDIR)/usr/$(LIBDIR) - ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxc.so.$(MAJOR) - ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxc.so - $(INSTALL_DATA) xc.h $(DESTDIR)/usr/include + $(INSTALL_PROG) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DATA) libxenctrl.a $(DESTDIR)/usr/$(LIBDIR) + ln -sf libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxenctrl.so.$(MAJOR) + ln -sf libxenctrl.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxenctrl.so + $(INSTALL_DATA) xenctrl.h $(DESTDIR)/usr/include + + $(INSTALL_PROG) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) + $(INSTALL_DATA) libxenguest.a $(DESTDIR)/usr/$(LIBDIR) + ln -sf libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxenguest.so.$(MAJOR) + ln -sf libxenguest.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxenguest.so .PHONY: TAGS clean rpm install all @@ -100,18 +116,30 @@ mv staging/i386/*.rpm . rm -rf staging -libxc.a: $(LIB_OBJS) +# libxenctrl + +libxenctrl.a: $(LIB_OBJS) $(AR) rc $@ $^ -libxc-pic.a: $(PIC_OBJS) +libxenctrl.so: libxenctrl.so.$(MAJOR) + ln -sf $< $@ +libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR) + ln -sf $< $@ + +libxenctrl.so.$(MAJOR).$(MINOR): $(PIC_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenctrl.so.$(MAJOR) -shared -o $@ $^ + +# libxenguest + +libxenguest.a: $(LIB_BUILD_OBJS) $(AR) rc $@ $^ -libxc.so: libxc.so.$(MAJOR) +libxenguest.so: libxenguest.so.$(MAJOR) ln -sf $< $@ -libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR) +libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR) ln -sf $< $@ -libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -lz +libxenguest.so.$(MAJOR).$(MINOR): $(PIC_BUILD_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxenguest.so.$(MAJOR) -shared -o $@ $^ -lz -lxenctrl -include $(DEPS) diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_core.c --- a/tools/libxc/xc_core.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_core.c Thu Aug 25 18:18:47 2005 @@ -1,4 +1,4 @@ -#include "xc_private.h" +#include "xg_private.h" #define ELFSIZE 32 #include "xc_elf.h" #include <stdlib.h> diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_domain.c Thu Aug 25 18:18:47 2005 @@ -266,7 +266,7 @@ int err; unsigned int npages = mem_kb / (PAGE_SIZE/1024); - err = do_dom_mem_op(xc_handle, MEMOP_increase_reservation, NULL, + err = xc_dom_mem_op(xc_handle, MEMOP_increase_reservation, NULL, npages, 0, domid); if (err == npages) return 0; diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_linux_build.c Thu Aug 25 18:18:47 2005 @@ -2,7 +2,8 @@ * xc_linux_build.c */ -#include "xc_private.h" +#include "xg_private.h" +#include <xenctrl.h> #if defined(__i386__) #define ELFSIZE 32 @@ -340,7 +341,7 @@ unsigned long count, i; start_info_t *start_info; shared_info_t *shared_info; - mmu_t *mmu = NULL; + xc_mmu_t *mmu = NULL; int rc; unsigned long nr_pt_pages; @@ -490,7 +491,7 @@ } } - if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL ) + if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL ) goto error_out; /* setup page tables */ @@ -520,9 +521,9 @@ page_array[physmap_pfn++]); for ( count = 0; count < nr_pages; count++ ) { - if ( add_mmu_update(xc_handle, mmu, - (page_array[count] << PAGE_SHIFT) | - MMU_MACHPHYS_UPDATE, count) ) + if ( xc_add_mmu_update(xc_handle, mmu, + (page_array[count] << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE, count) ) { munmap(physmap, PAGE_SIZE); goto error_out; @@ -602,7 +603,7 @@ munmap(shared_info, PAGE_SIZE); /* Send the page update requests down to the hypervisor. */ - if ( finish_mmu_updates(xc_handle, mmu) ) + if ( xc_finish_mmu_updates(xc_handle, mmu) ) goto error_out; free(mmu); @@ -676,7 +677,7 @@ op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; - if ( (do_dom0_op(xc_handle, &op) < 0) || + if ( (xc_dom0_op(xc_handle, &op) < 0) || ((u16)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); @@ -793,7 +794,7 @@ launch_op.u.setdomaininfo.ctxt = ctxt; launch_op.cmd = DOM0_SETDOMAININFO; - rc = do_dom0_op(xc_handle, &launch_op); + rc = xc_dom0_op(xc_handle, &launch_op); return rc; diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_linux_restore.c Thu Aug 25 18:18:47 2005 @@ -6,7 +6,12 @@ * Copyright (c) 2003, K A Fraser. */ -#include "xc_private.h" +#include <stdlib.h> +#include <unistd.h> + +#include "xg_private.h" +#include <xenctrl.h> + #include <xen/linux/suspend.h> #define MAX_BATCH_SIZE 1024 @@ -89,7 +94,7 @@ char *region_base; - mmu_t *mmu = NULL; + xc_mmu_t *mmu = NULL; /* used by debug verify code */ unsigned long buf[PAGE_SIZE/sizeof(unsigned long)]; @@ -132,7 +137,7 @@ /* Get the domain's shared-info frame. */ op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)dom; - if (do_dom0_op(xc_handle, &op) < 0) { + if (xc_dom0_op(xc_handle, &op) < 0) { ERR("Could not get information on new domain"); goto out; } @@ -158,7 +163,7 @@ goto out; } - mmu = init_mmu_updates(xc_handle, dom); + mmu = xc_init_mmu_updates(xc_handle, dom); if (mmu == NULL) { ERR("Could not initialise for MMU updates"); goto out; @@ -355,8 +360,9 @@ } } - if ( add_mmu_update(xc_handle, mmu, - (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) ) + if ( xc_add_mmu_update(xc_handle, mmu, + (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, + pfn) ) { printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn); goto out; @@ -370,7 +376,7 @@ DPRINTF("Received all pages\n"); - if ( finish_mmu_updates(xc_handle, mmu) ) + if ( xc_finish_mmu_updates(xc_handle, mmu) ) goto out; /* @@ -388,14 +394,14 @@ pin[nr_pins].mfn = pfn_to_mfn_table[i]; if ( ++nr_pins == MAX_PIN_BATCH ) { - if ( do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 ) + if ( xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 ) goto out; nr_pins = 0; } } if ( (nr_pins != 0) && - (do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) ) + (xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) ) goto out; DPRINTF("\b\b\b\b100%%\n"); @@ -435,7 +441,7 @@ if ( count > 0 ) { - if ( (rc = do_dom_mem_op( xc_handle, + if ( (rc = xc_dom_mem_op( xc_handle, MEMOP_decrease_reservation, pfntab, count, 0, dom )) <0 ) { @@ -586,7 +592,7 @@ op.u.setdomaininfo.domain = (domid_t)dom; op.u.setdomaininfo.vcpu = 0; op.u.setdomaininfo.ctxt = &ctxt; - rc = do_dom0_op(xc_handle, &op); + rc = xc_dom0_op(xc_handle, &op); if ( rc != 0 ) { @@ -597,7 +603,7 @@ DPRINTF("Domain ready to be unpaused\n"); op.cmd = DOM0_UNPAUSEDOMAIN; op.u.unpausedomain.domain = (domid_t)dom; - rc = do_dom0_op(xc_handle, &op); + rc = xc_dom0_op(xc_handle, &op); if (rc == 0) { /* Success: print the domain id. */ DPRINTF("DOM=%u\n", dom); diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_linux_save.c --- a/tools/libxc/xc_linux_save.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_linux_save.c Thu Aug 25 18:18:47 2005 @@ -7,11 +7,15 @@ */ #include <inttypes.h> +#include <time.h> +#include <stdlib.h> +#include <unistd.h> #include <sys/time.h> -#include "xc_private.h" + +#include "xg_private.h" + #include <xen/linux/suspend.h> #include <xen/io/domain_controller.h> -#include <time.h> #define BATCH_SIZE 1024 /* 1024 pages (4MB) at a time */ @@ -772,7 +776,7 @@ goto out; } - if ( get_pfn_type_batch(xc_handle, dom, batch, pfn_type) ){ + if ( xc_get_pfn_type_batch(xc_handle, dom, batch, pfn_type) ){ ERR("get_pfn_type_batch failed"); goto out; } diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_aout9.c --- a/tools/libxc/xc_load_aout9.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_load_aout9.c Thu Aug 25 18:18:47 2005 @@ -1,5 +1,5 @@ -#include "xc_private.h" +#include "xg_private.h" #include "xc_aout9.h" #if defined(__i386__) diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_bin.c --- a/tools/libxc/xc_load_bin.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_load_bin.c Thu Aug 25 18:18:47 2005 @@ -66,7 +66,7 @@ * Free Software Foundation, Inc. */ -#include "xc_private.h" +#include "xg_private.h" #include <stdlib.h> #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_load_elf.c --- a/tools/libxc/xc_load_elf.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_load_elf.c Thu Aug 25 18:18:47 2005 @@ -2,7 +2,7 @@ * xc_elf_load.c */ -#include "xc_private.h" +#include "xg_private.h" #if defined(__i386__) #define ELFSIZE 32 diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_private.c Thu Aug 25 18:18:47 2005 @@ -64,8 +64,8 @@ /*******************/ /* NB: arr must be mlock'ed */ -int get_pfn_type_batch(int xc_handle, - u32 dom, int num, unsigned long *arr) +int xc_get_pfn_type_batch(int xc_handle, + u32 dom, int num, unsigned long *arr) { dom0_op_t op; op.cmd = DOM0_GETPAGEFRAMEINFO2; @@ -92,25 +92,40 @@ return op.u.getpageframeinfo.type; } - - -/*******************/ - -int pin_table( - int xc_handle, unsigned int type, unsigned long mfn, domid_t dom) -{ - struct mmuext_op op; - - op.cmd = type; - op.mfn = mfn; - - if ( do_mmuext_op(xc_handle, &op, 1, dom) < 0 ) - return 1; - - return 0; -} - -static int flush_mmu_updates(int xc_handle, mmu_t *mmu) +int xc_mmuext_op( + int xc_handle, + struct mmuext_op *op, + unsigned int nr_ops, + domid_t dom) +{ + privcmd_hypercall_t hypercall; + long ret = -EINVAL; + + hypercall.op = __HYPERVISOR_mmuext_op; + hypercall.arg[0] = (unsigned long)op; + hypercall.arg[1] = (unsigned long)nr_ops; + hypercall.arg[2] = (unsigned long)0; + hypercall.arg[3] = (unsigned long)dom; + + if ( mlock(op, nr_ops*sizeof(*op)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) + { + fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" + " rebuild the user-space tool set?\n",ret,errno); + } + + safe_munlock(op, nr_ops*sizeof(*op)); + + out1: + return ret; +} + +static int flush_mmu_updates(int xc_handle, xc_mmu_t *mmu) { int err = 0; privcmd_hypercall_t hypercall; @@ -145,9 +160,9 @@ return err; } -mmu_t *init_mmu_updates(int xc_handle, domid_t dom) -{ - mmu_t *mmu = malloc(sizeof(mmu_t)); +xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom) +{ + xc_mmu_t *mmu = malloc(sizeof(xc_mmu_t)); if ( mmu == NULL ) return mmu; mmu->idx = 0; @@ -155,8 +170,8 @@ return mmu; } -int add_mmu_update(int xc_handle, mmu_t *mmu, - unsigned long ptr, unsigned long val) +int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, + unsigned long ptr, unsigned long val) { mmu->updates[mmu->idx].ptr = ptr; mmu->updates[mmu->idx].val = val; @@ -167,10 +182,47 @@ return 0; } -int finish_mmu_updates(int xc_handle, mmu_t *mmu) +int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu) { return flush_mmu_updates(xc_handle, mmu); } + +int xc_dom_mem_op(int xc_handle, + unsigned int memop, + unsigned int *extent_list, + unsigned int nr_extents, + unsigned int extent_order, + domid_t domid) +{ + privcmd_hypercall_t hypercall; + long ret = -EINVAL; + + hypercall.op = __HYPERVISOR_dom_mem_op; + hypercall.arg[0] = (unsigned long)memop; + hypercall.arg[1] = (unsigned long)extent_list; + hypercall.arg[2] = (unsigned long)nr_extents; + hypercall.arg[3] = (unsigned long)extent_order; + hypercall.arg[4] = (unsigned long)domid; + + if ( (extent_list != NULL) && + (mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0) ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) + { + fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" + " rebuild the user-space tool set?\n",ret,errno); + } + + if ( extent_list != NULL ) + safe_munlock(extent_list, nr_extents*sizeof(unsigned long)); + + out1: + return ret; +} long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu ) @@ -189,19 +241,6 @@ return op.u.getvcpucontext.cpu_time; } - -/* This is shared between save and restore, and may generally be useful. */ -unsigned long csum_page (void * page) -{ - int i; - unsigned long *p = page; - unsigned long long sum=0; - - for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ ) - sum += p[i]; - - return sum ^ (sum>>32); -} unsigned long xc_get_m2p_start_mfn ( int xc_handle ) { @@ -332,53 +371,6 @@ return sz; } -char *xc_read_kernel_image(const char *filename, unsigned long *size) -{ - int kernel_fd = -1; - gzFile kernel_gfd = NULL; - char *image = NULL; - unsigned int bytes; - - if ( (kernel_fd = open(filename, O_RDONLY)) < 0 ) - { - PERROR("Could not open kernel image"); - goto out; - } - - if ( (*size = xc_get_filesz(kernel_fd)) == 0 ) - { - PERROR("Could not read kernel image"); - goto out; - } - - if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL ) - { - PERROR("Could not allocate decompression state for state file"); - goto out; - } - - if ( (image = malloc(*size)) == NULL ) - { - PERROR("Could not allocate memory for kernel image"); - goto out; - } - - if ( (bytes = gzread(kernel_gfd, image, *size)) != *size ) - { - PERROR("Error reading kernel image, could not" - " read the whole image (%d != %ld).", bytes, *size); - free(image); - image = NULL; - } - - out: - if ( kernel_gfd != NULL ) - gzclose(kernel_gfd); - else if ( kernel_fd >= 0 ) - close(kernel_fd); - return image; -} - void xc_map_memcpy(unsigned long dst, char *src, unsigned long size, int xch, u32 dom, unsigned long *parray, unsigned long vstart) diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_private.h --- a/tools/libxc/xc_private.h Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_private.h Thu Aug 25 18:18:47 2005 @@ -1,123 +1,25 @@ -#ifndef __XC_PRIVATE_H__ -#define __XC_PRIVATE_H__ +#ifndef XC_PRIVATE_H +#define XC_PRIVATE_H #include <unistd.h> #include <stdio.h> #include <errno.h> #include <fcntl.h> +#include <string.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <sys/ioctl.h> -#include <errno.h> -#include <string.h> -#include "xc.h" +#include "xenctrl.h" #include <xen/linux/privcmd.h> -#define _PAGE_PRESENT 0x001 -#define _PAGE_RW 0x002 -#define _PAGE_USER 0x004 -#define _PAGE_PWT 0x008 -#define _PAGE_PCD 0x010 -#define _PAGE_ACCESSED 0x020 -#define _PAGE_DIRTY 0x040 -#define _PAGE_PAT 0x080 -#define _PAGE_PSE 0x080 -#define _PAGE_GLOBAL 0x100 - -#if defined(__i386__) -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 22 -#define L1_PAGETABLE_SHIFT_PAE 12 -#define L2_PAGETABLE_SHIFT_PAE 21 -#define L3_PAGETABLE_SHIFT_PAE 30 -#elif defined(__x86_64__) -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 21 -#define L3_PAGETABLE_SHIFT 30 -#define L4_PAGETABLE_SHIFT 39 -#endif - -#if defined(__i386__) -#define ENTRIES_PER_L1_PAGETABLE 1024 -#define ENTRIES_PER_L2_PAGETABLE 1024 -#define L1_PAGETABLE_ENTRIES_PAE 512 -#define L2_PAGETABLE_ENTRIES_PAE 512 -#define L3_PAGETABLE_ENTRIES_PAE 4 -#elif defined(__x86_64__) -#define L1_PAGETABLE_ENTRIES 512 -#define L2_PAGETABLE_ENTRIES 512 -#define L3_PAGETABLE_ENTRIES 512 -#define L4_PAGETABLE_ENTRIES 512 -#endif - #define PAGE_SHIFT XC_PAGE_SHIFT #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) - -typedef u32 l1_pgentry_32_t; -typedef u32 l2_pgentry_32_t; -typedef u64 l1_pgentry_64_t; -typedef u64 l2_pgentry_64_t; -typedef u64 l3_pgentry_64_t; -typedef unsigned long l1_pgentry_t; -typedef unsigned long l2_pgentry_t; -#if defined(__x86_64__) -typedef unsigned long l3_pgentry_t; -typedef unsigned long l4_pgentry_t; -#endif - -#if defined(__i386__) -#define l1_table_offset(_a) \ - (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1)) -#define l2_table_offset(_a) \ - ((_a) >> L2_PAGETABLE_SHIFT) -#define l1_table_offset_pae(_a) \ - (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1)) -#define l2_table_offset_pae(_a) \ - (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1)) -#define l3_table_offset_pae(_a) \ - (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1)) -#elif defined(__x86_64__) -#define l1_table_offset(_a) \ - (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) -#define l2_table_offset(_a) \ - (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) -#define l3_table_offset(_a) \ - (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) -#define l4_table_offset(_a) \ - (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) -#endif - -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 load_symtab; - unsigned int pae_kernel; - unsigned long symtab_addr; - unsigned long symtab_len; -}; - -typedef int (*parseimagefunc)(char *image, unsigned long image_size, - struct domain_setup_info *dsi); -typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch, - u32 dom, unsigned long *parray, - struct domain_setup_info *dsi); - -struct load_funcs -{ - parseimagefunc parseimage; - loadimagefunc loadimage; -}; #define ERROR(_m, _a...) \ do { \ @@ -186,97 +88,6 @@ return ret; } -static inline int do_dom_mem_op(int xc_handle, - unsigned int memop, - unsigned int *extent_list, - unsigned int nr_extents, - unsigned int extent_order, - domid_t domid) -{ - privcmd_hypercall_t hypercall; - long ret = -EINVAL; - - hypercall.op = __HYPERVISOR_dom_mem_op; - hypercall.arg[0] = (unsigned long)memop; - hypercall.arg[1] = (unsigned long)extent_list; - hypercall.arg[2] = (unsigned long)nr_extents; - hypercall.arg[3] = (unsigned long)extent_order; - hypercall.arg[4] = (unsigned long)domid; - - if ( (extent_list != NULL) && - (mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0) ) - { - PERROR("Could not lock memory for Xen hypercall"); - goto out1; - } - - if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) - { - fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" - " rebuild the user-space tool set?\n",ret,errno); - } - - if ( extent_list != NULL ) - safe_munlock(extent_list, nr_extents*sizeof(unsigned long)); - - out1: - return ret; -} - -static inline int do_mmuext_op( - int xc_handle, - struct mmuext_op *op, - unsigned int nr_ops, - domid_t dom) -{ - privcmd_hypercall_t hypercall; - long ret = -EINVAL; - - hypercall.op = __HYPERVISOR_mmuext_op; - hypercall.arg[0] = (unsigned long)op; - hypercall.arg[1] = (unsigned long)nr_ops; - hypercall.arg[2] = (unsigned long)0; - hypercall.arg[3] = (unsigned long)dom; - - if ( mlock(op, nr_ops*sizeof(*op)) != 0 ) - { - PERROR("Could not lock memory for Xen hypercall"); - goto out1; - } - - if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) - { - fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" - " rebuild the user-space tool set?\n",ret,errno); - } - - safe_munlock(op, nr_ops*sizeof(*op)); - - out1: - return ret; -} - - -/* - * PFN mapping. - */ -int get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr); -unsigned long csum_page (void * page); - -/* - * MMU updates. - */ -#define MAX_MMU_UPDATES 1024 -typedef struct { - mmu_update_t updates[MAX_MMU_UPDATES]; - int idx; - domid_t subject; -} mmu_t; -mmu_t *init_mmu_updates(int xc_handle, domid_t dom); -int add_mmu_update(int xc_handle, mmu_t *mmu, - unsigned long ptr, unsigned long val); -int finish_mmu_updates(int xc_handle, mmu_t *mmu); - /* * ioctl-based mfn mapping interface @@ -296,38 +107,4 @@ } privcmd_mmap_t; */ -#define mfn_mapper_queue_size 128 - -typedef struct mfn_mapper { - int xc_handle; - int size; - int prot; - int error; - int max_queue_size; - void * addr; - privcmd_mmap_t ioctl; - -} mfn_mapper_t; - -unsigned long xc_get_m2p_start_mfn (int xc_handle); - -int xc_copy_to_domain_page(int xc_handle, u32 domid, - unsigned long dst_pfn, void *src_page); - -unsigned long xc_get_filesz(int fd); - -char *xc_read_kernel_image(const char *filename, unsigned long *size); - -void xc_map_memcpy(unsigned long dst, char *src, unsigned long size, - int xch, u32 dom, unsigned long *parray, - unsigned long vstart); - -int pin_table(int xc_handle, unsigned int type, unsigned long mfn, - domid_t dom); - -/* image loading */ -int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs); -int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs); -int probe_aout9(char *image, unsigned long image_size, struct load_funcs *funcs); - #endif /* __XC_PRIVATE_H__ */ diff -r e2025593f702 -r 112d44270733 tools/libxc/xc_vmx_build.c --- a/tools/libxc/xc_vmx_build.c Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xc_vmx_build.c Thu Aug 25 18:18:47 2005 @@ -3,7 +3,7 @@ */ #include <stddef.h> -#include "xc_private.h" +#include "xg_private.h" #define ELFSIZE 32 #include "xc_elf.h" #include <stdlib.h> @@ -243,7 +243,7 @@ shared_info_t *shared_info; struct linux_boot_params * boot_paramsp; __u16 * boot_gdtp; - mmu_t *mmu = NULL; + xc_mmu_t *mmu = NULL; int rc; unsigned long nr_pt_pages; @@ -358,7 +358,7 @@ } } - if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL ) + if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL ) goto error_out; #ifdef __i386__ @@ -459,9 +459,9 @@ /* Write the machine->phys table entries. */ for ( count = 0; count < nr_pages; count++ ) { - if ( add_mmu_update(xc_handle, mmu, - (page_array[count] << PAGE_SHIFT) | - MMU_MACHPHYS_UPDATE, count) ) + if ( xc_add_mmu_update(xc_handle, mmu, + (page_array[count] << PAGE_SHIFT) | + MMU_MACHPHYS_UPDATE, count) ) goto error_out; } @@ -587,7 +587,7 @@ #endif /* Send the page update requests down to the hypervisor. */ - if ( finish_mmu_updates(xc_handle, mmu) ) + if ( xc_finish_mmu_updates(xc_handle, mmu) ) goto error_out; free(mmu); @@ -708,7 +708,7 @@ op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; - if ( (do_dom0_op(xc_handle, &op) < 0) || + if ( (xc_dom0_op(xc_handle, &op) < 0) || ((u16)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); @@ -789,7 +789,7 @@ launch_op.u.setdomaininfo.ctxt = ctxt; launch_op.cmd = DOM0_SETDOMAININFO; - rc = do_dom0_op(xc_handle, &launch_op); + rc = xc_dom0_op(xc_handle, &launch_op); return rc; diff -r e2025593f702 -r 112d44270733 tools/misc/Makefile --- a/tools/misc/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/misc/Makefile Thu Aug 25 18:18:47 2005 @@ -50,4 +50,4 @@ $(CC) -c $(CFLAGS) -o $@ $< $(TARGETS): %: %.o Makefile - $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc + $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl diff -r e2025593f702 -r 112d44270733 tools/misc/cpuperf/Makefile --- a/tools/misc/cpuperf/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/misc/cpuperf/Makefile Thu Aug 25 18:18:47 2005 @@ -37,7 +37,7 @@ $(CC) $(CFLAGS) -o $@ $< cpuperf-xen: cpuperf.c $(HDRS) Makefile - $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -DXENO -o $@ $< + $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxenctrl -DXENO -o $@ $< cpuperf-perfcntr: cpuperf.c $(HDRS) Makefile $(CC) $(CFLAGS) -DPERFCNTR -o $@ $< diff -r e2025593f702 -r 112d44270733 tools/misc/cpuperf/cpuperf_xeno.h --- a/tools/misc/cpuperf/cpuperf_xeno.h Wed Aug 24 23:16:52 2005 +++ b/tools/misc/cpuperf/cpuperf_xeno.h Thu Aug 25 18:18:47 2005 @@ -9,7 +9,7 @@ * */ -#include <xc.h> +#include <xenctrl.h> static int xc_handle; diff -r e2025593f702 -r 112d44270733 tools/misc/xc_shadow.c --- a/tools/misc/xc_shadow.c Wed Aug 24 23:16:52 2005 +++ b/tools/misc/xc_shadow.c Thu Aug 25 18:18:47 2005 @@ -11,7 +11,7 @@ */ -#include <xc.h> +#include <xenctrl.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> diff -r e2025593f702 -r 112d44270733 tools/misc/xenperf.c --- a/tools/misc/xenperf.c Wed Aug 24 23:16:52 2005 +++ b/tools/misc/xenperf.c Thu Aug 25 18:18:47 2005 @@ -11,7 +11,7 @@ */ -#include <xc.h> +#include <xenctrl.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> diff -r e2025593f702 -r 112d44270733 tools/python/setup.py --- a/tools/python/setup.py Wed Aug 24 23:16:52 2005 +++ b/tools/python/setup.py Thu Aug 25 18:18:47 2005 @@ -17,7 +17,7 @@ XEN_ROOT + "/tools/xenstore", ] -libraries = [ "xc", "xenstore-pic" ] +libraries = [ "xenctrl", "xenguest", "xenstore" ] xc = Extension("xc", extra_compile_args = extra_compile_args, @@ -41,7 +41,7 @@ sources = [ "xen/lowlevel/xs/xs.c" ]) setup(name = 'xen', - version = '2.0', + version = '3.0', description = 'Xen', packages = ['xen', 'xen.lowlevel', diff -r e2025593f702 -r 112d44270733 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Wed Aug 24 23:16:52 2005 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Aug 25 18:18:47 2005 @@ -5,7 +5,8 @@ */ #include <Python.h> -#include <xc.h> +#include <xenctrl.h> +#include <xenguest.h> #include <zlib.h> #include <fcntl.h> #include <netinet/in.h> diff -r e2025593f702 -r 112d44270733 tools/python/xen/lowlevel/xu/xu.c --- a/tools/python/xen/lowlevel/xu/xu.c Wed Aug 24 23:16:52 2005 +++ b/tools/python/xen/lowlevel/xu/xu.c Thu Aug 25 18:18:47 2005 @@ -21,7 +21,7 @@ #include <unistd.h> #include <errno.h> #include <signal.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/xen.h> #include <xen/io/domain_controller.h> diff -r e2025593f702 -r 112d44270733 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Aug 24 23:16:52 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Aug 25 18:18:47 2005 @@ -265,6 +265,8 @@ self.info = None self.blkif_backend = False self.netif_backend = False + self.netif_idx = 0 + #todo: state: running, suspended self.state = STATE_VM_OK self.state_updated = threading.Condition() @@ -400,8 +402,7 @@ db['virtual-device'] = "%i" % devnum #db['backend'] = sxp.child_value(devconfig, 'backend', '0') db['backend'] = backdb.getPath() - db['backend-id'] = "%i" % int(sxp.child_value(devconfig, - 'backend', '0')) + db['backend-id'] = "%i" % backdom.id backdb['frontend'] = db.getPath() (type, params) = string.split(sxp.child_value(devconfig, 'uname'), ':', 1) @@ -417,6 +418,37 @@ db.saveDB(save=True) return + + if type == 'vif': + backdom = domain_exists(sxp.child_value(devconfig, 'backend', '0')) + + log.error(devconfig) + + devnum = self.netif_idx + self.netif_idx += 1 + + # create backend db + backdb = backdom.db.addChild("/backend/%s/%s/%d" % + (type, self.uuid, devnum)) + + # create frontend db + db = self.db.addChild("/device/%s/%d" % (type, devnum)) + + backdb['frontend'] = db.getPath() + backdb['frontend-id'] = "%i" % self.id + backdb['handle'] = "%i" % devnum + backdb.saveDB(save=True) + + db['backend'] = backdb.getPath() + db['backend-id'] = "%i" % backdom.id + db['handle'] = "%i" % devnum + log.error(sxp.child_value(devconfig, 'mac')) + db['mac'] = sxp.child_value(devconfig, 'mac') + + db.saveDB(save=True) + + return + ctrl = self.findDeviceController(type) return ctrl.createDevice(devconfig, recreate=self.recreate, change=change) @@ -718,6 +750,11 @@ devdb['node'].getData()) typedb[dev].delete() typedb.saveDB(save=True) + if type == 'vif': + typedb = ddb.addChild(type) + for dev in typedb.keys(): + typedb[dev].delete() + typedb.saveDB(save=True) def show(self): """Print virtual machine info. diff -r e2025593f702 -r 112d44270733 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Aug 24 23:16:52 2005 +++ b/tools/python/xen/xm/main.py Thu Aug 25 18:18:47 2005 @@ -665,8 +665,10 @@ err("Most commands need root access. Please try again as root") sys.exit(1) except XendError, ex: + if args[0] == "bogus": + args.remove("bogus") if len(args) > 0: - handle_xend_error(argv[1], args[1], ex) + handle_xend_error(argv[1], args[0], ex) else: print "Unexpected error:", sys.exc_info()[0] print diff -r e2025593f702 -r 112d44270733 tools/xcs/Makefile --- a/tools/xcs/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/xcs/Makefile Thu Aug 25 18:18:47 2005 @@ -34,10 +34,10 @@ xcsdump: xcsdump.c dump.c $(CC) $(CFLAGS) -o xcsdump xcsdump.c -L$(XEN_LIBXC) \ - ctrl_interface.c evtchn.c dump.c -lxc + ctrl_interface.c evtchn.c dump.c -lxenctrl $(BIN): $(OBJS) - $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -lxc + $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -lxenctrl $(OBJS): $(HDRS) diff -r e2025593f702 -r 112d44270733 tools/xcs/dump.h --- a/tools/xcs/dump.h Wed Aug 24 23:16:52 2005 +++ b/tools/xcs/dump.h Thu Aug 25 18:18:47 2005 @@ -20,7 +20,7 @@ #define XENCTLD_ERROR_H #include <stdint.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/io/domain_controller.h> void dump_msg(const control_msg_t *msg, uint64_t flags); diff -r e2025593f702 -r 112d44270733 tools/xcs/xcs.h --- a/tools/xcs/xcs.h Wed Aug 24 23:16:52 2005 +++ b/tools/xcs/xcs.h Thu Aug 25 18:18:47 2005 @@ -11,7 +11,7 @@ #define __XCS_H__ #include <pthread.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/xen.h> #include <xen/io/domain_controller.h> #include <xen/linux/privcmd.h> diff -r e2025593f702 -r 112d44270733 tools/xcs/xcsdump.c --- a/tools/xcs/xcsdump.c Wed Aug 24 23:16:52 2005 +++ b/tools/xcs/xcsdump.c Thu Aug 25 18:18:47 2005 @@ -16,7 +16,7 @@ #include <sys/socket.h> #include <sys/un.h> #include <ctype.h> -#include <xc.h> +#include <xenctrl.h> #include <xen/xen.h> #include <xen/io/domain_controller.h> #include <getopt.h> diff -r e2025593f702 -r 112d44270733 tools/xcutils/Makefile --- a/tools/xcutils/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/xcutils/Makefile Thu Aug 25 18:18:47 2005 @@ -30,7 +30,7 @@ PROGRAMS = xc_restore xc_save -LDLIBS = -L$(XEN_LIBXC) -lxc +LDLIBS = -L$(XEN_LIBXC) -lxenguest -lxenctrl .PHONY: all all: build diff -r e2025593f702 -r 112d44270733 tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Wed Aug 24 23:16:52 2005 +++ b/tools/xcutils/xc_restore.c Thu Aug 25 18:18:47 2005 @@ -7,11 +7,12 @@ * */ +#include <err.h> #include <stdlib.h> +#include <stdint.h> #include <stdio.h> -#include <err.h> -#include <xc.h> +#include <xenguest.h> int main(int argc, char **argv) diff -r e2025593f702 -r 112d44270733 tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Wed Aug 24 23:16:52 2005 +++ b/tools/xcutils/xc_save.c Thu Aug 25 18:18:47 2005 @@ -7,11 +7,12 @@ * */ +#include <err.h> #include <stdlib.h> +#include <stdint.h> #include <stdio.h> -#include <err.h> -#include <xc.h> +#include <xenguest.h> int main(int argc, char **argv) diff -r e2025593f702 -r 112d44270733 tools/xenstore/Makefile --- a/tools/xenstore/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/xenstore/Makefile Thu Aug 25 18:18:47 2005 @@ -32,7 +32,7 @@ ln -sf $(XEN_ROOT)/xen/include/public $@ xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o - $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxc -o $@ + $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@ xenstored_test: xenstored_core_test.o xenstored_watch_test.o xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o fake_libxc.o utils.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ @@ -109,7 +109,7 @@ export $(TESTENV); PID=`./xenstored_test --output-pid --trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret xs_dom0_test: xs_dom0_test.o utils.o - $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxc -o $@ + $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@ TAGS: etags `find . -name '*.[ch]'` diff -r e2025593f702 -r 112d44270733 tools/xenstore/xs_dom0_test.c --- a/tools/xenstore/xs_dom0_test.c Wed Aug 24 23:16:52 2005 +++ b/tools/xenstore/xs_dom0_test.c Thu Aug 25 18:18:47 2005 @@ -3,7 +3,7 @@ #include <sys/ioctl.h> #include "xs.h" #include "utils.h" -#include <xc.h> +#include <xenctrl.h> #include <xen/linux/privcmd.h> #include <stdio.h> #include <unistd.h> diff -r e2025593f702 -r 112d44270733 tools/xenstore/xs_lib.h --- a/tools/xenstore/xs_lib.h Wed Aug 24 23:16:52 2005 +++ b/tools/xenstore/xs_lib.h Thu Aug 25 18:18:47 2005 @@ -22,7 +22,7 @@ #include <stdbool.h> #include <limits.h> -#include <xc.h> +#include <xenctrl.h> /* Bitmask of permissions. */ enum xs_perm_type { diff -r e2025593f702 -r 112d44270733 tools/xentrace/Makefile --- a/tools/xentrace/Makefile Wed Aug 24 23:16:52 2005 +++ b/tools/xentrace/Makefile Thu Aug 25 18:18:47 2005 @@ -36,4 +36,4 @@ $(RM) *.a *.so *.o *.rpm $(BIN) %: %.c $(HDRS) Makefile - $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc + $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxenctrl diff -r e2025593f702 -r 112d44270733 tools/xentrace/xenctx.c --- a/tools/xentrace/xenctx.c Wed Aug 24 23:16:52 2005 +++ b/tools/xentrace/xenctx.c Thu Aug 25 18:18:47 2005 @@ -21,7 +21,7 @@ #include <argp.h> #include <signal.h> -#include "xc.h" +#include "xenctrl.h" #ifdef __i386__ void print_ctx(vcpu_guest_context_t *ctx1) diff -r e2025593f702 -r 112d44270733 xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c Wed Aug 24 23:16:52 2005 +++ b/xen/arch/x86/x86_32/mm.c Thu Aug 25 18:18:47 2005 @@ -93,15 +93,10 @@ /* * Allocate and map the machine-to-phys table and create read-only mapping - * of MPT for guest-OS use. Without PAE we'll end up with one 4MB page, - * with PAE we'll allocate 2MB pages depending on the amount of memory - * installed, but at least 4MB to cover 4GB address space. This is needed - * to make PCI I/O memory address lookups work in guests. + * of MPT for guest-OS use. */ mpt_size = (max_page * 4) + (1UL << L2_PAGETABLE_SHIFT) - 1UL; mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL); - if ( mpt_size < (4 << 20) ) - mpt_size = 4 << 20; for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ ) { if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL ) diff -r e2025593f702 -r 112d44270733 xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Wed Aug 24 23:16:52 2005 +++ b/xen/arch/x86/x86_64/mm.c Thu Aug 25 18:18:47 2005 @@ -74,7 +74,7 @@ void __init paging_init(void) { - unsigned long i; + unsigned long i, mpt_size; l3_pgentry_t *l3_ro_mpt; l2_pgentry_t *l2_ro_mpt; struct pfn_info *pg; @@ -98,16 +98,17 @@ * Allocate and map the machine-to-phys table. * This also ensures L3 is present for fixmaps. */ - for ( i = 0; i < max_page; i += ((1UL << L2_PAGETABLE_SHIFT) / 8) ) - { - pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0); - if ( pg == NULL ) + mpt_size = (max_page * 4) + (1UL << L2_PAGETABLE_SHIFT) - 1UL; + mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL); + for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ ) + { + if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL ) panic("Not enough memory for m2p table\n"); map_pages_to_xen( - RDWR_MPT_VIRT_START + i*8, page_to_pfn(pg), + RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), page_to_pfn(pg), 1UL << PAGETABLE_ORDER, PAGE_HYPERVISOR); - memset((void *)(RDWR_MPT_VIRT_START + i*8), 0x55, + memset((void *)(RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), 0x55, 1UL << L2_PAGETABLE_SHIFT); *l2_ro_mpt++ = l2e_from_page( pg, _PAGE_GLOBAL|_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT); diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Thu Aug 25 18:18:47 2005 @@ -0,0 +1,257 @@ +/* Xenbus code for netif backend + Copyright (C) 2005 Rusty Russell <rusty@xxxxxxxxxxxxxxx> + + 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include <stdarg.h> +#include <linux/module.h> +#include <asm-xen/xenbus.h> +#include "common.h" + +struct backend_info +{ + struct xenbus_device *dev; + + /* our communications channel */ + netif_t *netif; + + long int frontend_id; +#if 0 + long int pdev; + long int readonly; +#endif + + /* watch back end for changes */ + struct xenbus_watch backend_watch; + + /* watch front end for changes */ + struct xenbus_watch watch; + char *frontpath; +}; + +static int netback_remove(struct xenbus_device *dev) +{ + struct backend_info *be = dev->data; + + if (be->watch.node) + unregister_xenbus_watch(&be->watch); + unregister_xenbus_watch(&be->backend_watch); + if (be->netif) + netif_disconnect(be->netif); + if (be->frontpath) + kfree(be->frontpath); + kfree(be); + return 0; +} + +/* Front end tells us frame. */ +static void frontend_changed(struct xenbus_watch *watch, const char *node) +{ + unsigned long tx_ring_ref, rx_ring_ref; + unsigned int evtchn; + int err; + struct backend_info *be + = container_of(watch, struct backend_info, watch); + char *mac, *e, *s; + int i; + + /* If other end is gone, delete ourself. */ + if (node && !xenbus_exists(be->frontpath, "")) { + xenbus_rm(be->dev->nodename, ""); + device_unregister(&be->dev->dev); + return; + } + if (be->netif == NULL || be->netif->status == CONNECTED) + return; + + mac = xenbus_read(be->frontpath, "mac", NULL); + if (IS_ERR(mac)) { + err = PTR_ERR(mac); + xenbus_dev_error(be->dev, err, "reading %s/mac", + be->dev->nodename); + return; + } + s = mac; + for (i = 0; i < ETH_ALEN; i++) { + be->netif->fe_dev_addr[i] = simple_strtoul(s, &e, 16); + if (s == e || (e[0] != ':' && e[0] != 0)) { + kfree(mac); + err = -ENOENT; + xenbus_dev_error(be->dev, err, "parsing %s/mac", + be->dev->nodename); + return; + } + s = &e[1]; + } + kfree(mac); + + err = xenbus_gather(be->frontpath, "tx-ring-ref", "%lu", &tx_ring_ref, + "rx-ring-ref", "%lu", &rx_ring_ref, + "event-channel", "%u", &evtchn, NULL); + if (err) { + xenbus_dev_error(be->dev, err, + "reading %s/ring-ref and event-channel", + be->frontpath); + return; + } + + /* Map the shared frame, irq etc. */ + err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn); + if (err) { + xenbus_dev_error(be->dev, err, + "mapping shared-frames %lu/%lu port %u", + tx_ring_ref, rx_ring_ref, evtchn); + return; + } + + xenbus_dev_ok(be->dev); + + return; +} + +/* + Setup supplies physical device. + We provide event channel and device details to front end. + Frontend supplies shared frame and event channel. + */ +static void backend_changed(struct xenbus_watch *watch, const char *node) +{ + int err; + long int handle; + struct backend_info *be + = container_of(watch, struct backend_info, backend_watch); + struct xenbus_device *dev = be->dev; + u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + err = xenbus_scanf(dev->nodename, "handle", "%li", &handle); + if (XENBUS_EXIST_ERR(err)) + return; + if (err < 0) { + xenbus_dev_error(dev, err, "reading handle"); + return; + } + + if (be->netif == NULL) { + be->netif = alloc_netif(be->frontend_id, handle, be_mac); + if (IS_ERR(be->netif)) { + err = PTR_ERR(be->netif); + be->netif = NULL; + xenbus_dev_error(dev, err, "creating interface"); + return; + } + +#if 0 + err = vbd_create(be->netif, handle, be->pdev, be->readonly); + if (err) { + xenbus_dev_error(dev, err, "creating vbd structure"); + return; + } +#endif + + /* Pass in NULL node to skip exist test. */ + frontend_changed(&be->watch, NULL); + } +} + +static int netback_probe(struct xenbus_device *dev, + const struct xenbus_device_id *id) +{ + struct backend_info *be; + char *frontend; + int err; + + be = kmalloc(sizeof(*be), GFP_KERNEL); + if (!be) { + xenbus_dev_error(dev, -ENOMEM, "allocating backend structure"); + return -ENOMEM; + } + memset(be, 0, sizeof(*be)); + + frontend = NULL; + err = xenbus_gather(dev->nodename, + "frontend-id", "%li", &be->frontend_id, + "frontend", NULL, &frontend, + NULL); + if (XENBUS_EXIST_ERR(err)) + goto free_be; + if (err < 0) { + xenbus_dev_error(dev, err, + "reading %s/frontend or frontend-id", + dev->nodename); + goto free_be; + } + if (strlen(frontend) == 0 || !xenbus_exists(frontend, "")) { + /* If we can't get a frontend path and a frontend-id, + * then our bus-id is no longer valid and we need to + * destroy the backend device. + */ + err = -ENOENT; + goto free_be; + } + + be->dev = dev; + be->backend_watch.node = dev->nodename; + be->backend_watch.callback = backend_changed; + err = register_xenbus_watch(&be->backend_watch); + if (err) { + be->backend_watch.node = NULL; + xenbus_dev_error(dev, err, "adding backend watch on %s", + dev->nodename); + goto free_be; + } + + be->frontpath = frontend; + be->watch.node = be->frontpath; + be->watch.callback = frontend_changed; + err = register_xenbus_watch(&be->watch); + if (err) { + be->watch.node = NULL; + xenbus_dev_error(dev, err, + "adding frontend watch on %s", + be->frontpath); + goto free_be; + } + + dev->data = be; + + backend_changed(&be->backend_watch, dev->nodename); + return 0; + + free_be: + if (be->backend_watch.node) + unregister_xenbus_watch(&be->backend_watch); + if (frontend) + kfree(frontend); + kfree(be); + return err; +} + +static struct xenbus_device_id netback_ids[] = { + { "vif" }, + { "" } +}; + +static struct xenbus_driver netback = { + .name = "vif", + .owner = THIS_MODULE, + .ids = netback_ids, + .probe = netback_probe, + .remove = netback_remove, +}; + +void netif_xenbus_init(void) +{ + xenbus_register_backend(&netback); +} diff -r e2025593f702 -r 112d44270733 tools/examples/backend.hotplug --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/tools/examples/backend.hotplug Thu Aug 25 18:18:47 2005 @@ -0,0 +1,21 @@ +#! /bin/sh + +#DEVPATH=/devices/xen-backend/vif-1-0 +#ACTION=add + +PATH=/etc/xen/scripts:$PATH + +DEV=$(basename "$DEVPATH") +case "$ACTION" in + add) + case "$DEV" in + vif-*) + vif=$(echo "$DEV" | sed 's/-\([0-9]*\)-\([0-9]*\)/\1.\2/') + vif-bridge up domain=unknown vif="$vif" mac=fe:ff:ff:ff:ff:ff bridge=xen-br0 >/dev/null 2>&1 + ;; + esac + ;; + remove) + ;; +esac + diff -r e2025593f702 -r 112d44270733 tools/libxc/xenctrl.h --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xenctrl.h Thu Aug 25 18:18:47 2005 @@ -0,0 +1,526 @@ +/****************************************************************************** + * xenctrl.h + * + * A library for low-level access to the Xen control interfaces. + * + * Copyright (c) 2003-2004, K A Fraser. + */ + +#ifndef XENCTRL_H +#define XENCTRL_H + +#include <stdint.h> + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#include <sys/ptrace.h> +#include <xen/xen.h> +#include <xen/dom0_ops.h> +#include <xen/event_channel.h> +#include <xen/sched_ctl.h> +#include <xen/acm.h> + +#ifdef __ia64__ +#define XC_PAGE_SHIFT 14 +#else +#define XC_PAGE_SHIFT 12 +#endif +#define XC_PAGE_SIZE (1UL << XC_PAGE_SHIFT) +#define XC_PAGE_MASK (~(XC_PAGE_SIZE-1)) + +/* + * DEFINITIONS FOR CPU BARRIERS + */ + +#if defined(__i386__) +#define mb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) +#define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) +#define wmb() __asm__ __volatile__ ( "" : : : "memory") +#elif defined(__x86_64__) +#define mb() __asm__ __volatile__ ( "mfence" : : : "memory") +#define rmb() __asm__ __volatile__ ( "lfence" : : : "memory") +#define wmb() __asm__ __volatile__ ( "" : : : "memory") +#elif defined(__ia64__) +/* FIXME */ +#define mb() +#define rmb() +#define wmb() +#else +#error "Define barriers" +#endif + +/* + * INITIALIZATION FUNCTIONS + */ + +/** + * This function opens a handle to the hypervisor interface. This function can + * be called multiple times within a single process. Multiple processes can + * have an open hypervisor interface at the same time. + * + * Each call to this function should have a corresponding call to + * xc_interface_close(). + * + * This function can fail if the caller does not have superuser permission or + * if a Xen-enabled kernel is not currently running. + * + * @return a handle to the hypervisor interface or -1 on failure + */ +int xc_interface_open(void); + +/** + * This function closes an open hypervisor interface. + * + * This function can fail if the handle does not represent an open interface or + * if there were problems closing the interface. + * + * @parm xc_handle a handle to an open hypervisor interface + * @return 0 on success, -1 otherwise. + */ +int xc_interface_close(int xc_handle); + +/* + * DOMAIN DEBUGGING FUNCTIONS + */ + +typedef struct xc_core_header { + unsigned int xch_magic; + unsigned int xch_nr_vcpus; + unsigned int xch_nr_pages; + unsigned int xch_ctxt_offset; + unsigned int xch_index_offset; + unsigned int xch_pages_offset; +} xc_core_header_t; + + +long xc_ptrace(enum __ptrace_request request, + u32 domid, + long addr, + long data); + +long xc_ptrace_core(enum __ptrace_request request, + u32 domid, + long addr, + long data); + +int xc_waitdomain(int domain, + int *status, + int options); + +int xc_waitdomain_core(int domain, + int *status, + int options); + +/* + * DOMAIN MANAGEMENT FUNCTIONS + */ + +typedef struct { + u32 domid; + u32 ssidref; + unsigned int dying:1, crashed:1, shutdown:1, + paused:1, blocked:1, running:1; + unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ + unsigned long nr_pages; + unsigned long shared_info_frame; + u64 cpu_time; + unsigned long max_memkb; + unsigned int vcpus; + s32 vcpu_to_cpu[MAX_VIRT_CPUS]; + cpumap_t cpumap[MAX_VIRT_CPUS]; +} xc_dominfo_t; + +typedef dom0_getdomaininfo_t xc_domaininfo_t; +int xc_domain_create(int xc_handle, + u32 ssidref, + u32 *pdomid); + + +int xc_domain_dumpcore(int xc_handle, + u32 domid, + const char *corename); + + +/** + * This function pauses a domain. A paused domain still exists in memory + * however it does not receive any timeslices from the hypervisor. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain id to pause + * @return 0 on success, -1 on failure. + */ +int xc_domain_pause(int xc_handle, + u32 domid); +/** + * This function unpauses a domain. The domain should have been previously + * paused. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain id to unpause + * return 0 on success, -1 on failure + */ +int xc_domain_unpause(int xc_handle, + u32 domid); + +/** + * This function will destroy a domain. Destroying a domain removes the domain + * completely from memory. This function should be called after sending the + * domain a SHUTDOWN control message to free up the domain resources. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain id to destroy + * @return 0 on success, -1 on failure + */ +int xc_domain_destroy(int xc_handle, + u32 domid); +int xc_domain_pincpu(int xc_handle, + u32 domid, + int vcpu, + cpumap_t *cpumap); +/** + * This function will return information about one or more domains. It is + * designed to iterate over the list of domains. If a single domain is + * requested, this function will return the next domain in the list - if + * one exists. It is, therefore, important in this case to make sure the + * domain requested was the one returned. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm first_domid the first domain to enumerate information from. Domains + * are currently enumerate in order of creation. + * @parm max_doms the number of elements in info + * @parm info an array of max_doms size that will contain the information for + * the enumerated domains. + * @return the number of domains enumerated or -1 on error + */ +int xc_domain_getinfo(int xc_handle, + u32 first_domid, + unsigned int max_doms, + xc_dominfo_t *info); + +/** + * This function will return information about one or more domains, using a + * single hypercall. The domain information will be stored into the supplied + * array of xc_domaininfo_t structures. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm first_domain the first domain to enumerate information from. + * Domains are currently enumerate in order of creation. + * @parm max_domains the number of elements in info + * @parm info an array of max_doms size that will contain the information for + * the enumerated domains. + * @return the number of domains enumerated or -1 on error + */ +int xc_domain_getinfolist(int xc_handle, + u32 first_domain, + unsigned int max_domains, + xc_domaininfo_t *info); + +/** + * This function returns information about one domain. This information is + * more detailed than the information from xc_domain_getinfo(). + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm domid the domain to get information from + * @parm info a pointer to an xc_domaininfo_t to store the domain information + * @parm ctxt a pointer to a structure to store the execution context of the + * domain + * @return 0 on success, -1 on failure + */ +int xc_domain_get_vcpu_context(int xc_handle, + u32 domid, + u32 vcpu, + vcpu_guest_context_t *ctxt); + +int xc_domain_setcpuweight(int xc_handle, + u32 domid, + float weight); +long long xc_domain_get_cpu_usage(int xc_handle, + domid_t domid, + int vcpu); + + +typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t; +int xc_shadow_control(int xc_handle, + u32 domid, + unsigned int sop, + unsigned long *dirty_bitmap, + unsigned long pages, + xc_shadow_control_stats_t *stats); + +int xc_bvtsched_global_set(int xc_handle, + unsigned long ctx_allow); + +int xc_bvtsched_domain_set(int xc_handle, + u32 domid, + u32 mcuadv, + int warpback, + s32 warpvalue, + long long warpl, + long long warpu); + +int xc_bvtsched_global_get(int xc_handle, + unsigned long *ctx_allow); + +int xc_bvtsched_domain_get(int xc_handle, + u32 domid, + u32 *mcuadv, + int *warpback, + s32 *warpvalue, + long long *warpl, + long long *warpu); + +int xc_sedf_domain_set(int xc_handle, + u32 domid, + u64 period, u64 slice, u64 latency, u16 extratime, u16 weight); + +int xc_sedf_domain_get(int xc_handle, + u32 domid, + u64* period, u64 *slice, u64 *latency, u16 *extratime, u16* weight); + +typedef evtchn_status_t xc_evtchn_status_t; + +/* + * EVENT CHANNEL FUNCTIONS + */ + +/** + * This function allocates an unbound port. Ports are named endpoints used for + * interdomain communication. This function is most useful in opening a + * well-known port within a domain to receive events on. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm dom the ID of the domain. This maybe DOMID_SELF + * @parm port a pointer to a port. This is an in/out parameter. If *port is + * 0, then a new port will be assigned, if port is > 0 then that + * port is allocated if the port is unallocated. + * @return 0 on success, -1 on failure + */ +int xc_evtchn_alloc_unbound(int xc_handle, + u32 dom, + int *port); + +/** + * This function creates a pair of ports between two domains. A port can only + * be bound once within a domain. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm dom1 one of the two domains to connect. Can be DOMID_SELF. + * @parm dom2 the other domain to connect. Can be DOMID_SELF. + * @parm port1 an in/out parameter. If > 0, then try to connect *port. If + * 0, then allocate a new port and store the port in *port. + * @parm port2 the port connected on port2. This parameter behaves the same + * way as port1. + * @return 0 on success, -1 on error. + */ +int xc_evtchn_bind_interdomain(int xc_handle, + u32 dom1, + u32 dom2, + int *port1, + int *port2); +int xc_evtchn_bind_virq(int xc_handle, + int virq, + int *port); + +/** + * This function will close a single port on an event channel. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm dom the domain that the port exists on. May be DOMID_SELF. + * @parm port the port to close + * @return 0 on success, -1 on error + */ +int xc_evtchn_close(int xc_handle, + u32 dom, /* may be DOMID_SELF */ + int port); + +/** + * This function generates a notify event on a bound port. + * + * Notifies can be read within Linux by opening /dev/xen/evtchn and reading + * a 16 bit value. The result will be the port the event occurred on. When + * events occur, the port is masked until the 16 bit port value is written back + * to the file. When /dev/xen/evtchn is opened, it has to be bound via an + * ioctl to each port to listen on. The ioctl for binding is _IO('E', 2). The + * parameter is the port to listen on. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm local_port the port to generate the notify on + * @return 0 on success, -1 on error + */ +int xc_evtchn_send(int xc_handle, + int local_port); +int xc_evtchn_status(int xc_handle, + u32 dom, /* may be DOMID_SELF */ + int port, + xc_evtchn_status_t *status); + +int xc_physdev_pci_access_modify(int xc_handle, + u32 domid, + int bus, + int dev, + int func, + int enable); + +int xc_readconsolering(int xc_handle, + char **pbuffer, + unsigned int *pnr_chars, + int clear); + +typedef dom0_physinfo_t xc_physinfo_t; +int xc_physinfo(int xc_handle, + xc_physinfo_t *info); + +int xc_sched_id(int xc_handle, + int *sched_id); + +int xc_domain_setmaxmem(int xc_handle, + u32 domid, + unsigned int max_memkb); + +int xc_domain_memory_increase_reservation(int xc_handle, + u32 domid, + unsigned int mem_kb); + +typedef dom0_perfc_desc_t xc_perfc_desc_t; +/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ +int xc_perfc_control(int xc_handle, + u32 op, + xc_perfc_desc_t *desc); + +/* read/write msr */ +long long xc_msr_read(int xc_handle, int cpu_mask, int msr); +int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low, + unsigned int high); + +/** + * Memory maps a range within one domain to a local address range. Mappings + * should be unmapped with munmap and should follow the same rules as mmap + * regarding page alignment. Returns NULL on failure. + * + * In Linux, the ring queue for the control channel is accessible by mapping + * the shared_info_frame (from xc_domain_getinfo()) + 2048. The structure + * stored there is of type control_if_t. + * + * @parm xc_handle a handle on an open hypervisor interface + * @parm dom the domain to map memory from + * @parm size the amount of memory to map (in multiples of page size) + * @parm prot same flag as in mmap(). + * @parm mfn the frame address to map. + */ +void *xc_map_foreign_range(int xc_handle, u32 dom, + int size, int prot, + unsigned long mfn ); + +void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, + unsigned long *arr, int num ); + +int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, + unsigned long max_pfns); + +int xc_ia64_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, + unsigned int start_page, unsigned int nr_pages); + +int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, + domid_t dom); + +int xc_dom_mem_op(int xc_handle, unsigned int memop, unsigned int *extent_list, + unsigned int nr_extents, unsigned int extent_order, + domid_t domid); + +int xc_get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr); + + +/*\ + * GRANT TABLE FUNCTIONS +\*/ + +/** + * This function opens a handle to the more restricted grant table hypervisor + * interface. This may be used where the standard interface is not + * available because the domain is not privileged. + * This function can be called multiple times within a single process. + * Multiple processes can have an open hypervisor interface at the same time. + * + * Each call to this function should have a corresponding call to + * xc_grant_interface_close(). + * + * This function can fail if a Xen-enabled kernel is not currently running. + * + * @return a handle to the hypervisor grant table interface or -1 on failure + */ +int xc_grant_interface_open(void); + +/** + * This function closes an open grant table hypervisor interface. + * + * This function can fail if the handle does not represent an open interface or + * if there were problems closing the interface. + * + * @parm xc_handle a handle to an open grant table hypervisor interface + * @return 0 on success, -1 otherwise. + */ +int xc_grant_interface_close(int xc_handle); + +int xc_gnttab_map_grant_ref(int xc_handle, + u64 host_virt_addr, + u32 dom, + u16 ref, + u16 flags, + s16 *handle, + u64 *dev_bus_addr); + +int xc_gnttab_unmap_grant_ref(int xc_handle, + u64 host_virt_addr, + u64 dev_bus_addr, + u16 handle, + s16 *status); + +int xc_gnttab_setup_table(int xc_handle, + u32 dom, + u16 nr_frames, + s16 *status, + unsigned long **frame_list); + +/* Grant debug builds only: */ +int xc_gnttab_dump_table(int xc_handle, + u32 dom, + s16 *status); + +/* Get current total pages allocated to a domain. */ +long xc_get_tot_pages(int xc_handle, u32 domid); + +/* Execute a privileged dom0 operation. */ +int xc_dom0_op(int xc_handle, dom0_op_t *op); + +/* Initializes the store (for dom0) + remote_port should be the remote end of a bound interdomain channel between + the store and dom0. + + This function returns a shared frame that should be passed to + xs_introduce_domain + */ +long xc_init_store(int xc_handle, int remote_port); + +/* + * MMU updates. + */ +#define MAX_MMU_UPDATES 1024 +struct xc_mmu { + mmu_update_t updates[MAX_MMU_UPDATES]; + int idx; + domid_t subject; +}; +typedef struct xc_mmu xc_mmu_t; +xc_mmu_t *xc_init_mmu_updates(int xc_handle, domid_t dom); +int xc_add_mmu_update(int xc_handle, xc_mmu_t *mmu, + unsigned long ptr, unsigned long val); +int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu); + +#endif diff -r e2025593f702 -r 112d44270733 tools/libxc/xenguest.h --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xenguest.h Thu Aug 25 18:18:47 2005 @@ -0,0 +1,66 @@ +/****************************************************************************** + * xenguest.h + * + * A library for guest domain management in Xen. + * + * Copyright (c) 2003-2004, K A Fraser. + */ + +#ifndef XENBUILD_H +#define XENBUILD_H + +#define XCFLAGS_VERBOSE 1 +#define XCFLAGS_LIVE 2 +#define XCFLAGS_DEBUG 4 +#define XCFLAGS_CONFIGURE 8 + +/** + * This function will save a domain running Linux. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm fd the file descriptor to save a domain to + * @parm dom the id of the domain + * @return 0 on success, -1 on failure + */ +int xc_linux_save(int xc_handle, int fd, uint32_t dom); + +/** + * This function will restore a saved domain running Linux. + * + * @parm xc_handle a handle to an open hypervisor interface + * @parm fd the file descriptor to restore a domain from + * @parm dom the id of the domain + * @parm nr_pfns the number of pages + * @parm store_evtchn the store event channel for this domain to use + * @parm store_mfn returned with the mfn of the store page + * @return 0 on success, -1 on failure + */ +int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, + unsigned int store_evtchn, unsigned long *store_mfn); + +int xc_linux_build(int xc_handle, + uint32_t domid, + const char *image_name, + const char *ramdisk_name, + const char *cmdline, + unsigned int control_evtchn, + unsigned long flags, + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn); + +struct mem_map; +int xc_vmx_build(int xc_handle, + uint32_t domid, + int memsize, + const char *image_name, + struct mem_map *memmap, + const char *ramdisk_name, + const char *cmdline, + unsigned int control_evtchn, + unsigned long flags, + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn); + +#endif diff -r e2025593f702 -r 112d44270733 tools/libxc/xg_private.c --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xg_private.c Thu Aug 25 18:18:47 2005 @@ -0,0 +1,86 @@ +/****************************************************************************** + * xg_private.c + * + * Helper functions for the rest of the library. + */ + +#include <stdlib.h> +#include <zlib.h> + +#include "xg_private.h" + +char *xc_read_kernel_image(const char *filename, unsigned long *size) +{ + int kernel_fd = -1; + gzFile kernel_gfd = NULL; + char *image = NULL; + unsigned int bytes; + + if ( (kernel_fd = open(filename, O_RDONLY)) < 0 ) + { + PERROR("Could not open kernel image"); + goto out; + } + + if ( (*size = xc_get_filesz(kernel_fd)) == 0 ) + { + PERROR("Could not read kernel image"); + goto out; + } + + if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL ) + { + PERROR("Could not allocate decompression state for state file"); + goto out; + } + + if ( (image = malloc(*size)) == NULL ) + { + PERROR("Could not allocate memory for kernel image"); + goto out; + } + + if ( (bytes = gzread(kernel_gfd, image, *size)) != *size ) + { + PERROR("Error reading kernel image, could not" + " read the whole image (%d != %ld).", bytes, *size); + free(image); + image = NULL; + } + + out: + if ( kernel_gfd != NULL ) + gzclose(kernel_gfd); + else if ( kernel_fd >= 0 ) + close(kernel_fd); + return image; +} + +/*******************/ + +int pin_table( + int xc_handle, unsigned int type, unsigned long mfn, domid_t dom) +{ + struct mmuext_op op; + + op.cmd = type; + op.mfn = mfn; + + if ( xc_mmuext_op(xc_handle, &op, 1, dom) < 0 ) + return 1; + + return 0; +} + +/* This is shared between save and restore, and may generally be useful. */ +unsigned long csum_page (void * page) +{ + int i; + unsigned long *p = page; + unsigned long long sum=0; + + for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ ) + sum += p[i]; + + return sum ^ (sum>>32); +} diff -r e2025593f702 -r 112d44270733 tools/libxc/xg_private.h --- /dev/null Wed Aug 24 23:16:52 2005 +++ b/tools/libxc/xg_private.h Thu Aug 25 18:18:47 2005 @@ -0,0 +1,170 @@ +#ifndef XG_PRIVATE_H +#define XG_PRIVATE_H + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "xenctrl.h" + +#include <xen/linux/privcmd.h> + +char *xc_read_kernel_image(const char *filename, unsigned long *size); +unsigned long csum_page (void * page); + +#define _PAGE_PRESENT 0x001 +#define _PAGE_RW 0x002 +#define _PAGE_USER 0x004 +#define _PAGE_PWT 0x008 +#define _PAGE_PCD 0x010 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_PAT 0x080 +#define _PAGE_PSE 0x080 +#define _PAGE_GLOBAL 0x100 + +#if defined(__i386__) +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 22 +#define L1_PAGETABLE_SHIFT_PAE 12 +#define L2_PAGETABLE_SHIFT_PAE 21 +#define L3_PAGETABLE_SHIFT_PAE 30 +#elif defined(__x86_64__) +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 21 +#define L3_PAGETABLE_SHIFT 30 +#define L4_PAGETABLE_SHIFT 39 +#endif + +#if defined(__i386__) +#define ENTRIES_PER_L1_PAGETABLE 1024 +#define ENTRIES_PER_L2_PAGETABLE 1024 +#define L1_PAGETABLE_ENTRIES_PAE 512 +#define L2_PAGETABLE_ENTRIES_PAE 512 +#define L3_PAGETABLE_ENTRIES_PAE 4 +#elif defined(__x86_64__) +#define L1_PAGETABLE_ENTRIES 512 +#define L2_PAGETABLE_ENTRIES 512 +#define L3_PAGETABLE_ENTRIES 512 +#define L4_PAGETABLE_ENTRIES 512 +#endif + +#define PAGE_SHIFT XC_PAGE_SHIFT +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +typedef u32 l1_pgentry_32_t; +typedef u32 l2_pgentry_32_t; +typedef u64 l1_pgentry_64_t; +typedef u64 l2_pgentry_64_t; +typedef u64 l3_pgentry_64_t; +typedef unsigned long l1_pgentry_t; +typedef unsigned long l2_pgentry_t; +#if defined(__x86_64__) +typedef unsigned long l3_pgentry_t; +typedef unsigned long l4_pgentry_t; +#endif + +#if defined(__i386__) +#define l1_table_offset(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1)) +#define l2_table_offset(_a) \ + ((_a) >> L2_PAGETABLE_SHIFT) +#define l1_table_offset_pae(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1)) +#define l2_table_offset_pae(_a) \ + (((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1)) +#define l3_table_offset_pae(_a) \ + (((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1)) +#elif defined(__x86_64__) +#define l1_table_offset(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) +#define l2_table_offset(_a) \ + (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +#define l3_table_offset(_a) \ + (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) +#define l4_table_offset(_a) \ + (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) +#endif + +#define ERROR(_m, _a...) \ +do { \ + int __saved_errno = errno; \ + fprintf(stderr, "ERROR: " _m "\n" , ## _a ); \ + errno = __saved_errno; \ +} while (0) + + +#define PERROR(_m, _a...) \ +do { \ + int __saved_errno = errno; \ + fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ + __saved_errno, strerror(__saved_errno)); \ + errno = __saved_errno; \ +} while (0) + + +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 load_symtab; + unsigned int pae_kernel; + unsigned long symtab_addr; + unsigned long symtab_len; +}; + +typedef int (*parseimagefunc)(char *image, unsigned long image_size, + struct domain_setup_info *dsi); +typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch, + u32 dom, unsigned long *parray, + struct domain_setup_info *dsi); + +struct load_funcs +{ + parseimagefunc parseimage; + loadimagefunc loadimage; +}; + +#define mfn_mapper_queue_size 128 + +typedef struct mfn_mapper { + int xc_handle; + int size; + int prot; + int error; + int max_queue_size; + void * addr; + privcmd_mmap_t ioctl; + +} mfn_mapper_t; + +unsigned long xc_get_m2p_start_mfn (int xc_handle); + +int xc_copy_to_domain_page(int xc_handle, u32 domid, + unsigned long dst_pfn, void *src_page); + +unsigned long xc_get_filesz(int fd); + +void xc_map_memcpy(unsigned long dst, char *src, unsigned long size, + int xch, u32 dom, unsigned long *parray, + unsigned long vstart); + +int pin_table(int xc_handle, unsigned int type, unsigned long mfn, + domid_t dom); + +/* image loading */ +int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs); +int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs); +int probe_aout9(char *image, unsigned long image_size, struct load_funcs *funcs); + +#endif + diff -r e2025593f702 -r 112d44270733 linux-2.6-xen-sparse/drivers/xen/netback/control.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/control.c Wed Aug 24 23:16:52 2005 +++ /dev/null Thu Aug 25 18:18:47 2005 @@ -1,58 +0,0 @@ -/****************************************************************************** - * arch/xen/drivers/netif/backend/control.c - * - * Routines for interfacing with the control plane. - * - * Copyright (c) 2004, Keir Fraser - */ - -#include "common.h" - -static void netif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id) -{ - DPRINTK("Received netif backend message, subtype=%d\n", msg->subtype); - - switch ( msg->subtype ) - { - case CMSG_NETIF_BE_CREATE: - netif_create((netif_be_create_t *)&msg->msg[0]); - break; - case CMSG_NETIF_BE_DESTROY: - netif_destroy((netif_be_destroy_t *)&msg->msg[0]); - break; - case CMSG_NETIF_BE_CREDITLIMIT: - netif_creditlimit((netif_be_creditlimit_t *)&msg->msg[0]); - break; - case CMSG_NETIF_BE_CONNECT: - netif_connect((netif_be_connect_t *)&msg->msg[0]); - break; - case CMSG_NETIF_BE_DISCONNECT: - if ( !netif_disconnect((netif_be_disconnect_t *)&msg->msg[0],msg->id) ) - return; /* Sending the response is deferred until later. */ - break; - default: - DPRINTK("Parse error while reading message subtype %d, len %d\n", - msg->subtype, msg->length); - msg->length = 0; - break; - } - - ctrl_if_send_response(msg); -} - -void netif_ctrlif_init(void) -{ - ctrl_msg_t cmsg; - netif_be_driver_status_t st; - - (void)ctrl_if_register_receiver(CMSG_NETIF_BE, netif_ctrlif_rx, - CALLBACK_IN_BLOCKING_CONTEXT); - - /* Send a driver-UP notification to the domain controller. */ - cmsg.type = CMSG_NETIF_BE; - cmsg.subtype = CMSG_NETIF_BE_DRIVER_STATUS; - cmsg.length = sizeof(netif_be_driver_status_t); - st.status = NETIF_DRIVER_STATUS_UP; - memcpy(cmsg.msg, &st, sizeof(st)); - ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); -} diff -r e2025593f702 -r 112d44270733 patches/linux-2.6.12/workaround_double_br_del_if.patch --- a/patches/linux-2.6.12/workaround_double_br_del_if.patch Wed Aug 24 23:16:52 2005 +++ /dev/null Thu Aug 25 18:18:47 2005 @@ -1,11 +0,0 @@ ---- linux-2.6.12/net/bridge/br_if.c 2005-06-17 14:48:29.000000000 -0500 -+++ linux-2.6.12-xen0-smp/net/bridge/br_if.c 2005-08-18 15:17:27.302615846 -0500 -@@ -382,7 +382,7 @@ - { - struct net_bridge_port *p = dev->br_port; - -- if (!p || p->br != br) -+ if (!p || p->br != br || p->state == BR_STATE_DISABLED) - return -EINVAL; - - br_sysfs_removeif(p); diff -r e2025593f702 -r 112d44270733 tools/libxc/xc.h --- a/tools/libxc/xc.h Wed Aug 24 23:16:52 2005 +++ /dev/null Thu Aug 25 18:18:47 2005 @@ -1,558 +0,0 @@ -/****************************************************************************** - * xc.h - * - * A library for low-level access to the Xen control interfaces. - * - * Copyright (c) 2003-2004, K A Fraser. - */ - -#ifndef __XC_H__ -#define __XC_H__ - -#include <stdint.h> - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; - -#include <sys/ptrace.h> -#include <xen/xen.h> -#include <xen/dom0_ops.h> -#include <xen/event_channel.h> -#include <xen/sched_ctl.h> -#include <xen/acm.h> - -#ifdef __ia64__ -#define XC_PAGE_SHIFT 14 -#else -#define XC_PAGE_SHIFT 12 -#endif -#define XC_PAGE_SIZE (1UL << XC_PAGE_SHIFT) -#define XC_PAGE_MASK (~(XC_PAGE_SIZE-1)) - -/* - * DEFINITIONS FOR CPU BARRIERS - */ - -#if defined(__i386__) -#define mb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) -#define rmb() __asm__ __volatile__ ( "lock; addl $0,0(%%esp)" : : : "memory" ) -#define wmb() __asm__ __volatile__ ( "" : : : "memory") -#elif defined(__x86_64__) -#define mb() __asm__ __volatile__ ( "mfence" : : : "memory") -#define rmb() __asm__ __volatile__ ( "lfence" : : : "memory") -#define wmb() __asm__ __volatile__ ( "" : : : "memory") -#elif defined(__ia64__) -/* FIXME */ -#define mb() -#define rmb() -#define wmb() -#else -#error "Define barriers" -#endif - -/* - * INITIALIZATION FUNCTIONS - */ - -/** - * This function opens a handle to the hypervisor interface. This function can - * be called multiple times within a single process. Multiple processes can - * have an open hypervisor interface at the same time. - * - * Each call to this function should have a corresponding call to - * xc_interface_close(). - * - * This function can fail if the caller does not have superuser permission or - * if a Xen-enabled kernel is not currently running. - * - * @return a handle to the hypervisor interface or -1 on failure - */ -int xc_interface_open(void); - -/** - * This function closes an open hypervisor interface. - * - * This function can fail if the handle does not represent an open interface or - * if there were problems closing the interface. - * - * @parm xc_handle a handle to an open hypervisor interface - * @return 0 on success, -1 otherwise. - */ -int xc_interface_close(int xc_handle); - -/* - * DOMAIN DEBUGGING FUNCTIONS - */ - -typedef struct xc_core_header { - unsigned int xch_magic; - unsigned int xch_nr_vcpus; - unsigned int xch_nr_pages; - unsigned int xch_ctxt_offset; - unsigned int xch_index_offset; - unsigned int xch_pages_offset; -} xc_core_header_t; - - -long xc_ptrace(enum __ptrace_request request, - u32 domid, - long addr, - long data); - -long xc_ptrace_core(enum __ptrace_request request, - u32 domid, - long addr, - long data); - -int xc_waitdomain(int domain, - int *status, - int options); - -int xc_waitdomain_core(int domain, - int *status, - int options); - -/* - * DOMAIN MANAGEMENT FUNCTIONS - */ - -typedef struct { - u32 domid; - u32 ssidref; - unsigned int dying:1, crashed:1, shutdown:1, - paused:1, blocked:1, running:1; - unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ - unsigned long nr_pages; - unsigned long shared_info_frame; - u64 cpu_time; - unsigned long max_memkb; - unsigned int vcpus; - s32 vcpu_to_cpu[MAX_VIRT_CPUS]; - cpumap_t cpumap[MAX_VIRT_CPUS]; -} xc_dominfo_t; - -typedef dom0_getdomaininfo_t xc_domaininfo_t; -int xc_domain_create(int xc_handle, - u32 ssidref, - u32 *pdomid); - - -int xc_domain_dumpcore(int xc_handle, - u32 domid, - const char *corename); - - -/** - * This function pauses a domain. A paused domain still exists in memory - * however it does not receive any timeslices from the hypervisor. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm domid the domain id to pause - * @return 0 on success, -1 on failure. - */ -int xc_domain_pause(int xc_handle, - u32 domid); -/** - * This function unpauses a domain. The domain should have been previously - * paused. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm domid the domain id to unpause - * return 0 on success, -1 on failure - */ -int xc_domain_unpause(int xc_handle, - u32 domid); - -/** - * This function will destroy a domain. Destroying a domain removes the domain - * completely from memory. This function should be called after sending the - * domain a SHUTDOWN control message to free up the domain resources. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm domid the domain id to destroy - * @return 0 on success, -1 on failure - */ -int xc_domain_destroy(int xc_handle, - u32 domid); -int xc_domain_pincpu(int xc_handle, - u32 domid, - int vcpu, - cpumap_t *cpumap); -/** - * This function will return information about one or more domains. It is - * designed to iterate over the list of domains. If a single domain is - * requested, this function will return the next domain in the list - if - * one exists. It is, therefore, important in this case to make sure the - * domain requested was the one returned. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm first_domid the first domain to enumerate information from. Domains - * are currently enumerate in order of creation. - * @parm max_doms the number of elements in info - * @parm info an array of max_doms size that will contain the information for - * the enumerated domains. - * @return the number of domains enumerated or -1 on error - */ -int xc_domain_getinfo(int xc_handle, - u32 first_domid, - unsigned int max_doms, - xc_dominfo_t *info); - -/** - * This function will return information about one or more domains, using a - * single hypercall. The domain information will be stored into the supplied - * array of xc_domaininfo_t structures. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm first_domain the first domain to enumerate information from. - * Domains are currently enumerate in order of creation. - * @parm max_domains the number of elements in info - * @parm info an array of max_doms size that will contain the information for - * the enumerated domains. - * @return the number of domains enumerated or -1 on error - */ -int xc_domain_getinfolist(int xc_handle, - u32 first_domain, - unsigned int max_domains, - xc_domaininfo_t *info); - -/** - * This function returns information about one domain. This information is - * more detailed than the information from xc_domain_getinfo(). - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm domid the domain to get information from - * @parm info a pointer to an xc_domaininfo_t to store the domain information - * @parm ctxt a pointer to a structure to store the execution context of the - * domain - * @return 0 on success, -1 on failure - */ -int xc_domain_get_vcpu_context(int xc_handle, - u32 domid, - u32 vcpu, - vcpu_guest_context_t *ctxt); - -int xc_domain_setcpuweight(int xc_handle, - u32 domid, - float weight); -long long xc_domain_get_cpu_usage(int xc_handle, - domid_t domid, - int vcpu); - - -typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t; -int xc_shadow_control(int xc_handle, - u32 domid, - unsigned int sop, - unsigned long *dirty_bitmap, - unsigned long pages, - xc_shadow_control_stats_t *stats); - - -#define XCFLAGS_VERBOSE 1 -#define XCFLAGS_LIVE 2 -#define XCFLAGS_DEBUG 4 -#define XCFLAGS_CONFIGURE 8 - -struct XcIOContext; - -/** - * This function will save a domain running Linux. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm fd the file descriptor to save a domain to - * @parm dom the id of the domain - * @return 0 on success, -1 on failure - */ -int xc_linux_save(int xc_handle, int fd, u32 dom); - -/** - * This function will restore a saved domain running Linux. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm fd the file descriptor to restore a domain from - * @parm dom the id of the domain - * @parm nr_pfns the number of pages - * @parm store_evtchn the store event channel for this domain to use - * @parm store_mfn returned with the mfn of the store page - * @return 0 on success, -1 on failure - */ -int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, - unsigned int store_evtchn, unsigned long *store_mfn); - -int xc_linux_build(int xc_handle, - u32 domid, - const char *image_name, - const char *ramdisk_name, - const char *cmdline, - unsigned int control_evtchn, - unsigned long flags, - unsigned int vcpus, - unsigned int store_evtchn, - unsigned long *store_mfn); - -struct mem_map; -int xc_vmx_build(int xc_handle, - u32 domid, - int memsize, - const char *image_name, - struct mem_map *memmap, - const char *ramdisk_name, - const char *cmdline, - unsigned int control_evtchn, - unsigned long flags, - unsigned int vcpus, - unsigned int store_evtchn, - unsigned long *store_mfn); - -int xc_bvtsched_global_set(int xc_handle, - unsigned long ctx_allow); - -int xc_bvtsched_domain_set(int xc_handle, - u32 domid, - u32 mcuadv, - int warpback, - s32 warpvalue, - long long warpl, - long long warpu); - -int xc_bvtsched_global_get(int xc_handle, - unsigned long *ctx_allow); - -int xc_bvtsched_domain_get(int xc_handle, - u32 domid, - u32 *mcuadv, - int *warpback, - s32 *warpvalue, - long long *warpl, - long long *warpu); - -int xc_sedf_domain_set(int xc_handle, - u32 domid, - u64 period, u64 slice, u64 latency, u16 extratime, u16 weight); - -int xc_sedf_domain_get(int xc_handle, - u32 domid, - u64* period, u64 *slice, u64 *latency, u16 *extratime, u16* weight); - -typedef evtchn_status_t xc_evtchn_status_t; - -/* - * EVENT CHANNEL FUNCTIONS - */ - -/** - * This function allocates an unbound port. Ports are named endpoints used for - * interdomain communication. This function is most useful in opening a - * well-known port within a domain to receive events on. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm dom the ID of the domain. This maybe DOMID_SELF - * @parm port a pointer to a port. This is an in/out parameter. If *port is - * 0, then a new port will be assigned, if port is > 0 then that - * port is allocated if the port is unallocated. - * @return 0 on success, -1 on failure - */ -int xc_evtchn_alloc_unbound(int xc_handle, - u32 dom, - int *port); - -/** - * This function creates a pair of ports between two domains. A port can only - * be bound once within a domain. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm dom1 one of the two domains to connect. Can be DOMID_SELF. - * @parm dom2 the other domain to connect. Can be DOMID_SELF. - * @parm port1 an in/out parameter. If > 0, then try to connect *port. If - * 0, then allocate a new port and store the port in *port. - * @parm port2 the port connected on port2. This parameter behaves the same - * way as port1. - * @return 0 on success, -1 on error. - */ -int xc_evtchn_bind_interdomain(int xc_handle, - u32 dom1, - u32 dom2, - int *port1, - int *port2); -int xc_evtchn_bind_virq(int xc_handle, - int virq, - int *port); - -/** - * This function will close a single port on an event channel. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm dom the domain that the port exists on. May be DOMID_SELF. - * @parm port the port to close - * @return 0 on success, -1 on error - */ -int xc_evtchn_close(int xc_handle, - u32 dom, /* may be DOMID_SELF */ - int port); - -/** - * This function generates a notify event on a bound port. - * - * Notifies can be read within Linux by opening /dev/xen/evtchn and reading - * a 16 bit value. The result will be the port the event occurred on. When - * events occur, the port is masked until the 16 bit port value is written back - * to the file. When /dev/xen/evtchn is opened, it has to be bound via an - * ioctl to each port to listen on. The ioctl for binding is _IO('E', 2). The - * parameter is the port to listen on. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm local_port the port to generate the notify on - * @return 0 on success, -1 on error - */ -int xc_evtchn_send(int xc_handle, - int local_port); -int xc_evtchn_status(int xc_handle, - u32 dom, /* may be DOMID_SELF */ - int port, - xc_evtchn_status_t *status); - -int xc_physdev_pci_access_modify(int xc_handle, - u32 domid, - int bus, - int dev, - int func, - int enable); - -int xc_readconsolering(int xc_handle, - char **pbuffer, - unsigned int *pnr_chars, - int clear); - -typedef dom0_physinfo_t xc_physinfo_t; -int xc_physinfo(int xc_handle, - xc_physinfo_t *info); - -int xc_sched_id(int xc_handle, - int *sched_id); - -int xc_domain_setmaxmem(int xc_handle, - u32 domid, - unsigned int max_memkb); - -int xc_domain_memory_increase_reservation(int xc_handle, - u32 domid, - unsigned int mem_kb); - -typedef dom0_perfc_desc_t xc_perfc_desc_t; -/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ -int xc_perfc_control(int xc_handle, - u32 op, - xc_perfc_desc_t *desc); - -/* read/write msr */ -long long xc_msr_read(int xc_handle, int cpu_mask, int msr); -int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low, - unsigned int high); - -/** - * Memory maps a range within one domain to a local address range. Mappings - * should be unmapped with munmap and should follow the same rules as mmap - * regarding page alignment. Returns NULL on failure. - * - * In Linux, the ring queue for the control channel is accessible by mapping - * the shared_info_frame (from xc_domain_getinfo()) + 2048. The structure - * stored there is of type control_if_t. - * - * @parm xc_handle a handle on an open hypervisor interface - * @parm dom the domain to map memory from - * @parm size the amount of memory to map (in multiples of page size) - * @parm prot same flag as in mmap(). - * @parm mfn the frame address to map. - */ -void *xc_map_foreign_range(int xc_handle, u32 dom, - int size, int prot, - unsigned long mfn ); - -void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, - unsigned long *arr, int num ); - -int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, - unsigned long max_pfns); - -int xc_ia64_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, - unsigned int start_page, unsigned int nr_pages); - -/*\ - * GRANT TABLE FUNCTIONS -\*/ - -/** - * This function opens a handle to the more restricted grant table hypervisor - * interface. This may be used where the standard interface is not - * available because the domain is not privileged. - * This function can be called multiple times within a single process. - * Multiple processes can have an open hypervisor interface at the same time. - * - * Each call to this function should have a corresponding call to - * xc_grant_interface_close(). - * - * This function can fail if a Xen-enabled kernel is not currently running. - * - * @return a handle to the hypervisor grant table interface or -1 on failure - */ -int xc_grant_interface_open(void); - -/** - * This function closes an open grant table hypervisor interface. - * - * This function can fail if the handle does not represent an open interface or - * if there were problems closing the interface. - * - * @parm xc_handle a handle to an open grant table hypervisor interface - * @return 0 on success, -1 otherwise. - */ -int xc_grant_interface_close(int xc_handle); - -int xc_gnttab_map_grant_ref(int xc_handle, - u64 host_virt_addr, - u32 dom, - u16 ref, - u16 flags, - s16 *handle, - u64 *dev_bus_addr); - -int xc_gnttab_unmap_grant_ref(int xc_handle, - u64 host_virt_addr, - u64 dev_bus_addr, - u16 handle, - s16 *status); - -int xc_gnttab_setup_table(int xc_handle, - u32 dom, - u16 nr_frames, - s16 *status, - unsigned long **frame_list); - -/* Grant debug builds only: */ -int xc_gnttab_dump_table(int xc_handle, - u32 dom, - s16 *status); - -/* Get current total pages allocated to a domain. */ -long xc_get_tot_pages(int xc_handle, u32 domid); - -/* Execute a privileged dom0 operation. */ -int xc_dom0_op(int xc_handle, dom0_op_t *op); - -/* Initializes the store (for dom0) - remote_port should be the remote end of a bound interdomain channel between - the store and dom0. - - This function returns a shared frame that should be passed to - xs_introduce_domain - */ -long xc_init_store(int xc_handle, int remote_port); - -#endif /* __XC_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |