[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Merge.
# HG changeset patch # User adsharma@xxxxxxxxxxxxxxxxxxxx # Node ID 287d36b46fa3b7ec38f40a8ca799e8223d3df5ff # Parent ae390c2b9d4c846bbbe3678d04e239db04076e67 # Parent 551870a55f240791695d30fd7fa92a1bf4e48387 Merge. diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Tue Aug 30 20:36:49 2005 @@ -195,6 +195,7 @@ # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/pci-dma.c Tue Aug 30 20:36:49 2005 @@ -115,9 +115,9 @@ if (swiotlb) return swiotlb_dma_supported(dev, mask); /* - * By default we'll BUG when an infeasible DMA is requested, and - * request swiotlb=force (see IOMMU_BUG_ON). - */ + * By default we'll BUG when an infeasible DMA is requested, and + * request swiotlb=force (see IOMMU_BUG_ON). + */ return 1; } EXPORT_SYMBOL(dma_supported); diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c Tue Aug 30 20:36:49 2005 @@ -55,6 +55,7 @@ #include <asm/io.h> #include <asm-xen/hypervisor.h> #include <asm-xen/xen-public/physdev.h> +#include <asm-xen/xen-public/memory.h> #include "setup_arch_pre.h" #include <bios_ebda.h> @@ -1585,15 +1586,21 @@ (unsigned int *)xen_start_info.mfn_list, xen_start_info.nr_pages * sizeof(unsigned int)); } else { + struct xen_memory_reservation reservation = { + .extent_start = (unsigned long *)xen_start_info.mfn_list + max_pfn, + .nr_extents = xen_start_info.nr_pages - max_pfn, + .extent_order = 0, + .domid = DOMID_SELF + }; + memcpy(phys_to_machine_mapping, (unsigned int *)xen_start_info.mfn_list, max_pfn * sizeof(unsigned int)); /* N.B. below relies on sizeof(int) == sizeof(long). */ - if (HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, - (unsigned long *)xen_start_info.mfn_list + max_pfn, - xen_start_info.nr_pages - max_pfn, 0) != - (xen_start_info.nr_pages - max_pfn)) BUG(); + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, + &reservation) != + (xen_start_info.nr_pages - max_pfn)); } free_bootmem( __pa(xen_start_info.mfn_list), diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c Tue Aug 30 20:36:49 2005 @@ -35,6 +35,7 @@ #include <asm/pgtable.h> #include <asm-xen/hypervisor.h> #include <asm-xen/balloon.h> +#include <asm-xen/xen-public/memory.h> #include <linux/module.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include <linux/percpu.h> @@ -320,6 +321,12 @@ pmd_t *pmd; pte_t *pte; unsigned long mfn, i, flags; + struct xen_memory_reservation reservation = { + .extent_start = &mfn, + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; scrub_pages(vstart, 1 << order); @@ -336,13 +343,15 @@ vstart + (i*PAGE_SIZE), __pte_ma(0), 0)); phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = INVALID_P2M_ENTRY; - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, &mfn, 1, 0) != 1); + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, &reservation) != 1); } /* 2. Get a new contiguous memory extent. */ - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, &mfn, 1, order | (32<<8)) != 1); + reservation.extent_order = order; + reservation.address_bits = 31; /* aacraid limitation */ + BUG_ON(HYPERVISOR_memory_op( + XENMEM_increase_reservation, &reservation) != 1); /* 3. Map the new extent in place of old pages. */ for (i = 0; i < (1<<order); i++) { @@ -367,6 +376,12 @@ pmd_t *pmd; pte_t *pte; unsigned long mfn, i, flags; + struct xen_memory_reservation reservation = { + .extent_start = &mfn, + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; scrub_pages(vstart, 1 << order); @@ -385,14 +400,14 @@ vstart + (i*PAGE_SIZE), __pte_ma(0), 0)); phys_to_machine_mapping[(__pa(vstart)>>PAGE_SHIFT)+i] = INVALID_P2M_ENTRY; - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, &mfn, 1, 0) != 1); + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, &reservation) != 1); } /* 2. Map new pages in place of old pages. */ for (i = 0; i < (1<<order); i++) { - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, &mfn, 1, 0) != 1); + BUG_ON(HYPERVISOR_memory_op( + XENMEM_increase_reservation, &reservation) != 1); BUG_ON(HYPERVISOR_update_va_mapping( vstart + (i*PAGE_SIZE), pfn_pte_ma(mfn, PAGE_KERNEL), 0)); diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Aug 30 20:36:49 2005 @@ -44,13 +44,6 @@ #include <asm-xen/hypervisor.h> #include <asm-xen/evtchn.h> -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -EXPORT_SYMBOL(force_evtchn_callback); -EXPORT_SYMBOL(evtchn_do_upcall); -EXPORT_SYMBOL(bind_evtchn_to_irq); -EXPORT_SYMBOL(unbind_evtchn_from_irq); -#endif - /* * This lock protects updates to the following mapping and reference-count * arrays. The lock does not need to be acquired to read the mapping tables. @@ -133,6 +126,7 @@ { (void)HYPERVISOR_xen_version(0); } +EXPORT_SYMBOL(force_evtchn_callback); /* NB. Interrupts are disabled on entry. */ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) @@ -165,6 +159,7 @@ } } } +EXPORT_SYMBOL(evtchn_do_upcall); static int find_unbound_irq(void) { @@ -211,6 +206,7 @@ return irq; } +EXPORT_SYMBOL(bind_virq_to_irq); void unbind_virq_from_irq(int virq) { @@ -244,6 +240,7 @@ spin_unlock(&irq_mapping_update_lock); } +EXPORT_SYMBOL(unbind_virq_from_irq); int bind_ipi_to_irq(int ipi) { @@ -279,6 +276,7 @@ return irq; } +EXPORT_SYMBOL(bind_ipi_to_irq); void unbind_ipi_from_irq(int ipi) { @@ -306,6 +304,7 @@ spin_unlock(&irq_mapping_update_lock); } +EXPORT_SYMBOL(unbind_ipi_from_irq); int bind_evtchn_to_irq(unsigned int evtchn) { @@ -326,6 +325,7 @@ return irq; } +EXPORT_SYMBOL(bind_evtchn_to_irq); void unbind_evtchn_from_irq(unsigned int evtchn) { @@ -341,6 +341,7 @@ spin_unlock(&irq_mapping_update_lock); } +EXPORT_SYMBOL(unbind_evtchn_from_irq); int bind_evtchn_to_irqhandler( unsigned int evtchn, @@ -359,6 +360,7 @@ return retval; } +EXPORT_SYMBOL(bind_evtchn_to_irqhandler); void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id) { @@ -366,6 +368,7 @@ free_irq(irq, dev_id); unbind_evtchn_from_irq(evtchn); } +EXPORT_SYMBOL(unbind_evtchn_from_irqhandler); #ifdef CONFIG_SMP static void do_nothing_function(void *ign) diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/kernel/reboot.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Tue Aug 30 20:36:49 2005 @@ -65,16 +65,11 @@ #define cpu_up(x) (-EOPNOTSUPP) #endif -#ifdef CONFIG_SMP -#endif static int __do_suspend(void *ignore) { int i, j; suspend_record_t *suspend_record; - - /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */ - /* XXX SMH: yes it would :-( */ #ifdef CONFIG_XEN_USB_FRONTEND extern void usbif_resume(); @@ -108,7 +103,8 @@ #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU) if (num_online_cpus() > 1) { - printk(KERN_WARNING "Can't suspend SMP guests without CONFIG_HOTPLUG_CPU\n"); + printk(KERN_WARNING + "Can't suspend SMP guests without CONFIG_HOTPLUG_CPU\n"); return -EOPNOTSUPP; } #endif diff -r ae390c2b9d4c -r 287d36b46fa3 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 Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c Tue Aug 30 20:36:49 2005 @@ -734,9 +734,9 @@ /* Make sure we have a large enough P->M table. */ if (end_pfn > xen_start_info.nr_pages) { phys_to_machine_mapping = alloc_bootmem( - max_pfn * sizeof(u32)); + end_pfn * sizeof(u32)); memset(phys_to_machine_mapping, ~0, - max_pfn * sizeof(u32)); + end_pfn * sizeof(u32)); memcpy(phys_to_machine_mapping, (u32 *)xen_start_info.mfn_list, xen_start_info.nr_pages * sizeof(u32)); @@ -749,11 +749,8 @@ pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE); for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(u32)), j++ ) - { pfn_to_mfn_frame_list[j] = virt_to_mfn(&phys_to_machine_mapping[i]); - } - } #endif diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c --- a/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c Tue Aug 30 20:36:49 2005 @@ -149,7 +149,7 @@ pmd_t *pmd; pte_t *pte; - pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id()); + pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id()); pgd += pgd_index(address); printk("PGD %lx ", pgd_val(*pgd)); @@ -296,9 +296,9 @@ #define MEM_VERBOSE 1 #ifdef MEM_VERBOSE -#define MEM_LOG(_f, _a...) \ - printk("fault.c:[%d]-> " _f "\n", \ - __LINE__ , ## _a ) +#define MEM_LOG(_f, _a...) \ + printk("fault.c:[%d]-> " _f "\n", \ + __LINE__ , ## _a ) #else #define MEM_LOG(_f, _a...) ((void)0) #endif @@ -325,7 +325,7 @@ siginfo_t info; if (!user_mode(regs)) - error_code &= ~4; /* means kernel */ + error_code &= ~4; /* means kernel */ #ifdef CONFIG_CHECKING { diff -r ae390c2b9d4c -r 287d36b46fa3 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 Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c Tue Aug 30 20:36:49 2005 @@ -62,14 +62,16 @@ * avaialble in init_memory_mapping(). */ -#define addr_to_page(addr, page) \ - (addr) &= PHYSICAL_PAGE_MASK; \ - (page) = ((unsigned long *) ((unsigned long)(((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) + __START_KERNEL_map))) +#define addr_to_page(addr, page) \ + (addr) &= PHYSICAL_PAGE_MASK; \ + (page) = ((unsigned long *) ((unsigned long) \ + (((mfn_to_pfn((addr) >> PAGE_SHIFT)) << PAGE_SHIFT) + \ + __START_KERNEL_map))) static void __make_page_readonly(unsigned long va) { - unsigned long addr; - pte_t pte, *ptep; + unsigned long addr; + pte_t pte, *ptep; unsigned long *page = (unsigned long *) init_level4_pgt; addr = (unsigned long) page[pgd_index(va)]; @@ -89,22 +91,22 @@ static void __make_page_writable(unsigned long va) { - unsigned long addr; - pte_t pte, *ptep; - unsigned long *page = (unsigned long *) init_level4_pgt; - - addr = (unsigned long) page[pgd_index(va)]; - addr_to_page(addr, page); - - addr = page[pud_index(va)]; - addr_to_page(addr, page); - - addr = page[pmd_index(va)]; - addr_to_page(addr, page); - - ptep = (pte_t *) &page[pte_index(va)]; + unsigned long addr; + pte_t pte, *ptep; + unsigned long *page = (unsigned long *) init_level4_pgt; + + addr = (unsigned long) page[pgd_index(va)]; + addr_to_page(addr, page); + + addr = page[pud_index(va)]; + addr_to_page(addr, page); + + addr = page[pmd_index(va)]; + addr_to_page(addr, page); + + ptep = (pte_t *) &page[pte_index(va)]; pte.pte = (ptep->pte | _PAGE_RW); - xen_l1_entry_update(ptep, pte); + xen_l1_entry_update(ptep, pte); __flush_tlb_one(addr); } @@ -115,55 +117,55 @@ void make_page_readonly(void *va) { pgd_t* pgd; pud_t *pud; pmd_t* pmd; pte_t pte, *ptep; - unsigned long addr = (unsigned long) va; - - if (!init_mapping_done) { - __make_page_readonly(addr); - return; - } - - pgd = pgd_offset_k(addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - ptep = pte_offset_kernel(pmd, addr); + unsigned long addr = (unsigned long) va; + + if (!init_mapping_done) { + __make_page_readonly(addr); + return; + } + + pgd = pgd_offset_k(addr); + pud = pud_offset(pgd, addr); + pmd = pmd_offset(pud, addr); + ptep = pte_offset_kernel(pmd, addr); pte.pte = (ptep->pte & ~_PAGE_RW); - xen_l1_entry_update(ptep, pte); + xen_l1_entry_update(ptep, pte); __flush_tlb_one(addr); } void make_page_writable(void *va) { - pgd_t* pgd; pud_t *pud; pmd_t* pmd; pte_t pte, *ptep; - unsigned long addr = (unsigned long) va; - - if (!init_mapping_done) { - __make_page_writable(addr); - return; - } - - pgd = pgd_offset_k(addr); - pud = pud_offset(pgd, addr); - pmd = pmd_offset(pud, addr); - ptep = pte_offset_kernel(pmd, addr); + pgd_t* pgd; pud_t *pud; pmd_t* pmd; pte_t pte, *ptep; + unsigned long addr = (unsigned long) va; + + if (!init_mapping_done) { + __make_page_writable(addr); + return; + } + + pgd = pgd_offset_k(addr); + pud = pud_offset(pgd, addr); + pmd = pmd_offset(pud, addr); + ptep = pte_offset_kernel(pmd, addr); pte.pte = (ptep->pte | _PAGE_RW); - xen_l1_entry_update(ptep, pte); + xen_l1_entry_update(ptep, pte); __flush_tlb_one(addr); } void make_pages_readonly(void* va, unsigned nr) { - while ( nr-- != 0 ) { - make_page_readonly(va); - va = (void*)((unsigned long)va + PAGE_SIZE); - } + while (nr-- != 0) { + make_page_readonly(va); + va = (void*)((unsigned long)va + PAGE_SIZE); + } } void make_pages_writable(void* va, unsigned nr) { - while ( nr-- != 0 ) { - make_page_writable(va); - va = (void*)((unsigned long)va + PAGE_SIZE); - } + while (nr-- != 0) { + make_page_writable(va); + va = (void*)((unsigned long)va + PAGE_SIZE); + } } /* @@ -389,7 +391,7 @@ set_pte_phys(address, phys, prot, SET_FIXMAP_USER); } -unsigned long __initdata table_start, table_end, tables_space; +unsigned long __initdata table_start, tables_space; unsigned long get_machine_pfn(unsigned long addr) { @@ -400,40 +402,15 @@ return pte_mfn(*pte); } -#define ALIGN_TO_4K __attribute__((section(".data.page_aligned"))) -#define MAX_LOW_PAGES 0x20 -static unsigned long __init_pgt[MAX_LOW_PAGES][512] ALIGN_TO_4K; -static int __init_pgt_index; - -/* - * We start using from start_pfn - */ static __init void *alloc_static_page(unsigned long *phys) { - int i = __init_pgt_index++; - - if (__init_pgt_index >= MAX_LOW_PAGES) { - printk("Need to increase MAX_LOW_PAGES"); - BUG(); - } - - *phys = __pa(__init_pgt[i]); - - return (void *) __init_pgt[i]; + unsigned long va = (start_pfn << PAGE_SHIFT) + __START_KERNEL_map; + *phys = start_pfn << PAGE_SHIFT; + start_pfn++; + memset((void *)va, 0, PAGE_SIZE); + return (void *)va; } -/* - * Get RO page - */ -static void __init *alloc_low_page(unsigned long *phys) -{ - unsigned long pfn = table_end++; - - *phys = (pfn << PAGE_SHIFT); - memset((void *) ((pfn << PAGE_SHIFT) + __START_KERNEL_map), 0, PAGE_SIZE); - return (void *)((pfn << PAGE_SHIFT) + __START_KERNEL_map); -} - #define PTE_SIZE PAGE_SIZE static inline void __set_pte(pte_t *dst, pte_t val) @@ -443,30 +420,24 @@ static inline int make_readonly(unsigned long paddr) { - int readonly = 0; - - /* Make new page tables read-only. */ - if ((paddr < ((table_start << PAGE_SHIFT) + tables_space)) && - (paddr >= (table_start << PAGE_SHIFT))) - readonly = 1; - - /* Make old page tables read-only. */ - if ((paddr < ((xen_start_info.pt_base - __START_KERNEL_map) + - (xen_start_info.nr_pt_frames << PAGE_SHIFT))) && - (paddr >= (xen_start_info.pt_base - __START_KERNEL_map))) - readonly = 1; - - /* - * No need for writable mapping of kernel image. This also ensures that - * page and descriptor tables embedded inside don't have writable mappings. - */ - if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end))) - readonly = 1; - - return readonly; -} - -void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) + int readonly = 0; + + /* Make old and new page tables read-only. */ + if ((paddr >= (xen_start_info.pt_base - __START_KERNEL_map)) + && (paddr < ((table_start << PAGE_SHIFT) + tables_space))) + readonly = 1; + /* + * No need for writable mapping of kernel image. This also ensures that + * page and descriptor tables embedded inside don't have writable + * mappings. + */ + if ((paddr >= __pa_symbol(&_text)) && (paddr < __pa_symbol(&_end))) + readonly = 1; + + return readonly; +} + +static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) { long i, j, k; unsigned long paddr; @@ -485,7 +456,7 @@ break; } - pmd = alloc_low_page(&pmd_phys); + pmd = alloc_static_page(&pmd_phys); make_page_readonly(pmd); xen_pmd_pin(pmd_phys); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); @@ -499,18 +470,19 @@ set_pmd(pmd, __pmd(0)); break; } - pte = alloc_low_page(&pte_phys); + pte = alloc_static_page(&pte_phys); pte_save = pte; for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) { + if ((paddr >= end) || + ((paddr >> PAGE_SHIFT) + >= xen_start_info.nr_pages)) { + __set_pte(pte, __pte(0)); + continue; + } if (make_readonly(paddr)) { __set_pte(pte, __pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW))); continue; - } - if (paddr >= end) { - for (; k < PTRS_PER_PTE; k++, pte++) - __set_pte(pte, __pte(0)); - break; } __set_pte(pte, __pte(paddr | _KERNPG_TABLE)); } @@ -525,15 +497,16 @@ static void __init find_early_table_space(unsigned long end) { - unsigned long puds, pmds, ptes; + unsigned long puds, pmds, ptes; puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; - ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT; - - tables_space = round_up(puds * 8, PAGE_SIZE) + - round_up(pmds * 8, PAGE_SIZE) + - round_up(ptes * 8, PAGE_SIZE); + ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT; + + tables_space = + round_up(puds * 8, PAGE_SIZE) + + round_up(pmds * 8, PAGE_SIZE) + + round_up(ptes * 8, PAGE_SIZE); } void __init xen_init_pt(void) @@ -579,65 +552,58 @@ mk_kernel_pgd(__pa_symbol(level3_user_pgt))); } -/* - * Extend kernel mapping to access pages for page tables. The initial - * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the - * mapping for early initialization. - */ -static unsigned long current_size, extended_size; - void __init extend_init_mapping(void) { unsigned long va = __START_KERNEL_map; unsigned long phys, addr, *pte_page; - pmd_t *pmd; + pmd_t *pmd; pte_t *pte, new_pte; - unsigned long *page = (unsigned long *) init_level4_pgt; - int i; + unsigned long *page = (unsigned long *)init_level4_pgt; addr = page[pgd_index(va)]; addr_to_page(addr, page); addr = page[pud_index(va)]; addr_to_page(addr, page); - for (;;) { + /* Kill mapping of low 1MB. */ + while (va < (unsigned long)&_text) { + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); + va += PAGE_SIZE; + } + + /* Ensure init mappings cover kernel text/data and initial tables. */ + while (va < (__START_KERNEL_map + + (start_pfn << PAGE_SHIFT) + + tables_space)) { 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; + if (pmd_none(*pmd)) { + pte_page = alloc_static_page(&phys); + make_page_readonly(pte_page); + xen_pte_pin(phys); + set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER)); + } else { + addr = page[pmd_index(va)]; + addr_to_page(addr, pte_page); } - } - - while (va < __START_KERNEL_map + current_size + tables_space) { - pmd = (pmd_t *) &page[pmd_index(va)]; - 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) { + pte = (pte_t *)&pte_page[pte_index(va)]; + if (pte_none(*pte)) { 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) + va += PAGE_SIZE; + } + + /* Finally, blow away any spurious initial mappings. */ + while (1) { + pmd = (pmd_t *)&page[pmd_index(va)]; + if (pmd_none(*pmd)) + break; HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); -} - + va += PAGE_SIZE; + } +} /* Setup the direct mapping of the physical memory at PAGE_OFFSET. This runs before bootmem is initialized and gets pages directly from the @@ -650,34 +616,31 @@ find_early_table_space(end); extend_init_mapping(); - start_pfn = current_size >> PAGE_SHIFT; table_start = start_pfn; - table_end = table_start; start = (unsigned long)__va(start); end = (unsigned long)__va(end); for (; start < end; start = next) { unsigned long pud_phys; - pud_t *pud = alloc_low_page(&pud_phys); - make_page_readonly(pud); - xen_pud_pin(pud_phys); + pud_t *pud = alloc_static_page(&pud_phys); + make_page_readonly(pud); + xen_pud_pin(pud_phys); next = start + PGDIR_SIZE; if (next > end) next = end; phys_pud_init(pud, __pa(start), __pa(next)); set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); - } - - printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, - table_start<<PAGE_SHIFT, - table_end<<PAGE_SHIFT); - - start_pfn = ((current_size + extended_size) >> PAGE_SHIFT); + } + + printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", + __pa(end), table_start<<PAGE_SHIFT, start_pfn<<PAGE_SHIFT); + + BUG_ON(start_pfn != (table_start + (tables_space >> PAGE_SHIFT))); __flush_tlb_all(); - init_mapping_done = 1; + init_mapping_done = 1; } extern struct x8664_pda cpu_pda[NR_CPUS]; @@ -1002,3 +965,13 @@ { return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); } + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c Tue Aug 30 20:36:49 2005 @@ -44,6 +44,7 @@ #include <asm-xen/xen_proc.h> #include <asm-xen/hypervisor.h> #include <asm-xen/balloon.h> +#include <asm-xen/xen-public/memory.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -168,6 +169,11 @@ struct page *page; long credit, debt, rc; void *v; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; down(&balloon_mutex); @@ -180,14 +186,18 @@ goto out; balloon_lock(flags); - rc = HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, mfn_list, credit, 0); + reservation.extent_start = mfn_list; + reservation.nr_extents = credit; + rc = HYPERVISOR_memory_op( + XENMEM_increase_reservation, &reservation); balloon_unlock(flags); if (rc < credit) { /* We hit the Xen hard limit: reprobe. */ - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, - mfn_list, rc, 0) != rc); + reservation.extent_start = mfn_list; + reservation.nr_extents = rc; + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, + &reservation) != rc); hard_limit = current_pages + rc - driver_pages; vfree(mfn_list); goto retry; @@ -261,8 +271,10 @@ balloon_append(pfn_to_page(pfn)); } - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation,mfn_list, debt, 0) != debt); + reservation.extent_start = mfn_list; + reservation.nr_extents = debt; + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, &reservation) != debt); current_pages -= debt; } @@ -438,11 +450,17 @@ pte_t *pte, struct page *pte_page, unsigned long addr, void *data) { unsigned long mfn = pte_mfn(*pte); + struct xen_memory_reservation reservation = { + .extent_start = &mfn, + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; set_pte(pte, __pte_ma(0)); phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = INVALID_P2M_ENTRY; - BUG_ON(HYPERVISOR_dom_mem_op( - MEMOP_decrease_reservation, &mfn, 1, 0) != 1); + BUG_ON(HYPERVISOR_memory_op( + XENMEM_decrease_reservation, &reservation) != 1); return 0; } diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Aug 30 20:36:49 2005 @@ -368,7 +368,7 @@ free_page((unsigned long)info->ring.sring); info->ring.sring = NULL; } - unbind_evtchn_from_irqhandler(info->evtchn, NULL); + unbind_evtchn_from_irqhandler(info->evtchn, info); info->evtchn = 0; } diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/console/Makefile --- a/linux-2.6-xen-sparse/drivers/xen/console/Makefile Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/Makefile Tue Aug 30 20:36:49 2005 @@ -1,2 +1,2 @@ -obj-y := console.o +obj-y := console.o xencons_ring.o diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/console/console.c --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Aug 30 20:36:49 2005 @@ -51,8 +51,8 @@ #include <asm-xen/xen-public/event_channel.h> #include <asm-xen/hypervisor.h> #include <asm-xen/evtchn.h> -#include <asm-xen/ctrl_if.h> - + +#include "xencons_ring.h" /* * Modes: * 'xencons=off' [XC_OFF]: Console is disabled. @@ -118,13 +118,6 @@ /* Common transmit-kick routine. */ static void __xencons_tx_flush(void); -/* This task is used to defer sending console data until there is space. */ -static void xencons_tx_flush_task_routine(void *data); - -static DECLARE_TQUEUE(xencons_tx_flush_task, - xencons_tx_flush_task_routine, - NULL); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) static struct tty_driver *xencons_driver; #else @@ -264,39 +257,22 @@ /*** Forcibly flush console data before dying. ***/ void xencons_force_flush(void) { - ctrl_msg_t msg; int sz; /* Emergency console is synchronous, so there's nothing to flush. */ if ( xen_start_info.flags & SIF_INITDOMAIN ) return; - /* - * We use dangerous control-interface functions that require a quiescent - * system and no interrupts. Try to ensure this with a global cli(). - */ - local_irq_disable(); /* XXXsmp */ /* Spin until console data is flushed through to the domain controller. */ - while ( (wc != wp) && !ctrl_if_transmitter_empty() ) - { - /* Interrupts are disabled -- we must manually reap responses. */ - ctrl_if_discard_responses(); - + while ( (wc != wp) ) + { + int sent = 0; if ( (sz = wp - wc) == 0 ) continue; - if ( sz > sizeof(msg.msg) ) - sz = sizeof(msg.msg); - if ( sz > (wbuf_size - WBUF_MASK(wc)) ) - sz = wbuf_size - WBUF_MASK(wc); - - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = sz; - memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - wc += sz; + sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); + if (sent > 0) + wc += sent; } } @@ -320,7 +296,7 @@ static char x_char; /* Non-privileged receive callback. */ -static void xencons_rx(ctrl_msg_t *msg, unsigned long id) +static void xencons_rx(char *buf, unsigned len) { int i; unsigned long flags; @@ -328,21 +304,18 @@ spin_lock_irqsave(&xencons_lock, flags); if ( xencons_tty != NULL ) { - for ( i = 0; i < msg->length; i++ ) - tty_insert_flip_char(xencons_tty, msg->msg[i], 0); + for ( i = 0; i < len; i++ ) + tty_insert_flip_char(xencons_tty, buf[i], 0); tty_flip_buffer_push(xencons_tty); } spin_unlock_irqrestore(&xencons_lock, flags); - msg->length = 0; - ctrl_if_send_response(msg); } /* Privileged and non-privileged transmit worker. */ static void __xencons_tx_flush(void) { int sz, work_done = 0; - ctrl_msg_t msg; if ( xen_start_info.flags & SIF_INITDOMAIN ) { @@ -367,38 +340,23 @@ { while ( x_char ) { - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = 1; - msg.msg[0] = x_char; - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - x_char = 0; - else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) ) - break; - - work_done = 1; + if (xencons_ring_send(&x_char, 1) == 1) { + x_char = 0; + work_done = 1; + } } while ( wc != wp ) { + int sent; sz = wp - wc; - if ( sz > sizeof(msg.msg) ) - sz = sizeof(msg.msg); - if ( sz > (wbuf_size - WBUF_MASK(wc)) ) - sz = wbuf_size - WBUF_MASK(wc); - - msg.type = CMSG_CONSOLE; - msg.subtype = CMSG_CONSOLE_DATA; - msg.length = sz; - memcpy(msg.msg, &wbuf[WBUF_MASK(wc)], sz); - - if ( ctrl_if_send_message_noblock(&msg, NULL, 0) == 0 ) - wc += sz; - else if ( ctrl_if_enqueue_space_callback(&xencons_tx_flush_task) ) - break; - - work_done = 1; + if ( sz > (wbuf_size - WBUF_MASK(wc)) ) + sz = wbuf_size - WBUF_MASK(wc); + sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); + if ( sent > 0 ) { + wc += sent; + work_done = 1; + } } } @@ -409,15 +367,6 @@ (xencons_tty->ldisc.write_wakeup != NULL) ) (xencons_tty->ldisc.write_wakeup)(xencons_tty); } -} - -/* Non-privileged transmit kicker. */ -static void xencons_tx_flush_task_routine(void *data) -{ - unsigned long flags; - spin_lock_irqsave(&xencons_lock, flags); - __xencons_tx_flush(); - spin_unlock_irqrestore(&xencons_lock, flags); } /* Privileged receive callback and transmit kicker. */ @@ -726,6 +675,8 @@ if ( xc_mode == XC_OFF ) return 0; + xencons_ring_init(); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ? 1 : MAX_NR_CONSOLES); @@ -802,7 +753,8 @@ } else { - (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0); + + xencons_ring_register_receiver(xencons_rx); } printk("Xen virtual console successfully installed as %s%d\n", diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Aug 30 20:36:49 2005 @@ -12,6 +12,7 @@ #include "common.h" #include <asm-xen/balloon.h> +#include <asm-xen/xen-public/memory.h> #if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX) #include <asm-xen/xen-public/grant_table.h> @@ -110,10 +111,16 @@ static unsigned long alloc_mfn(void) { unsigned long mfn = 0, flags; + struct xen_memory_reservation reservation = { + .extent_start = mfn_list, + .nr_extents = MAX_MFN_ALLOC, + .extent_order = 0, + .domid = DOMID_SELF + }; spin_lock_irqsave(&mfn_lock, flags); if ( unlikely(alloc_index == 0) ) - alloc_index = HYPERVISOR_dom_mem_op( - MEMOP_increase_reservation, mfn_list, MAX_MFN_ALLOC, 0); + alloc_index = HYPERVISOR_memory_op( + XENMEM_increase_reservation, &reservation); if ( alloc_index != 0 ) mfn = mfn_list[--alloc_index]; spin_unlock_irqrestore(&mfn_lock, flags); @@ -124,11 +131,17 @@ static void free_mfn(unsigned long mfn) { unsigned long flags; + struct xen_memory_reservation reservation = { + .extent_start = &mfn, + .nr_extents = 1, + .extent_order = 0, + .domid = DOMID_SELF + }; spin_lock_irqsave(&mfn_lock, flags); if ( alloc_index != MAX_MFN_ALLOC ) mfn_list[alloc_index++] = mfn; - else if ( HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation, - &mfn, 1, 0) != 1 ) + else if ( HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) + != 1 ) BUG(); spin_unlock_irqrestore(&mfn_lock, flags); } diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Aug 30 20:36:49 2005 @@ -50,6 +50,7 @@ #include <asm-xen/evtchn.h> #include <asm-xen/xenbus.h> #include <asm-xen/xen-public/io/netif.h> +#include <asm-xen/xen-public/memory.h> #include <asm-xen/balloon.h> #include <asm/page.h> #include <asm/uaccess.h> @@ -328,6 +329,7 @@ struct sk_buff *skb; int i, batch_target; NETIF_RING_IDX req_prod = np->rx->req_prod; + struct xen_memory_reservation reservation; #ifdef CONFIG_XEN_NETDEV_GRANT_RX int ref; #endif @@ -388,12 +390,15 @@ rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; /* Give away a batch of pages. */ - rx_mcl[i].op = __HYPERVISOR_dom_mem_op; - rx_mcl[i].args[0] = MEMOP_decrease_reservation; - rx_mcl[i].args[1] = (unsigned long)rx_pfn_array; - rx_mcl[i].args[2] = (unsigned long)i; - rx_mcl[i].args[3] = 0; - rx_mcl[i].args[4] = DOMID_SELF; + rx_mcl[i].op = __HYPERVISOR_memory_op; + rx_mcl[i].args[0] = XENMEM_decrease_reservation; + rx_mcl[i].args[1] = (unsigned long)&reservation; + + reservation.extent_start = rx_pfn_array; + reservation.nr_extents = i; + reservation.extent_order = 0; + reservation.address_bits = 0; + reservation.domid = DOMID_SELF; /* Tell the ballon driver what is going on. */ balloon_update_driver_allowance(i); @@ -401,7 +406,7 @@ /* Zap PTEs and give away pages in one big multicall. */ (void)HYPERVISOR_multicall(rx_mcl, i+1); - /* Check return status of HYPERVISOR_dom_mem_op(). */ + /* Check return status of HYPERVISOR_memory_op(). */ if (unlikely(rx_mcl[i].result != i)) panic("Unable to reduce memory reservation\n"); diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Aug 30 20:36:49 2005 @@ -66,7 +66,7 @@ { long ign1, ign2, ign3; __asm__ __volatile__ ( - "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR + "movq %8,%%r10; movq %9,%%r8;" TRAP_INSTR : "=a" (ret), "=D" (ign1), "=S" (ign2), "=d" (ign3) : "0" ((unsigned long)hypercall.op), "1" ((unsigned long)hypercall.arg[0]), diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Tue Aug 30 20:36:49 2005 @@ -209,6 +209,7 @@ { return xenbus_register_driver(drv, &xenbus_frontend); } +EXPORT_SYMBOL(xenbus_register_device); int xenbus_register_backend(struct xenbus_driver *drv) { diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c Tue Aug 30 20:36:49 2005 @@ -45,7 +45,9 @@ static char printf_buffer[4096]; static LIST_HEAD(watches); + DECLARE_MUTEX(xenbus_lock); +EXPORT_SYMBOL(xenbus_lock); static int get_error(const char *errorstring) { @@ -224,6 +226,7 @@ ret[(*num)++] = p; return ret; } +EXPORT_SYMBOL(xenbus_directory); /* Check if a path exists. Return 1 if it does. */ int xenbus_exists(const char *dir, const char *node) @@ -237,6 +240,7 @@ kfree(d); return 1; } +EXPORT_SYMBOL(xenbus_exists); /* Get the value of a single file. * Returns a kmalloced value: call free() on it after use. @@ -246,6 +250,7 @@ { return xs_single(XS_READ, join(dir, node), len); } +EXPORT_SYMBOL(xenbus_read); /* Write the value of a single file. * Returns -err on failure. createflags can be 0, O_CREAT, or O_CREAT|O_EXCL. @@ -276,18 +281,21 @@ return xs_error(xs_talkv(XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL)); } +EXPORT_SYMBOL(xenbus_write); /* Create a new directory. */ int xenbus_mkdir(const char *dir, const char *node) { return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL)); } +EXPORT_SYMBOL(xenbus_mkdir); /* Destroy a file or directory (directories must be empty). */ int xenbus_rm(const char *dir, const char *node) { return xs_error(xs_single(XS_RM, join(dir, node), NULL)); } +EXPORT_SYMBOL(xenbus_rm); /* Start a transaction: changes by others will not be seen during this * transaction, and changes will not be visible to others until end. @@ -298,6 +306,7 @@ { return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL)); } +EXPORT_SYMBOL(xenbus_transaction_start); /* End a transaction. * If abandon is true, transaction is discarded instead of committed. @@ -312,6 +321,7 @@ strcpy(abortstr, "T"); return xs_error(xs_single(XS_TRANSACTION_END, abortstr, NULL)); } +EXPORT_SYMBOL(xenbus_transaction_end); /* Single read and scanf: returns -errno or num scanned. */ int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...) @@ -333,6 +343,7 @@ return -ERANGE; return ret; } +EXPORT_SYMBOL(xenbus_scanf); /* Single printf and write: returns -errno or 0. */ int xenbus_printf(const char *dir, const char *node, const char *fmt, ...) @@ -348,6 +359,7 @@ BUG_ON(ret > sizeof(printf_buffer)-1); return xenbus_write(dir, node, printf_buffer, O_CREAT); } +EXPORT_SYMBOL(xenbus_printf); /* Report a (negative) errno into the store, with explanation. */ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) @@ -369,6 +381,7 @@ printk("xenbus: failed to write error node for %s (%s)\n", dev->nodename, printf_buffer); } +EXPORT_SYMBOL(xenbus_dev_error); /* Clear any error. */ void xenbus_dev_ok(struct xenbus_device *dev) @@ -381,6 +394,7 @@ dev->has_error = 0; } } +EXPORT_SYMBOL(xenbus_dev_ok); /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ int xenbus_gather(const char *dir, ...) @@ -410,6 +424,7 @@ va_end(ap); return ret; } +EXPORT_SYMBOL(xenbus_gather); static int xs_watch(const char *path, const char *token) { @@ -482,6 +497,7 @@ list_add(&watch->list, &watches); return err; } +EXPORT_SYMBOL(register_xenbus_watch); void unregister_xenbus_watch(struct xenbus_watch *watch) { @@ -499,6 +515,7 @@ "XENBUS Failed to release watch %s: %i\n", watch->node, err); } +EXPORT_SYMBOL(unregister_xenbus_watch); /* Re-register callbacks to all watches. */ void reregister_xenbus_watches(void) diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Aug 30 20:36:49 2005 @@ -236,12 +236,10 @@ } static inline int -HYPERVISOR_dom_mem_op( - unsigned int op, unsigned long *extent_list, - unsigned long nr_extents, unsigned int extent_order) -{ - return _hypercall5(int, dom_mem_op, op, extent_list, - nr_extents, extent_order, DOMID_SELF); +HYPERVISOR_memory_op( + unsigned int cmd, void *arg) +{ + return _hypercall2(int, memory_op, cmd, arg); } static inline int diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Aug 30 20:36:49 2005 @@ -231,12 +231,10 @@ } static inline int -HYPERVISOR_dom_mem_op( - unsigned int op, unsigned long *extent_list, - unsigned long nr_extents, unsigned int extent_order) -{ - return _hypercall5(int, dom_mem_op, op, extent_list, - nr_extents, extent_order, DOMID_SELF); +HYPERVISOR_memory_op( + unsigned int cmd, void *arg) +{ + return _hypercall2(int, memory_op, cmd, arg); } static inline int diff -r ae390c2b9d4c -r 287d36b46fa3 tools/Makefile --- a/tools/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/Makefile Tue Aug 30 20:36:49 2005 @@ -7,14 +7,18 @@ SUBDIRS += misc SUBDIRS += examples SUBDIRS += xentrace -SUBDIRS += python SUBDIRS += xcs SUBDIRS += xcutils -#SUBDIRS += pygrub SUBDIRS += firmware SUBDIRS += security SUBDIRS += console SUBDIRS += xenstat + +# These don't cross-compile +ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) +SUBDIRS += python +#SUBDIRS += pygrub +endif .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean diff -r ae390c2b9d4c -r 287d36b46fa3 tools/console/Makefile --- a/tools/console/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/console/Makefile Tue Aug 30 20:36:49 2005 @@ -9,8 +9,7 @@ INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DIR = $(INSTALL) -d -m0755 -CC = gcc -CFLAGS = -Wall -Werror -g3 +CFLAGS += -Wall -Werror -g3 CFLAGS += -I $(XEN_XCS) CFLAGS += -I $(XEN_LIBXC) diff -r ae390c2b9d4c -r 287d36b46fa3 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Aug 29 23:05:29 2005 +++ b/tools/console/daemon/io.c Tue Aug 30 20:36:49 2005 @@ -36,6 +36,9 @@ #include <fcntl.h> #include <unistd.h> #include <termios.h> +#include <stdarg.h> +#include <sys/ioctl.h> +#include <sys/mman.h> #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -48,41 +51,6 @@ size_t max_capacity; }; -static void buffer_append(struct buffer *buffer, const void *data, size_t size) -{ - if ((buffer->capacity - buffer->size) < size) { - buffer->capacity += (size + 1024); - buffer->data = realloc(buffer->data, buffer->capacity); - if (buffer->data == NULL) { - dolog(LOG_ERR, "Memory allocation failed"); - exit(ENOMEM); - } - } - - memcpy(buffer->data + buffer->size, data, size); - buffer->size += size; - - if (buffer->max_capacity && - buffer->size > buffer->max_capacity) { - memmove(buffer->data + (buffer->size - buffer->max_capacity), - buffer->data, buffer->max_capacity); - buffer->data = realloc(buffer->data, buffer->max_capacity); - buffer->capacity = buffer->max_capacity; - } -} - -static bool buffer_empty(struct buffer *buffer) -{ - return buffer->size == 0; -} - -static void buffer_advance(struct buffer *buffer, size_t size) -{ - size = MIN(size, buffer->size); - memmove(buffer->data, buffer + size, buffer->size - size); - buffer->size -= size; -} - struct domain { int domid; @@ -90,9 +58,74 @@ bool is_dead; struct buffer buffer; struct domain *next; + unsigned long mfn; + int local_port; + int remote_port; + char *page; + int evtchn_fd; }; static struct domain *dom_head; + +struct ring_head +{ + u32 cons; + u32 prod; + char buf[0]; +} __attribute__((packed)); + +#define PAGE_SIZE (getpagesize()) +#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) +#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) +#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) +#define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons)) + +static void buffer_append(struct domain *dom) +{ + struct buffer *buffer = &dom->buffer; + struct ring_head *ring = (struct ring_head *)dom->page; + size_t size; + + while ((size = ring->prod - ring->cons) != 0) { + if ((buffer->capacity - buffer->size) < size) { + buffer->capacity += (size + 1024); + buffer->data = realloc(buffer->data, buffer->capacity); + if (buffer->data == NULL) { + dolog(LOG_ERR, "Memory allocation failed"); + exit(ENOMEM); + } + } + + while (ring->cons < ring->prod) { + buffer->data[buffer->size] = + ring->buf[XENCONS_IDX(ring->cons)]; + buffer->size++; + ring->cons++; + } + + if (buffer->max_capacity && + buffer->size > buffer->max_capacity) { + memmove(buffer->data + (buffer->size - + buffer->max_capacity), + buffer->data, buffer->max_capacity); + buffer->data = realloc(buffer->data, + buffer->max_capacity); + buffer->capacity = buffer->max_capacity; + } + } +} + +static bool buffer_empty(struct buffer *buffer) +{ + return buffer->size == 0; +} + +static void buffer_advance(struct buffer *buffer, size_t size) +{ + size = MIN(size, buffer->size); + memmove(buffer->data, buffer + size, buffer->size - size); + buffer->size -= size; +} static bool domain_is_valid(int domid) { @@ -107,7 +140,7 @@ static int domain_create_tty(struct domain *dom) { - char path[1024]; + char *path; int master; if ((master = getpt()) == -1 || @@ -126,22 +159,106 @@ tcsetattr(master, TCSAFLUSH, &term); } - xs_mkdir(xs, "/console"); - snprintf(path, sizeof(path), "/console/%d", dom->domid); - xs_mkdir(xs, path); - strcat(path, "/tty"); - + asprintf(&path, "/console/%d/tty", dom->domid); xs_write(xs, path, slave, strlen(slave), O_CREAT); - - snprintf(path, sizeof(path), "/console/%d/limit", dom->domid); + free(path); + + asprintf(&path, "/console/%d/limit", dom->domid); data = xs_read(xs, path, &len); if (data) { dom->buffer.max_capacity = strtoul(data, 0, 0); free(data); } + free(path); } return master; +} + +/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ +int xs_gather(struct xs_handle *xs, const char *dir, ...) +{ + va_list ap; + const char *name; + char *path; + int ret = 0; + + va_start(ap, dir); + while (ret == 0 && (name = va_arg(ap, char *)) != NULL) { + const char *fmt = va_arg(ap, char *); + void *result = va_arg(ap, void *); + char *p; + + asprintf(&path, "%s/%s", dir, name); + p = xs_read(xs, path, NULL); + free(path); + if (p == NULL) { + ret = ENOENT; + break; + } + if (fmt) { + if (sscanf(p, fmt, result) == 0) + ret = EINVAL; + free(p); + } else + *(char **)result = p; + } + va_end(ap); + return ret; +} + +#define EVENTCHN_BIND _IO('E', 2) +#define EVENTCHN_UNBIND _IO('E', 3) + +static int domain_create_ring(struct domain *dom) +{ + char *dompath, *path; + int err; + + dom->page = NULL; + dom->evtchn_fd = -1; + + asprintf(&path, "/console/%d/domain", dom->domid); + dompath = xs_read(xs, path, NULL); + free(path); + if (!dompath) + return ENOENT; + + err = xs_gather(xs, dompath, + "console_mfn", "%li", &dom->mfn, + "console_channel/port1", "%i", &dom->local_port, + "console_channel/port2", "%i", &dom->remote_port, + NULL); + if (err) + goto out; + + dom->page = xc_map_foreign_range(xc, dom->domid, getpagesize(), + PROT_READ|PROT_WRITE, dom->mfn); + if (dom->page == NULL) { + err = EINVAL; + goto out; + } + + /* Opening evtchn independently for each console is a bit + * wastefule, but that's how the code is structured... */ + err = open("/dev/xen/evtchn", O_RDWR); + if (err == -1) { + err = errno; + goto out; + } + dom->evtchn_fd = err; + + if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, dom->local_port) == -1) { + err = errno; + munmap(dom->page, getpagesize()); + close(dom->evtchn_fd); + dom->evtchn_fd = -1; + goto out; + } + + out: + free(dompath); + return err; } static struct domain *create_domain(int domid) @@ -162,7 +279,9 @@ dom->buffer.size = 0; dom->buffer.capacity = 0; dom->buffer.max_capacity = 0; - dom->next = 0; + dom->next = NULL; + + domain_create_ring(dom); dolog(LOG_DEBUG, "New domain %d", domid); @@ -200,9 +319,14 @@ if (dom->domid == d->domid) { *pp = d->next; - if (d->buffer.data) { + if (d->buffer.data) free(d->buffer.data); - } + if (d->page) + munmap(d->page, getpagesize()); + if (d->evtchn_fd != -1) + close(d->evtchn_fd); + if (d->tty_fd != -1) + close(d->tty_fd); free(d); break; } @@ -211,28 +335,28 @@ static void remove_dead_domains(struct domain *dom) { - if (dom == NULL) return; - remove_dead_domains(dom->next); - - if (dom->is_dead) { - remove_domain(dom); + struct domain *n; + + while (dom != NULL) { + n = dom->next; + if (dom->is_dead) + remove_domain(dom); + dom = n; } } static void handle_tty_read(struct domain *dom) { ssize_t len; - xcs_msg_t msg; - - msg.type = XCS_REQUEST; - msg.u.control.remote_dom = dom->domid; - msg.u.control.msg.type = CMSG_CONSOLE; - msg.u.control.msg.subtype = CMSG_CONSOLE_DATA; - msg.u.control.msg.id = 1; - - len = read(dom->tty_fd, msg.u.control.msg.msg, 60); + char msg[80]; + struct ring_head *inring = + (struct ring_head *)(dom->page + PAGE_SIZE/2); + int i; + + len = read(dom->tty_fd, msg, MAX(XENCONS_SPACE(inring), sizeof(msg))); if (len < 1) { close(dom->tty_fd); + dom->tty_fd = -1; if (domain_is_valid(dom->domid)) { dom->tty_fd = domain_create_tty(dom); @@ -240,14 +364,14 @@ dom->is_dead = true; } } else if (domain_is_valid(dom->domid)) { - msg.u.control.msg.length = len; - - if (!write_sync(xcs_data_fd, &msg, sizeof(msg))) { - dolog(LOG_ERR, "Write to xcs failed: %m"); - exit(1); - } + for (i = 0; i < len; i++) { + inring->buf[XENCONS_IDX(inring->prod)] = msg[i]; + inring->prod++; + } + xc_evtchn_send(xc, dom->local_port); } else { close(dom->tty_fd); + dom->tty_fd = -1; dom->is_dead = true; } } @@ -259,6 +383,7 @@ len = write(dom->tty_fd, dom->buffer.data, dom->buffer.size); if (len < 1) { close(dom->tty_fd); + dom->tty_fd = -1; if (domain_is_valid(dom->domid)) { dom->tty_fd = domain_create_tty(dom); @@ -270,6 +395,18 @@ } } +static void handle_ring_read(struct domain *dom) +{ + u16 v; + + if (!read_sync(dom->evtchn_fd, &v, sizeof(v))) + return; + + buffer_append(dom); + + (void)write_sync(dom->evtchn_fd, &v, sizeof(v)); +} + static void handle_xcs_msg(int fd) { xcs_msg_t msg; @@ -277,13 +414,6 @@ if (!read_sync(fd, &msg, sizeof(msg))) { dolog(LOG_ERR, "read from xcs failed! %m"); exit(1); - } else if (msg.type == XCS_REQUEST) { - struct domain *dom; - - dom = lookup_domain(msg.u.control.remote_dom); - buffer_append(&dom->buffer, - msg.u.control.msg.msg, - msg.u.control.msg.length); } } @@ -291,9 +421,12 @@ { int domid = 0; xc_dominfo_t dominfo; + struct domain *dom; while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) { - lookup_domain(dominfo.domid); + dom = lookup_domain(dominfo.domid); + if (dominfo.dying || dominfo.crashed || dominfo.shutdown) + dom->is_dead = true; domid = dominfo.domid + 1; } } @@ -302,12 +435,11 @@ { fd_set readfds, writefds; int ret; - int max_fd = -1; - int num_of_writes = 0; do { struct domain *d; struct timeval tv = { 1, 0 }; + int max_fd = -1; FD_ZERO(&readfds); FD_ZERO(&writefds); @@ -319,42 +451,36 @@ if (d->tty_fd != -1) { FD_SET(d->tty_fd, &readfds); } + if (d->evtchn_fd != -1) + FD_SET(d->evtchn_fd, &readfds); if (d->tty_fd != -1 && !buffer_empty(&d->buffer)) { FD_SET(d->tty_fd, &writefds); } max_fd = MAX(d->tty_fd, max_fd); + max_fd = MAX(d->evtchn_fd, max_fd); } ret = select(max_fd + 1, &readfds, &writefds, 0, &tv); - if (tv.tv_sec == 1 && (++num_of_writes % 100) == 0) { -#if 0 - /* FIXME */ - /* This is a nasty hack. xcs does not handle the - control channels filling up well at all. We'll - throttle ourselves here since we do proper - queueing to give the domains a shot at pulling out - the data. Fixing xcs is not worth it as it's - going away */ - tv.tv_usec = 1000; - select(0, 0, 0, 0, &tv); -#endif - } enum_domains(); - if (FD_ISSET(xcs_data_fd, &readfds)) { + if (FD_ISSET(xcs_data_fd, &readfds)) handle_xcs_msg(xcs_data_fd); - } for (d = dom_head; d; d = d->next) { - if (!d->is_dead && FD_ISSET(d->tty_fd, &readfds)) { + if (d->is_dead || d->tty_fd == -1 || + d->evtchn_fd == -1) + continue; + + if (FD_ISSET(d->tty_fd, &readfds)) handle_tty_read(d); - } - - if (!d->is_dead && FD_ISSET(d->tty_fd, &writefds)) { + + if (FD_ISSET(d->evtchn_fd, &readfds)) + handle_ring_read(d); + + if (FD_ISSET(d->tty_fd, &writefds)) handle_tty_write(d); - } } remove_dead_domains(dom_head); diff -r ae390c2b9d4c -r 287d36b46fa3 tools/console/daemon/utils.c --- a/tools/console/daemon/utils.c Mon Aug 29 23:05:29 2005 +++ b/tools/console/daemon/utils.c Tue Aug 30 20:36:49 2005 @@ -226,14 +226,10 @@ goto out_close_data; } - /* Since the vast majority of control messages are console messages - it's just easier to ignore other messages that try to bind to - a specific type. */ - msg.type = XCS_MSG_BIND; - msg.u.bind.port = PORT_WILDCARD; - msg.u.bind.type = TYPE_WILDCARD; + msg.type = XCS_VIRQ_BIND; + msg.u.virq.virq = VIRQ_DOM_EXC; if (!xcs_send_recv(xcs_ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) { - dolog(LOG_ERR, "xcs vind failed. Possible bug."); + dolog(LOG_ERR, "xcs virq bind failed. Possible bug."); goto out_close_data; } diff -r ae390c2b9d4c -r 287d36b46fa3 tools/examples/Makefile --- a/tools/examples/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/examples/Makefile Tue Aug 30 20:36:49 2005 @@ -1,3 +1,6 @@ +XEN_ROOT = ../../ +include $(XEN_ROOT)/tools/Rules.mk + INSTALL = install INSTALL_DIR = $(INSTALL) -d -m0755 INSTALL_PROG = $(INSTALL) -m0755 diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_core.c --- a/tools/libxc/xc_core.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_core.c Tue Aug 30 20:36:49 2005 @@ -2,6 +2,7 @@ #define ELFSIZE 32 #include "xc_elf.h" #include <stdlib.h> +#include <unistd.h> #include <zlib.h> /* number of pages to write at a time */ diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_domain.c Tue Aug 30 20:36:49 2005 @@ -7,6 +7,7 @@ */ #include "xc_private.h" +#include <xen/memory.h> int xc_domain_create(int xc_handle, u32 ssidref, @@ -265,9 +266,13 @@ { int err; unsigned int npages = mem_kb / (PAGE_SIZE/1024); - - err = xc_dom_mem_op(xc_handle, MEMOP_increase_reservation, NULL, - npages, 0, domid); + struct xen_memory_reservation reservation = { + .nr_extents = npages, + .extent_order = 0, + .domid = domid + }; + + err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation); if (err == npages) return 0; diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_linux_build.c Tue Aug 30 20:36:49 2005 @@ -17,6 +17,7 @@ #include "xc_elf.h" #include "xc_aout9.h" #include <stdlib.h> +#include <unistd.h> #include <zlib.h> #if defined(__i386__) @@ -335,7 +336,8 @@ unsigned int control_evtchn, unsigned long flags, unsigned int vcpus, - unsigned int store_evtchn, unsigned long *store_mfn) + unsigned int store_evtchn, unsigned long *store_mfn, + unsigned int console_evtchn, unsigned long *console_mfn) { unsigned long *page_array = NULL; unsigned long count, i; @@ -358,6 +360,8 @@ unsigned long vstartinfo_end; unsigned long vstoreinfo_start; unsigned long vstoreinfo_end; + unsigned long vconsole_start; + unsigned long vconsole_end; unsigned long vstack_start; unsigned long vstack_end; unsigned long vpt_start; @@ -393,7 +397,9 @@ vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); vstoreinfo_start = round_pgup(vphysmap_end); vstoreinfo_end = vstoreinfo_start + PAGE_SIZE; - vpt_start = vstoreinfo_end; + vconsole_start = vstoreinfo_end; + vconsole_end = vstoreinfo_end + PAGE_SIZE; + vpt_start = vconsole_end; for ( nr_pt_pages = 2; ; nr_pt_pages++ ) { @@ -437,6 +443,7 @@ " Init. ramdisk: %p->%p\n" " Phys-Mach map: %p->%p\n" " Store page: %p->%p\n" + " Console page: %p->%p\n" " Page tables: %p->%p\n" " Start info: %p->%p\n" " Boot stack: %p->%p\n" @@ -445,6 +452,7 @@ _p(vinitrd_start), _p(vinitrd_end), _p(vphysmap_start), _p(vphysmap_end), _p(vstoreinfo_start), _p(vstoreinfo_end), + _p(vconsole_start), _p(vconsole_end), _p(vpt_start), _p(vpt_end), _p(vstartinfo_start), _p(vstartinfo_end), _p(vstack_start), _p(vstack_end), @@ -566,6 +574,8 @@ #endif *store_mfn = page_array[(vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT]; + *console_mfn = page_array[(vconsole_start-dsi.v_start) >> PAGE_SHIFT]; + start_info = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, @@ -580,6 +590,8 @@ start_info->domain_controller_evtchn = control_evtchn; start_info->store_mfn = *store_mfn; start_info->store_evtchn = store_evtchn; + start_info->console_mfn = *console_mfn; + start_info->console_evtchn = console_evtchn; if ( initrd_len != 0 ) { start_info->mod_start = vinitrd_start; @@ -631,7 +643,9 @@ unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, - unsigned long *store_mfn) + unsigned long *store_mfn, + unsigned int console_evtchn, + unsigned long *console_mfn) { dom0_op_t launch_op, op; int initrd_fd = -1; @@ -707,7 +721,8 @@ &vstack_start, ctxt, cmdline, op.u.getdomaininfo.shared_info_frame, control_evtchn, flags, vcpus, - store_evtchn, store_mfn) < 0 ) + store_evtchn, store_mfn, + console_evtchn, console_mfn) < 0 ) { ERROR("Error constructing guest OS"); goto error_out; diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_linux_restore.c Tue Aug 30 20:36:49 2005 @@ -8,24 +8,23 @@ #include <stdlib.h> #include <unistd.h> - #include "xg_private.h" #include <xenctrl.h> - #include <xen/linux/suspend.h> +#include <xen/memory.h> #define MAX_BATCH_SIZE 1024 #define DEBUG 0 #if 1 -#define ERR(_f, _a...) fprintf ( stderr, _f , ## _a ); fflush(stderr) +#define ERR(_f, _a...) do { fprintf ( stderr, _f , ## _a ); fflush(stderr); } while(0) #else #define ERR(_f, _a...) ((void)0) #endif #if DEBUG -#define DPRINTF(_f, _a...) fprintf ( stdout, _f , ## _a ); fflush(stdout) +#define DPRINTF(_f, _a...) do { fprintf ( stdout, _f , ## _a ); fflush(stdout); } while (0) #else #define DPRINTF(_f, _a...) ((void)0) #endif @@ -103,7 +102,7 @@ struct mmuext_op pin[MAX_PIN_BATCH]; unsigned int nr_pins = 0; - DPRINTF("xc_linux_restore start\n"); + DPRINTF("xc_linux_restore start: nr_pfns = %lx\n", nr_pfns); if (mlock(&ctxt, sizeof(ctxt))) { /* needed for when we do the build dom0 op, @@ -152,6 +151,8 @@ err = xc_domain_memory_increase_reservation(xc_handle, dom, nr_pfns * PAGE_SIZE / 1024); if (err != 0) { + ERR("Failed to increate reservation by %lx\n", + nr_pfns * PAGE_SIZE / 1024); errno = ENOMEM; goto out; } @@ -409,7 +410,8 @@ /* Get the list of PFNs that are not in the psuedo-phys map */ { - unsigned int count, *pfntab; + unsigned int count; + unsigned long *pfntab; int rc; if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) ) @@ -441,9 +443,15 @@ if ( count > 0 ) { - if ( (rc = xc_dom_mem_op( xc_handle, - MEMOP_decrease_reservation, - pfntab, count, 0, dom )) <0 ) + struct xen_memory_reservation reservation = { + .extent_start = pfntab, + .nr_extents = count, + .extent_order = 0, + .domid = dom + }; + if ( (rc = xc_memory_op(xc_handle, + XENMEM_decrease_reservation, + &reservation)) != count ) { ERR("Could not decrease reservation : %d",rc); goto out; diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_private.c --- a/tools/libxc/xc_private.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_private.c Tue Aug 30 20:36:49 2005 @@ -6,6 +6,7 @@ #include <zlib.h> #include "xc_private.h" +#include <xen/memory.h> void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, unsigned long *arr, int num ) @@ -187,28 +188,43 @@ 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) +int xc_memory_op(int xc_handle, + int cmd, + void *arg) { privcmd_hypercall_t hypercall; + struct xen_memory_reservation *reservation = arg; 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; + hypercall.op = __HYPERVISOR_memory_op; + hypercall.arg[0] = (unsigned long)cmd; + hypercall.arg[1] = (unsigned long)arg; + + switch ( cmd ) + { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + if ( mlock(reservation, sizeof(*reservation)) != 0 ) + { + PERROR("Could not mlock"); + goto out1; + } + if ( (reservation->extent_start != NULL) && + (mlock(reservation->extent_start, + reservation->nr_extents * sizeof(unsigned long)) != 0) ) + { + PERROR("Could not mlock"); + safe_munlock(reservation, sizeof(*reservation)); + goto out1; + } + break; + case XENMEM_maximum_ram_page: + if ( mlock(arg, sizeof(unsigned long)) != 0 ) + { + PERROR("Could not mlock"); + goto out1; + } + break; } if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) @@ -217,8 +233,19 @@ " rebuild the user-space tool set?\n",ret,errno); } - if ( extent_list != NULL ) - safe_munlock(extent_list, nr_extents*sizeof(unsigned long)); + switch ( cmd ) + { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + safe_munlock(reservation, sizeof(*reservation)); + if ( reservation->extent_start != NULL ) + safe_munlock(reservation->extent_start, + reservation->nr_extents * sizeof(unsigned long)); + break; + case XENMEM_maximum_ram_page: + safe_munlock(arg, sizeof(unsigned long)); + break; + } out1: return ret; diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xc_vmx_build.c --- a/tools/libxc/xc_vmx_build.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xc_vmx_build.c Tue Aug 30 20:36:49 2005 @@ -7,6 +7,7 @@ #define ELFSIZE 32 #include "xc_elf.h" #include <stdlib.h> +#include <unistd.h> #include <zlib.h> #include <xen/io/ioreq.h> #include "linux_boot_params.h" diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xenctrl.h Tue Aug 30 20:36:49 2005 @@ -430,9 +430,7 @@ 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_memory_op(int xc_handle, int cmd, void *arg); int xc_get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr); diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xenguest.h Tue Aug 30 20:36:49 2005 @@ -47,7 +47,9 @@ unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, - unsigned long *store_mfn); + unsigned long *store_mfn, + unsigned int console_evtchn, + unsigned long *console_mfn); struct mem_map; int xc_vmx_build(int xc_handle, diff -r ae390c2b9d4c -r 287d36b46fa3 tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Mon Aug 29 23:05:29 2005 +++ b/tools/libxc/xg_private.c Tue Aug 30 20:36:49 2005 @@ -5,6 +5,7 @@ */ #include <stdlib.h> +#include <unistd.h> #include <zlib.h> #include "xg_private.h" diff -r ae390c2b9d4c -r 287d36b46fa3 tools/misc/cpuperf/cpuperf.c --- a/tools/misc/cpuperf/cpuperf.c Mon Aug 29 23:05:29 2005 +++ b/tools/misc/cpuperf/cpuperf.c Tue Aug 30 20:36:49 2005 @@ -243,16 +243,12 @@ } if (read) { - while((cpu_mask&1)) { - int i; - for (i=0x300;i<0x312;i++) { - printf("%010llu ",cpus_rdmsr( cpu_mask, i ) ); - } - printf("\n"); - cpu_mask>>=1; - } + int i; + for (i=0x300;i<0x312;i++) + printf("%010llu ",cpus_rdmsr( cpu_mask, i ) ); + printf("\n"); exit(1); - } + } if (!escr) { fprintf(stderr, "Need an ESCR.\n"); diff -r ae390c2b9d4c -r 287d36b46fa3 tools/misc/mbootpack/Makefile --- a/tools/misc/mbootpack/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/misc/mbootpack/Makefile Tue Aug 30 20:36:49 2005 @@ -20,8 +20,7 @@ INCS := -I. -I- DEFS := LDFLAGS := -CC := gcc -CFLAGS := -Wall -Wpointer-arith -Wcast-qual -Wno-unused -Wno-format +CFLAGS := -Wall -Wpointer-arith -Wcast-qual -Wno-unused -Wno-format CFLAGS += -Wmissing-prototypes #CFLAGS += -pipe -g -O0 -Wcast-align CFLAGS += -pipe -O3 @@ -34,7 +33,7 @@ DEPS = .*.d mbootpack: $(OBJS) - $(CC) -o $@ $(filter-out %.a, $^) $(LDFLAGS) + $(HOSTCC) -o $@ $(filter-out %.a, $^) $(LDFLAGS) clean: $(RM) mbootpack *.o $(DEPS) bootsect setup bzimage_header.c bin2c @@ -48,7 +47,7 @@ $(LD) -m elf_i386 -Ttext 0x0 -s --oformat binary setup.o -o $@ bin2c: bin2c.o - $(CC) -o $@ $^ + $(HOSTCC) -o $@ $^ bzimage_header.c: bootsect setup bin2c ./bin2c -n 8 -b1 -a bzimage_bootsect bootsect > bzimage_header.c @@ -58,10 +57,10 @@ @ %.o: %.S - $(CC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ + $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ %.o: %.c - $(CC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ + $(HOSTCC) $(DEPFLAGS) $(CFLAGS) $(INCS) $(DEFS) -c $< -o $@ .PHONY: all clean gdb .PRECIOUS: $(OBJS) $(OBJS:.o=.c) $(DEPS) diff -r ae390c2b9d4c -r 287d36b46fa3 tools/misc/mbootpack/buildimage.c --- a/tools/misc/mbootpack/buildimage.c Mon Aug 29 23:05:29 2005 +++ b/tools/misc/mbootpack/buildimage.c Tue Aug 30 20:36:49 2005 @@ -42,6 +42,7 @@ #include "mbootpack.h" #include "mb_header.h" + /* We will build an image that a bzImage-capable bootloader will load like * this: @@ -105,8 +106,8 @@ section_t *s; /* Patch the kernel and mbi addresses into the setup code */ - *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = entry; - *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = mbi; + *(address_t *)(bzimage_setup + BZ_ENTRY_OFFSET) = eswap(entry); + *(address_t *)(bzimage_setup + BZ_MBI_OFFSET) = eswap(mbi); if (!quiet) printf("Kernel entry is %p, MBI is %p.\n", entry, mbi); /* Write out header and trampoline */ diff -r ae390c2b9d4c -r 287d36b46fa3 tools/misc/mbootpack/mbootpack.c --- a/tools/misc/mbootpack/mbootpack.c Mon Aug 29 23:05:29 2005 +++ b/tools/misc/mbootpack/mbootpack.c Tue Aug 30 20:36:49 2005 @@ -252,20 +252,21 @@ for (i = 0; i <= MIN(len - 12, MULTIBOOT_SEARCH - 12); i += 4) { mbh = (struct multiboot_header *)(headerbuf + i); - if (mbh->magic != MULTIBOOT_MAGIC - || ((mbh->magic+mbh->flags+mbh->checksum) & 0xffffffff)) + if (eswap(mbh->magic) != MULTIBOOT_MAGIC + || ((eswap(mbh->magic)+eswap(mbh->flags)+eswap(mbh->checksum)) + & 0xffffffff)) { /* Not a multiboot header */ continue; } - if (mbh->flags & MULTIBOOT_UNSUPPORTED) { + if (eswap(mbh->flags) & MULTIBOOT_UNSUPPORTED) { /* Requires options we don't support */ printf("Fatal: found a multiboot header, but it " "requires multiboot options that I\n" "don't understand. Sorry.\n"); exit(1); } - if (mbh->flags & MULTIBOOT_VIDEO_MODE) { + if (eswap(mbh->flags) & MULTIBOOT_VIDEO_MODE) { /* Asked for screen mode information */ /* XXX carry on regardless */ printf("Warning: found a multiboot header which asks " @@ -275,22 +276,22 @@ } /* This kernel will do: place and load it */ - if (mbh->flags & MULTIBOOT_AOUT_KLUDGE) { + if (eswap(mbh->flags) & MULTIBOOT_AOUT_KLUDGE) { /* Load using the offsets in the multiboot header */ if(!quiet) printf("Loading %s using multiboot header.\n", filename); /* How much is there? */ - start = mbh->load_addr; - if (mbh->load_end_addr != 0) - loadsize = mbh->load_end_addr - mbh->load_addr; + start = eswap(mbh->load_addr); + if (eswap(mbh->load_end_addr) != 0) + loadsize = eswap(mbh->load_end_addr) - eswap(mbh->load_addr); else loadsize = sb.st_size; /* How much memory will it take up? */ - if (mbh->bss_end_addr != 0) - size = mbh->bss_end_addr - mbh->load_addr; + if (eswap(mbh->bss_end_addr) != 0) + size = eswap(mbh->bss_end_addr) - eswap(mbh->load_addr); else size = loadsize; @@ -335,32 +336,34 @@ /* Done. */ if (!quiet) printf("Loaded kernel from %s\n", filename); - return mbh->entry_addr; + return eswap(mbh->entry_addr); } else { /* Now look for an ELF32 header */ ehdr = (Elf32_Ehdr *)headerbuf; - if (*(unsigned long *)ehdr != 0x464c457f + if (*(unsigned long *)ehdr != eswap(0x464c457f) || ehdr->e_ident[EI_DATA] != ELFDATA2LSB || ehdr->e_ident[EI_CLASS] != ELFCLASS32 - || ehdr->e_machine != EM_386) + || eswap(ehdr->e_machine) != EM_386) { printf("Fatal: kernel has neither ELF32/x86 nor multiboot load" " headers.\n"); exit(1); } - if (ehdr->e_phoff + ehdr->e_phnum*sizeof(*phdr) > HEADERBUF_SIZE) { + if (eswap(ehdr->e_phoff) + eswap(ehdr->e_phnum)*sizeof(*phdr) + > HEADERBUF_SIZE) { /* Don't expect this will happen with sane kernels */ printf("Fatal: too much ELF for me. Try increasing " "HEADERBUF_SIZE in mbootpack.\n"); exit(1); } - if (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > len) { + if (eswap(ehdr->e_phoff) + eswap(ehdr->e_phnum)*sizeof (*phdr) + > len) { printf("Fatal: malformed ELF header overruns EOF.\n"); exit(1); } - if (ehdr->e_phnum <= 0) { + if (eswap(ehdr->e_phnum) <= 0) { printf("Fatal: ELF kernel has no program headers.\n"); exit(1); } @@ -368,22 +371,22 @@ if(!quiet) printf("Loading %s using ELF header.\n", filename); - if (ehdr->e_type != ET_EXEC - || ehdr->e_version != EV_CURRENT - || ehdr->e_phentsize != sizeof (Elf32_Phdr)) { + if (eswap(ehdr->e_type) != ET_EXEC + || eswap(ehdr->e_version) != EV_CURRENT + || eswap(ehdr->e_phentsize) != sizeof (Elf32_Phdr)) { printf("Warning: funny-looking ELF header.\n"); } - phdr = (Elf32_Phdr *)(headerbuf + ehdr->e_phoff); + phdr = (Elf32_Phdr *)(headerbuf + eswap(ehdr->e_phoff)); /* Obey the program headers to load the kernel */ - for(i = 0; i < ehdr->e_phnum; i++) { - - start = phdr[i].p_paddr; - size = phdr[i].p_memsz; - if (phdr[i].p_type != PT_LOAD) + for(i = 0; i < eswap(ehdr->e_phnum); i++) { + + start = eswap(phdr[i].p_paddr); + size = eswap(phdr[i].p_memsz); + if (eswap(phdr[i].p_type) != PT_LOAD) loadsize = 0; else - loadsize = MIN((long int)phdr[i].p_filesz, size); + loadsize = MIN((long int)eswap(phdr[i].p_filesz), size); if ((buffer = malloc(size)) == NULL) { printf("Fatal: malloc() for kernel load failed: %s\n", @@ -396,7 +399,7 @@ /* Load section from file */ if (loadsize > 0) { - if (fseek(fp, phdr[i].p_offset, SEEK_SET) != 0) { + if (fseek(fp, eswap(phdr[i].p_offset), SEEK_SET) != 0) { printf("Fatal: seek failed in %s\n", strerror(errno)); exit(1); @@ -452,7 +455,7 @@ /* Done! */ if (!quiet) printf("Loaded kernel from %s\n", filename); - return ehdr->e_entry; + return eswap(ehdr->e_entry); } } @@ -568,12 +571,12 @@ /* Command line */ p = (char *)(mbi + 1); sprintf(p, "%s %s", imagename, command_line); - mbi->cmdline = ((address_t)p) + mbi_reloc_offset; + mbi->cmdline = eswap(((address_t)p) + mbi_reloc_offset); p += command_line_len; /* Bootloader ID */ sprintf(p, version_string); - mbi->boot_loader_name = ((address_t)p) + mbi_reloc_offset; + mbi->boot_loader_name = eswap(((address_t)p) + mbi_reloc_offset); p += strlen(version_string) + 1; /* Next is space for the module command lines */ @@ -582,17 +585,17 @@ /* Last come the module info structs */ modp = (struct mod_list *) ((((address_t)p + mod_command_line_space) + 3) & ~3); - mbi->mods_count = modules; - mbi->mods_addr = ((address_t)modp) + mbi_reloc_offset; + mbi->mods_count = eswap(modules); + mbi->mods_addr = eswap(((address_t)modp) + mbi_reloc_offset); /* Memory information will be added at boot time, by setup.S * or trampoline.S. */ - mbi->flags = MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME; + mbi->flags = eswap(MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME); /* Load the modules */ if (modules) { - mbi->flags |= MB_INFO_MODS; + mbi->flags = eswap(eswap(mbi->flags) | MB_INFO_MODS); /* Go back and parse the module command lines */ optind = opterr = 1; @@ -652,10 +655,10 @@ if (p != NULL) *p = ' '; /* Fill in the module info struct */ - modp->mod_start = start; - modp->mod_end = start + size; - modp->cmdline = (address_t)mod_clp + mbi_reloc_offset; - modp->pad = 0; + modp->mod_start = eswap(start); + modp->mod_end = eswap(start + size); + modp->cmdline = eswap((address_t)mod_clp + mbi_reloc_offset); + modp->pad = eswap(0); modp++; /* Store the module command line */ diff -r ae390c2b9d4c -r 287d36b46fa3 tools/misc/mbootpack/mbootpack.h --- a/tools/misc/mbootpack/mbootpack.h Mon Aug 29 23:05:29 2005 +++ b/tools/misc/mbootpack/mbootpack.h Tue Aug 30 20:36:49 2005 @@ -31,6 +31,24 @@ #undef NDEBUG #include <stdio.h> + +#include <endian.h> +#include <byteswap.h> +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define eswap(x) (x) +#else +#define eswap(x) \ + ({ \ + typeof(x) y = (x); \ + switch(sizeof(y)) \ + { \ + case 2: y = __bswap_16(y); break; \ + case 4: y = __bswap_32(y); break; \ + case 8: y = __bswap_64(y); break; \ + } \ + y; \ + }) +#endif /* Flags */ extern int quiet; diff -r ae390c2b9d4c -r 287d36b46fa3 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Mon Aug 29 23:05:29 2005 +++ b/tools/python/xen/lowlevel/xc/xc.c Tue Aug 30 20:36:49 2005 @@ -268,25 +268,33 @@ u32 dom; char *image, *ramdisk = NULL, *cmdline = ""; int flags = 0, vcpus = 1; - int control_evtchn, store_evtchn; + int control_evtchn, store_evtchn, console_evtchn; unsigned long store_mfn = 0; + unsigned long console_mfn = 0; static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", - "image", "ramdisk", "cmdline", "flags", + "console_evtchn", "image", + /* optional */ + "ramdisk", "cmdline", "flags", "vcpus", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssii", kwd_list, &dom, &control_evtchn, &store_evtchn, - &image, &ramdisk, &cmdline, &flags, + &console_evtchn, &image, + /* optional */ + &ramdisk, &cmdline, &flags, &vcpus) ) return NULL; if ( xc_linux_build(xc->xc_handle, dom, image, ramdisk, cmdline, control_evtchn, flags, vcpus, - store_evtchn, &store_mfn) != 0 ) - return PyErr_SetFromErrno(xc_error); - - return Py_BuildValue("{s:i}", "store_mfn", store_mfn); + store_evtchn, &store_mfn, + console_evtchn, &console_mfn) != 0 ) + return PyErr_SetFromErrno(xc_error); + + return Py_BuildValue("{s:i,s:i}", + "store_mfn", store_mfn, + "console_mfn", console_mfn); } static PyObject *pyxc_vmx_build(PyObject *self, diff -r ae390c2b9d4c -r 287d36b46fa3 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Aug 29 23:05:29 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Aug 30 20:36:49 2005 @@ -47,7 +47,7 @@ from xen.xend.XendRoot import get_component from xen.xend.uuid import getUuid -from xen.xend.xenstore import DBVar +from xen.xend.xenstore import DBVar, XenNode, DBMap """Shutdown code for poweroff.""" DOMAIN_POWEROFF = 0 @@ -231,6 +231,7 @@ DBVar('start_time', ty='float'), DBVar('state', ty='str'), DBVar('store_mfn', ty='long'), + DBVar('console_mfn', ty='long'), DBVar('restart_mode', ty='str'), DBVar('restart_state', ty='str'), DBVar('restart_time', ty='float'), @@ -260,6 +261,8 @@ self.channel = None self.store_channel = None self.store_mfn = None + self.console_channel = None + self.console_mfn = None self.controllers = {} self.info = None @@ -297,6 +300,9 @@ if self.store_channel: self.store_channel.saveToDB(self.db.addChild("store_channel"), save=save) + if self.console_channel: + self.console_channel.saveToDB(self.db.addChild("console_channel"), + save=save) if self.image: self.image.exportToDB(save=save, sync=sync) self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync) @@ -328,6 +334,9 @@ def getStoreChannel(self): return self.store_channel + + def getConsoleChannel(self): + return self.console_channel def update(self, info): """Update with info from xc.domain_getinfo(). @@ -518,6 +527,14 @@ sxpr.append(self.store_channel.sxpr()) if self.store_mfn: sxpr.append(['store_mfn', self.store_mfn]) + if self.console_channel: + sxpr.append(['console_channel', self.console_channel.sxpr()]) + if self.console_mfn: + sxpr.append(['console_mfn', self.console_mfn]) +# already in (devices) +# console = self.getConsole() +# if console: +# sxpr.append(console.sxpr()) if self.restart_count: sxpr.append(['restart_count', self.restart_count]) @@ -712,6 +729,13 @@ except Exception, ex: log.warning("error in domain release on xenstore: %s", ex) pass + if self.console_channel: + # notify processes using this cosole? + try: + self.console_channel.close() + self.console_channel = None + except: + pass if self.image: try: self.device_model_pid = 0 @@ -808,6 +832,7 @@ """ self.channel = self.openChannel("channel", 0, 1) self.store_channel = self.eventChannel("store_channel") + self.console_channel = self.eventChannel("console_channel") def create_configured_devices(self): devices = sxp.children(self.config, 'device') @@ -1003,6 +1028,7 @@ self.configure_fields() self.create_devices() self.create_blkif() + self.publish_console() def create_blkif(self): """Create the block device interface (blkif) for the vm. @@ -1017,6 +1043,12 @@ backend = blkif.getBackend(0) backend.connect(recreate=self.recreate) + def publish_console(self): + db = DBMap(db=XenNode("/console/%d" % self.id)) + db.clear() + db['domain'] = self.db.getPath() + db.saveDB(save=True) + def configure_fields(self): """Process the vm configuration fields using the registered handlers. """ diff -r ae390c2b9d4c -r 287d36b46fa3 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Mon Aug 29 23:05:29 2005 +++ b/tools/python/xen/xend/image.py Tue Aug 30 20:36:49 2005 @@ -238,16 +238,33 @@ store_evtchn = self.vm.store_channel.port2 else: store_evtchn = 0 + if self.vm.console_channel: + console_evtchn = self.vm.console_channel.port2 + else: + console_evtchn = 0 + + log.debug("dom = %d", self.vm.getDomain()) + log.debug("image = %s", self.kernel) + log.debug("control_evtchn = %s", self.vm.channel.getRemotePort()) + log.debug("store_evtchn = %d", store_evtchn) + log.debug("console_evtchn = %d", console_evtchn) + log.debug("cmdline = %s", self.cmdline) + log.debug("ramdisk = %s", self.ramdisk) + log.debug("flags = %d", self.flags) + log.debug("vcpus = %d", self.vm.vcpus) + ret = xc.linux_build(dom = self.vm.getDomain(), image = self.kernel, control_evtchn = self.vm.channel.getRemotePort(), store_evtchn = store_evtchn, + console_evtchn = console_evtchn, cmdline = self.cmdline, ramdisk = self.ramdisk, flags = self.flags, vcpus = self.vm.vcpus) if isinstance(ret, dict): self.vm.store_mfn = ret.get('store_mfn') + self.vm.console_mfn = ret.get('console_mfn') return 0 return ret diff -r ae390c2b9d4c -r 287d36b46fa3 tools/xcs/Makefile --- a/tools/xcs/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/xcs/Makefile Tue Aug 30 20:36:49 2005 @@ -10,8 +10,7 @@ INSTALL_PROG = $(INSTALL) -m0755 INSTALL_DIR = $(INSTALL) -d -m0755 -CC = gcc -CFLAGS = -Wall -Werror -g3 -D _XOPEN_SOURCE=600 +CFLAGS += -Wall -Werror -g3 -D _XOPEN_SOURCE=600 CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff -r ae390c2b9d4c -r 287d36b46fa3 tools/xcutils/Makefile --- a/tools/xcutils/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/xcutils/Makefile Tue Aug 30 20:36:49 2005 @@ -18,8 +18,6 @@ PROGRAMS_INSTALL_DIR = /usr/libexec/xen INCLUDES += -I $(XEN_LIBXC) - -CC := gcc CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing CFLAGS += $(INCLUDES) diff -r ae390c2b9d4c -r 287d36b46fa3 tools/xenstat/Makefile --- a/tools/xenstat/Makefile Mon Aug 29 23:05:29 2005 +++ b/tools/xenstat/Makefile Tue Aug 30 20:36:49 2005 @@ -3,7 +3,11 @@ SUBDIRS := SUBDIRS += libxenstat + +# This doesn't cross-compile (cross-compile environments rarely have curses) +ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) SUBDIRS += xentop +endif .PHONY: all install clean diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/domain.c Tue Aug 30 20:36:49 2005 @@ -255,13 +255,13 @@ v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; v->cpumap = CPUMAP_RUNANYWHERE; SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); - machine_to_phys_mapping[virt_to_phys(d->shared_info) >> - PAGE_SHIFT] = INVALID_M2P_ENTRY; + set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, + INVALID_M2P_ENTRY); d->arch.mm_perdomain_pt = alloc_xenheap_page(); memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE); - machine_to_phys_mapping[virt_to_phys(d->arch.mm_perdomain_pt) >> - PAGE_SHIFT] = INVALID_M2P_ENTRY; + set_pfn_from_mfn(virt_to_phys(d->arch.mm_perdomain_pt) >> PAGE_SHIFT, + INVALID_M2P_ENTRY); v->arch.perdomain_ptes = d->arch.mm_perdomain_pt; v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/domain_build.c Tue Aug 30 20:36:49 2005 @@ -592,8 +592,7 @@ if ( opt_dom0_translate ) { si->shared_info = d->next_io_page << PAGE_SHIFT; - set_machinetophys(virt_to_phys(d->shared_info) >> PAGE_SHIFT, - d->next_io_page); + set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, d->next_io_page); d->next_io_page++; } else @@ -614,7 +613,7 @@ mfn = alloc_epfn - (pfn - REVERSE_START); #endif ((u32 *)vphysmap_start)[pfn] = mfn; - machine_to_phys_mapping[mfn] = pfn; + set_pfn_from_mfn(mfn, pfn); } while ( pfn < nr_pages ) { @@ -627,7 +626,7 @@ #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn))) #endif ((u32 *)vphysmap_start)[pfn] = mfn; - machine_to_phys_mapping[mfn] = pfn; + set_pfn_from_mfn(mfn, pfn); #undef pfn page++; pfn++; } diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/mm.c Tue Aug 30 20:36:49 2005 @@ -1452,7 +1452,7 @@ "!= exp %" PRtype_info ") " "for mfn %lx (pfn %x)", x, type, page_to_pfn(page), - machine_to_phys_mapping[page_to_pfn(page)]); + get_pfn_from_mfn(page_to_pfn(page))); return 0; } else if ( (x & PGT_va_mask) == PGT_va_mutable ) @@ -2206,7 +2206,7 @@ printk("privileged guest dom%d requests pfn=%lx to " "map mfn=%lx for dom%d\n", d->domain_id, gpfn, mfn, FOREIGNDOM->domain_id); - set_machinetophys(mfn, gpfn); + set_pfn_from_mfn(mfn, gpfn); set_p2m_entry(FOREIGNDOM, gpfn, mfn, &sh_mapcache, &mapcache); okay = 1; shadow_unlock(FOREIGNDOM); @@ -2225,7 +2225,7 @@ break; } - set_machinetophys(mfn, gpfn); + set_pfn_from_mfn(mfn, gpfn); okay = 1; /* diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/shadow32.c --- a/xen/arch/x86/shadow32.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/shadow32.c Tue Aug 30 20:36:49 2005 @@ -827,7 +827,7 @@ { page = list_entry(list_ent, struct pfn_info, list); mfn = page_to_pfn(page); - pfn = machine_to_phys_mapping[mfn]; + pfn = get_pfn_from_mfn(mfn); ASSERT(pfn != INVALID_M2P_ENTRY); ASSERT(pfn < (1u<<20)); @@ -841,7 +841,7 @@ { page = list_entry(list_ent, struct pfn_info, list); mfn = page_to_pfn(page); - pfn = machine_to_phys_mapping[mfn]; + pfn = get_pfn_from_mfn(mfn); if ( (pfn != INVALID_M2P_ENTRY) && (pfn < (1u<<20)) ) { diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/shadow_public.c --- a/xen/arch/x86/shadow_public.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/shadow_public.c Tue Aug 30 20:36:49 2005 @@ -1311,7 +1311,7 @@ { page = list_entry(list_ent, struct pfn_info, list); mfn = page_to_pfn(page); - pfn = machine_to_phys_mapping[mfn]; + pfn = get_pfn_from_mfn(mfn); ASSERT(pfn != INVALID_M2P_ENTRY); ASSERT(pfn < (1u<<20)); @@ -1325,7 +1325,7 @@ { page = list_entry(list_ent, struct pfn_info, list); mfn = page_to_pfn(page); - pfn = machine_to_phys_mapping[mfn]; + pfn = get_pfn_from_mfn(mfn); if ( (pfn != INVALID_M2P_ENTRY) && (pfn < (1u<<20)) ) { diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/traps.c Tue Aug 30 20:36:49 2005 @@ -100,6 +100,7 @@ static int debug_stack_lines = 20; integer_param("debug_stack_lines", debug_stack_lines); +#define stack_words_per_line (32 / BYTES_PER_LONG) int is_kernel_text(unsigned long addr) { @@ -125,7 +126,7 @@ printk("Guest stack trace from "__OP"sp=%p:\n ", stack); - for ( i = 0; i < (debug_stack_lines*8); i++ ) + for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ ) { if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; @@ -137,7 +138,7 @@ i = 1; break; } - if ( (i != 0) && ((i % 8) == 0) ) + if ( (i != 0) && ((i % stack_words_per_line) == 0) ) printk("\n "); printk("%p ", _p(addr)); stack++; @@ -176,11 +177,11 @@ printk("Xen stack trace from "__OP"sp=%p:\n ", stack); - for ( i = 0; i < (debug_stack_lines*8); i++ ) + for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ ) { if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; - if ( (i != 0) && ((i % 8) == 0) ) + if ( (i != 0) && ((i % stack_words_per_line) == 0) ) printk("\n "); addr = *stack++; printk("%p ", _p(addr)); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/vmx.c --- a/xen/arch/x86/vmx.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/vmx.c Tue Aug 30 20:36:49 2005 @@ -704,7 +704,7 @@ return 0; } - mfn = phys_to_machine_mapping(laddr >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT); addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK); if (dir == COPY_IN) @@ -805,7 +805,7 @@ * removed some translation or changed page attributes. * We simply invalidate the shadow. */ - mfn = phys_to_machine_mapping(c->cr3 >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT); if (mfn != pagetable_get_pfn(d->arch.guest_table)) { printk("Invalid CR3 value=%x", c->cr3); domain_crash_synchronous(); @@ -823,7 +823,7 @@ domain_crash_synchronous(); return 0; } - mfn = phys_to_machine_mapping(c->cr3 >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(c->cr3 >> PAGE_SHIFT); d->arch.guest_table = mk_pagetable(mfn << PAGE_SHIFT); update_pagetables(d); /* @@ -978,7 +978,7 @@ /* * The guest CR3 must be pointing to the guest physical. */ - if ( !VALID_MFN(mfn = phys_to_machine_mapping( + if ( !VALID_MFN(mfn = get_mfn_from_pfn( d->arch.arch_vmx.cpu_cr3 >> PAGE_SHIFT)) || !get_page(pfn_to_page(mfn), d->domain) ) { @@ -1174,7 +1174,7 @@ * removed some translation or changed page attributes. * We simply invalidate the shadow. */ - mfn = phys_to_machine_mapping(value >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(value >> PAGE_SHIFT); if (mfn != pagetable_get_pfn(d->arch.guest_table)) __vmx_bug(regs); shadow_sync_all(d->domain); @@ -1185,7 +1185,7 @@ */ VMX_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value); if ( ((value >> PAGE_SHIFT) > d->domain->max_pages ) || - !VALID_MFN(mfn = phys_to_machine_mapping(value >> PAGE_SHIFT)) || + !VALID_MFN(mfn = get_mfn_from_pfn(value >> PAGE_SHIFT)) || !get_page(pfn_to_page(mfn), d->domain) ) { printk("Invalid CR3 value=%lx", value); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/vmx_platform.c --- a/xen/arch/x86/vmx_platform.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/vmx_platform.c Tue Aug 30 20:36:49 2005 @@ -521,7 +521,7 @@ if ( vmx_paging_enabled(current) ) { gpa = gva_to_gpa(guest_eip); - mfn = phys_to_machine_mapping(gpa >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(gpa >> PAGE_SHIFT); /* Does this cross a page boundary ? */ if ( (guest_eip & PAGE_MASK) != ((guest_eip + inst_len) & PAGE_MASK) ) @@ -532,7 +532,7 @@ } else { - mfn = phys_to_machine_mapping(guest_eip >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(guest_eip >> PAGE_SHIFT); } inst_start = map_domain_page(mfn); @@ -542,7 +542,7 @@ if ( remaining ) { gpa = gva_to_gpa(guest_eip+inst_len+remaining); - mfn = phys_to_machine_mapping(gpa >> PAGE_SHIFT); + mfn = get_mfn_from_pfn(gpa >> PAGE_SHIFT); inst_start = map_domain_page(mfn); memcpy((char *)buf+inst_len, inst_start, remaining); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/vmx_vmcs.c --- a/xen/arch/x86/vmx_vmcs.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/vmx_vmcs.c Tue Aug 30 20:36:49 2005 @@ -148,7 +148,7 @@ offset = (addr & ~PAGE_MASK); addr = round_pgdown(addr); - mpfn = phys_to_machine_mapping(addr >> PAGE_SHIFT); + mpfn = get_mfn_from_pfn(addr >> PAGE_SHIFT); p = map_domain_page(mpfn); e820p = (struct e820entry *) ((unsigned long) p + offset); @@ -175,7 +175,7 @@ unmap_domain_page(p); /* Initialise shared page */ - mpfn = phys_to_machine_mapping(gpfn); + mpfn = get_mfn_from_pfn(gpfn); p = map_domain_page(mpfn); d->domain->arch.vmx_platform.shared_page_va = (unsigned long)p; diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/x86_32/entry.S Tue Aug 30 20:36:49 2005 @@ -796,7 +796,7 @@ .long do_get_debugreg .long do_update_descriptor /* 10 */ .long do_ni_hypercall - .long do_dom_mem_op + .long do_memory_op .long do_multicall .long do_update_va_mapping .long do_set_timer_op /* 15 */ @@ -829,7 +829,7 @@ .byte 1 /* do_get_debugreg */ .byte 4 /* do_update_descriptor */ /* 10 */ .byte 0 /* do_ni_hypercall */ - .byte 5 /* do_dom_mem_op */ + .byte 2 /* do_memory_op */ .byte 2 /* do_multicall */ .byte 4 /* do_update_va_mapping */ .byte 2 /* do_set_timer_op */ /* 15 */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/x86_64/entry.S Tue Aug 30 20:36:49 2005 @@ -339,7 +339,8 @@ 1: /* In kernel context already: push new frame at existing %rsp. */ movq UREGS_rsp+8(%rsp),%rsi andb $0xfc,UREGS_cs+8(%rsp) # Indicate kernel context to guest. -2: movq $HYPERVISOR_VIRT_START,%rax +2: andq $~0xf,%rsi # Stack frames are 16-byte aligned. + movq $HYPERVISOR_VIRT_START,%rax cmpq %rax,%rsi jb 1f # In +ve address space? Then okay. movq $HYPERVISOR_VIRT_END+60,%rax @@ -616,7 +617,7 @@ .quad do_get_debugreg .quad do_update_descriptor /* 10 */ .quad do_ni_hypercall - .quad do_dom_mem_op + .quad do_memory_op .quad do_multicall .quad do_update_va_mapping .quad do_set_timer_op /* 15 */ @@ -649,7 +650,7 @@ .byte 1 /* do_get_debugreg */ .byte 2 /* do_update_descriptor */ /* 10 */ .byte 0 /* do_ni_hypercall */ - .byte 5 /* do_dom_mem_op */ + .byte 2 /* do_memory_op */ .byte 2 /* do_multicall */ .byte 3 /* do_update_va_mapping */ .byte 1 /* do_set_timer_op */ /* 15 */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Mon Aug 29 23:05:29 2005 +++ b/xen/arch/x86/x86_64/traps.c Tue Aug 30 20:36:49 2005 @@ -15,19 +15,22 @@ void show_registers(struct cpu_user_regs *regs) { - printk("CPU: %d\nEIP: %04x:[<%016lx>]", + printk("CPU: %d\nRIP: %04x:[<%016lx>]", smp_processor_id(), 0xffff & regs->cs, regs->rip); if ( !GUEST_MODE(regs) ) print_symbol(" %s", regs->rip); - printk("\nEFLAGS: %016lx\n", regs->eflags); - printk("rax: %016lx rbx: %016lx rcx: %016lx rdx: %016lx\n", - regs->rax, regs->rbx, regs->rcx, regs->rdx); - printk("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", - regs->rsi, regs->rdi, regs->rbp, regs->rsp); - printk("r8: %016lx r9: %016lx r10: %016lx r11: %016lx\n", - regs->r8, regs->r9, regs->r10, regs->r11); - printk("r12: %016lx r13: %016lx r14: %016lx r15: %016lx\n", - regs->r12, regs->r13, regs->r14, regs->r15); + printk("\nRFLAGS: %016lx\n", regs->eflags); + printk("rax: %016lx rbx: %016lx rcx: %016lx\n", + regs->rax, regs->rbx, regs->rcx); + printk("rdx: %016lx rsi: %016lx rdi: %016lx\n", + regs->rdx, regs->rsi, regs->rdi); + printk("rbp: %016lx rsp: %016lx r8: %016lx\n", + regs->rbp, regs->rsp, regs->r8); + printk("r9: %016lx r10: %016lx r11: %016lx\n", + regs->r9, regs->r10, regs->r11); + printk("r12: %016lx r13: %016lx r14: %016lx\n", + regs->r12, regs->r13, regs->r14); + printk("r15: %016lx\n", regs->r15); if ( GUEST_MODE(regs) ) show_guest_stack(); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/common/Makefile --- a/xen/common/Makefile Mon Aug 29 23:05:29 2005 +++ b/xen/common/Makefile Tue Aug 30 20:36:49 2005 @@ -2,7 +2,6 @@ include $(BASEDIR)/Rules.mk ifeq ($(TARGET_ARCH),ia64) -#OBJS := $(subst dom_mem_ops.o,,$(OBJS)) OBJS := $(subst grant_table.o,,$(OBJS)) endif diff -r ae390c2b9d4c -r 287d36b46fa3 xen/common/grant_table.c --- a/xen/common/grant_table.c Mon Aug 29 23:05:29 2005 +++ b/xen/common/grant_table.c Tue Aug 30 20:36:49 2005 @@ -1211,13 +1211,13 @@ DPRINTK("Bad pfn (%lx)\n", pfn); else { - machine_to_phys_mapping[frame] = pfn; + set_pfn_from_mfn(frame, pfn); if ( unlikely(shadow_mode_log_dirty(ld))) mark_dirty(ld, frame); if (shadow_mode_translate(ld)) - __phys_to_machine_mapping[pfn] = frame; + set_mfn_from_pfn(pfn, frame); } sha->frame = __mfn_to_gpfn(rd, frame); sha->domid = rd->domain_id; @@ -1268,8 +1268,7 @@ { SHARE_PFN_WITH_DOMAIN( virt_to_page((char *)(t->shared)+(i*PAGE_SIZE)), d); - machine_to_phys_mapping[(virt_to_phys(t->shared) >> PAGE_SHIFT) + i] = - INVALID_M2P_ENTRY; + set_pfn_from_mfn((virt_to_phys(t->shared) >> PAGE_SHIFT) + i, INVALID_M2P_ENTRY); } /* Okay, install the structure. */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/common/page_alloc.c --- a/xen/common/page_alloc.c Mon Aug 29 23:05:29 2005 +++ b/xen/common/page_alloc.c Tue Aug 30 20:36:49 2005 @@ -216,7 +216,7 @@ #define NR_ZONES 3 -#define MAX_DMADOM_PFN 0xFFFFF +#define MAX_DMADOM_PFN 0x7FFFF /* 31 addressable bits */ #define pfn_dom_zone_type(_pfn) \ (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM) diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/asm-ia64/mm.h --- a/xen/include/asm-ia64/mm.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/asm-ia64/mm.h Tue Aug 30 20:36:49 2005 @@ -405,7 +405,7 @@ /* If pmt table is provided by control pannel later, we need __get_user * here. However if it's allocated by HV, we should access it directly */ -#define phys_to_machine_mapping(d, gpfn) \ +#define get_mfn_from_pfn(d, gpfn) \ ((d) == dom0 ? gpfn : \ (gpfn <= d->arch.max_pfn ? (d)->arch.pmt[(gpfn)] : \ INVALID_MFN)) @@ -414,7 +414,7 @@ machine_to_phys_mapping[(mfn)] #define __gpfn_to_mfn(_d, gpfn) \ - phys_to_machine_mapping((_d), (gpfn)) + get_mfn_from_pfn((_d), (gpfn)) #define __gpfn_invalid(_d, gpfn) \ (__gpfn_to_mfn((_d), (gpfn)) & GPFN_INV_MASK) diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/asm-x86/mm.h --- a/xen/include/asm-x86/mm.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/asm-x86/mm.h Tue Aug 30 20:36:49 2005 @@ -255,10 +255,13 @@ * contiguous (or near contiguous) physical memory. */ #undef machine_to_phys_mapping -#define machine_to_phys_mapping ((u32 *)RDWR_MPT_VIRT_START) +#define machine_to_phys_mapping ((u32 *)RDWR_MPT_VIRT_START) #define INVALID_M2P_ENTRY (~0U) #define VALID_M2P(_e) (!((_e) & (1U<<31))) #define IS_INVALID_M2P_ENTRY(_e) (!VALID_M2P(_e)) + +#define set_pfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn)) +#define get_pfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)]) /* * The phys_to_machine_mapping is the reversed mapping of MPT for full @@ -266,17 +269,17 @@ * guests, so we steal the address space that would have normally * been used by the read-only MPT map. */ -#define __phys_to_machine_mapping ((unsigned long *)RO_MPT_VIRT_START) -#define INVALID_MFN (~0UL) -#define VALID_MFN(_mfn) (!((_mfn) & (1U<<31))) - -/* Returns the machine physical */ -static inline unsigned long phys_to_machine_mapping(unsigned long pfn) +#define phys_to_machine_mapping ((unsigned long *)RO_MPT_VIRT_START) +#define INVALID_MFN (~0UL) +#define VALID_MFN(_mfn) (!((_mfn) & (1U<<31))) + +#define set_mfn_from_pfn(pfn, mfn) (phys_to_machine_mapping[(pfn)] = (mfn)) +static inline unsigned long get_mfn_from_pfn(unsigned long pfn) { unsigned long mfn; l1_pgentry_t pte; - if ( (__copy_from_user(&pte, &__phys_to_machine_mapping[pfn], + if ( (__copy_from_user(&pte, &phys_to_machine_mapping[pfn], sizeof(pte)) == 0) && (l1e_get_flags(pte) & _PAGE_PRESENT) ) mfn = l1e_get_pfn(pte); @@ -285,7 +288,6 @@ return mfn; } -#define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn) #ifdef MEMORY_GUARD void memguard_init(void); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/asm-x86/shadow.h Tue Aug 30 20:36:49 2005 @@ -269,14 +269,14 @@ #define __mfn_to_gpfn(_d, mfn) \ ( (shadow_mode_translate(_d)) \ - ? machine_to_phys_mapping[(mfn)] \ + ? get_pfn_from_mfn(mfn) \ : (mfn) ) #define __gpfn_to_mfn(_d, gpfn) \ ({ \ ASSERT(current->domain == (_d)); \ (shadow_mode_translate(_d)) \ - ? phys_to_machine_mapping(gpfn) \ + ? get_mfn_from_pfn(gpfn) \ : (gpfn); \ }) @@ -461,7 +461,7 @@ // This wants the nice compact set of PFNs from 0..domain's max, // which __mfn_to_gpfn() only returns for translated domains. // - pfn = machine_to_phys_mapping[mfn]; + pfn = get_pfn_from_mfn(mfn); /* * Values with the MSB set denote MFNs that aren't really part of the @@ -562,7 +562,7 @@ old_hl2e = v->arch.hl2_vtable[index]; if ( (l2e_get_flags(gl2e) & _PAGE_PRESENT) && - VALID_MFN(mfn = phys_to_machine_mapping(l2e_get_pfn(gl2e))) ) + VALID_MFN(mfn = get_mfn_from_pfn(l2e_get_pfn(gl2e))) ) new_hl2e = l1e_from_pfn(mfn, __PAGE_HYPERVISOR); else new_hl2e = l1e_empty(); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/asm-x86/shadow_64.h --- a/xen/include/asm-x86/shadow_64.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/asm-x86/shadow_64.h Tue Aug 30 20:36:49 2005 @@ -138,7 +138,7 @@ return NULL; mfn = entry_get_value(*le_e) >> PAGE_SHIFT; if ((flag & GUEST_ENTRY) && shadow_mode_translate(d)) - mfn = phys_to_machine_mapping(mfn); + mfn = get_mfn_from_pfn(mfn); le_p = (pgentry_64_t *)phys_to_virt(mfn << PAGE_SHIFT); index = table_offset_64(va, (level + i - 1)); le_e = &le_p[index]; @@ -257,7 +257,7 @@ if (unlikely(!(l2e_get_flags_32(gl2e) & _PAGE_PRESENT))) return NULL; - l1mfn = phys_to_machine_mapping( + l1mfn = get_mfn_from_pfn( l2e_get_pfn(gl2e)); l1va = (l1_pgentry_32_t *) @@ -299,7 +299,7 @@ return NULL; - l1mfn = phys_to_machine_mapping( + l1mfn = get_mfn_from_pfn( l2e_get_pfn(gl2e)); l1va = (l1_pgentry_32_t *) phys_to_virt( l1mfn << L1_PAGETABLE_SHIFT); diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/asm-x86/vmx_platform.h --- a/xen/include/asm-x86/vmx_platform.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/asm-x86/vmx_platform.h Tue Aug 30 20:36:49 2005 @@ -91,6 +91,6 @@ extern void vmx_io_assist(struct vcpu *v); // XXX - think about this -- maybe use bit 30 of the mfn to signify an MMIO frame. -#define mmio_space(gpa) (!VALID_MFN(phys_to_machine_mapping((gpa) >> PAGE_SHIFT))) +#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_pfn((gpa) >> PAGE_SHIFT))) #endif diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/public/xen.h --- a/xen/include/public/xen.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/public/xen.h Tue Aug 30 20:36:49 2005 @@ -42,7 +42,7 @@ #define __HYPERVISOR_set_debugreg 8 #define __HYPERVISOR_get_debugreg 9 #define __HYPERVISOR_update_descriptor 10 -#define __HYPERVISOR_dom_mem_op 12 +#define __HYPERVISOR_memory_op 12 #define __HYPERVISOR_multicall 13 #define __HYPERVISOR_update_va_mapping 14 #define __HYPERVISOR_set_timer_op 15 @@ -223,12 +223,6 @@ */ #define CONSOLEIO_write 0 #define CONSOLEIO_read 1 - -/* - * Commands to HYPERVISOR_dom_mem_op(). - */ -#define MEMOP_increase_reservation 0 -#define MEMOP_decrease_reservation 1 /* * Commands to HYPERVISOR_vm_assist(). @@ -438,19 +432,21 @@ #define MAX_GUEST_CMDLINE 1024 typedef struct start_info { /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */ - unsigned long nr_pages; /* Total pages allocated to this domain. */ - unsigned long shared_info;/* MACHINE address of shared info struct. */ - u32 flags; /* SIF_xxx flags. */ + unsigned long nr_pages; /* Total pages allocated to this domain. */ + unsigned long shared_info; /* MACHINE address of shared info struct. */ + u32 flags; /* SIF_xxx flags. */ u16 domain_controller_evtchn; /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */ - unsigned long pt_base; /* VIRTUAL address of page directory. */ - unsigned long nr_pt_frames;/* Number of bootstrap p.t. frames. */ - unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ - unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ - unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ + unsigned long pt_base; /* VIRTUAL address of page directory. */ + unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */ + unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ + unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ + unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ s8 cmd_line[MAX_GUEST_CMDLINE]; - unsigned long store_mfn; /* MACHINE page number of shared page. */ - u16 store_evtchn; /* Event channel for store communication. */ + unsigned long store_mfn; /* MACHINE page number of shared page. */ + u16 store_evtchn; /* Event channel for store communication. */ + unsigned long console_mfn; /* MACHINE address of console page. */ + u16 console_evtchn; /* Event channel for console messages. */ } start_info_t; /* These flags are passed in the 'flags' field of start_info_t. */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/xen/perfc.h --- a/xen/include/xen/perfc.h Mon Aug 29 23:05:29 2005 +++ b/xen/include/xen/perfc.h Tue Aug 30 20:36:49 2005 @@ -4,6 +4,7 @@ #ifdef PERF_COUNTERS +#include <xen/lib.h> #include <asm/atomic.h> /* @@ -87,7 +88,7 @@ * Histogram: special treatment for 0 and 1 count. After that equally spaced * with last bucket taking the rest. */ -#ifdef PERFC_ARRAYS +#ifdef PERF_ARRAYS #define perfc_incr_histo(_x,_v,_n) \ do { \ if ( (_v) == 0 ) \ diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c --- /dev/null Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Aug 30 20:36:49 2005 @@ -0,0 +1,124 @@ +#include <linux/version.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/serial.h> +#include <linux/major.h> +#include <linux/ptrace.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/slab.h> + +#include <asm-xen/hypervisor.h> +#include <asm-xen/evtchn.h> +#include <linux/wait.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/err.h> +#include "xencons_ring.h" + + +struct ring_head +{ + u32 cons; + u32 prod; + char buf[0]; +} __attribute__((packed)); + + +#define XENCONS_RING_SIZE (PAGE_SIZE/2 - sizeof (struct ring_head)) +#define XENCONS_IDX(cnt) ((cnt) % XENCONS_RING_SIZE) +#define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) + +static inline struct ring_head *outring(void) +{ + return machine_to_virt(xen_start_info.console_mfn << PAGE_SHIFT); +} + +static inline struct ring_head *inring(void) +{ + return machine_to_virt(xen_start_info.console_mfn << PAGE_SHIFT) + + PAGE_SIZE/2; +} + + +/* don't block - write as much as possible and return */ +static int __xencons_ring_send(struct ring_head *ring, const char *data, unsigned len) +{ + int copied = 0; + + mb(); + while (copied < len && !XENCONS_FULL(ring)) { + ring->buf[XENCONS_IDX(ring->prod)] = data[copied]; + ring->prod++; + copied++; + } + mb(); + + return copied; +} + +int xencons_ring_send(const char *data, unsigned len) +{ + struct ring_head *out = outring(); + int sent = 0; + + sent = __xencons_ring_send(out, data, len); + notify_via_evtchn(xen_start_info.console_evtchn); + return sent; + +} + + +static xencons_receiver_func *xencons_receiver; + +static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) +{ + struct ring_head *ring = inring(); + while (ring->cons < ring->prod) { + if (xencons_receiver != NULL) { + xencons_receiver(ring->buf + XENCONS_IDX(ring->cons), + 1); + } + ring->cons++; + } + return IRQ_HANDLED; +} + +void xencons_ring_register_receiver(xencons_receiver_func *f) +{ + xencons_receiver = f; +} + +int xencons_ring_init(void) +{ + int err; + + if (!xen_start_info.console_evtchn) + return 0; + + err = bind_evtchn_to_irqhandler( + xen_start_info.console_evtchn, handle_input, + 0, "xencons", inring()); + if (err) { + xprintk(KERN_ERR "XEN console request irq failed %i\n", err); + unbind_evtchn_from_irq(xen_start_info.console_evtchn); + return err; + } + + return 0; +} + +void xencons_suspend_comms(void) +{ + + if (!xen_start_info.console_evtchn) + return; + + unbind_evtchn_from_irqhandler(xen_start_info.console_evtchn, inring()); +} + diff -r ae390c2b9d4c -r 287d36b46fa3 linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h --- /dev/null Mon Aug 29 23:05:29 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h Tue Aug 30 20:36:49 2005 @@ -0,0 +1,13 @@ +#ifndef _XENCONS_RING_H +#define _XENCONS_RING_H + +asmlinkage int xprintk(const char *fmt, ...); + + +int xencons_ring_init(void); +int xencons_ring_send(const char *data, unsigned len); + +typedef void (xencons_receiver_func)(char *buf, unsigned len); +void xencons_ring_register_receiver(xencons_receiver_func *f); + +#endif /* _XENCONS_RING_H */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/common/memory.c --- /dev/null Mon Aug 29 23:05:29 2005 +++ b/xen/common/memory.c Tue Aug 30 20:36:49 2005 @@ -0,0 +1,205 @@ +/****************************************************************************** + * memory.c + * + * Code to handle memory-related requests. + * + * Copyright (c) 2003-2004, B Dragovic + * Copyright (c) 2003-2005, K A Fraser + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/perfc.h> +#include <xen/sched.h> +#include <xen/event.h> +#include <xen/shadow.h> +#include <asm/current.h> +#include <asm/hardirq.h> +#include <public/memory.h> + +static long +increase_reservation( + struct domain *d, + unsigned long *extent_list, + unsigned int nr_extents, + unsigned int extent_order, + unsigned int flags) +{ + struct pfn_info *page; + unsigned long i; + + if ( (extent_list != NULL) + && !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) + return 0; + + if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) ) + { + DPRINTK("Only I/O-capable domains may allocate > order-0 memory.\n"); + return 0; + } + + for ( i = 0; i < nr_extents; i++ ) + { + if ( hypercall_preempt_check() ) + return i; + + if ( unlikely((page = alloc_domheap_pages( + d, extent_order, flags)) == NULL) ) + { + DPRINTK("Could not allocate a frame\n"); + return i; + } + + /* Inform the domain of the new page's machine address. */ + if ( (extent_list != NULL) + && (__put_user(page_to_pfn(page), &extent_list[i]) != 0) ) + return i; + } + + return nr_extents; +} + +static long +decrease_reservation( + struct domain *d, + unsigned long *extent_list, + unsigned int nr_extents, + unsigned int extent_order, + unsigned int flags) +{ + struct pfn_info *page; + unsigned long i, j, mpfn; + + if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) + return 0; + + for ( i = 0; i < nr_extents; i++ ) + { + if ( hypercall_preempt_check() ) + return i; + + if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) ) + return i; + + for ( j = 0; j < (1 << extent_order); j++ ) + { + if ( unlikely((mpfn + j) >= max_page) ) + { + DPRINTK("Domain %u page number out of range (%lx >= %lx)\n", + d->domain_id, mpfn + j, max_page); + return i; + } + + page = &frame_table[mpfn + j]; + if ( unlikely(!get_page(page, d)) ) + { + DPRINTK("Bad page free for domain %u\n", d->domain_id); + return i; + } + + if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) + put_page_and_type(page); + + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) + put_page(page); + + shadow_sync_and_drop_references(d, page); + + put_page(page); + } + } + + return nr_extents; +} + +/* + * To allow safe resume of do_memory_op() after preemption, we need to know + * at what point in the page list to resume. For this purpose I steal the + * high-order bits of the @cmd parameter, which are otherwise unused and zero. + */ +#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ + +long do_memory_op(int cmd, void *arg) +{ + struct domain *d; + int rc, start_extent, op, flags = 0; + struct xen_memory_reservation reservation; + + op = cmd & ((1 << START_EXTENT_SHIFT) - 1); + + switch ( op ) + { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + if ( copy_from_user(&reservation, arg, sizeof(reservation)) ) + return -EFAULT; + + start_extent = cmd >> START_EXTENT_SHIFT; + if ( unlikely(start_extent > reservation.nr_extents) ) + return -EINVAL; + + if ( reservation.extent_start != NULL ) + reservation.extent_start += start_extent; + reservation.nr_extents -= start_extent; + + if ( unlikely(reservation.address_bits != 0) + && (reservation.address_bits > (get_order(max_page)+PAGE_SHIFT)) ) + { + if ( reservation.address_bits < 31 ) + return -ENOMEM; + flags = ALLOC_DOM_DMA; + } + + if ( likely(reservation.domid == DOMID_SELF) ) + d = current->domain; + else if ( !IS_PRIV(current->domain) ) + return -EPERM; + else if ( (d = find_domain_by_id(reservation.domid)) == NULL ) + return -ESRCH; + + rc = ((op == XENMEM_increase_reservation) ? + increase_reservation : decrease_reservation)( + d, + reservation.extent_start, + reservation.nr_extents, + reservation.extent_order, + flags); + + if ( unlikely(reservation.domid != DOMID_SELF) ) + put_domain(d); + + rc += start_extent; + + if ( (rc != reservation.nr_extents) && hypercall_preempt_check() ) + return hypercall2_create_continuation( + __HYPERVISOR_memory_op, + op | (rc << START_EXTENT_SHIFT), + arg); + + break; + + case XENMEM_maximum_ram_page: + if ( put_user(max_page, (unsigned long *)arg) ) + return -EFAULT; + rc = -ENOSYS; + break; + + default: + rc = -ENOSYS; + break; + } + + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/include/public/memory.h --- /dev/null Mon Aug 29 23:05:29 2005 +++ b/xen/include/public/memory.h Tue Aug 30 20:36:49 2005 @@ -0,0 +1,50 @@ +/****************************************************************************** + * memory.h + * + * Memory reservation and information. + * + * Copyright (c) 2005, Keir Fraser <keir@xxxxxxxxxxxxx> + */ + +#ifndef __XEN_PUBLIC_MEMORY_H__ +#define __XEN_PUBLIC_MEMORY_H__ + +/* arg == addr of struct xen_memory_reservation. */ +#define XENMEM_increase_reservation 0 + +/* arg == addr of struct xen_memory_reservation. */ +#define XENMEM_decrease_reservation 1 + +/* arg == addr of unsigned long. */ +#define XENMEM_maximum_ram_page 2 + +typedef struct xen_memory_reservation { + + /* + * MFN bases of extents to free (XENMEM_decrease_reservation). + * MFN bases of extents that were allocated (XENMEM_increase_reservation). + */ + unsigned long *extent_start; + + /* Number of extents, and size/alignment of each (2^extent_order pages). */ + unsigned long nr_extents; + unsigned int extent_order; + + /* + * XENMEM_increase_reservation: maximum # bits addressable by the user + * of the allocated region (e.g., I/O devices often have a 32-bit + * limitation even in 64-bit systems). If zero then the user has no + * addressing restriction. + * XENMEM_decrease_reservation: unused. + */ + unsigned int address_bits; + + /* + * Domain whose reservation is being changed. + * Unprivileged domains can specify only DOMID_SELF. + */ + domid_t domid; + +} xen_memory_reservation_t; + +#endif /* __XEN_PUBLIC_MEMORY_H__ */ diff -r ae390c2b9d4c -r 287d36b46fa3 xen/common/dom_mem_ops.c --- a/xen/common/dom_mem_ops.c Mon Aug 29 23:05:29 2005 +++ /dev/null Tue Aug 30 20:36:49 2005 @@ -1,186 +0,0 @@ -/****************************************************************************** - * dom_mem_ops.c - * - * Code to handle memory related requests from domains eg. balloon driver. - * - * Copyright (c) 2003-2004, B Dragovic & K A Fraser. - */ - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/mm.h> -#include <xen/perfc.h> -#include <xen/sched.h> -#include <xen/event.h> -#include <xen/shadow.h> -#include <asm/current.h> -#include <asm/hardirq.h> - -/* - * To allow safe resume of do_dom_mem_op() after preemption, we need to know - * at what point in the page list to resume. For this purpose I steal the - * high-order bits of the @op parameter, which are otherwise unused and zero. - */ -#define START_EXTENT_SHIFT 4 /* op[:4] == start_extent */ - -#define PREEMPT_CHECK(_op) \ - if ( hypercall_preempt_check() ) \ - return hypercall5_create_continuation( \ - __HYPERVISOR_dom_mem_op, \ - (_op) | (i << START_EXTENT_SHIFT), \ - extent_list, nr_extents, extent_order, \ - (d == current->domain) ? DOMID_SELF : d->domain_id); - -static long -alloc_dom_mem(struct domain *d, - unsigned long *extent_list, - unsigned long start_extent, - unsigned int nr_extents, - unsigned int extent_order, - unsigned int flags) -{ - struct pfn_info *page; - unsigned long i; - - if ( (extent_list != NULL) && - !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) - return start_extent; - - if ( (extent_order != 0) && !IS_CAPABLE_PHYSDEV(current->domain) ) - { - DPRINTK("Only I/O-capable domains may allocate > order-0 memory.\n"); - return start_extent; - } - - for ( i = start_extent; i < nr_extents; i++ ) - { - PREEMPT_CHECK(MEMOP_increase_reservation); - - if ( unlikely((page = alloc_domheap_pages(d, extent_order, - flags)) == NULL) ) - { - DPRINTK("Could not allocate a frame\n"); - return i; - } - - /* Inform the domain of the new page's machine address. */ - if ( (extent_list != NULL) && - (__put_user(page_to_pfn(page), &extent_list[i]) != 0) ) - return i; - } - - return i; -} - -static long -free_dom_mem(struct domain *d, - unsigned long *extent_list, - unsigned long start_extent, - unsigned int nr_extents, - unsigned int extent_order) -{ - struct pfn_info *page; - unsigned long i, j, mpfn; - - if ( !array_access_ok(extent_list, nr_extents, sizeof(*extent_list)) ) - return start_extent; - - for ( i = start_extent; i < nr_extents; i++ ) - { - PREEMPT_CHECK(MEMOP_decrease_reservation); - - if ( unlikely(__get_user(mpfn, &extent_list[i]) != 0) ) - return i; - - for ( j = 0; j < (1 << extent_order); j++ ) - { - if ( unlikely((mpfn + j) >= max_page) ) - { - DPRINTK("Domain %u page number out of range (%lx >= %lx)\n", - d->domain_id, mpfn + j, max_page); - return i; - } - - page = &frame_table[mpfn + j]; - if ( unlikely(!get_page(page, d)) ) - { - DPRINTK("Bad page free for domain %u\n", d->domain_id); - return i; - } - - if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) - put_page_and_type(page); - - if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) - put_page(page); - - shadow_sync_and_drop_references(d, page); - - put_page(page); - } - } - - return i; -} - -long -do_dom_mem_op(unsigned long op, - unsigned long *extent_list, - unsigned int nr_extents, - unsigned int extent_order, - domid_t domid) -{ - struct domain *d; - unsigned long rc, start_extent; - unsigned int address_bits_order; - - /* Extract @start_extent from @op. */ - start_extent = op >> START_EXTENT_SHIFT; - op &= (1 << START_EXTENT_SHIFT) - 1; - - /* seperate extent_order and address_bits_order */ - address_bits_order = (extent_order >> 8) & 0xff; - extent_order &= 0xff; - - if ( unlikely(start_extent > nr_extents) ) - return -EINVAL; - - if ( likely(domid == DOMID_SELF) ) - d = current->domain; - else if ( unlikely(!IS_PRIV(current->domain)) ) - return -EPERM; - else if ( unlikely((d = find_domain_by_id(domid)) == NULL) ) - return -ESRCH; - - switch ( op ) - { - case MEMOP_increase_reservation: - rc = alloc_dom_mem( - d, extent_list, start_extent, nr_extents, extent_order, - (address_bits_order <= 32) ? ALLOC_DOM_DMA : 0); - break; - case MEMOP_decrease_reservation: - rc = free_dom_mem( - d, extent_list, start_extent, nr_extents, extent_order); - break; - default: - rc = -ENOSYS; - break; - } - - if ( unlikely(domid != DOMID_SELF) ) - put_domain(d); - - return rc; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |