# 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
|