mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
merge
This commit is contained in:
commit
44784246fc
254 files changed
+4439
-2223
No files matched your search
@@ -1,5 +1,8 @@
|
||||
# -*- mode: Makefile; -*-
|
||||
|
||||
# A debug build of Xen and tools?
|
||||
debug ?= n
|
||||
|
||||
# Currently supported architectures: x86_32, x86_64
|
||||
XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/)
|
||||
XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH)
|
||||
@@ -27,6 +30,22 @@ INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
INSTALL_DATA = $(INSTALL) -m0644
|
||||
INSTALL_PROG = $(INSTALL) -m0755
|
||||
|
||||
ifneq ($(debug),y)
|
||||
# Optimisation flags are overridable
|
||||
CFLAGS ?= -O2 -fomit-frame-pointer
|
||||
CFLAGS += -DNDEBUG
|
||||
else
|
||||
CFLAGS += -g
|
||||
endif
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),x86_32)
|
||||
CFLAGS += -m32 -march=i686
|
||||
endif
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),x86_64)
|
||||
CFLAGS += -m64
|
||||
endif
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),x86_64)
|
||||
LIBDIR = lib64
|
||||
else
|
||||
@@ -40,6 +59,8 @@ endif
|
||||
|
||||
test-gcc-flag = $(shell $(1) -v --help 2>&1 | grep -q " $(2) " && echo $(2))
|
||||
|
||||
CFLAGS += -Wall -Wstrict-prototypes
|
||||
|
||||
HOSTCFLAGS += $(call test-gcc-flag,$(HOSTCC),-Wdeclaration-after-statement)
|
||||
CFLAGS += $(call test-gcc-flag,$(CC),-Wdeclaration-after-statement)
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ CONFIG_MICROCODE=y
|
||||
CONFIG_X86_IO_APIC=y
|
||||
CONFIG_X86_XEN_GENAPIC=y
|
||||
CONFIG_X86_LOCAL_APIC=y
|
||||
CONFIG_MTRR=y
|
||||
# CONFIG_SMP is not set
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
|
||||
@@ -111,6 +111,7 @@ CONFIG_MICROCODE=y
|
||||
CONFIG_X86_IO_APIC=y
|
||||
CONFIG_X86_XEN_GENAPIC=y
|
||||
CONFIG_X86_LOCAL_APIC=y
|
||||
CONFIG_MTRR=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_PREEMPT_NONE=y
|
||||
# CONFIG_PREEMPT_VOLUNTARY is not set
|
||||
|
||||
@@ -32,6 +32,7 @@ OBJS := $(TARGET_ARCH).o
|
||||
OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
|
||||
OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
|
||||
#OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
|
||||
|
||||
HDRS := $(wildcard include/*.h)
|
||||
HDRS += $(wildcard include/xen/*.h)
|
||||
|
||||
@@ -15,3 +15,5 @@ memory = 32
|
||||
|
||||
# A name for your domain. All domains must have different names.
|
||||
name = "Mini-OS"
|
||||
|
||||
on_crash = 'destroy'
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
/* printing */
|
||||
#define printk printf
|
||||
#define kprintf printf
|
||||
|
||||
+51
-23
@@ -25,18 +25,34 @@
|
||||
#ifndef _MM_H_
|
||||
#define _MM_H_
|
||||
|
||||
#ifdef __i386__
|
||||
#if defined(__i386__)
|
||||
#include <xen/arch-x86_32.h>
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#elif defined(__x86_64__)
|
||||
#include <xen/arch-x86_64.h>
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
#include <lib.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define L1_FRAME 1
|
||||
#define L2_FRAME 2
|
||||
#define L3_FRAME 3
|
||||
|
||||
#define L1_PAGETABLE_SHIFT 12
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
#define L2_PAGETABLE_SHIFT 22
|
||||
|
||||
#define L1_PAGETABLE_ENTRIES 1024
|
||||
#define L2_PAGETABLE_ENTRIES 1024
|
||||
|
||||
#define PADDR_BITS 32
|
||||
#define PADDR_MASK (~0UL)
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
|
||||
#define L2_PAGETABLE_SHIFT 21
|
||||
#define L3_PAGETABLE_SHIFT 30
|
||||
#define L4_PAGETABLE_SHIFT 39
|
||||
@@ -52,29 +68,29 @@
|
||||
#define PADDR_MASK ((1UL << PADDR_BITS)-1)
|
||||
#define VADDR_MASK ((1UL << VADDR_BITS)-1)
|
||||
|
||||
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
|
||||
/* Get physical address of page mapped by pte (paddr_t). */
|
||||
#define l1e_get_paddr(x) \
|
||||
((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
|
||||
#define l2e_get_paddr(x) \
|
||||
((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
|
||||
#define l3e_get_paddr(x) \
|
||||
((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
|
||||
#define l4e_get_paddr(x) \
|
||||
((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
|
||||
|
||||
#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1)
|
||||
#define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#define L1_PAGETABLE_SHIFT 12
|
||||
#define L2_PAGETABLE_SHIFT 22
|
||||
|
||||
#define L1_PAGETABLE_ENTRIES 1024
|
||||
#define L2_PAGETABLE_ENTRIES 1024
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
#endif
|
||||
#define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1)
|
||||
|
||||
/* Given a virtual address, get an entry offset into a page table. */
|
||||
#define l1_table_offset(_a) \
|
||||
(((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
|
||||
#define l2_table_offset(_a) \
|
||||
(((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
|
||||
#ifdef __x86_64__
|
||||
#if defined(__x86_64__)
|
||||
#define l3_table_offset(_a) \
|
||||
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
|
||||
#define l4_table_offset(_a) \
|
||||
@@ -92,8 +108,15 @@
|
||||
#define _PAGE_PSE 0x080UL
|
||||
#define _PAGE_GLOBAL 0x100UL
|
||||
|
||||
#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
|
||||
#define L2_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_USER)
|
||||
#if defined(__i386__)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
|
||||
#elif defined(__x86_64__)
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
|
||||
#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
|
||||
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT)
|
||||
#define PAGE_SHIFT L1_PAGETABLE_SHIFT
|
||||
@@ -124,9 +147,9 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine)
|
||||
return phys;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
#if defined(__x86_64__)
|
||||
#define VIRT_START 0xFFFFFFFF00000000UL
|
||||
#else
|
||||
#elif defined(__i386__)
|
||||
#define VIRT_START 0xC0000000UL
|
||||
#endif
|
||||
|
||||
@@ -136,6 +159,11 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine)
|
||||
#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
|
||||
#define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach)))
|
||||
#define mfn_to_virt(_mfn) (mach_to_virt(_mfn << PAGE_SHIFT))
|
||||
#define pfn_to_virt(_pfn) (to_virt(_pfn << PAGE_SHIFT))
|
||||
|
||||
/* Pagetable walking. */
|
||||
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
|
||||
#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
|
||||
|
||||
void init_mm(void);
|
||||
unsigned long alloc_pages(int order);
|
||||
|
||||
@@ -59,6 +59,8 @@ extern shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
void trap_init(void);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The use of 'barrier' in the following reflects their use as local-lock
|
||||
* operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
|
||||
|
||||
+171
-99
@@ -51,7 +51,8 @@
|
||||
unsigned long *phys_to_machine_mapping;
|
||||
extern char *stack;
|
||||
extern char _text, _etext, _edata, _end;
|
||||
|
||||
extern void do_exit(void);
|
||||
extern void page_walk(unsigned long virt_addr);
|
||||
|
||||
/*********************
|
||||
* ALLOCATION BITMAP
|
||||
@@ -64,7 +65,6 @@ static unsigned long *alloc_bitmap;
|
||||
#define allocated_in_map(_pn) \
|
||||
(alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & (1<<((_pn)&(PAGES_PER_MAPWORD-1))))
|
||||
|
||||
|
||||
/*
|
||||
* Hint regarding bitwise arithmetic in map_{alloc,free}:
|
||||
* -(1<<n) sets all bits >= n.
|
||||
@@ -208,7 +208,6 @@ static void init_page_allocator(unsigned long min, unsigned long max)
|
||||
unsigned long range, bitmap_size;
|
||||
chunk_head_t *ch;
|
||||
chunk_tail_t *ct;
|
||||
|
||||
for ( i = 0; i < FREELIST_SIZE; i++ )
|
||||
{
|
||||
free_head[i] = &free_tail[i];
|
||||
@@ -366,106 +365,181 @@ void free_pages(void *pointer, int order)
|
||||
free_head[order] = freed_ch;
|
||||
|
||||
}
|
||||
void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
|
||||
{
|
||||
unsigned long pfn_to_map, pt_frame;
|
||||
unsigned long mach_ptd, max_mach_ptd;
|
||||
int count;
|
||||
unsigned long mach_pte, virt_pte;
|
||||
unsigned long *ptd = (unsigned long *)start_info.pt_base;
|
||||
mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
|
||||
|
||||
|
||||
void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
|
||||
unsigned long offset, unsigned long level)
|
||||
{
|
||||
unsigned long *tab = (unsigned long *)start_info.pt_base;
|
||||
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
|
||||
unsigned long prot_e, prot_t, pincmd;
|
||||
mmu_update_t mmu_updates[0];
|
||||
struct mmuext_op pin_request;
|
||||
|
||||
/* Firstly work out what is the first pfn that is not yet in page tables
|
||||
NB. Assuming that builder fills whole pt_frames (which it does at the
|
||||
moment)
|
||||
*/
|
||||
DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
|
||||
"prev_l_mfn=%lx, offset=%lx\n",
|
||||
level, *pt_pfn, prev_l_mfn, offset);
|
||||
|
||||
if (level == L1_FRAME)
|
||||
{
|
||||
prot_e = L1_PROT;
|
||||
prot_t = L2_PROT;
|
||||
pincmd = MMUEXT_PIN_L1_TABLE;
|
||||
}
|
||||
#if (defined __x86_64__)
|
||||
else if (level == L2_FRAME)
|
||||
{
|
||||
prot_e = L2_PROT;
|
||||
prot_t = L3_PROT;
|
||||
pincmd = MMUEXT_PIN_L2_TABLE;
|
||||
}
|
||||
else if (level == L3_FRAME)
|
||||
{
|
||||
prot_e = L3_PROT;
|
||||
prot_t = L4_PROT;
|
||||
pincmd = MMUEXT_PIN_L3_TABLE;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
printk("new_pt_frame() called with invalid level number %d\n", level);
|
||||
do_exit();
|
||||
}
|
||||
|
||||
/* Update the entry */
|
||||
#if (defined __x86_64__)
|
||||
tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
|
||||
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
|
||||
#endif
|
||||
mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) +
|
||||
sizeof(void *)* l1_table_offset(pt_page);
|
||||
mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
|
||||
(prot_e & ~_PAGE_RW);
|
||||
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("PTE for new page table page could not be updated\n");
|
||||
do_exit();
|
||||
}
|
||||
|
||||
/* Pin the page to provide correct protection */
|
||||
pin_request.cmd = pincmd;
|
||||
pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
|
||||
if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("ERROR: pinning failed\n");
|
||||
do_exit();
|
||||
}
|
||||
|
||||
/* Now fill the new page table page with entries.
|
||||
Update the page directory as well. */
|
||||
mmu_updates[0].ptr = (prev_l_mfn << PAGE_SHIFT) + sizeof(void *) * offset;
|
||||
mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
|
||||
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("ERROR: mmu_update failed\n");
|
||||
do_exit();
|
||||
}
|
||||
|
||||
*pt_pfn += 1;
|
||||
}
|
||||
|
||||
void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
|
||||
{
|
||||
unsigned long start_address, end_address;
|
||||
unsigned long pfn_to_map, pt_pfn = *start_pfn;
|
||||
static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
|
||||
unsigned long *tab = (unsigned long *)start_info.pt_base;
|
||||
unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
|
||||
unsigned long page, offset;
|
||||
int count = 0;
|
||||
|
||||
#if defined(__x86_64__)
|
||||
pfn_to_map = (start_info.nr_pt_frames - 3) * L1_PAGETABLE_ENTRIES;
|
||||
#else
|
||||
pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES;
|
||||
DEBUG("start_pfn=%ld, first pfn_to_map %ld, max_pfn=%ld",
|
||||
*start_pfn, pfn_to_map, *max_pfn);
|
||||
#endif
|
||||
start_address = (unsigned long)pfn_to_virt(pfn_to_map);
|
||||
end_address = (unsigned long)pfn_to_virt(*max_pfn);
|
||||
|
||||
/* We worked out the virtual memory range to map, now mapping loop */
|
||||
printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
|
||||
|
||||
/* Machine address of page table directory */
|
||||
mach_ptd = phys_to_machine(to_phys(start_info.pt_base));
|
||||
mach_ptd += sizeof(void *) *
|
||||
l2_table_offset((unsigned long)to_virt(PFN_PHYS(pfn_to_map)));
|
||||
|
||||
max_mach_ptd = sizeof(void *) *
|
||||
l2_table_offset((unsigned long)to_virt(PFN_PHYS(*max_pfn)));
|
||||
|
||||
/* Check that we are not trying to access Xen region */
|
||||
if(max_mach_ptd > sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START))
|
||||
while(start_address < end_address)
|
||||
{
|
||||
printk("WARNING: mini-os will not use all the memory supplied\n");
|
||||
max_mach_ptd = sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START);
|
||||
*max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
|
||||
}
|
||||
max_mach_ptd += phys_to_machine(to_phys(start_info.pt_base));
|
||||
DEBUG("Max_mach_ptd 0x%lx", max_mach_ptd);
|
||||
|
||||
pt_frame = *start_pfn;
|
||||
/* Should not happen - no empty, mapped pages */
|
||||
if(pt_frame >= pfn_to_map)
|
||||
{
|
||||
printk("ERROR: Not even a single empty, mapped page\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
|
||||
while(mach_ptd < max_mach_ptd)
|
||||
{
|
||||
/* Correct protection needs to be set for the new page table frame */
|
||||
virt_pte = (unsigned long)to_virt(PFN_PHYS(pt_frame));
|
||||
mach_pte = ptd[l2_table_offset(virt_pte)] & ~(PAGE_SIZE-1);
|
||||
mach_pte += sizeof(void *) * l1_table_offset(virt_pte);
|
||||
DEBUG("New page table page: pfn=0x%lx, mfn=0x%lx, virt_pte=0x%lx, "
|
||||
"mach_pte=0x%lx", pt_frame, pfn_to_mfn(pt_frame),
|
||||
virt_pte, mach_pte);
|
||||
tab = (unsigned long *)start_info.pt_base;
|
||||
mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
|
||||
|
||||
#if defined(__x86_64__)
|
||||
offset = l4_table_offset(start_address);
|
||||
/* Need new L3 pt frame */
|
||||
if(!(start_address & L3_MASK))
|
||||
new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
|
||||
|
||||
/* Update the entry */
|
||||
mmu_updates[0].ptr = mach_pte;
|
||||
mmu_updates[0].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT |
|
||||
(L1_PROT & ~_PAGE_RW);
|
||||
if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("PTE for new page table page could not be updated\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
|
||||
/* Pin the page to provide correct protection */
|
||||
pin_request.cmd = MMUEXT_PIN_L1_TABLE;
|
||||
pin_request.arg1.mfn = pfn_to_mfn(pt_frame);
|
||||
if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("ERROR: pinning failed\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
|
||||
/* Now fill the new page table page with entries.
|
||||
Update the page directory as well. */
|
||||
count = 0;
|
||||
mmu_updates[count].ptr = mach_ptd;
|
||||
mmu_updates[count].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT |
|
||||
L2_PROT;
|
||||
page = tab[offset];
|
||||
mfn = pte_to_mfn(page);
|
||||
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
|
||||
offset = l3_table_offset(start_address);
|
||||
/* Need new L2 pt frame */
|
||||
if(!(start_address & L2_MASK))
|
||||
new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
|
||||
|
||||
page = tab[offset];
|
||||
mfn = pte_to_mfn(page);
|
||||
tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
|
||||
#endif
|
||||
offset = l2_table_offset(start_address);
|
||||
/* Need new L1 pt frame */
|
||||
if(!(start_address & L1_MASK))
|
||||
new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
|
||||
|
||||
page = tab[offset];
|
||||
mfn = pte_to_mfn(page);
|
||||
offset = l1_table_offset(start_address);
|
||||
|
||||
mmu_updates[count].ptr = (mfn << PAGE_SHIFT) + sizeof(void *) * offset;
|
||||
mmu_updates[count].val =
|
||||
pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
|
||||
count++;
|
||||
mach_ptd += sizeof(void *);
|
||||
mach_pte = phys_to_machine(PFN_PHYS(pt_frame++));
|
||||
|
||||
for(;count <= L1_PAGETABLE_ENTRIES && pfn_to_map <= *max_pfn; count++)
|
||||
if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
|
||||
{
|
||||
mmu_updates[count].ptr = mach_pte;
|
||||
mmu_updates[count].val =
|
||||
pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
|
||||
if(count == 1) DEBUG("mach_pte 0x%lx", mach_pte);
|
||||
mach_pte += sizeof(void *);
|
||||
if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("PTE could not be updated\n");
|
||||
do_exit();
|
||||
}
|
||||
count = 0;
|
||||
}
|
||||
if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
|
||||
{
|
||||
printk("ERROR: mmu_update failed\n");
|
||||
*(int*)0=0;
|
||||
}
|
||||
(*start_pfn)++;
|
||||
start_address += PAGE_SIZE;
|
||||
}
|
||||
|
||||
*start_pfn = pt_pfn;
|
||||
}
|
||||
|
||||
|
||||
void mem_test(unsigned long *start_add, unsigned long *end_add)
|
||||
{
|
||||
unsigned long mask = 0x10000;
|
||||
unsigned long *pointer;
|
||||
|
||||
for(pointer = start_add; pointer < end_add; pointer++)
|
||||
{
|
||||
if(!(((unsigned long)pointer) & 0xfffff))
|
||||
{
|
||||
printk("Writing to %lx\n", pointer);
|
||||
page_walk((unsigned long)pointer);
|
||||
}
|
||||
*pointer = (unsigned long)pointer & ~mask;
|
||||
}
|
||||
|
||||
for(pointer = start_add; pointer < end_add; pointer++)
|
||||
{
|
||||
if(((unsigned long)pointer & ~mask) != *pointer)
|
||||
printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
|
||||
(unsigned long)pointer,
|
||||
*pointer,
|
||||
((unsigned long)pointer & ~mask));
|
||||
}
|
||||
|
||||
*start_pfn = pt_frame;
|
||||
}
|
||||
|
||||
void init_mm(void)
|
||||
@@ -485,23 +559,21 @@ void init_mm(void)
|
||||
phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
|
||||
|
||||
/* First page follows page table pages and 3 more pages (store page etc) */
|
||||
start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames + 3;
|
||||
start_pfn = PFN_UP(to_phys(start_info.pt_base)) +
|
||||
start_info.nr_pt_frames + 3;
|
||||
max_pfn = start_info.nr_pages;
|
||||
|
||||
|
||||
printk(" start_pfn: %lx\n", start_pfn);
|
||||
printk(" max_pfn: %lx\n", max_pfn);
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
build_pagetable(&start_pfn, &max_pfn);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* now we can initialise the page allocator
|
||||
*/
|
||||
printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
|
||||
(u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn),
|
||||
(u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
|
||||
init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
|
||||
init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
|
||||
printk("MM: done\n");
|
||||
}
|
||||
@@ -70,6 +70,30 @@ DO_ERROR(12, "stack segment", stack_segment)
|
||||
DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
|
||||
DO_ERROR(18, "machine check", machine_check)
|
||||
|
||||
void page_walk(unsigned long virt_address)
|
||||
{
|
||||
unsigned long *tab = (unsigned long *)start_info.pt_base;
|
||||
unsigned long addr = virt_address, page;
|
||||
printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base);
|
||||
|
||||
#if defined(__x86_64__)
|
||||
page = tab[l4_table_offset(addr)];
|
||||
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
|
||||
printk(" L4 = %p (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr));
|
||||
|
||||
page = tab[l3_table_offset(addr)];
|
||||
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
|
||||
printk(" L3 = %p (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr));
|
||||
#endif
|
||||
page = tab[l2_table_offset(addr)];
|
||||
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
|
||||
printk(" L2 = %p (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr));
|
||||
|
||||
page = tab[l1_table_offset(addr)];
|
||||
printk(" L1 = %p (%p) [offset = %lx]\n", page, tab, l1_table_offset(addr));
|
||||
|
||||
}
|
||||
|
||||
void do_page_fault(struct pt_regs *regs, unsigned long error_code,
|
||||
unsigned long addr)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <asm/mtrr.h>
|
||||
#include "mtrr.h"
|
||||
|
||||
static DECLARE_MUTEX(mtrr_sem);
|
||||
|
||||
void generic_get_mtrr(unsigned int reg, unsigned long *base,
|
||||
unsigned int *size, mtrr_type * type)
|
||||
{
|
||||
@@ -63,12 +65,15 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||
int error;
|
||||
dom0_op_t op;
|
||||
|
||||
down(&mtrr_sem);
|
||||
|
||||
op.cmd = DOM0_ADD_MEMTYPE;
|
||||
op.u.add_memtype.mfn = base;
|
||||
op.u.add_memtype.nr_mfns = size;
|
||||
op.u.add_memtype.type = type;
|
||||
error = HYPERVISOR_dom0_op(&op);
|
||||
if (error) {
|
||||
up(&mtrr_sem);
|
||||
BUG_ON(error > 0);
|
||||
return error;
|
||||
}
|
||||
@@ -76,6 +81,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||
if (increment)
|
||||
++usage_table[op.u.add_memtype.reg];
|
||||
|
||||
up(&mtrr_sem);
|
||||
|
||||
return op.u.add_memtype.reg;
|
||||
}
|
||||
|
||||
@@ -104,17 +111,18 @@ mtrr_add(unsigned long base, unsigned long size, unsigned int type,
|
||||
|
||||
int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
int i, max;
|
||||
unsigned i;
|
||||
mtrr_type ltype;
|
||||
unsigned long lbase;
|
||||
unsigned int lsize;
|
||||
int error = -EINVAL;
|
||||
dom0_op_t op;
|
||||
|
||||
max = num_var_ranges;
|
||||
down(&mtrr_sem);
|
||||
|
||||
if (reg < 0) {
|
||||
/* Search for existing MTRR */
|
||||
for (i = 0; i < max; ++i) {
|
||||
for (i = 0; i < num_var_ranges; ++i) {
|
||||
mtrr_if->get(i, &lbase, &lsize, <ype);
|
||||
if (lbase == base && lsize == size) {
|
||||
reg = i;
|
||||
@@ -143,6 +151,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||
}
|
||||
error = reg;
|
||||
out:
|
||||
up(&mtrr_sem);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@ VM_MASK = 0x00020000
|
||||
/* Pseudo-eflags. */
|
||||
NMI_MASK = 0x80000000
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
#define DISABLE_INTERRUPTS cli
|
||||
#define ENABLE_INTERRUPTS sti
|
||||
#else
|
||||
/* Offsets into shared_info_t. */
|
||||
#define evtchn_upcall_pending /* 0 */
|
||||
#define evtchn_upcall_mask 1
|
||||
@@ -86,33 +90,24 @@ NMI_MASK = 0x80000000
|
||||
#define sizeof_vcpu_shift 6
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define preempt_disable(reg) incl TI_preempt_count(reg)
|
||||
#define preempt_enable(reg) decl TI_preempt_count(reg)
|
||||
#define XEN_GET_VCPU_INFO(reg) preempt_disable(%ebp) ; \
|
||||
movl TI_cpu(%ebp),reg ; \
|
||||
shl $sizeof_vcpu_shift,reg ; \
|
||||
addl HYPERVISOR_shared_info,reg
|
||||
#define XEN_PUT_VCPU_INFO(reg) preempt_enable(%ebp)
|
||||
#define XEN_PUT_VCPU_INFO_fixup .byte 0xff,0xff,0xff
|
||||
#define GET_VCPU_INFO movl TI_cpu(%ebp),%esi ; \
|
||||
shl $sizeof_vcpu_shift,%esi ; \
|
||||
addl HYPERVISOR_shared_info,%esi
|
||||
#else
|
||||
#define XEN_GET_VCPU_INFO(reg) movl HYPERVISOR_shared_info,reg
|
||||
#define XEN_PUT_VCPU_INFO(reg)
|
||||
#define XEN_PUT_VCPU_INFO_fixup
|
||||
#define GET_VCPU_INFO movl HYPERVISOR_shared_info,%esi
|
||||
#endif
|
||||
|
||||
#define XEN_LOCKED_BLOCK_EVENTS(reg) movb $1,evtchn_upcall_mask(reg)
|
||||
#define XEN_LOCKED_UNBLOCK_EVENTS(reg) movb $0,evtchn_upcall_mask(reg)
|
||||
#define XEN_BLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
|
||||
XEN_LOCKED_BLOCK_EVENTS(reg) ; \
|
||||
XEN_PUT_VCPU_INFO(reg)
|
||||
#define XEN_UNBLOCK_EVENTS(reg) XEN_GET_VCPU_INFO(reg) ; \
|
||||
XEN_LOCKED_UNBLOCK_EVENTS(reg) ; \
|
||||
XEN_PUT_VCPU_INFO(reg)
|
||||
#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
|
||||
#define __DISABLE_INTERRUPTS movb $1,evtchn_upcall_mask(%esi)
|
||||
#define __ENABLE_INTERRUPTS movb $0,evtchn_upcall_mask(%esi)
|
||||
#define DISABLE_INTERRUPTS GET_VCPU_INFO ; \
|
||||
__DISABLE_INTERRUPTS
|
||||
#define ENABLE_INTERRUPTS GET_VCPU_INFO ; \
|
||||
__ENABLE_INTERRUPTS
|
||||
#define __TEST_PENDING testb $0xFF,evtchn_upcall_pending(%esi)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
#define preempt_stop GET_THREAD_INFO(%ebp) ; \
|
||||
XEN_BLOCK_EVENTS(%esi)
|
||||
#define preempt_stop cli
|
||||
#else
|
||||
#define preempt_stop
|
||||
#define resume_kernel restore_nocheck
|
||||
@@ -159,21 +154,6 @@ NMI_MASK = 0x80000000
|
||||
.previous
|
||||
|
||||
|
||||
#define RESTORE_ALL \
|
||||
RESTORE_REGS \
|
||||
addl $4, %esp; \
|
||||
1: iret; \
|
||||
.section .fixup,"ax"; \
|
||||
2: pushl $0; \
|
||||
pushl $do_iret_error; \
|
||||
jmp error_code; \
|
||||
.previous; \
|
||||
.section __ex_table,"a";\
|
||||
.align 4; \
|
||||
.long 1b,2b; \
|
||||
.previous
|
||||
|
||||
|
||||
ENTRY(ret_from_fork)
|
||||
pushl %eax
|
||||
call schedule_tail
|
||||
@@ -199,7 +179,7 @@ ret_from_intr:
|
||||
testl $(VM_MASK | 2), %eax
|
||||
jz resume_kernel
|
||||
ENTRY(resume_userspace)
|
||||
XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt
|
||||
DISABLE_INTERRUPTS # make sure we don't miss an interrupt
|
||||
# setting need_resched or sigpending
|
||||
# between sampling and the iret
|
||||
movl TI_flags(%ebp), %ecx
|
||||
@@ -210,15 +190,15 @@ ENTRY(resume_userspace)
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
ENTRY(resume_kernel)
|
||||
XEN_BLOCK_EVENTS(%esi)
|
||||
cli
|
||||
cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
|
||||
jnz restore_nocheck
|
||||
need_resched:
|
||||
movl TI_flags(%ebp), %ecx # need_resched set ?
|
||||
testb $_TIF_NEED_RESCHED, %cl
|
||||
jz restore_all
|
||||
testb $0xFF,EVENT_MASK(%esp) # interrupts off (exception path) ?
|
||||
jnz restore_all
|
||||
testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ?
|
||||
jz restore_all
|
||||
call preempt_schedule_irq
|
||||
jmp need_resched
|
||||
#endif
|
||||
@@ -289,7 +269,7 @@ syscall_call:
|
||||
call *sys_call_table(,%eax,4)
|
||||
movl %eax,EAX(%esp) # store the return value
|
||||
syscall_exit:
|
||||
XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt
|
||||
DISABLE_INTERRUPTS # make sure we don't miss an interrupt
|
||||
# setting need_resched or sigpending
|
||||
# between sampling and the iret
|
||||
movl TI_flags(%ebp), %ecx
|
||||
@@ -297,7 +277,7 @@ syscall_exit:
|
||||
jne syscall_exit_work
|
||||
|
||||
restore_all:
|
||||
#if 0 /* XEN */
|
||||
#ifndef CONFIG_XEN
|
||||
movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
|
||||
# Warning: OLDSS(%esp) contains the wrong/random values if we
|
||||
# are returning to the kernel.
|
||||
@@ -307,22 +287,26 @@ restore_all:
|
||||
andl $(VM_MASK | (4 << 8) | 3), %eax
|
||||
cmpl $((4 << 8) | 3), %eax
|
||||
je ldt_ss # returning to user-space with LDT SS
|
||||
#endif /* XEN */
|
||||
restore_nocheck:
|
||||
#else
|
||||
restore_nocheck:
|
||||
testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
|
||||
jnz hypervisor_iret
|
||||
movb EVENT_MASK(%esp), %al
|
||||
notb %al # %al == ~saved_mask
|
||||
XEN_GET_VCPU_INFO(%esi)
|
||||
GET_VCPU_INFO
|
||||
andb evtchn_upcall_mask(%esi),%al
|
||||
andb $1,%al # %al == mask & ~saved_mask
|
||||
jnz restore_all_enable_events # != 0 => reenable event delivery
|
||||
XEN_PUT_VCPU_INFO(%esi)
|
||||
#endif
|
||||
RESTORE_REGS
|
||||
addl $4, %esp
|
||||
1: iret
|
||||
.section .fixup,"ax"
|
||||
iret_exc:
|
||||
#ifndef CONFIG_XEN
|
||||
sti
|
||||
#endif
|
||||
pushl $0 # no error code
|
||||
pushl $do_iret_error
|
||||
jmp error_code
|
||||
@@ -332,13 +316,7 @@ iret_exc:
|
||||
.long 1b,iret_exc
|
||||
.previous
|
||||
|
||||
hypervisor_iret:
|
||||
andl $~NMI_MASK, EFLAGS(%esp)
|
||||
RESTORE_REGS
|
||||
addl $4, %esp
|
||||
jmp hypercall_page + (__HYPERVISOR_iret * 32)
|
||||
|
||||
#if 0 /* XEN */
|
||||
#ifndef CONFIG_XEN
|
||||
ldt_ss:
|
||||
larl OLDSS(%esp), %eax
|
||||
jnz restore_nocheck
|
||||
@@ -363,7 +341,13 @@ ldt_ss:
|
||||
.align 4
|
||||
.long 1b,iret_exc
|
||||
.previous
|
||||
#endif /* XEN */
|
||||
#else
|
||||
hypervisor_iret:
|
||||
andl $~NMI_MASK, EFLAGS(%esp)
|
||||
RESTORE_REGS
|
||||
addl $4, %esp
|
||||
jmp hypercall_page + (__HYPERVISOR_iret * 32)
|
||||
#endif
|
||||
|
||||
# perform work that needs to be done immediately before resumption
|
||||
ALIGN
|
||||
@@ -372,7 +356,7 @@ work_pending:
|
||||
jz work_notifysig
|
||||
work_resched:
|
||||
call schedule
|
||||
XEN_BLOCK_EVENTS(%esi) # make sure we don't miss an interrupt
|
||||
DISABLE_INTERRUPTS # make sure we don't miss an interrupt
|
||||
# setting need_resched or sigpending
|
||||
# between sampling and the iret
|
||||
movl TI_flags(%ebp), %ecx
|
||||
@@ -424,7 +408,7 @@ syscall_trace_entry:
|
||||
syscall_exit_work:
|
||||
testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
|
||||
jz work_pending
|
||||
XEN_UNBLOCK_EVENTS(%esi) # could let do_syscall_trace() call
|
||||
ENABLE_INTERRUPTS # could let do_syscall_trace() call
|
||||
# schedule() instead
|
||||
movl %esp, %eax
|
||||
movl $1, %edx
|
||||
@@ -444,7 +428,7 @@ syscall_badsys:
|
||||
movl $-ENOSYS,EAX(%esp)
|
||||
jmp resume_userspace
|
||||
|
||||
#if 0 /* XEN */
|
||||
#ifndef CONFIG_XEN
|
||||
#define FIXUP_ESPFIX_STACK \
|
||||
movl %esp, %eax; \
|
||||
/* switch to 32bit stack using the pointer on top of 16bit stack */ \
|
||||
@@ -503,7 +487,9 @@ ENTRY(name) \
|
||||
|
||||
/* The include is where all of the SMP etc. interrupts come from */
|
||||
#include "entry_arch.h"
|
||||
#endif /* XEN */
|
||||
#else
|
||||
#define UNWIND_ESPFIX_STACK
|
||||
#endif
|
||||
|
||||
ENTRY(divide_error)
|
||||
pushl $0 # no error code
|
||||
@@ -522,7 +508,7 @@ error_code:
|
||||
pushl %ebx
|
||||
cld
|
||||
pushl %es
|
||||
# UNWIND_ESPFIX_STACK
|
||||
UNWIND_ESPFIX_STACK
|
||||
popl %ecx
|
||||
movl ES(%esp), %edi # get the function address
|
||||
movl ORIG_EAX(%esp), %edx # get the error code
|
||||
@@ -535,6 +521,7 @@ error_code:
|
||||
call *%edi
|
||||
jmp ret_from_exception
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
# A note on the "critical region" in our callback handler.
|
||||
# We want to avoid stacking callback handlers due to events occurring
|
||||
# during handling of the last event. To do this, we keep events disabled
|
||||
@@ -560,15 +547,24 @@ ENTRY(hypervisor_callback)
|
||||
jmp ret_from_intr
|
||||
|
||||
ALIGN
|
||||
restore_all_enable_events:
|
||||
XEN_LOCKED_UNBLOCK_EVENTS(%esi)
|
||||
restore_all_enable_events:
|
||||
__ENABLE_INTERRUPTS
|
||||
scrit: /**** START OF CRITICAL REGION ****/
|
||||
XEN_TEST_PENDING(%esi)
|
||||
__TEST_PENDING
|
||||
jnz 14f # process more events if necessary...
|
||||
XEN_PUT_VCPU_INFO(%esi)
|
||||
RESTORE_ALL
|
||||
14: XEN_LOCKED_BLOCK_EVENTS(%esi)
|
||||
XEN_PUT_VCPU_INFO(%esi)
|
||||
RESTORE_REGS
|
||||
addl $4, %esp
|
||||
1: iret
|
||||
.section .fixup,"ax"
|
||||
2: pushl $0
|
||||
pushl $do_iret_error
|
||||
jmp error_code
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
.align 4
|
||||
.long 1b,2b
|
||||
.previous
|
||||
14: __DISABLE_INTERRUPTS
|
||||
jmp 11b
|
||||
ecrit: /**** END OF CRITICAL REGION ****/
|
||||
# [How we do the fixup]. We want to merge the current stack frame with the
|
||||
@@ -577,14 +573,13 @@ ecrit: /**** END OF CRITICAL REGION ****/
|
||||
# registers are in each frame. We do this quickly using the lookup table
|
||||
# 'critical_fixup_table'. For each byte offset in the critical region, it
|
||||
# provides the number of bytes which have already been popped from the
|
||||
# interrupted stack frame.
|
||||
# interrupted stack frame.
|
||||
critical_region_fixup:
|
||||
addl $critical_fixup_table-scrit,%eax
|
||||
movzbl (%eax),%eax # %eax contains num bytes popped
|
||||
cmpb $0xff,%al # 0xff => vcpu_info critical region
|
||||
jne 15f
|
||||
GET_THREAD_INFO(%ebp)
|
||||
XEN_PUT_VCPU_INFO(%esi) # abort vcpu_info critical region
|
||||
xorl %eax,%eax
|
||||
15: mov %esp,%esi
|
||||
add %eax,%esi # %esi points at end of src region
|
||||
@@ -602,9 +597,8 @@ critical_region_fixup:
|
||||
jmp 11b
|
||||
|
||||
critical_fixup_table:
|
||||
.byte 0xff,0xff,0xff # testb $0xff,(%esi) = XEN_TEST_PENDING
|
||||
.byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING
|
||||
.byte 0xff,0xff # jnz 14f
|
||||
XEN_PUT_VCPU_INFO_fixup
|
||||
.byte 0x00 # pop %ebx
|
||||
.byte 0x04 # pop %ecx
|
||||
.byte 0x08 # pop %edx
|
||||
@@ -617,7 +611,6 @@ critical_fixup_table:
|
||||
.byte 0x24,0x24,0x24 # add $4,%esp
|
||||
.byte 0x28 # iret
|
||||
.byte 0xff,0xff,0xff,0xff # movb $1,1(%esi)
|
||||
XEN_PUT_VCPU_INFO_fixup
|
||||
.byte 0x00,0x00 # jmp 11b
|
||||
|
||||
# Hypervisor uses this for application faults while it executes.
|
||||
@@ -646,6 +639,7 @@ ENTRY(failsafe_callback)
|
||||
.long 3b,8b; \
|
||||
.long 4b,9b; \
|
||||
.previous
|
||||
#endif
|
||||
|
||||
ENTRY(coprocessor_error)
|
||||
pushl $0
|
||||
@@ -660,7 +654,17 @@ ENTRY(simd_coprocessor_error)
|
||||
ENTRY(device_not_available)
|
||||
pushl $-1 # mark this as an int
|
||||
SAVE_ALL
|
||||
#preempt_stop /* This is already an interrupt gate on Xen. */
|
||||
#ifndef CONFIG_XEN
|
||||
movl %cr0, %eax
|
||||
testl $0x4, %eax # EM (math emulation bit)
|
||||
je device_available_emulate
|
||||
pushl $0 # temporary storage for ORIG_EIP
|
||||
call math_emulate
|
||||
addl $4, %esp
|
||||
jmp ret_from_exception
|
||||
device_available_emulate:
|
||||
#endif
|
||||
preempt_stop
|
||||
call math_state_restore
|
||||
jmp ret_from_exception
|
||||
|
||||
@@ -703,16 +707,7 @@ debug_stack_correct:
|
||||
jmp ret_from_exception
|
||||
.previous .text
|
||||
|
||||
ENTRY(nmi)
|
||||
pushl %eax
|
||||
SAVE_ALL
|
||||
xorl %edx,%edx # zero error code
|
||||
movl %esp,%eax # pt_regs pointer
|
||||
call do_nmi
|
||||
orl $NMI_MASK, EFLAGS(%esp)
|
||||
jmp restore_all
|
||||
|
||||
#if 0 /* XEN */
|
||||
#ifndef CONFIG_XEN
|
||||
/*
|
||||
* NMI is doubly nasty. It can happen _while_ we're handling
|
||||
* a debug fault, and the debug fault hasn't yet been able to
|
||||
@@ -783,7 +778,16 @@ nmi_16bit_stack:
|
||||
.align 4
|
||||
.long 1b,iret_exc
|
||||
.previous
|
||||
#endif /* XEN */
|
||||
#else
|
||||
ENTRY(nmi)
|
||||
pushl %eax
|
||||
SAVE_ALL
|
||||
xorl %edx,%edx # zero error code
|
||||
movl %esp,%eax # pt_regs pointer
|
||||
call do_nmi
|
||||
orl $NMI_MASK, EFLAGS(%esp)
|
||||
jmp restore_all
|
||||
#endif
|
||||
|
||||
KPROBE_ENTRY(int3)
|
||||
pushl $-1 # mark this as an int
|
||||
|
||||
@@ -30,8 +30,6 @@ ENTRY(startup_32)
|
||||
/* Set up the stack pointer */
|
||||
movl $(init_thread_union+THREAD_SIZE),%esp
|
||||
|
||||
checkCPUtype:
|
||||
|
||||
/* get vendor info */
|
||||
xorl %eax,%eax # call CPUID with 0 -> return vendor ID
|
||||
cpuid
|
||||
|
||||
@@ -107,9 +107,9 @@ void xen_idle(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
|
||||
if (need_resched()) {
|
||||
if (need_resched())
|
||||
local_irq_enable();
|
||||
} else {
|
||||
else {
|
||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||
smp_mb__after_clear_bit();
|
||||
stop_hz_timer();
|
||||
|
||||
@@ -157,18 +157,26 @@ static int __init __independent_wallclock(char *str)
|
||||
}
|
||||
__setup("independent_wallclock", __independent_wallclock);
|
||||
|
||||
/* Permitted clock jitter, in usecs, beyond which a warning will be printed. */
|
||||
static unsigned long permitted_clock_jitter = 10000UL;
|
||||
static int __init __permitted_clock_jitter(char *str)
|
||||
{
|
||||
permitted_clock_jitter = simple_strtoul(str, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
__setup("permitted_clock_jitter=", __permitted_clock_jitter);
|
||||
|
||||
int tsc_disable __devinitdata = 0;
|
||||
|
||||
static void delay_tsc(unsigned long loops)
|
||||
{
|
||||
unsigned long bclock, now;
|
||||
|
||||
|
||||
rdtscl(bclock);
|
||||
do
|
||||
{
|
||||
do {
|
||||
rep_nop();
|
||||
rdtscl(now);
|
||||
} while ((now-bclock) < loops);
|
||||
} while ((now - bclock) < loops);
|
||||
}
|
||||
|
||||
struct timer_opts timer_tsc = {
|
||||
@@ -187,7 +195,7 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
|
||||
u32 tmp1, tmp2;
|
||||
#endif
|
||||
|
||||
if ( shift < 0 )
|
||||
if (shift < 0)
|
||||
delta >>= -shift;
|
||||
else
|
||||
delta <<= shift;
|
||||
@@ -226,7 +234,7 @@ void init_cpu_khz(void)
|
||||
struct vcpu_time_info *info;
|
||||
info = &HYPERVISOR_shared_info->vcpu_info[0].time;
|
||||
do_div(__cpu_khz, info->tsc_to_system_mul);
|
||||
if ( info->tsc_shift < 0 )
|
||||
if (info->tsc_shift < 0)
|
||||
cpu_khz = __cpu_khz << -info->tsc_shift;
|
||||
else
|
||||
cpu_khz = __cpu_khz >> info->tsc_shift;
|
||||
@@ -284,8 +292,7 @@ static void update_wallclock(void)
|
||||
shadow_tv.tv_sec = s->wc_sec;
|
||||
shadow_tv.tv_nsec = s->wc_nsec;
|
||||
rmb();
|
||||
}
|
||||
while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
|
||||
} while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
|
||||
|
||||
if (!independent_wallclock)
|
||||
__update_wallclock(shadow_tv.tv_sec, shadow_tv.tv_nsec);
|
||||
@@ -312,8 +319,7 @@ static void get_time_values_from_xen(void)
|
||||
dst->tsc_to_nsec_mul = src->tsc_to_system_mul;
|
||||
dst->tsc_shift = src->tsc_shift;
|
||||
rmb();
|
||||
}
|
||||
while ((src->version & 1) | (dst->version ^ src->version));
|
||||
} while ((src->version & 1) | (dst->version ^ src->version));
|
||||
|
||||
dst->tsc_to_usec_mul = dst->tsc_to_nsec_mul / 1000;
|
||||
}
|
||||
@@ -324,8 +330,9 @@ static inline int time_values_up_to_date(int cpu)
|
||||
struct shadow_time_info *dst;
|
||||
|
||||
src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
|
||||
dst = &per_cpu(shadow_time, cpu);
|
||||
dst = &per_cpu(shadow_time, cpu);
|
||||
|
||||
rmb();
|
||||
return (dst->version == src->version);
|
||||
}
|
||||
|
||||
@@ -454,7 +461,7 @@ int do_settimeofday(struct timespec *tv)
|
||||
* overflows. If that were to happen then our shadow time values would
|
||||
* be stale, so we can retry with fresh ones.
|
||||
*/
|
||||
for ( ; ; ) {
|
||||
for (;;) {
|
||||
nsec = tv->tv_nsec - get_nsec_offset(shadow);
|
||||
if (time_values_up_to_date(cpu))
|
||||
break;
|
||||
@@ -552,11 +559,11 @@ unsigned long long monotonic_clock(void)
|
||||
|
||||
do {
|
||||
local_time_version = shadow->version;
|
||||
smp_rmb();
|
||||
barrier();
|
||||
time = shadow->system_timestamp + get_nsec_offset(shadow);
|
||||
if (!time_values_up_to_date(cpu))
|
||||
get_time_values_from_xen();
|
||||
smp_rmb();
|
||||
barrier();
|
||||
} while (local_time_version != shadow->version);
|
||||
|
||||
put_cpu();
|
||||
@@ -614,7 +621,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
get_time_values_from_xen();
|
||||
|
||||
/* Obtain a consistent snapshot of elapsed wallclock cycles. */
|
||||
delta = delta_cpu =
|
||||
delta = delta_cpu =
|
||||
shadow->system_timestamp + get_nsec_offset(shadow);
|
||||
delta -= processed_system_time;
|
||||
delta_cpu -= per_cpu(processed_system_time, cpu);
|
||||
@@ -633,13 +640,13 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
per_cpu(processed_blocked_time, cpu);
|
||||
barrier();
|
||||
} while (sched_time != runstate->state_entry_time);
|
||||
}
|
||||
while (!time_values_up_to_date(cpu));
|
||||
} while (!time_values_up_to_date(cpu));
|
||||
|
||||
if ((unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0))
|
||||
if ((unlikely(delta < -(s64)permitted_clock_jitter) ||
|
||||
unlikely(delta_cpu < -(s64)permitted_clock_jitter))
|
||||
&& printk_ratelimit()) {
|
||||
printk("Timer ISR/%d: Time went backwards: "
|
||||
"delta=%lld cpu_delta=%lld shadow=%lld "
|
||||
"delta=%lld delta_cpu=%lld shadow=%lld "
|
||||
"off=%lld processed=%lld cpu_processed=%lld\n",
|
||||
cpu, delta, delta_cpu, shadow->system_timestamp,
|
||||
(s64)get_nsec_offset(shadow),
|
||||
@@ -669,8 +676,10 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* HACK: Passing NULL to account_steal_time()
|
||||
* ensures that the ticks are accounted as stolen.
|
||||
*/
|
||||
if (stolen > 0) {
|
||||
if ((stolen > 0) && (delta_cpu > 0)) {
|
||||
delta_cpu -= stolen;
|
||||
if (unlikely(delta_cpu < 0))
|
||||
stolen += delta_cpu; /* clamp local-time progress */
|
||||
do_div(stolen, NS_PER_TICK);
|
||||
per_cpu(processed_stolen_time, cpu) += stolen * NS_PER_TICK;
|
||||
per_cpu(processed_system_time, cpu) += stolen * NS_PER_TICK;
|
||||
@@ -682,8 +691,10 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
* HACK: Passing idle_task to account_steal_time()
|
||||
* ensures that the ticks are accounted as idle/wait.
|
||||
*/
|
||||
if (blocked > 0) {
|
||||
if ((blocked > 0) && (delta_cpu > 0)) {
|
||||
delta_cpu -= blocked;
|
||||
if (unlikely(delta_cpu < 0))
|
||||
blocked += delta_cpu; /* clamp local-time progress */
|
||||
do_div(blocked, NS_PER_TICK);
|
||||
per_cpu(processed_blocked_time, cpu) += blocked * NS_PER_TICK;
|
||||
per_cpu(processed_system_time, cpu) += blocked * NS_PER_TICK;
|
||||
@@ -938,7 +949,7 @@ void __init time_init(void)
|
||||
}
|
||||
|
||||
/* Convert jiffies to system time. */
|
||||
static inline u64 jiffies_to_st(unsigned long j)
|
||||
u64 jiffies_to_st(unsigned long j)
|
||||
{
|
||||
unsigned long seq;
|
||||
long delta;
|
||||
@@ -949,13 +960,14 @@ static inline u64 jiffies_to_st(unsigned long j)
|
||||
delta = j - jiffies;
|
||||
/* NB. The next check can trigger in some wrap-around cases,
|
||||
* but that's ok: we'll just end up with a shorter timeout. */
|
||||
if (delta < 1)
|
||||
if (delta < 1)
|
||||
delta = 1;
|
||||
st = processed_system_time + (delta * (u64)NS_PER_TICK);
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
|
||||
return st;
|
||||
}
|
||||
EXPORT_SYMBOL(jiffies_to_st);
|
||||
|
||||
/*
|
||||
* stop_hz_timer / start_hz_timer - enter/exit 'tickless mode' on an idle cpu
|
||||
@@ -965,7 +977,7 @@ void stop_hz_timer(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
unsigned long j;
|
||||
|
||||
|
||||
/* We must do this /before/ checking rcu_pending(). */
|
||||
cpu_set(cpu, nohz_cpu_mask);
|
||||
smp_mb();
|
||||
@@ -1012,7 +1024,7 @@ void local_setup_timer(unsigned int cpu)
|
||||
do {
|
||||
seq = read_seqbegin(&xtime_lock);
|
||||
/* Use cpu0 timestamp: cpu's shadow is not initialised yet. */
|
||||
per_cpu(processed_system_time, cpu) =
|
||||
per_cpu(processed_system_time, cpu) =
|
||||
per_cpu(shadow_time, 0).system_timestamp;
|
||||
init_missing_ticks_accounting(cpu);
|
||||
} while (read_seqretry(&xtime_lock, seq));
|
||||
@@ -1041,13 +1053,31 @@ void local_teardown_timer(unsigned int cpu)
|
||||
* now however.
|
||||
*/
|
||||
static ctl_table xen_subtable[] = {
|
||||
{1, "independent_wallclock", &independent_wallclock,
|
||||
sizeof(independent_wallclock), 0644, NULL, proc_dointvec},
|
||||
{0}
|
||||
{
|
||||
.ctl_name = 1,
|
||||
.procname = "independent_wallclock",
|
||||
.data = &independent_wallclock,
|
||||
.maxlen = sizeof(independent_wallclock),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{
|
||||
.ctl_name = 2,
|
||||
.procname = "permitted_clock_jitter",
|
||||
.data = &permitted_clock_jitter,
|
||||
.maxlen = sizeof(permitted_clock_jitter),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_doulongvec_minmax
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
static ctl_table xen_table[] = {
|
||||
{123, "xen", NULL, 0, 0555, xen_subtable},
|
||||
{0}
|
||||
{
|
||||
.ctl_name = 123,
|
||||
.procname = "xen",
|
||||
.mode = 0555,
|
||||
.child = xen_subtable},
|
||||
{ 0 }
|
||||
};
|
||||
static int __init xen_sysctl_init(void)
|
||||
{
|
||||
|
||||
@@ -201,56 +201,6 @@ void xen_pgd_unpin(unsigned long ptr)
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
void xen_pte_pin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_PIN_L1_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
void xen_pte_unpin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_UNPIN_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
void xen_pud_pin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_PIN_L3_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
void xen_pud_unpin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_UNPIN_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
void xen_pmd_pin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_PIN_L2_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
|
||||
void xen_pmd_unpin(unsigned long ptr)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
op.cmd = MMUEXT_UNPIN_TABLE;
|
||||
op.arg1.mfn = pfn_to_mfn(ptr >> PAGE_SHIFT);
|
||||
BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
|
||||
}
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
void xen_set_ldt(unsigned long ptr, unsigned long len)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
|
||||
@@ -556,10 +556,15 @@ void __init paging_init(void)
|
||||
|
||||
kmap_init();
|
||||
|
||||
/* Switch to the real shared_info page, and clear the dummy page. */
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
if (!xen_feature(XENFEAT_auto_translated_physmap) ||
|
||||
xen_start_info->shared_info >= xen_start_info->nr_pages) {
|
||||
/* Switch to the real shared_info page, and clear the
|
||||
* dummy page. */
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info =
|
||||
(shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
}
|
||||
|
||||
/* Setup mapping of lower 1st MB */
|
||||
for (i = 0; i < NR_FIX_ISAMAPS; i++)
|
||||
|
||||
@@ -222,7 +222,7 @@ config X86_LOCAL_APIC
|
||||
|
||||
config MTRR
|
||||
bool "MTRR (Memory Type Range Register) support"
|
||||
depends on !X86_64_XEN
|
||||
depends on !XEN_UNPRIVILEGED_GUEST
|
||||
---help---
|
||||
On Intel P6 family processors (Pentium Pro, Pentium II and later)
|
||||
the Memory Type Range Registers (MTRRs) may be used to control
|
||||
|
||||
@@ -124,9 +124,9 @@ void xen_idle(void)
|
||||
{
|
||||
local_irq_disable();
|
||||
|
||||
if (need_resched()) {
|
||||
if (need_resched())
|
||||
local_irq_enable();
|
||||
} else {
|
||||
else {
|
||||
clear_thread_flag(TIF_POLLING_NRFLAG);
|
||||
smp_mb__after_clear_bit();
|
||||
stop_hz_timer();
|
||||
|
||||
@@ -664,6 +664,13 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
setup_xen_features();
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap) &&
|
||||
xen_start_info->shared_info < xen_start_info->nr_pages) {
|
||||
HYPERVISOR_shared_info =
|
||||
(shared_info_t *)__va(xen_start_info->shared_info);
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
}
|
||||
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_writable_pagetables);
|
||||
|
||||
|
||||
@@ -244,7 +244,6 @@ static void set_pte_phys(unsigned long vaddr,
|
||||
if (pud_none(*pud)) {
|
||||
pmd = (pmd_t *) spp_getpage();
|
||||
make_page_readonly(pmd, XENFEAT_writable_page_tables);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pmd != pmd_offset(pud, 0)) {
|
||||
printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
|
||||
@@ -255,7 +254,6 @@ static void set_pte_phys(unsigned long vaddr,
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) spp_getpage();
|
||||
make_page_readonly(pte, XENFEAT_writable_page_tables);
|
||||
xen_pte_pin(__pa(pte));
|
||||
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pte != pte_offset_kernel(pmd, 0)) {
|
||||
printk("PAGETABLE BUG #02!\n");
|
||||
@@ -297,7 +295,6 @@ static void set_pte_phys_ma(unsigned long vaddr,
|
||||
|
||||
pmd = (pmd_t *) spp_getpage();
|
||||
make_page_readonly(pmd, XENFEAT_writable_page_tables);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
|
||||
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
|
||||
|
||||
@@ -311,7 +308,6 @@ static void set_pte_phys_ma(unsigned long vaddr,
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) spp_getpage();
|
||||
make_page_readonly(pte, XENFEAT_writable_page_tables);
|
||||
xen_pte_pin(__pa(pte));
|
||||
|
||||
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pte != pte_offset_kernel(pmd, 0)) {
|
||||
@@ -461,7 +457,6 @@ phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
|
||||
}
|
||||
pte = pte_save;
|
||||
early_make_page_readonly(pte, XENFEAT_writable_page_tables);
|
||||
xen_pte_pin(pte_phys);
|
||||
set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
|
||||
}
|
||||
}
|
||||
@@ -500,7 +495,6 @@ static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned
|
||||
|
||||
pmd = alloc_static_page(&pmd_phys);
|
||||
early_make_page_readonly(pmd, XENFEAT_writable_page_tables);
|
||||
xen_pmd_pin(pmd_phys);
|
||||
spin_lock(&init_mm.page_table_lock);
|
||||
set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
|
||||
phys_pmd_init(pmd, paddr, end);
|
||||
@@ -545,9 +539,6 @@ void __init xen_init_pt(void)
|
||||
|
||||
xen_pgd_pin(__pa_symbol(init_level4_pgt));
|
||||
xen_pgd_pin(__pa_symbol(init_level4_user_pgt));
|
||||
xen_pud_pin(__pa_symbol(level3_kernel_pgt));
|
||||
xen_pud_pin(__pa_symbol(level3_user_pgt));
|
||||
xen_pmd_pin(__pa_symbol(level2_kernel_pgt));
|
||||
|
||||
set_pgd((pgd_t *)(init_level4_user_pgt + 511),
|
||||
mk_kernel_pgd(__pa_symbol(level3_user_pgt)));
|
||||
@@ -581,7 +572,6 @@ void __init extend_init_mapping(void)
|
||||
pte_page = alloc_static_page(&phys);
|
||||
early_make_page_readonly(
|
||||
pte_page, XENFEAT_writable_page_tables);
|
||||
xen_pte_pin(phys);
|
||||
set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
|
||||
} else {
|
||||
addr = page[pmd_index(va)];
|
||||
@@ -662,7 +652,6 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end)
|
||||
pud = alloc_static_page(&pud_phys);
|
||||
early_make_page_readonly(pud, XENFEAT_writable_page_tables);
|
||||
}
|
||||
xen_pud_pin(pud_phys);
|
||||
next = start + PGDIR_SIZE;
|
||||
if (next > end)
|
||||
next = end;
|
||||
@@ -757,10 +746,16 @@ void __init paging_init(void)
|
||||
free_area_init_node(0, NODE_DATA(0), zones,
|
||||
__pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
|
||||
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
if (!xen_feature(XENFEAT_auto_translated_physmap) ||
|
||||
xen_start_info->shared_info >= xen_start_info->nr_pages) {
|
||||
/* Switch to the real shared_info page, and clear the
|
||||
* dummy page. */
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info =
|
||||
(shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
}
|
||||
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
init_mm.context.pinned = 1;
|
||||
|
||||
/* Setup mapping of lower 1st MB */
|
||||
@@ -937,7 +932,6 @@ void free_initmem(void)
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
|
||||
xen_pte_unpin(__pa(addr));
|
||||
make_page_writable(
|
||||
__va(__pa(addr)), XENFEAT_writable_page_tables);
|
||||
/*
|
||||
|
||||
@@ -30,12 +30,14 @@ config XEN_UNPRIVILEGED_GUEST
|
||||
default !XEN_PRIVILEGED_GUEST
|
||||
|
||||
config XEN_PCIDEV_BACKEND
|
||||
bool "PCI device backend driver"
|
||||
select PCI
|
||||
default y if XEN_PRIVILEGED_GUEST
|
||||
tristate "PCI device backend driver"
|
||||
depends PCI
|
||||
default XEN_PRIVILEGED_GUEST
|
||||
help
|
||||
The PCI device backend driver allows the kernel to export arbitrary
|
||||
PCI devices to other guests.
|
||||
PCI devices to other guests. If you select this to be a module, you
|
||||
will need to make sure no other driver has bound to the device(s)
|
||||
you want to make visible to other guests.
|
||||
|
||||
choice
|
||||
prompt "PCI Backend Mode"
|
||||
|
||||
@@ -468,6 +468,7 @@ static int __init balloon_init(void)
|
||||
return -1;
|
||||
|
||||
current_pages = min(xen_start_info->nr_pages, max_pfn);
|
||||
totalram_pages = current_pages;
|
||||
target_pages = current_pages;
|
||||
balloon_low = 0;
|
||||
balloon_high = 0;
|
||||
@@ -547,6 +548,7 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
|
||||
&init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL);
|
||||
BUG_ON(ret);
|
||||
current_pages -= 1UL << order;
|
||||
totalram_pages = current_pages;
|
||||
balloon_unlock(flags);
|
||||
|
||||
schedule_work(&balloon_worker);
|
||||
|
||||
@@ -95,21 +95,17 @@ static int blkfront_probe(struct xenbus_device *dev,
|
||||
xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->xbdev = dev;
|
||||
info->vdevice = vdevice;
|
||||
info->connected = BLKIF_STATE_DISCONNECTED;
|
||||
info->mi = NULL;
|
||||
info->gd = NULL;
|
||||
INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
|
||||
|
||||
info->shadow_free = 0;
|
||||
memset(info->shadow, 0, sizeof(info->shadow));
|
||||
for (i = 0; i < BLK_RING_SIZE; i++)
|
||||
info->shadow[i].req.id = i+1;
|
||||
info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
|
||||
|
||||
info->users = 0;
|
||||
|
||||
/* Front end dir is a number, which is used as the id. */
|
||||
info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
|
||||
dev->data = info;
|
||||
@@ -182,9 +178,8 @@ again:
|
||||
}
|
||||
|
||||
err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
|
||||
if (err) {
|
||||
if (err)
|
||||
goto abort_transaction;
|
||||
}
|
||||
|
||||
err = xenbus_transaction_end(xbt, 0);
|
||||
if (err) {
|
||||
@@ -295,17 +290,17 @@ static void backend_changed(struct xenbus_device *dev,
|
||||
/* ** Connection ** */
|
||||
|
||||
|
||||
/*
|
||||
** Invoked when the backend is finally 'ready' (and has told produced
|
||||
** the details about the physical device - #sectors, size, etc).
|
||||
*/
|
||||
/*
|
||||
* Invoked when the backend is finally 'ready' (and has told produced
|
||||
* the details about the physical device - #sectors, size, etc).
|
||||
*/
|
||||
static void connect(struct blkfront_info *info)
|
||||
{
|
||||
unsigned long sectors, sector_size;
|
||||
unsigned int binfo;
|
||||
int err;
|
||||
|
||||
if( (info->connected == BLKIF_STATE_CONNECTED) ||
|
||||
if ((info->connected == BLKIF_STATE_CONNECTED) ||
|
||||
(info->connected == BLKIF_STATE_SUSPENDED) )
|
||||
return;
|
||||
|
||||
@@ -330,7 +325,7 @@ static void connect(struct blkfront_info *info)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
|
||||
/* Kick pending requests. */
|
||||
spin_lock_irq(&blkif_io_lock);
|
||||
@@ -353,11 +348,7 @@ static void blkfront_closing(struct xenbus_device *dev)
|
||||
|
||||
DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
|
||||
|
||||
if (info->mi) {
|
||||
DPRINTK("Calling xlvbd_del\n");
|
||||
xlvbd_del(info);
|
||||
info->mi = NULL;
|
||||
}
|
||||
xlvbd_del(info);
|
||||
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
}
|
||||
@@ -463,8 +454,7 @@ int blkif_ioctl(struct inode *inode, struct file *filep,
|
||||
DPRINTK_IOCTL("command: 0x%x, argument: 0x%lx, dev: 0x%04x\n",
|
||||
command, (long)argument, inode->i_rdev);
|
||||
|
||||
switch ( command )
|
||||
{
|
||||
switch (command) {
|
||||
case HDIO_GETGEO:
|
||||
/* return ENOSYS to use defaults */
|
||||
return -ENOSYS;
|
||||
@@ -490,7 +480,7 @@ int blkif_ioctl(struct inode *inode, struct file *filep,
|
||||
* blkif_queue_request
|
||||
*
|
||||
* request block io
|
||||
*
|
||||
*
|
||||
* id: for guest use only.
|
||||
* operation: BLKIF_OP_{READ,WRITE,PROBE}
|
||||
* buffer: buffer to read/write into. this should be a
|
||||
@@ -557,7 +547,7 @@ static int blkif_queue_request(struct request *req)
|
||||
ring_req->seg[ring_req->nr_segments] =
|
||||
(struct blkif_request_segment) {
|
||||
.gref = ref,
|
||||
.first_sect = fsect,
|
||||
.first_sect = fsect,
|
||||
.last_sect = lsect };
|
||||
|
||||
ring_req->nr_segments++;
|
||||
@@ -679,9 +669,8 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
|
||||
RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do);
|
||||
if (more_to_do)
|
||||
goto again;
|
||||
} else {
|
||||
} else
|
||||
info->ring.sring->rsp_event = i + 1;
|
||||
}
|
||||
|
||||
kick_pending_request_queues(info);
|
||||
|
||||
@@ -694,8 +683,8 @@ static void blkif_free(struct blkfront_info *info, int suspend)
|
||||
{
|
||||
/* Prevent new requests being issued until we fix things up. */
|
||||
spin_lock_irq(&blkif_io_lock);
|
||||
info->connected = suspend ?
|
||||
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
|
||||
info->connected = suspend ?
|
||||
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
|
||||
spin_unlock_irq(&blkif_io_lock);
|
||||
|
||||
/* Free resources associated with old device channel. */
|
||||
@@ -706,7 +695,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
|
||||
info->ring.sring = NULL;
|
||||
}
|
||||
if (info->irq)
|
||||
unbind_from_irqhandler(info->irq, info);
|
||||
unbind_from_irqhandler(info->irq, info);
|
||||
info->evtchn = info->irq = 0;
|
||||
|
||||
}
|
||||
@@ -767,11 +756,11 @@ static void blkif_recover(struct blkfront_info *info)
|
||||
|
||||
kfree(copy);
|
||||
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
|
||||
/* Now safe for us to use the shared ring */
|
||||
spin_lock_irq(&blkif_io_lock);
|
||||
info->connected = BLKIF_STATE_CONNECTED;
|
||||
info->connected = BLKIF_STATE_CONNECTED;
|
||||
spin_unlock_irq(&blkif_io_lock);
|
||||
|
||||
/* Send off requeued requests */
|
||||
|
||||
@@ -55,24 +55,24 @@
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
#define IPRINTK(fmt, args...) \
|
||||
printk(KERN_INFO "xen_blk: " fmt, ##args)
|
||||
#else
|
||||
#define IPRINTK(fmt, args...) ((void)0)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 1
|
||||
#define WPRINTK(fmt, args...) \
|
||||
printk(KERN_WARNING "xen_blk: " fmt, ##args)
|
||||
#else
|
||||
#define WPRINTK(fmt, args...) ((void)0)
|
||||
#endif
|
||||
|
||||
#define DPRINTK(_f, _a...) pr_debug ( _f , ## _a )
|
||||
|
||||
#define DPRINTK(_f, _a...) pr_debug(_f, ## _a)
|
||||
|
||||
#if 0
|
||||
#define DPRINTK_IOCTL(_f, _a...) printk ( KERN_ALERT _f , ## _a )
|
||||
#define DPRINTK_IOCTL(_f, _a...) printk(KERN_ALERT _f, ## _a)
|
||||
#else
|
||||
#define DPRINTK_IOCTL(_f, _a...) ((void)0)
|
||||
#endif
|
||||
@@ -139,7 +139,7 @@ extern int blkif_ioctl(struct inode *inode, struct file *filep,
|
||||
unsigned command, unsigned long argument);
|
||||
extern int blkif_check(dev_t dev);
|
||||
extern int blkif_revalidate(dev_t dev);
|
||||
extern void do_blkif_request (request_queue_t *rq);
|
||||
extern void do_blkif_request (request_queue_t *rq);
|
||||
|
||||
/* Virtual block-device subsystem. */
|
||||
/* Note that xlvbd_add doesn't call add_disk for you: you're expected
|
||||
|
||||
@@ -216,6 +216,10 @@ xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
|
||||
int nr_minors = 1;
|
||||
int err = -ENODEV;
|
||||
|
||||
BUG_ON(info->gd != NULL);
|
||||
BUG_ON(info->mi != NULL);
|
||||
BUG_ON(info->rq != NULL);
|
||||
|
||||
mi = xlbd_get_major_info(vdevice);
|
||||
if (mi == NULL)
|
||||
goto out;
|
||||
@@ -268,6 +272,7 @@ xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
|
||||
out:
|
||||
if (mi)
|
||||
xlbd_put_major_info(mi);
|
||||
info->mi = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -294,22 +299,20 @@ xlvbd_add(blkif_sector_t capacity, int vdevice, u16 vdisk_info,
|
||||
void
|
||||
xlvbd_del(struct blkfront_info *info)
|
||||
{
|
||||
struct block_device *bd;
|
||||
|
||||
bd = bdget(info->dev);
|
||||
if (bd == NULL)
|
||||
return;
|
||||
|
||||
if (info->gd == NULL)
|
||||
if (info->mi == NULL)
|
||||
return;
|
||||
|
||||
BUG_ON(info->gd == NULL);
|
||||
del_gendisk(info->gd);
|
||||
put_disk(info->gd);
|
||||
info->gd = NULL;
|
||||
|
||||
xlbd_put_major_info(info->mi);
|
||||
info->mi = NULL;
|
||||
blk_cleanup_queue(info->rq);
|
||||
|
||||
bdput(bd);
|
||||
BUG_ON(info->rq == NULL);
|
||||
blk_cleanup_queue(info->rq);
|
||||
info->rq = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -85,8 +85,7 @@ static int __init xencons_setup(char *str)
|
||||
else if (!strncmp(str, "off", 3))
|
||||
xc_mode = XC_OFF;
|
||||
|
||||
switch ( xc_mode )
|
||||
{
|
||||
switch (xc_mode) {
|
||||
case XC_SERIAL:
|
||||
n = simple_strtol(str+4, &q, 10);
|
||||
if (q > (str + 4))
|
||||
@@ -227,7 +226,7 @@ asmlinkage int xprintk(const char *fmt, ...)
|
||||
va_list args;
|
||||
int printk_len;
|
||||
static char printk_buf[1024];
|
||||
|
||||
|
||||
/* Emit the output into the temporary buffer */
|
||||
va_start(args, fmt);
|
||||
printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
|
||||
@@ -485,7 +484,7 @@ static void xencons_flush_chars(struct tty_struct *tty)
|
||||
|
||||
spin_lock_irqsave(&xencons_lock, flags);
|
||||
__xencons_tx_flush();
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
}
|
||||
|
||||
static void xencons_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
@@ -495,17 +494,15 @@ static void xencons_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
if (TTY_INDEX(tty) != 0)
|
||||
return;
|
||||
|
||||
while (DRV(tty->driver)->chars_in_buffer(tty))
|
||||
{
|
||||
while (DRV(tty->driver)->chars_in_buffer(tty)) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(1);
|
||||
if (signal_pending(current))
|
||||
break;
|
||||
if ( (timeout != 0) &&
|
||||
time_after(jiffies, orig_jiffies + timeout) )
|
||||
if (timeout && time_after(jiffies, orig_jiffies + timeout))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
set_current_state(TASK_RUNNING);
|
||||
}
|
||||
|
||||
@@ -521,7 +518,7 @@ static int xencons_open(struct tty_struct *tty, struct file *filp)
|
||||
if (xencons_tty == NULL)
|
||||
xencons_tty = tty;
|
||||
__xencons_tx_flush();
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -543,7 +540,7 @@ static void xencons_close(struct tty_struct *tty, struct file *filp)
|
||||
tty->closing = 0;
|
||||
spin_lock_irqsave(&xencons_lock, flags);
|
||||
xencons_tty = NULL;
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
spin_unlock_irqrestore(&xencons_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,7 +571,7 @@ static int __init xencons_init(void)
|
||||
|
||||
xencons_ring_init();
|
||||
|
||||
xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
|
||||
xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
|
||||
1 : MAX_NR_CONSOLES);
|
||||
if (xencons_driver == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -584,15 +581,14 @@ static int __init xencons_init(void)
|
||||
DRV(xencons_driver)->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
DRV(xencons_driver)->subtype = SERIAL_TYPE_NORMAL;
|
||||
DRV(xencons_driver)->init_termios = tty_std_termios;
|
||||
DRV(xencons_driver)->flags =
|
||||
DRV(xencons_driver)->flags =
|
||||
TTY_DRIVER_REAL_RAW |
|
||||
TTY_DRIVER_RESET_TERMIOS |
|
||||
TTY_DRIVER_NO_DEVFS;
|
||||
DRV(xencons_driver)->termios = xencons_termios;
|
||||
DRV(xencons_driver)->termios_locked = xencons_termios_locked;
|
||||
|
||||
if (xc_mode == XC_SERIAL)
|
||||
{
|
||||
if (xc_mode == XC_SERIAL) {
|
||||
DRV(xencons_driver)->name = "ttyS";
|
||||
DRV(xencons_driver)->minor_start = 64 + xc_num;
|
||||
DRV(xencons_driver)->name_base = 0 + xc_num;
|
||||
@@ -630,7 +626,7 @@ static int __init xencons_init(void)
|
||||
printk("Xen virtual console successfully installed as %s%d\n",
|
||||
DRV(xencons_driver)->name,
|
||||
DRV(xencons_driver)->name_base );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ int xencons_ring_send(const char *data, unsigned len)
|
||||
notify_daemon();
|
||||
|
||||
return sent;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
|
||||
|
||||
/* IRQ <-> IPI mapping. */
|
||||
#ifndef NR_IPIS
|
||||
#define NR_IPIS 1
|
||||
#define NR_IPIS 1
|
||||
#endif
|
||||
DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
|
||||
|
||||
@@ -209,7 +209,7 @@ static int bind_evtchn_to_irq(unsigned int evtchn)
|
||||
irq_bindcount[irq]++;
|
||||
|
||||
spin_unlock(&irq_mapping_update_lock);
|
||||
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
|
||||
irq_bindcount[irq]++;
|
||||
|
||||
spin_unlock(&irq_mapping_update_lock);
|
||||
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
@@ -535,9 +535,9 @@ static unsigned int startup_pirq(unsigned int irq)
|
||||
/* NB. We are happy to share unless we are probing. */
|
||||
op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
|
||||
if (HYPERVISOR_event_channel_op(&op) != 0) {
|
||||
if ( !probing_irq(irq) )
|
||||
printk(KERN_INFO "Failed to obtain physical "
|
||||
"IRQ %d\n", irq);
|
||||
if (!probing_irq(irq))
|
||||
printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
|
||||
irq);
|
||||
return 0;
|
||||
}
|
||||
evtchn = op.u.bind_pirq.port;
|
||||
@@ -669,7 +669,7 @@ void unmask_evtchn(int port)
|
||||
* like a real IO-APIC we 'lose the interrupt edge' if the channel is
|
||||
* masked.
|
||||
*/
|
||||
if (synch_test_bit(port, &s->evtchn_pending[0]) &&
|
||||
if (synch_test_bit(port, &s->evtchn_pending[0]) &&
|
||||
!synch_test_and_set_bit(port / BITS_PER_LONG,
|
||||
&vcpu_info->evtchn_pending_sel)) {
|
||||
vcpu_info->evtchn_upcall_pending = 1;
|
||||
@@ -722,7 +722,7 @@ void irq_resume(void)
|
||||
op.u.bind_virq.vcpu = 0;
|
||||
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
|
||||
evtchn = op.u.bind_virq.port;
|
||||
|
||||
|
||||
/* Record the new mapping. */
|
||||
evtchn_to_irq[evtchn] = irq;
|
||||
irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
|
||||
@@ -744,7 +744,7 @@ void irq_resume(void)
|
||||
op.u.bind_ipi.vcpu = 0;
|
||||
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
|
||||
evtchn = op.u.bind_ipi.port;
|
||||
|
||||
|
||||
/* Record the new mapping. */
|
||||
evtchn_to_irq[evtchn] = irq;
|
||||
irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
|
||||
@@ -794,8 +794,7 @@ void __init init_IRQ(void)
|
||||
}
|
||||
|
||||
/* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
|
||||
for (i = 0; i < NR_PIRQS; i++)
|
||||
{
|
||||
for (i = 0; i < NR_PIRQS; i++) {
|
||||
irq_bindcount[pirq_to_irq(i)] = 1;
|
||||
|
||||
#ifdef RTC_IRQ
|
||||
|
||||
@@ -19,7 +19,7 @@ void setup_xen_features(void)
|
||||
xen_feature_info_t fi;
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<XENFEAT_NR_SUBMAPS; i++) {
|
||||
for (i = 0; i < XENFEAT_NR_SUBMAPS; i++) {
|
||||
fi.submap_idx = i;
|
||||
if (HYPERVISOR_xen_version(XENVER_get_features, &fi) < 0)
|
||||
break;
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <asm/fixmap.h>
|
||||
@@ -40,7 +42,7 @@
|
||||
|
||||
#if 1
|
||||
#define ASSERT(_p) \
|
||||
if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
|
||||
if (!(_p)) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \
|
||||
#_p , __LINE__, __FILE__); *(int*)0=0; }
|
||||
#else
|
||||
#define ASSERT(_p) ((void)0)
|
||||
@@ -77,7 +79,7 @@ static int gnttab_free_count;
|
||||
static grant_ref_t gnttab_free_head;
|
||||
static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static grant_entry_t *shared;
|
||||
static grant_entry_t *shared = NULL;
|
||||
|
||||
static struct gnttab_free_callback *gnttab_free_callback_list = NULL;
|
||||
|
||||
@@ -152,7 +154,7 @@ int
|
||||
gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
|
||||
{
|
||||
int ref;
|
||||
|
||||
|
||||
if (unlikely((ref = get_free_entry()) == -1))
|
||||
return -ENOSPC;
|
||||
|
||||
@@ -192,13 +194,12 @@ gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
|
||||
|
||||
nflags = shared[ref].flags;
|
||||
do {
|
||||
if ( (flags = nflags) & (GTF_reading|GTF_writing) ) {
|
||||
if ((flags = nflags) & (GTF_reading|GTF_writing)) {
|
||||
printk(KERN_ALERT "WARNING: g.e. still in use!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
|
||||
flags);
|
||||
} while ((nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) !=
|
||||
flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -211,8 +212,7 @@ gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
|
||||
if (page != 0) {
|
||||
free_page(page);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* XXX This needs to be fixed so that the ref and page are
|
||||
placed on a list to be freed up later. */
|
||||
printk(KERN_WARNING
|
||||
@@ -253,7 +253,7 @@ gnttab_end_foreign_transfer_ref(grant_ref_t ref)
|
||||
* reference and return failure (== 0).
|
||||
*/
|
||||
while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
|
||||
if ( synch_cmpxchg(&shared[ref].flags, flags, 0) == flags )
|
||||
if (synch_cmpxchg(&shared[ref].flags, flags, 0) == flags)
|
||||
return 0;
|
||||
cpu_relax();
|
||||
}
|
||||
@@ -356,12 +356,35 @@ gnttab_request_free_callback(struct gnttab_free_callback *callback,
|
||||
spin_unlock_irqrestore(&gnttab_list_lock, flags);
|
||||
}
|
||||
|
||||
#ifndef __ia64__
|
||||
static int map_pte_fn(pte_t *pte, struct page *pte_page,
|
||||
unsigned long addr, void *data)
|
||||
{
|
||||
unsigned long **frames = (unsigned long **)data;
|
||||
|
||||
set_pte_at(&init_mm, addr, pte, pfn_pte_ma((*frames)[0], PAGE_KERNEL));
|
||||
(*frames)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unmap_pte_fn(pte_t *pte, struct page *pte_page,
|
||||
unsigned long addr, void *data)
|
||||
{
|
||||
|
||||
set_pte_at(&init_mm, addr, pte, __pte(0));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
gnttab_resume(void)
|
||||
{
|
||||
gnttab_setup_table_t setup;
|
||||
unsigned long frames[NR_GRANT_FRAMES];
|
||||
int i;
|
||||
unsigned long frames[NR_GRANT_FRAMES];
|
||||
#ifndef __ia64__
|
||||
void *pframes = frames;
|
||||
struct vm_struct *area;
|
||||
#endif
|
||||
|
||||
setup.dom = DOMID_SELF;
|
||||
setup.nr_frames = NR_GRANT_FRAMES;
|
||||
@@ -370,12 +393,18 @@ gnttab_resume(void)
|
||||
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
|
||||
BUG_ON(setup.status != 0);
|
||||
|
||||
#ifdef __ia64__
|
||||
#ifndef __ia64__
|
||||
if (shared == NULL) {
|
||||
area = get_vm_area(PAGE_SIZE * NR_GRANT_FRAMES, VM_IOREMAP);
|
||||
BUG_ON(area == NULL);
|
||||
shared = area->addr;
|
||||
}
|
||||
BUG_ON(generic_page_range(&init_mm, (unsigned long)shared,
|
||||
PAGE_SIZE * NR_GRANT_FRAMES,
|
||||
map_pte_fn, &pframes));
|
||||
#else
|
||||
shared = __va(frames[0] << PAGE_SHIFT);
|
||||
printk("grant table at %p\n", shared);
|
||||
#else
|
||||
for (i = 0; i < NR_GRANT_FRAMES; i++)
|
||||
set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -384,10 +413,12 @@ gnttab_resume(void)
|
||||
int
|
||||
gnttab_suspend(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_GRANT_FRAMES; i++)
|
||||
clear_fixmap(FIX_GNTTAB_END - i);
|
||||
#ifndef __ia64__
|
||||
generic_page_range(&init_mm, (unsigned long)shared,
|
||||
PAGE_SIZE * NR_GRANT_FRAMES,
|
||||
unmap_pte_fn, NULL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -402,10 +433,6 @@ gnttab_init(void)
|
||||
|
||||
BUG_ON(gnttab_resume());
|
||||
|
||||
#ifndef __ia64__
|
||||
shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END);
|
||||
#endif
|
||||
|
||||
for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
|
||||
gnttab_list[i] = i + 1;
|
||||
gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
|
||||
|
||||
@@ -29,10 +29,11 @@ EXPORT_SYMBOL(pm_power_off);
|
||||
#define SHUTDOWN_POWEROFF 0
|
||||
#define SHUTDOWN_REBOOT 1
|
||||
#define SHUTDOWN_SUSPEND 2
|
||||
// Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
|
||||
// report a crash, not be instructed to crash!
|
||||
// HALT is the same as POWEROFF, as far as we're concerned. The tools use
|
||||
// the distinction when we return the reason code to them.
|
||||
/* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
|
||||
* report a crash, not be instructed to crash!
|
||||
* HALT is the same as POWEROFF, as far as we're concerned. The tools use
|
||||
* the distinction when we return the reason code to them.
|
||||
*/
|
||||
#define SHUTDOWN_HALT 4
|
||||
|
||||
void machine_emergency_restart(void)
|
||||
@@ -84,14 +85,14 @@ static int __do_suspend(void *ignore)
|
||||
{
|
||||
int i, j, k, fpp;
|
||||
|
||||
extern int gnttab_suspend(void);
|
||||
extern int gnttab_resume(void);
|
||||
|
||||
extern void time_resume(void);
|
||||
extern unsigned long max_pfn;
|
||||
extern unsigned long *pfn_to_mfn_frame_list_list;
|
||||
extern unsigned long *pfn_to_mfn_frame_list[];
|
||||
|
||||
extern int gnttab_suspend(void);
|
||||
extern int gnttab_resume(void);
|
||||
extern void time_resume(void);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_t prev_online_cpus;
|
||||
int vcpu_prepare(int vcpu);
|
||||
@@ -167,26 +168,26 @@ static int __do_suspend(void *ignore)
|
||||
*/
|
||||
HYPERVISOR_suspend(virt_to_mfn(xen_start_info));
|
||||
|
||||
shutting_down = SHUTDOWN_INVALID;
|
||||
shutting_down = SHUTDOWN_INVALID;
|
||||
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
|
||||
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
|
||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
|
||||
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
|
||||
virt_to_mfn(pfn_to_mfn_frame_list_list);
|
||||
|
||||
|
||||
fpp = PAGE_SIZE/sizeof(unsigned long);
|
||||
for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
|
||||
if ((j % fpp) == 0) {
|
||||
k++;
|
||||
pfn_to_mfn_frame_list_list[k] =
|
||||
pfn_to_mfn_frame_list_list[k] =
|
||||
virt_to_mfn(pfn_to_mfn_frame_list[k]);
|
||||
j = 0;
|
||||
}
|
||||
pfn_to_mfn_frame_list[k][j] =
|
||||
pfn_to_mfn_frame_list[k][j] =
|
||||
virt_to_mfn(&phys_to_machine_mapping[i]);
|
||||
}
|
||||
HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
|
||||
@@ -207,7 +208,7 @@ static int __do_suspend(void *ignore)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
/*
|
||||
* Only resume xenbus /after/ we've prepared our VCPUs; otherwise
|
||||
* the VCPU hotplug callback can race with our vcpu_prepare
|
||||
*/
|
||||
@@ -231,7 +232,7 @@ static int __do_suspend(void *ignore)
|
||||
|
||||
static int shutdown_process(void *__unused)
|
||||
{
|
||||
static char *envp[] = { "HOME=/", "TERM=linux",
|
||||
static char *envp[] = { "HOME=/", "TERM=linux",
|
||||
"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
|
||||
static char *restart_argv[] = { "/sbin/reboot", NULL };
|
||||
static char *poweroff_argv[] = { "/sbin/poweroff", NULL };
|
||||
@@ -291,7 +292,7 @@ static void __shutdown_handler(void *unused)
|
||||
else
|
||||
err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0);
|
||||
|
||||
if ( err < 0 ) {
|
||||
if (err < 0) {
|
||||
printk(KERN_WARNING "Error creating shutdown process (%d): "
|
||||
"retrying...\n", -err);
|
||||
schedule_delayed_work(&shutdown_work, HZ/2);
|
||||
@@ -406,14 +407,12 @@ static int setup_shutdown_watcher(struct notifier_block *notifier,
|
||||
err2 = register_xenbus_watch(&sysrq_watch);
|
||||
#endif
|
||||
|
||||
if (err1) {
|
||||
if (err1)
|
||||
printk(KERN_ERR "Failed to set shutdown watcher\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
if (err2) {
|
||||
if (err2)
|
||||
printk(KERN_ERR "Failed to set sysrq watcher\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return NOTIFY_DONE;
|
||||
@@ -421,11 +420,11 @@ static int setup_shutdown_watcher(struct notifier_block *notifier,
|
||||
|
||||
static int __init setup_shutdown_event(void)
|
||||
{
|
||||
|
||||
|
||||
xenstore_notifier.notifier_call = setup_shutdown_watcher;
|
||||
|
||||
register_xenstore_notifier(&xenstore_notifier);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,8 @@ int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
|
||||
int i;
|
||||
char *e;
|
||||
char *macstr = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
|
||||
if (IS_ERR(macstr)) {
|
||||
if (IS_ERR(macstr))
|
||||
return PTR_ERR(macstr);
|
||||
}
|
||||
s = macstr;
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
mac[i] = simple_strtoul(s, &e, 16);
|
||||
|
||||
@@ -91,7 +91,7 @@ struct netfront_info
|
||||
|
||||
struct net_device_stats stats;
|
||||
unsigned int tx_full;
|
||||
|
||||
|
||||
netif_tx_front_ring_t tx;
|
||||
netif_rx_front_ring_t rx;
|
||||
|
||||
@@ -129,9 +129,9 @@ struct netfront_info
|
||||
struct sk_buff *rx_skbs[NET_RX_RING_SIZE+1];
|
||||
|
||||
grant_ref_t gref_tx_head;
|
||||
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
|
||||
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1];
|
||||
grant_ref_t gref_rx_head;
|
||||
grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1];
|
||||
grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1];
|
||||
|
||||
struct xenbus_device *xbdev;
|
||||
int tx_ring_ref;
|
||||
@@ -433,7 +433,7 @@ static int send_fake_arp(struct net_device *dev)
|
||||
|
||||
skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
|
||||
dst_ip, dev, src_ip,
|
||||
/*dst_hw*/ NULL, /*src_hw*/ NULL,
|
||||
/*dst_hw*/ NULL, /*src_hw*/ NULL,
|
||||
/*target_hw*/ dev->dev_addr);
|
||||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -480,7 +480,7 @@ static void network_tx_buf_gc(struct net_device *dev)
|
||||
printk(KERN_ALERT "network_tx_buf_gc: warning "
|
||||
"-- grant still in use by backend "
|
||||
"domain.\n");
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
gnttab_end_foreign_access_ref(
|
||||
np->grant_tx_ref[id], GNTMAP_readonly);
|
||||
@@ -490,9 +490,9 @@ static void network_tx_buf_gc(struct net_device *dev)
|
||||
ADD_ID_TO_FREELIST(np->tx_skbs, id);
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
|
||||
|
||||
np->tx.rsp_cons = prod;
|
||||
|
||||
|
||||
/*
|
||||
* Set a new event, then check for race with update of tx_cons.
|
||||
* Note that it is essential to schedule a callback, no matter
|
||||
@@ -506,7 +506,7 @@ static void network_tx_buf_gc(struct net_device *dev)
|
||||
mb();
|
||||
} while (prod != np->tx.sring->rsp_prod);
|
||||
|
||||
out:
|
||||
out:
|
||||
if (np->tx_full &&
|
||||
((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE)) {
|
||||
np->tx_full = 0;
|
||||
@@ -582,7 +582,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
id = GET_ID_FROM_FREELIST(np->rx_skbs);
|
||||
|
||||
np->rx_skbs[id] = skb;
|
||||
|
||||
|
||||
RING_GET_REQUEST(&np->rx, req_prod + i)->id = id;
|
||||
ref = gnttab_claim_grant_reference(&np->gref_rx_head);
|
||||
BUG_ON((signed short)ref < 0);
|
||||
@@ -628,11 +628,10 @@ static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
/* Check return status of HYPERVISOR_memory_op(). */
|
||||
if (unlikely(rx_mcl[i].result != i))
|
||||
panic("Unable to reduce memory reservation\n");
|
||||
} else {
|
||||
} else
|
||||
if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
|
||||
&reservation) != i)
|
||||
panic("Unable to reduce memory reservation\n");
|
||||
}
|
||||
|
||||
/* Above is a suitable barrier to ensure backend will see requests. */
|
||||
np->rx.req_prod_pvt = req_prod + i;
|
||||
@@ -668,7 +667,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
dev_kfree_skb(skb);
|
||||
skb = nskb;
|
||||
}
|
||||
|
||||
|
||||
spin_lock_irq(&np->tx_lock);
|
||||
|
||||
if (np->backend_state != BEST_CONNECTED) {
|
||||
@@ -765,7 +764,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
|
||||
rp = np->rx.sring->rsp_prod;
|
||||
rmb(); /* Ensure we see queued responses up to 'rp'. */
|
||||
|
||||
for (i = np->rx.rsp_cons, work_done = 0;
|
||||
for (i = np->rx.rsp_cons, work_done = 0;
|
||||
(i != rp) && (work_done < budget);
|
||||
i++, work_done++) {
|
||||
rx = RING_GET_RESPONSE(&np->rx, i);
|
||||
@@ -807,7 +806,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
|
||||
skb->len = rx->status;
|
||||
skb->tail = skb->data + skb->len;
|
||||
|
||||
if ( rx->flags & NETRXF_csum_valid )
|
||||
if (rx->flags & NETRXF_csum_valid)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
np->stats.rx_packets++;
|
||||
@@ -862,7 +861,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
|
||||
* Enough room in skbuff for the data we were passed? Also,
|
||||
* Linux expects at least 16 bytes headroom in each rx buffer.
|
||||
*/
|
||||
if (unlikely(skb->tail > skb->end) ||
|
||||
if (unlikely(skb->tail > skb->end) ||
|
||||
unlikely((skb->data - skb->head) < 16)) {
|
||||
if (net_ratelimit()) {
|
||||
if (skb->tail > skb->end)
|
||||
@@ -894,7 +893,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
|
||||
if ((skb = nskb) == NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Set the shinfo area, which is hidden behind the data. */
|
||||
init_skb_shinfo(skb);
|
||||
/* Ethernet work: Delayed to here as it peeks the header. */
|
||||
@@ -995,9 +994,9 @@ static void network_connect(struct net_device *dev)
|
||||
|
||||
tx->id = i;
|
||||
gnttab_grant_foreign_access_ref(
|
||||
np->grant_tx_ref[i], np->xbdev->otherend_id,
|
||||
np->grant_tx_ref[i], np->xbdev->otherend_id,
|
||||
virt_to_mfn(np->tx_skbs[i]->data),
|
||||
GNTMAP_readonly);
|
||||
GNTMAP_readonly);
|
||||
tx->gref = np->grant_tx_ref[i];
|
||||
tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
|
||||
tx->size = skb->len;
|
||||
@@ -1012,7 +1011,7 @@ static void network_connect(struct net_device *dev)
|
||||
RING_PUSH_REQUESTS(&np->tx);
|
||||
|
||||
/* Rebuild the RX buffer freelist and the RX ring itself. */
|
||||
for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
|
||||
for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
|
||||
if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
|
||||
continue;
|
||||
gnttab_grant_foreign_transfer_ref(
|
||||
@@ -1021,7 +1020,7 @@ static void network_connect(struct net_device *dev)
|
||||
RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
|
||||
np->grant_rx_ref[i];
|
||||
RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
|
||||
requeue_idx++;
|
||||
requeue_idx++;
|
||||
}
|
||||
|
||||
np->rx.req_prod_pvt = requeue_idx;
|
||||
@@ -1055,9 +1054,8 @@ static void show_device(struct netfront_info *np)
|
||||
np->evtchn,
|
||||
np->tx,
|
||||
np->rx);
|
||||
} else {
|
||||
} else
|
||||
IPRINTK("<vif NULL>\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1150,7 +1148,7 @@ static int create_netdev(int handle, struct xenbus_device *dev,
|
||||
SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
|
||||
SET_MODULE_OWNER(netdev);
|
||||
SET_NETDEV_DEV(netdev, &dev->dev);
|
||||
|
||||
|
||||
if ((err = register_netdev(netdev)) != 0) {
|
||||
printk(KERN_WARNING "%s> register_netdev err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
@@ -1181,16 +1179,16 @@ static int create_netdev(int handle, struct xenbus_device *dev,
|
||||
* We use this notifier to send out a fake ARP reply to reset switches and
|
||||
* router ARP caches when an IP interface is brought up on a VIF.
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
|
||||
{
|
||||
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
|
||||
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
|
||||
struct net_device *dev = ifa->ifa_dev->dev;
|
||||
|
||||
/* UP event and is it one of our devices? */
|
||||
if (event == NETDEV_UP && dev->open == network_open)
|
||||
(void)send_fake_arp(dev);
|
||||
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
@@ -1336,8 +1334,8 @@ static void netif_exit(void)
|
||||
module_exit(netif_exit);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
|
||||
|
||||
|
||||
/* ** /proc **/
|
||||
|
||||
|
||||
@@ -1354,9 +1352,8 @@ static int xennet_proc_read(
|
||||
(struct net_device *)((unsigned long)data & ~3UL);
|
||||
struct netfront_info *np = netdev_priv(dev);
|
||||
int len = 0, which_target = (long)data & 3;
|
||||
|
||||
switch (which_target)
|
||||
{
|
||||
|
||||
switch (which_target) {
|
||||
case TARGET_MIN:
|
||||
len = sprintf(page, "%d\n", np->rx_min_target);
|
||||
break;
|
||||
@@ -1403,8 +1400,7 @@ static int xennet_proc_write(
|
||||
|
||||
spin_lock(&np->rx_lock);
|
||||
|
||||
switch (which_target)
|
||||
{
|
||||
switch (which_target) {
|
||||
case TARGET_MIN:
|
||||
if (target > np->rx_max_target)
|
||||
np->rx_max_target = target;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
obj-y += pciback.o
|
||||
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback.o
|
||||
|
||||
pciback-y := pci_stub.o pciback_ops.o xenbus.o
|
||||
pciback-y += conf_space.o conf_space_header.o
|
||||
pciback-${CONFIG_XEN_PCIDEV_BACKEND_VPCI} += vpci.o
|
||||
pciback-${CONFIG_XEN_PCIDEV_BACKEND_PASS} += passthrough.o
|
||||
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
|
||||
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
|
||||
|
||||
ifeq ($(CONFIG_XEN_PCIDEV_BE_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include "pciback.h"
|
||||
#include "conf_space.h"
|
||||
|
||||
static int permissive = 0;
|
||||
module_param(permissive, bool, 0644);
|
||||
|
||||
#define DEFINE_PCI_CONFIG(op,size,type) \
|
||||
int pciback_##op##_config_##size \
|
||||
(struct pci_dev *dev, int offset, type value, void *data) \
|
||||
@@ -198,7 +201,7 @@ int pciback_config_read(struct pci_dev *dev, int offset, int size,
|
||||
|
||||
int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
|
||||
{
|
||||
int err = 0;
|
||||
int err = 0, handled = 0;
|
||||
struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
|
||||
struct config_field_entry *cfg_entry;
|
||||
struct config_field *field;
|
||||
@@ -233,6 +236,21 @@ int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
|
||||
field_start - req_start);
|
||||
|
||||
err = conf_space_write(dev, cfg_entry, offset, tmp_val);
|
||||
handled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled && !err && permissive) {
|
||||
switch (size) {
|
||||
case 1:
|
||||
err = pci_write_config_byte(dev, offset, (u8)value);
|
||||
break;
|
||||
case 2:
|
||||
err = pci_write_config_word(dev, offset, (u16)value);
|
||||
break;
|
||||
case 4:
|
||||
err = pci_write_config_dword(dev, offset, (u32)value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,21 +24,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
|
||||
if (unlikely(verbose_request))
|
||||
printk(KERN_DEBUG "pciback: %s: enable\n",
|
||||
pci_name(dev));
|
||||
dev->is_enabled = 1;
|
||||
pcibios_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
|
||||
pci_enable_device(dev);
|
||||
} else if (dev->is_enabled && !is_enable_cmd(value)) {
|
||||
if (unlikely(verbose_request))
|
||||
printk(KERN_DEBUG "pciback: %s: disable\n",
|
||||
pci_name(dev));
|
||||
pciback_disable_device(dev);
|
||||
pci_disable_device(dev);
|
||||
}
|
||||
|
||||
if (!dev->is_busmaster && is_master_cmd(value)) {
|
||||
if (unlikely(verbose_request))
|
||||
printk(KERN_DEBUG "pciback: %s: set bus master\n",
|
||||
pci_name(dev));
|
||||
dev->is_busmaster = 1;
|
||||
pcibios_set_master(dev);
|
||||
pci_set_master(dev);
|
||||
}
|
||||
|
||||
if (value & PCI_COMMAND_INVALIDATE) {
|
||||
|
||||
@@ -208,8 +208,6 @@ static int __init pcistub_init_devices_late(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(pcistub_init_devices_late);
|
||||
|
||||
static int __devinit pcistub_seize(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_stub_device *psdev;
|
||||
@@ -367,6 +365,7 @@ static int __init pcistub_init(void)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
/*
|
||||
* fs_initcall happens before device_initcall
|
||||
* so pciback *should* get called first (b/c we
|
||||
@@ -375,3 +374,34 @@ static int __init pcistub_init(void)
|
||||
* driver to register)
|
||||
*/
|
||||
fs_initcall(pcistub_init);
|
||||
#endif
|
||||
|
||||
static int __init pciback_init(void)
|
||||
{
|
||||
#ifdef MODULE
|
||||
int err;
|
||||
|
||||
err = pcistub_init();
|
||||
if (err < 0)
|
||||
return err;
|
||||
#endif
|
||||
|
||||
if (list_empty(&pci_stub_device_ids))
|
||||
return -ENODEV;
|
||||
pcistub_init_devices_late();
|
||||
pciback_xenbus_register();
|
||||
|
||||
__unsafe(THIS_MODULE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pciback_cleanup(void)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
|
||||
module_init(pciback_init);
|
||||
module_exit(pciback_cleanup);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
@@ -43,7 +43,6 @@ struct pci_dev *pcistub_get_pci_dev(struct pci_dev *dev);
|
||||
void pcistub_put_pci_dev(struct pci_dev *dev);
|
||||
|
||||
/* Ensure a device is turned off or reset */
|
||||
void pciback_disable_device(struct pci_dev *dev);
|
||||
void pciback_reset_device(struct pci_dev *pdev);
|
||||
|
||||
/* Access a virtual configuration space for a PCI device */
|
||||
@@ -69,5 +68,7 @@ void pciback_release_devices(struct pciback_device *pdev);
|
||||
/* Handles events from front-end */
|
||||
irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
|
||||
|
||||
int pciback_xenbus_register(void);
|
||||
|
||||
extern int verbose_request;
|
||||
#endif
|
||||
@@ -5,22 +5,12 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <asm/bitops.h>
|
||||
#include <xen/evtchn.h>
|
||||
#include "pciback.h"
|
||||
|
||||
int verbose_request = 0;
|
||||
module_param(verbose_request, int, 0644);
|
||||
|
||||
/* For those architectures without a pcibios_disable_device */
|
||||
void __attribute__ ((weak)) pcibios_disable_device(struct pci_dev *dev) { }
|
||||
|
||||
void pciback_disable_device(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->is_enabled) {
|
||||
dev->is_enabled = 0;
|
||||
pcibios_disable_device(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure a device is "turned off" and ready to be exported.
|
||||
* This also sets up the device's private data to keep track of what should
|
||||
* be in the base address registers (BARs) so that we can keep the
|
||||
@@ -32,7 +22,7 @@ void pciback_reset_device(struct pci_dev *dev)
|
||||
|
||||
/* Disable devices (but not bridges) */
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
|
||||
pciback_disable_device(dev);
|
||||
pci_disable_device(dev);
|
||||
|
||||
pci_write_config_word(dev, PCI_COMMAND, 0);
|
||||
|
||||
@@ -78,6 +68,7 @@ irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
wmb();
|
||||
clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
|
||||
notify_remote_via_irq(pdev->evtchn_irq);
|
||||
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -430,10 +430,7 @@ static struct xenbus_driver xenbus_pciback_driver = {
|
||||
.otherend_changed = pciback_frontend_changed,
|
||||
};
|
||||
|
||||
static __init int pciback_xenbus_register(void)
|
||||
int __init pciback_xenbus_register(void)
|
||||
{
|
||||
return xenbus_register_backend(&xenbus_pciback_driver);
|
||||
}
|
||||
|
||||
/* Must only initialize our xenbus driver after the pcistub driver */
|
||||
device_initcall(pciback_xenbus_register);
|
||||
@@ -18,8 +18,10 @@ int pcifront_connect(struct pcifront_device *pdev)
|
||||
|
||||
spin_lock(&pcifront_dev_lock);
|
||||
|
||||
if (!pcifront_dev)
|
||||
if (!pcifront_dev) {
|
||||
dev_info(&pdev->xdev->dev, "Installing PCI frontend\n");
|
||||
pcifront_dev = pdev;
|
||||
}
|
||||
else {
|
||||
dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
|
||||
err = -EEXIST;
|
||||
|
||||
@@ -40,9 +40,8 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
|
||||
{
|
||||
int err = 0;
|
||||
struct xen_pci_op *active_op = &pdev->sh_info->op;
|
||||
unsigned long irq_flags;
|
||||
|
||||
unsigned int volatile ttl = (1U << 29);
|
||||
unsigned long irq_flags, poll_end;
|
||||
evtchn_port_t port = pdev->evtchn;
|
||||
|
||||
spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
|
||||
|
||||
@@ -51,14 +50,17 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
|
||||
/* Go */
|
||||
wmb();
|
||||
set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
|
||||
notify_remote_via_evtchn(pdev->evtchn);
|
||||
notify_remote_via_evtchn(port);
|
||||
|
||||
/* IRQs are disabled for the pci config. space reads/writes,
|
||||
* which means no event channel to notify us that the backend
|
||||
* is done so spin while waiting for the answer */
|
||||
while (test_bit
|
||||
(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags)) {
|
||||
if (!ttl) {
|
||||
poll_end = jiffies + 5*HZ;
|
||||
clear_evtchn(port);
|
||||
|
||||
while (test_bit(_XEN_PCIF_active,
|
||||
(unsigned long *)&pdev->sh_info->flags)) {
|
||||
if (HYPERVISOR_poll(&port, 1, poll_end))
|
||||
BUG();
|
||||
clear_evtchn(port);
|
||||
if (time_after(jiffies, poll_end)) {
|
||||
dev_err(&pdev->xdev->dev,
|
||||
"pciback not responding!!!\n");
|
||||
clear_bit(_XEN_PCIF_active,
|
||||
@@ -66,7 +68,6 @@ static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op)
|
||||
err = XEN_PCI_ERR_dev_not_found;
|
||||
goto out;
|
||||
}
|
||||
ttl--;
|
||||
}
|
||||
|
||||
memcpy(op, active_op, sizeof(struct xen_pci_op));
|
||||
|
||||
@@ -310,7 +310,8 @@ again:
|
||||
goto abort_transaction;
|
||||
}
|
||||
|
||||
err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
|
||||
err = xenbus_printf(xbt, dev->nodename,
|
||||
"state", "%d", XenbusStateInitialised);
|
||||
if (err) {
|
||||
goto abort_transaction;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
obj-y += xenbus.o
|
||||
|
||||
xenbus-objs =
|
||||
xenbus-objs += xenbus_client.o
|
||||
xenbus-objs += xenbus_client.o
|
||||
xenbus-objs += xenbus_comms.o
|
||||
xenbus-objs += xenbus_xs.o
|
||||
xenbus-objs += xenbus_probe.o
|
||||
xenbus-objs += xenbus_dev.o
|
||||
xenbus-objs += xenbus_probe.o
|
||||
xenbus-objs += xenbus_dev.o
|
||||
@@ -39,7 +39,7 @@ extern char *kasprintf(const char *fmt, ...);
|
||||
pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
|
||||
|
||||
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
|
||||
struct xenbus_watch *watch,
|
||||
struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int))
|
||||
{
|
||||
@@ -62,7 +62,7 @@ EXPORT_SYMBOL(xenbus_watch_path);
|
||||
|
||||
|
||||
int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
|
||||
const char *path2, struct xenbus_watch *watch,
|
||||
const char *path2, struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int))
|
||||
{
|
||||
@@ -74,9 +74,8 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
|
||||
}
|
||||
err = xenbus_watch_path(dev, state, watch, callback);
|
||||
|
||||
if (err) {
|
||||
if (err)
|
||||
kfree(state);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(xenbus_watch_path2);
|
||||
@@ -190,7 +189,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
|
||||
va_start(ap, fmt);
|
||||
_dev_error(dev, err, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
|
||||
}
|
||||
EXPORT_SYMBOL(xenbus_dev_fatal);
|
||||
@@ -213,7 +212,6 @@ int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
|
||||
.u.alloc_unbound.dom = DOMID_SELF,
|
||||
.u.alloc_unbound.remote_dom = dev->otherend_id
|
||||
};
|
||||
|
||||
int err = HYPERVISOR_event_channel_op(&op);
|
||||
if (err)
|
||||
xenbus_dev_fatal(dev, err, "allocating event channel");
|
||||
@@ -231,7 +229,6 @@ int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
|
||||
.u.bind_interdomain.remote_dom = dev->otherend_id,
|
||||
.u.bind_interdomain.remote_port = remote_port,
|
||||
};
|
||||
|
||||
int err = HYPERVISOR_event_channel_op(&op);
|
||||
if (err)
|
||||
xenbus_dev_fatal(dev, err,
|
||||
@@ -388,7 +385,6 @@ EXPORT_SYMBOL(xenbus_unmap_ring);
|
||||
XenbusState xenbus_read_driver_state(const char *path)
|
||||
{
|
||||
XenbusState result;
|
||||
|
||||
int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
|
||||
if (err)
|
||||
result = XenbusStateClosed;
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
|
||||
static int xenbus_irq;
|
||||
|
||||
extern void xenbus_probe(void *);
|
||||
extern int xenstored_ready;
|
||||
extern void xenbus_probe(void *);
|
||||
extern int xenstored_ready;
|
||||
static DECLARE_WORK(probe_work, xenbus_probe, NULL);
|
||||
|
||||
DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
|
||||
@@ -52,9 +52,9 @@ static inline struct xenstore_domain_interface *xenstore_domain_interface(void)
|
||||
static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
|
||||
{
|
||||
if (unlikely(xenstored_ready == 0)) {
|
||||
xenstored_ready = 1;
|
||||
schedule_work(&probe_work);
|
||||
}
|
||||
xenstored_ready = 1;
|
||||
schedule_work(&probe_work);
|
||||
}
|
||||
|
||||
wake_up(&xb_waitq);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -366,7 +366,6 @@ fail:
|
||||
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
return -ENODEV;
|
||||
|
||||
}
|
||||
|
||||
static int xenbus_dev_remove(struct device *_dev)
|
||||
@@ -495,9 +494,8 @@ static void xenbus_dev_free(struct xenbus_device *xendev)
|
||||
|
||||
static void xenbus_dev_release(struct device *dev)
|
||||
{
|
||||
if (dev) {
|
||||
if (dev)
|
||||
xenbus_dev_free(to_xenbus_device(dev));
|
||||
}
|
||||
}
|
||||
|
||||
/* Simplified asprintf. */
|
||||
@@ -600,7 +598,7 @@ static int xenbus_probe_frontend(const char *type, const char *name)
|
||||
nodename = kasprintf("%s/%s/%s", xenbus_frontend.root, type, name);
|
||||
if (!nodename)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
DPRINTK("%s", nodename);
|
||||
|
||||
err = xenbus_probe_node(&xenbus_frontend, type, nodename);
|
||||
@@ -959,9 +957,8 @@ static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
|
||||
return -EINVAL;
|
||||
|
||||
vma->vm_pgoff = mfn_to_pfn(xen_start_info->store_mfn);
|
||||
|
||||
if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
|
||||
if (remap_pfn_range(vma, vma->vm_start,
|
||||
mfn_to_pfn(xen_start_info->store_mfn),
|
||||
size, vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
|
||||
@@ -972,6 +969,7 @@ static int xsd_kva_read(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = sprintf(page, "0x%p", mfn_to_virt(xen_start_info->store_mfn));
|
||||
*eof = 1;
|
||||
return len;
|
||||
@@ -1006,8 +1004,8 @@ static int __init xenbus_probe_init(void)
|
||||
device_register(&xenbus_backend.dev);
|
||||
|
||||
/*
|
||||
** Domain0 doesn't have a store_evtchn or store_mfn yet.
|
||||
*/
|
||||
* Domain0 doesn't have a store_evtchn or store_mfn yet.
|
||||
*/
|
||||
dom0 = (xen_start_info->store_evtchn == 0);
|
||||
|
||||
if (dom0) {
|
||||
@@ -1029,7 +1027,7 @@ static int __init xenbus_probe_init(void)
|
||||
xen_start_info->store_mfn =
|
||||
pfn_to_mfn(virt_to_phys((void *)page) >>
|
||||
PAGE_SHIFT);
|
||||
|
||||
|
||||
/* Next allocate a local port which xenstored can bind to */
|
||||
op.cmd = EVTCHNOP_alloc_unbound;
|
||||
op.u.alloc_unbound.dom = DOMID_SELF;
|
||||
@@ -1040,14 +1038,16 @@ static int __init xenbus_probe_init(void)
|
||||
xen_start_info->store_evtchn = op.u.alloc_unbound.port;
|
||||
|
||||
/* And finally publish the above info in /proc/xen */
|
||||
if ((xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0400))) {
|
||||
xsd_kva_intf = create_xen_proc_entry("xsd_kva", 0600);
|
||||
if (xsd_kva_intf) {
|
||||
memcpy(&xsd_kva_fops, xsd_kva_intf->proc_fops,
|
||||
sizeof(xsd_kva_fops));
|
||||
xsd_kva_fops.mmap = xsd_kva_mmap;
|
||||
xsd_kva_intf->proc_fops = &xsd_kva_fops;
|
||||
xsd_kva_intf->read_proc = xsd_kva_read;
|
||||
}
|
||||
if ((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400)))
|
||||
xsd_port_intf = create_xen_proc_entry("xsd_port", 0400);
|
||||
if (xsd_port_intf)
|
||||
xsd_port_intf->read_proc = xsd_port_read;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,9 +176,8 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
|
||||
if (err) {
|
||||
msg->type = XS_ERROR;
|
||||
ret = ERR_PTR(err);
|
||||
} else {
|
||||
} else
|
||||
ret = read_reply(&msg->type, &msg->len);
|
||||
}
|
||||
|
||||
up(&xs_state.request_mutex);
|
||||
|
||||
@@ -275,7 +274,7 @@ static unsigned int count_strings(const char *strings, unsigned int len)
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
|
||||
/* Return the path to dir with /name appended. Buffer must be kfree()'ed. */
|
||||
static char *join(const char *dir, const char *name)
|
||||
{
|
||||
char *buffer;
|
||||
|
||||
@@ -84,8 +84,6 @@ enum fixed_addresses {
|
||||
FIX_PCIE_MCFG,
|
||||
#endif
|
||||
FIX_SHARED_INFO,
|
||||
FIX_GNTTAB_BEGIN,
|
||||
FIX_GNTTAB_END = FIX_GNTTAB_BEGIN + NR_GRANT_FRAMES - 1,
|
||||
#define NR_FIX_ISAMAPS 256
|
||||
FIX_ISAMAP_END,
|
||||
FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/nmi.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define __STR(x) #x
|
||||
#define STR(x) __STR(x)
|
||||
@@ -169,6 +170,31 @@ HYPERVISOR_sched_op(
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op_new(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_new, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_poll(
|
||||
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
|
||||
{
|
||||
struct sched_poll sched_poll = {
|
||||
.ports = ports,
|
||||
.nr_ports = nr_ports,
|
||||
.timeout = jiffies_to_st(timeout)
|
||||
};
|
||||
|
||||
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
|
||||
|
||||
if (rc == -ENOSYS)
|
||||
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline long
|
||||
HYPERVISOR_set_timer_op(
|
||||
u64 timeout)
|
||||
@@ -304,8 +330,7 @@ HYPERVISOR_suspend(
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_nmi_op(
|
||||
unsigned long op,
|
||||
unsigned long arg)
|
||||
unsigned long op, void *arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
|
||||
@@ -79,12 +79,6 @@ void xen_l3_entry_update(pud_t *ptr, pud_t val); /* x86_64/PAE */
|
||||
void xen_l4_entry_update(pgd_t *ptr, pgd_t val); /* x86_64 only */
|
||||
void xen_pgd_pin(unsigned long ptr);
|
||||
void xen_pgd_unpin(unsigned long ptr);
|
||||
void xen_pud_pin(unsigned long ptr); /* x86_64 only */
|
||||
void xen_pud_unpin(unsigned long ptr); /* x86_64 only */
|
||||
void xen_pmd_pin(unsigned long ptr); /* x86_64 only */
|
||||
void xen_pmd_unpin(unsigned long ptr); /* x86_64 only */
|
||||
void xen_pte_pin(unsigned long ptr);
|
||||
void xen_pte_unpin(unsigned long ptr);
|
||||
|
||||
void xen_set_ldt(unsigned long ptr, unsigned long bytes);
|
||||
void xen_machphys_update(unsigned long mfn, unsigned long pfn);
|
||||
@@ -103,6 +97,9 @@ int xen_create_contiguous_region(
|
||||
void xen_destroy_contiguous_region(
|
||||
unsigned long vstart, unsigned int order);
|
||||
|
||||
/* Turn jiffies into Xen system time. */
|
||||
u64 jiffies_to_st(unsigned long jiffies);
|
||||
|
||||
#include <asm/hypercall.h>
|
||||
|
||||
#if defined(CONFIG_X86_64)
|
||||
|
||||
@@ -71,7 +71,8 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
|
||||
{
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return pfn;
|
||||
return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
|
||||
return phys_to_machine_mapping[(unsigned int)(pfn)] &
|
||||
~FOREIGN_FRAME_BIT;
|
||||
}
|
||||
|
||||
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
|
||||
|
||||
@@ -131,8 +131,8 @@ static inline int pte_none(pte_t pte)
|
||||
return !pte.pte_low && !pte.pte_high;
|
||||
}
|
||||
|
||||
#define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
|
||||
(((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
|
||||
#define pte_mfn(_pte) (((_pte).pte_low >> PAGE_SHIFT) |\
|
||||
(((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)))
|
||||
#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
|
||||
|
||||
extern unsigned long long __supported_pte_mask;
|
||||
|
||||
@@ -272,7 +272,16 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
|
||||
pte_t pte;
|
||||
if (full) {
|
||||
pte = *ptep;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/* Cannot do this in a single step, as the compiler may
|
||||
issue the two stores in either order, but the hypervisor
|
||||
must not see the high part before the low one. */
|
||||
ptep->pte_low = 0;
|
||||
barrier();
|
||||
ptep->pte_high = 0;
|
||||
#else
|
||||
*ptep = __pte(0);
|
||||
#endif
|
||||
} else {
|
||||
pte = ptep_get_and_clear(mm, addr, ptep);
|
||||
}
|
||||
|
||||
@@ -596,7 +596,7 @@ do { \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
|
||||
_vcpu->evtchn_upcall_mask = 0; \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
|
||||
if (unlikely(_vcpu->evtchn_upcall_pending)) \
|
||||
force_evtchn_callback(); \
|
||||
preempt_enable(); \
|
||||
} while (0)
|
||||
@@ -618,7 +618,7 @@ do { \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[__vcpu_id]; \
|
||||
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
|
||||
if (unlikely(_vcpu->evtchn_upcall_pending)) \
|
||||
force_evtchn_callback(); \
|
||||
preempt_enable(); \
|
||||
} else \
|
||||
|
||||
@@ -35,12 +35,21 @@ extern void nmi(void);
|
||||
static void __init machine_specific_arch_setup(void)
|
||||
{
|
||||
struct xen_platform_parameters pp;
|
||||
struct xennmi_callback cb;
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap) &&
|
||||
xen_start_info->shared_info < xen_start_info->nr_pages) {
|
||||
HYPERVISOR_shared_info =
|
||||
(shared_info_t *)__va(xen_start_info->shared_info);
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
}
|
||||
|
||||
HYPERVISOR_set_callbacks(
|
||||
__KERNEL_CS, (unsigned long)hypervisor_callback,
|
||||
__KERNEL_CS, (unsigned long)failsafe_callback);
|
||||
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
|
||||
cb.handler_address = (unsigned long)&nmi;
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
|
||||
|
||||
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/dom0_ops.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
/* FIXME: temp place to hold these page related macros */
|
||||
#include <asm/page.h>
|
||||
@@ -166,6 +167,31 @@ HYPERVISOR_sched_op(
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op_new(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_new, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_poll(
|
||||
evtchn_port_t *ports, unsigned int nr_ports, unsigned long timeout)
|
||||
{
|
||||
struct sched_poll sched_poll = {
|
||||
.ports = ports,
|
||||
.nr_ports = nr_ports,
|
||||
.timeout = jiffies_to_st(timeout)
|
||||
};
|
||||
|
||||
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
|
||||
|
||||
if (rc == -ENOSYS)
|
||||
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline long
|
||||
HYPERVISOR_set_timer_op(
|
||||
u64 timeout)
|
||||
|
||||
@@ -44,6 +44,9 @@ extern start_info_t *xen_start_info;
|
||||
|
||||
void force_evtchn_callback(void);
|
||||
|
||||
/* Turn jiffies into Xen system time. XXX Implement me. */
|
||||
#define jiffies_to_st(j) 0
|
||||
|
||||
#include <asm/hypercall.h>
|
||||
|
||||
// for drivers/xen/privcmd/privcmd.c
|
||||
|
||||
@@ -52,8 +52,6 @@ enum fixed_addresses {
|
||||
FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
|
||||
#endif
|
||||
FIX_SHARED_INFO,
|
||||
FIX_GNTTAB_BEGIN,
|
||||
FIX_GNTTAB_END = FIX_GNTTAB_BEGIN + NR_GRANT_FRAMES - 1,
|
||||
#define NR_FIX_ISAMAPS 256
|
||||
FIX_ISAMAP_END,
|
||||
FIX_ISAMAP_BEGIN = FIX_ISAMAP_END + NR_FIX_ISAMAPS - 1,
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/nmi.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define __STR(x) #x
|
||||
#define STR(x) __STR(x)
|
||||
@@ -173,6 +175,31 @@ HYPERVISOR_sched_op(
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op_new(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_new, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_poll(
|
||||
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
|
||||
{
|
||||
struct sched_poll sched_poll = {
|
||||
.ports = ports,
|
||||
.nr_ports = nr_ports,
|
||||
.timeout = jiffies_to_st(timeout)
|
||||
};
|
||||
|
||||
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
|
||||
|
||||
if (rc == -ENOSYS)
|
||||
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline long
|
||||
HYPERVISOR_set_timer_op(
|
||||
u64 timeout)
|
||||
@@ -304,8 +331,7 @@ HYPERVISOR_suspend(
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_nmi_op(
|
||||
unsigned long op,
|
||||
unsigned long arg)
|
||||
unsigned long op, void *arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,8 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
|
||||
{
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return pfn;
|
||||
return phys_to_machine_mapping[(unsigned int)(pfn)] & ~FOREIGN_FRAME_BIT;
|
||||
return phys_to_machine_mapping[(unsigned int)(pfn)] &
|
||||
~FOREIGN_FRAME_BIT;
|
||||
}
|
||||
|
||||
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
|
||||
|
||||
@@ -181,7 +181,6 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add
|
||||
static inline void pte_free_kernel(pte_t *pte)
|
||||
{
|
||||
BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
|
||||
xen_pte_unpin(__pa(pte));
|
||||
make_page_writable(pte, XENFEAT_writable_page_tables);
|
||||
free_page((unsigned long)pte);
|
||||
}
|
||||
|
||||
@@ -23,13 +23,18 @@ extern void nmi(void);
|
||||
|
||||
static void __init machine_specific_arch_setup(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
struct xennmi_callback cb;
|
||||
#endif
|
||||
|
||||
HYPERVISOR_set_callbacks(
|
||||
(unsigned long) hypervisor_callback,
|
||||
(unsigned long) failsafe_callback,
|
||||
(unsigned long) system_call);
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
|
||||
cb.handler_address = (unsigned long)&nmi;
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
|
||||
#endif
|
||||
|
||||
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
|
||||
|
||||
@@ -1020,9 +1020,9 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address,
|
||||
#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
|
||||
typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
|
||||
void *data);
|
||||
extern int generic_page_range(struct mm_struct *mm, unsigned long address,
|
||||
extern int generic_page_range(struct mm_struct *mm, unsigned long address,
|
||||
unsigned long size, pte_fn_t fn, void *data);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_XEN_XENBUS_H
|
||||
#define _ASM_XEN_XENBUS_H
|
||||
#ifndef _XEN_XENBUS_H
|
||||
#define _XEN_XENBUS_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/notifier.h>
|
||||
@@ -170,7 +170,7 @@ void xenbus_resume(void);
|
||||
* be saved in the store.
|
||||
*/
|
||||
int xenbus_watch_path(struct xenbus_device *dev, const char *path,
|
||||
struct xenbus_watch *watch,
|
||||
struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int));
|
||||
|
||||
@@ -185,7 +185,7 @@ int xenbus_watch_path(struct xenbus_device *dev, const char *path,
|
||||
* saved in the store.
|
||||
*/
|
||||
int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
|
||||
const char *path2, struct xenbus_watch *watch,
|
||||
const char *path2, struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int));
|
||||
|
||||
@@ -216,8 +216,8 @@ int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
|
||||
* page to that address, and sets *vaddr to that address.
|
||||
* xenbus_map_ring does not allocate the virtual address space (you must do
|
||||
* this yourself!). It only maps in the page to the specified address.
|
||||
* Returns 0 on success, and GNTST_* (see xen/include/public/grant_table.h) or
|
||||
* -ENOMEM on error. If an error is returned, device will switch to
|
||||
* Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h)
|
||||
* or -ENOMEM on error. If an error is returned, device will switch to
|
||||
* XenbusStateClosing and the error message will be saved in XenStore.
|
||||
*/
|
||||
int xenbus_map_ring_valloc(struct xenbus_device *dev,
|
||||
@@ -231,7 +231,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
|
||||
* Use xenbus_unmap_ring_vfree if you mapped in your memory with
|
||||
* xenbus_map_ring_valloc (it will free the virtual address space).
|
||||
* Returns 0 on success and returns GNTST_* on error
|
||||
* (see xen/include/public/grant_table.h).
|
||||
* (see xen/include/interface/grant_table.h).
|
||||
*/
|
||||
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr);
|
||||
int xenbus_unmap_ring(struct xenbus_device *dev,
|
||||
@@ -285,7 +285,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
|
||||
...);
|
||||
|
||||
|
||||
#endif /* _ASM_XEN_XENBUS_H */
|
||||
#endif /* _XEN_XENBUS_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
||||
@@ -10,16 +10,6 @@ XEN_LIBXC = $(XEN_ROOT)/tools/libxc
|
||||
XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore
|
||||
XEN_LIBXENSTAT = $(XEN_ROOT)/tools/xenstat/libxenstat/src
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),x86_32)
|
||||
CFLAGS += -m32 -march=i686
|
||||
LDFLAGS += -m32
|
||||
endif
|
||||
|
||||
ifeq ($(XEN_TARGET_ARCH),x86_64)
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
endif
|
||||
|
||||
X11_LDPATH = -L/usr/X11R6/$(LIBDIR)
|
||||
|
||||
%.opic: %.c
|
||||
|
||||
@@ -22,11 +22,8 @@ LIBS := -lpthread -lz
|
||||
SRCS :=
|
||||
SRCS += blktaplib.c xenbus.c blkif.c
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -Wno-unused
|
||||
#CFLAGS += -O3
|
||||
CFLAGS += -g3
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
|
||||
# get asprintf():
|
||||
|
||||
@@ -31,11 +31,8 @@ VDI_TOOLS += vdi_fill
|
||||
VDI_TOOLS += vdi_tree
|
||||
VDI_TOOLS += vdi_validate
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -Wno-unused
|
||||
#CFLAGS += -O3
|
||||
CFLAGS += -g3
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += $(INCLUDES)
|
||||
CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
|
||||
@@ -58,7 +55,7 @@ parallax: $(PLX_SRCS)
|
||||
$(CC) $(CFLAGS) -o parallax -L.. $(LDFLAGS) $(PLX_SRCS)
|
||||
|
||||
${VDI_TOOLS}: %: %.c $(VDI_SRCS)
|
||||
$(CC) $(CFLAGS) -g3 -o $@ $@.c $(LDFLAGS) $(VDI_SRCS)
|
||||
$(CC) $(CFLAGS) -o $@ $@.c $(LDFLAGS) $(VDI_SRCS)
|
||||
|
||||
.PHONY: TAGS clean install rpm
|
||||
-include $(DEPS)
|
||||
-include $(DEPS)
|
||||
@@ -9,11 +9,8 @@ INSTALL_PROG = $(INSTALL) -m0755
|
||||
IBIN = ublkback
|
||||
INSTALL_DIR = /usr/sbin
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -Wno-unused
|
||||
#CFLAGS += -O3
|
||||
CFLAGS += -g3
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -I $(XEN_LIBXC)
|
||||
CFLAGS += $(INCLUDES) -I.
|
||||
|
||||
@@ -9,7 +9,7 @@ INSTALL = install
|
||||
INSTALL_PROG = $(INSTALL) -m0755
|
||||
INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
|
||||
CFLAGS += -Wall -Werror -g3
|
||||
CFLAGS += -Werror -g
|
||||
|
||||
CFLAGS += -I $(XEN_LIBXC)
|
||||
CFLAGS += -I $(XEN_XENSTORE)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
CFLAGS=-g -Wall
|
||||
CC=gcc
|
||||
XEN_ROOT = ../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
LDFLAGS=-static
|
||||
|
||||
all: console-dom0 console-domU procpipe
|
||||
|
||||
@@ -229,8 +229,6 @@ linux_wait (char *status)
|
||||
if (xc_waitdomain(xc_handle, current_domid, &w, 0))
|
||||
return -1;
|
||||
|
||||
linux_set_inferior();
|
||||
|
||||
*status = 'T';
|
||||
if (expect_signal)
|
||||
return expect_signal;
|
||||
|
||||
@@ -7,14 +7,12 @@ INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
MAJOR = 3.0
|
||||
MINOR = 0
|
||||
|
||||
CC = gcc
|
||||
|
||||
XEN_ROOT = ../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
SRCS := xendebug.c
|
||||
|
||||
CFLAGS += -Wall -Werror -O3 -fno-strict-aliasing
|
||||
CFLAGS += -Werror -fno-strict-aliasing
|
||||
CFLAGS += $(INCLUDES) -I. -I$(XEN_ROOT)/tools/libxc
|
||||
# Get gcc to generate the dependencies for us.
|
||||
CFLAGS += -Wp,-MD,.$(@F).d
|
||||
|
||||
@@ -20,7 +20,6 @@ INCLUDES += -I ./linux-2.6-module
|
||||
INCLUDES += -I $(OCAML_ROOT)/lib/ocaml
|
||||
|
||||
CFLAGS += $(INCLUDES)
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -g
|
||||
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
# *
|
||||
# */
|
||||
#
|
||||
|
||||
XEN_ROOT = ../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
# Compiler flag
|
||||
CFLAG=-I. -I../../libxc
|
||||
|
||||
# Compiler tool
|
||||
CC=gcc
|
||||
HOSTCFLAGS += -I. -I../../libxc
|
||||
|
||||
# TARGET
|
||||
C_SRC=$(shell ls *.c)
|
||||
@@ -33,7 +34,7 @@ IASL_URL=http://developer.intel.com/technology/iapc/acpi/downloads/$(IASL_VER).t
|
||||
|
||||
vpath iasl $(PATH)
|
||||
all:$(ACPI_BIN)
|
||||
|
||||
|
||||
acpi_dsdt.c:acpi_dsdt.asl
|
||||
$(MAKE) iasl
|
||||
iasl -oa -tc acpi_dsdt.asl
|
||||
@@ -54,15 +55,13 @@ iasl:
|
||||
install $(IASL_VER)/compiler/iasl /usr/bin/iasl
|
||||
|
||||
$(ACPI_GEN):$(C_SRC) $(H_SRC) acpi_dsdt.c
|
||||
$(CC) -o $(ACPI_GEN) $(CFLAG) $(shell ls *.c)
|
||||
$(HOSTCC) -o $(ACPI_GEN) $(HOSTCFLAGS) $(shell ls *.c)
|
||||
|
||||
$(ACPI_BIN):$(ACPI_GEN)
|
||||
./$(ACPI_GEN) $(ACPI_BIN)
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o $(ACPI_GEN) $(ACPI_BIN) $(IASL_VER)
|
||||
# rm -f acpi_dsdt.c
|
||||
rm -rf $(IASL_VER).tar.gz
|
||||
install:all
|
||||
|
||||
|
||||
|
||||
install: all
|
||||
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
-include config-host.mak
|
||||
|
||||
CFLAGS+=-Wall -O2 -g -fno-strict-aliasing
|
||||
CFLAGS+=-g -fno-strict-aliasing
|
||||
ifdef CONFIG_DARWIN
|
||||
CFLAGS+= -mdynamic-no-pic
|
||||
endif
|
||||
|
||||
Vendored
+11
-11
@@ -392,17 +392,17 @@ echo "docdir=$docdir" >> $config_mak
|
||||
echo "configdir=$configdir" >> $config_mak
|
||||
echo "LIBDIR=$libdir" >> $config_mak
|
||||
echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
|
||||
echo "MAKE=$make" >> $config_mak
|
||||
echo "CC=$cc" >> $config_mak
|
||||
if test "$have_gcc3_options" = "yes" ; then
|
||||
echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
|
||||
fi
|
||||
echo "HOST_CC=$host_cc" >> $config_mak
|
||||
echo "AR=$ar" >> $config_mak
|
||||
echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
|
||||
echo "CFLAGS=$CFLAGS" >> $config_mak
|
||||
echo "LDFLAGS=$LDFLAGS" >> $config_mak
|
||||
echo "EXESUF=$EXESUF" >> $config_mak
|
||||
#echo "MAKE=$make" >> $config_mak
|
||||
#echo "CC=$cc" >> $config_mak
|
||||
#if test "$have_gcc3_options" = "yes" ; then
|
||||
# echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
|
||||
#fi
|
||||
#echo "HOST_CC=$host_cc" >> $config_mak
|
||||
#echo "AR=$ar" >> $config_mak
|
||||
#echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
|
||||
#echo "CFLAGS=$CFLAGS" >> $config_mak
|
||||
#echo "LDFLAGS=$LDFLAGS" >> $config_mak
|
||||
#echo "EXESUF=$EXESUF" >> $config_mak
|
||||
|
||||
if test "$bigendian" = "yes" ; then
|
||||
echo "WORDS_BIGENDIAN=yes" >> $config_mak
|
||||
|
||||
@@ -407,6 +407,7 @@ static int eject_device(BlockDriverState *bs, int force)
|
||||
|
||||
static void do_eject(int force, const char *filename)
|
||||
{
|
||||
char cmd[1024];
|
||||
BlockDriverState *bs;
|
||||
|
||||
bs = bdrv_find(filename);
|
||||
@@ -415,6 +416,9 @@ static void do_eject(int force, const char *filename)
|
||||
return;
|
||||
}
|
||||
eject_device(bs, force);
|
||||
sprintf(cmd, "eject %s", filename);
|
||||
system(cmd);
|
||||
|
||||
}
|
||||
|
||||
static void do_change(const char *device, const char *filename)
|
||||
|
||||
@@ -13,7 +13,7 @@ ifdef CONFIG_USER_ONLY
|
||||
VPATH+=:$(SRC_PATH)/linux-user
|
||||
DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
|
||||
endif
|
||||
CFLAGS+=-Wall -O2 -g -fno-strict-aliasing
|
||||
CFLAGS+=-g -fno-strict-aliasing
|
||||
LDFLAGS=-g
|
||||
LIBS=
|
||||
HELPER_CFLAGS=$(CFLAGS)
|
||||
@@ -99,7 +99,6 @@ LDFLAGS+=-static
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),i386)
|
||||
CFLAGS+=-fomit-frame-pointer
|
||||
OP_CFLAGS=$(CFLAGS) -mpreferred-stack-boundary=2
|
||||
ifeq ($(HAVE_GCC3_OPTIONS),yes)
|
||||
OP_CFLAGS+= -falign-functions=0 -fno-gcse
|
||||
@@ -236,7 +235,7 @@ endif
|
||||
all: $(PROGS)
|
||||
|
||||
$(QEMU_USER): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
ifeq ($(ARCH),alpha)
|
||||
# Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
|
||||
# the address space (31 bit so sign extending doesn't matter)
|
||||
@@ -312,7 +311,7 @@ endif
|
||||
endif
|
||||
|
||||
$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
|
||||
$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VNC_LIBS) $(VL_LIBS) -lpthread
|
||||
$(CC) $(CFLAGS) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VNC_LIBS) $(VL_LIBS) -lpthread
|
||||
|
||||
vnc.o: vnc.c keyboard_rdesktop.c
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(VNC_CFLAGS) -c -o $@ $<
|
||||
|
||||
+2
-2
@@ -697,7 +697,7 @@ void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
|
||||
void tcx_init(DisplayState *ds, uint32_t addr);
|
||||
|
||||
/* sched.c */
|
||||
void sched_init();
|
||||
void sched_init(uint32_t, uint32_t);
|
||||
|
||||
/* magic-load.c */
|
||||
void magic_init(const char *kfn, int kloadaddr, uint32_t addr);
|
||||
@@ -799,7 +799,7 @@ void readline_start(const char *prompt, int is_password,
|
||||
|
||||
int gdbserver_start(int port);
|
||||
void update_select_wakeup_events(void);
|
||||
void tun_receive_handler();
|
||||
void tun_receive_handler(fd_set *);
|
||||
|
||||
extern char domain_name[];
|
||||
#endif /* VL_H */
|
||||
@@ -7,8 +7,6 @@ INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
MAJOR = 3.0
|
||||
MINOR = 0
|
||||
|
||||
CC = gcc
|
||||
|
||||
XEN_ROOT = ../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
@@ -48,9 +46,7 @@ BUILD_SRCS += xc_linux_save.c
|
||||
BUILD_SRCS += xc_hvm_build.c
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Werror
|
||||
CFLAGS += -O3
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += $(INCLUDES) -I.
|
||||
|
||||
|
||||
+105
-47
@@ -6,18 +6,17 @@
|
||||
#include <zlib.h>
|
||||
|
||||
/* number of pages to write at a time */
|
||||
#define DUMP_INCREMENT 4 * 1024
|
||||
#define DUMP_INCREMENT (4 * 1024)
|
||||
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
|
||||
|
||||
static int
|
||||
copy_from_domain_page(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned long *page_array,
|
||||
unsigned long src_pfn,
|
||||
unsigned long mfn,
|
||||
void *dst_page)
|
||||
{
|
||||
void *vaddr = xc_map_foreign_range(
|
||||
xc_handle, domid, PAGE_SIZE, PROT_READ, page_array[src_pfn]);
|
||||
xc_handle, domid, PAGE_SIZE, PROT_READ, mfn);
|
||||
if ( vaddr == NULL )
|
||||
return -1;
|
||||
memcpy(dst_page, vaddr, PAGE_SIZE);
|
||||
@@ -26,95 +25,154 @@ copy_from_domain_page(int xc_handle,
|
||||
}
|
||||
|
||||
int
|
||||
xc_domain_dumpcore(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *corename)
|
||||
xc_domain_dumpcore_via_callback(int xc_handle,
|
||||
uint32_t domid,
|
||||
void *args,
|
||||
dumpcore_rtn_t dump_rtn)
|
||||
{
|
||||
unsigned long nr_pages;
|
||||
unsigned long *page_array;
|
||||
unsigned long *page_array = NULL;
|
||||
xc_dominfo_t info;
|
||||
int i, nr_vcpus = 0, dump_fd;
|
||||
int i, nr_vcpus = 0;
|
||||
char *dump_mem, *dump_mem_start = NULL;
|
||||
struct xc_core_header header;
|
||||
vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
|
||||
char dummy[PAGE_SIZE];
|
||||
int dummy_len;
|
||||
int sts;
|
||||
|
||||
|
||||
if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) {
|
||||
PERROR("Could not open corefile %s: %s", corename, strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ((dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL) {
|
||||
if ( (dump_mem_start = malloc(DUMP_INCREMENT*PAGE_SIZE)) == NULL )
|
||||
{
|
||||
PERROR("Could not allocate dump_mem");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (xc_domain_getinfo(xc_handle, domid, 1, &info) != 1) {
|
||||
if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
|
||||
{
|
||||
PERROR("Could not get info for domain");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < info.max_vcpu_id; i++)
|
||||
if (xc_vcpu_getcontext(xc_handle, domid,
|
||||
i, &ctxt[nr_vcpus]) == 0)
|
||||
if ( domid != info.domid )
|
||||
{
|
||||
PERROR("Domain %d does not exist", domid);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
for ( i = 0; i <= info.max_vcpu_id; i++ )
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0)
|
||||
nr_vcpus++;
|
||||
|
||||
nr_pages = info.nr_pages;
|
||||
|
||||
header.xch_magic = XC_CORE_MAGIC;
|
||||
header.xch_magic = XC_CORE_MAGIC;
|
||||
header.xch_nr_vcpus = nr_vcpus;
|
||||
header.xch_nr_pages = nr_pages;
|
||||
header.xch_ctxt_offset = sizeof(struct xc_core_header);
|
||||
header.xch_index_offset = sizeof(struct xc_core_header) +
|
||||
sizeof(vcpu_guest_context_t)*nr_vcpus;
|
||||
header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) +
|
||||
(sizeof(vcpu_guest_context_t) * nr_vcpus) +
|
||||
(nr_pages * sizeof(unsigned long)));
|
||||
|
||||
if (write(dump_fd, &header, sizeof(struct xc_core_header)) < 0 ||
|
||||
write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus) < 0)
|
||||
{
|
||||
PERROR("write failed");
|
||||
dummy_len = (sizeof(struct xc_core_header) +
|
||||
(sizeof(vcpu_guest_context_t) * nr_vcpus) +
|
||||
(nr_pages * sizeof(unsigned long)));
|
||||
header.xch_pages_offset = round_pgup(dummy_len);
|
||||
|
||||
sts = dump_rtn(args, (char *)&header, sizeof(struct xc_core_header));
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
|
||||
sts = dump_rtn(args, (char *)&ctxt, sizeof(ctxt[0]) * nr_vcpus);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
|
||||
if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
|
||||
{
|
||||
printf("Could not allocate memory\n");
|
||||
goto error_out;
|
||||
}
|
||||
if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
|
||||
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
|
||||
{
|
||||
printf("Could not get the page frame list\n");
|
||||
goto error_out;
|
||||
}
|
||||
if (write(dump_fd, page_array, nr_pages * sizeof(unsigned long)) < 0)
|
||||
{
|
||||
PERROR("write failed");
|
||||
sts = dump_rtn(args, (char *)page_array, nr_pages * sizeof(unsigned long));
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
}
|
||||
lseek(dump_fd, header.xch_pages_offset, SEEK_SET);
|
||||
for (dump_mem = dump_mem_start, i = 0; i < nr_pages; i++) {
|
||||
copy_from_domain_page(xc_handle, domid, page_array, i, dump_mem);
|
||||
|
||||
/* Pad the output data to page alignment. */
|
||||
memset(dummy, 0, PAGE_SIZE);
|
||||
sts = dump_rtn(args, dummy, header.xch_pages_offset - dummy_len);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
|
||||
for ( dump_mem = dump_mem_start, i = 0; i < nr_pages; i++ )
|
||||
{
|
||||
copy_from_domain_page(xc_handle, domid, page_array[i], dump_mem);
|
||||
dump_mem += PAGE_SIZE;
|
||||
if (((i + 1) % DUMP_INCREMENT == 0) || (i + 1) == nr_pages) {
|
||||
if (write(dump_fd, dump_mem_start, dump_mem - dump_mem_start) <
|
||||
dump_mem - dump_mem_start) {
|
||||
PERROR("Partial write, file system full?");
|
||||
if ( ((i + 1) % DUMP_INCREMENT == 0) || ((i + 1) == nr_pages) )
|
||||
{
|
||||
sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
|
||||
if ( sts != 0 )
|
||||
goto error_out;
|
||||
}
|
||||
dump_mem = dump_mem_start;
|
||||
}
|
||||
}
|
||||
|
||||
close(dump_fd);
|
||||
free(dump_mem_start);
|
||||
free(page_array);
|
||||
return 0;
|
||||
|
||||
error_out:
|
||||
if (dump_fd != -1)
|
||||
close(dump_fd);
|
||||
free(dump_mem_start);
|
||||
free(page_array);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Callback args for writing to a local dump file. */
|
||||
struct dump_args {
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* Callback routine for writing to a local dump file. */
|
||||
static int local_file_dump(void *args, char *buffer, unsigned int length)
|
||||
{
|
||||
struct dump_args *da = args;
|
||||
int bytes, offset;
|
||||
|
||||
for ( offset = 0; offset < length; offset += bytes )
|
||||
{
|
||||
bytes = write(da->fd, &buffer[offset], length-offset);
|
||||
if ( bytes <= 0 )
|
||||
{
|
||||
PERROR("Failed to write buffer: %s", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xc_domain_dumpcore(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *corename)
|
||||
{
|
||||
struct dump_args da;
|
||||
int sts;
|
||||
|
||||
if ( (da.fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0 )
|
||||
{
|
||||
PERROR("Could not open corefile %s: %s", corename, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
sts = xc_domain_dumpcore_via_callback(
|
||||
xc_handle, domid, &da, &local_file_dump);
|
||||
|
||||
close(da.fd);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
+104
-19
@@ -132,7 +132,7 @@ set_hvm_info_checksum(struct hvm_info_table *t)
|
||||
}
|
||||
|
||||
/*
|
||||
* Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
|
||||
* Use E820 reserved memory 0x9F800 to pass HVM info to hvmloader
|
||||
* hvmloader will use this info to set BIOS accordingly
|
||||
*/
|
||||
static int set_hvm_info(int xc_handle, uint32_t dom,
|
||||
@@ -338,25 +338,30 @@ static int setup_guest(int xc_handle,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xc_hvm_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
const char *image_name,
|
||||
unsigned int vcpus,
|
||||
unsigned int pae,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
static int xc_hvm_build_internal(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
char *image,
|
||||
unsigned long image_size,
|
||||
unsigned int vcpus,
|
||||
unsigned int pae,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
dom0_op_t launch_op, op;
|
||||
int rc, i;
|
||||
vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
|
||||
unsigned long nr_pages;
|
||||
char *image = NULL;
|
||||
unsigned long image_size;
|
||||
xen_capabilities_info_t xen_caps;
|
||||
|
||||
if ( (image == NULL) || (image_size == 0) )
|
||||
{
|
||||
ERROR("Image required");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
|
||||
{
|
||||
PERROR("Failed to get xen version info");
|
||||
@@ -376,9 +381,6 @@ int xc_hvm_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
|
||||
goto error_out;
|
||||
|
||||
if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
|
||||
{
|
||||
PERROR("%s: ctxt mlock failed", __func__);
|
||||
@@ -405,8 +407,6 @@ int xc_hvm_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
free(image);
|
||||
|
||||
/* FPU is set up to default initial state. */
|
||||
memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
|
||||
|
||||
@@ -450,7 +450,6 @@ int xc_hvm_build(int xc_handle,
|
||||
return rc;
|
||||
|
||||
error_out:
|
||||
free(image);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -580,6 +579,92 @@ loadelfimage(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* xc_hvm_build
|
||||
*
|
||||
* Create a domain for a virtualized Linux, using files/filenames
|
||||
*
|
||||
*/
|
||||
|
||||
int xc_hvm_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
const char *image_name,
|
||||
unsigned int vcpus,
|
||||
unsigned int pae,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
char *image;
|
||||
int sts;
|
||||
unsigned long image_size;
|
||||
|
||||
if ( (image_name == NULL) ||
|
||||
((image = xc_read_image(image_name, &image_size)) == NULL) )
|
||||
return -1;
|
||||
|
||||
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
|
||||
image, image_size,
|
||||
vcpus, pae, acpi, apic,
|
||||
store_evtchn, store_mfn);
|
||||
|
||||
free(image);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/* xc_hvm_build_mem
|
||||
*
|
||||
* Create a domain for a virtualized Linux, using buffers
|
||||
*
|
||||
*/
|
||||
|
||||
int xc_hvm_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
const char *image_buffer,
|
||||
unsigned long image_size,
|
||||
unsigned int vcpus,
|
||||
unsigned int pae,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
int sts;
|
||||
unsigned long img_len;
|
||||
char *img;
|
||||
|
||||
/* Validate that there is a kernel buffer */
|
||||
|
||||
if ( (image_buffer == NULL) || (image_size == 0) )
|
||||
{
|
||||
ERROR("kernel image buffer not present");
|
||||
return -1;
|
||||
}
|
||||
|
||||
img = xc_inflate_buffer(image_buffer, image_size, &img_len);
|
||||
if (img == NULL)
|
||||
{
|
||||
ERROR("unable to inflate ram disk buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
|
||||
img, img_len,
|
||||
vcpus, pae, acpi, apic,
|
||||
store_evtchn, store_mfn);
|
||||
|
||||
/* xc_inflate_buffer may return the original buffer pointer (for
|
||||
for already inflated buffers), so exercise some care in freeing */
|
||||
|
||||
if ( (img != NULL) && (img != image_buffer) )
|
||||
free(img);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -658,7 +658,7 @@ int xc_hvm_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){
|
||||
if ( (image = xc_read_image(image_name, &image_size)) == NULL ){
|
||||
PERROR("Could not read guest firmware image %s",image_name);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
+290
-167
@@ -46,6 +46,15 @@
|
||||
#define probe_aout9(image,image_size,load_funcs) 1
|
||||
#endif
|
||||
|
||||
struct initrd_info {
|
||||
enum { INITRD_none, INITRD_file, INITRD_mem } type;
|
||||
unsigned long len;
|
||||
union {
|
||||
gzFile file_handle;
|
||||
char *mem_addr;
|
||||
} u;
|
||||
};
|
||||
|
||||
static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
|
||||
[XENFEAT_writable_page_tables] = "writable_page_tables",
|
||||
[XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
|
||||
@@ -117,7 +126,7 @@ static int parse_features(
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int probeimageformat(char *image,
|
||||
static int probeimageformat(const char *image,
|
||||
unsigned long image_size,
|
||||
struct load_funcs *load_funcs)
|
||||
{
|
||||
@@ -132,6 +141,42 @@ static int probeimageformat(char *image,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_initrd(int xc_handle, domid_t dom,
|
||||
struct initrd_info *initrd,
|
||||
unsigned long physbase,
|
||||
unsigned long *phys_to_mach)
|
||||
{
|
||||
char page[PAGE_SIZE];
|
||||
unsigned long pfn_start, pfn, nr_pages;
|
||||
|
||||
if ( initrd->type == INITRD_none )
|
||||
return 0;
|
||||
|
||||
pfn_start = physbase >> PAGE_SHIFT;
|
||||
nr_pages = (initrd->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
|
||||
for ( pfn = pfn_start; pfn < (pfn_start + nr_pages); pfn++ )
|
||||
{
|
||||
if ( initrd->type == INITRD_mem )
|
||||
{
|
||||
xc_copy_to_domain_page(
|
||||
xc_handle, dom, phys_to_mach[pfn],
|
||||
&initrd->u.mem_addr[(pfn - pfn_start) << PAGE_SHIFT]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gzread(initrd->u.file_handle, page, PAGE_SIZE) == -1 )
|
||||
{
|
||||
PERROR("Error reading initrd image, could not");
|
||||
return -EINVAL;
|
||||
}
|
||||
xc_copy_to_domain_page(xc_handle, dom, phys_to_mach[pfn], page);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define alloc_pt(ltab, vltab, pltab) \
|
||||
do { \
|
||||
pltab = ppt_alloc++; \
|
||||
@@ -406,8 +451,8 @@ extern unsigned long xc_ia64_fpsr_default(void);
|
||||
|
||||
static int setup_guest(int xc_handle,
|
||||
uint32_t dom,
|
||||
char *image, unsigned long image_size,
|
||||
gzFile initrd_gfd, unsigned long initrd_len,
|
||||
const char *image, unsigned long image_size,
|
||||
struct initrd_info *initrd,
|
||||
unsigned long nr_pages,
|
||||
unsigned long *pvsi, unsigned long *pvke,
|
||||
unsigned long *pvss, vcpu_guest_context_t *ctxt,
|
||||
@@ -427,7 +472,6 @@ static int setup_guest(int xc_handle,
|
||||
unsigned long start_page, pgnr;
|
||||
start_info_t *start_info;
|
||||
int rc;
|
||||
unsigned long i;
|
||||
|
||||
rc = probeimageformat(image, image_size, &load_funcs);
|
||||
if ( rc != 0 )
|
||||
@@ -441,7 +485,7 @@ static int setup_guest(int xc_handle,
|
||||
|
||||
dsi.v_start = round_pgdown(dsi.v_start);
|
||||
vinitrd_start = round_pgup(dsi.v_end);
|
||||
vinitrd_end = vinitrd_start + initrd_len;
|
||||
vinitrd_end = vinitrd_start + initrd->len;
|
||||
v_end = round_pgup(vinitrd_end);
|
||||
|
||||
start_page = dsi.v_start >> PAGE_SHIFT;
|
||||
@@ -452,7 +496,8 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, start_page, pgnr) != pgnr )
|
||||
if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array,
|
||||
start_page, pgnr) != pgnr )
|
||||
{
|
||||
PERROR("Could not get the page frame list");
|
||||
goto error_out;
|
||||
@@ -472,23 +517,9 @@ static int setup_guest(int xc_handle,
|
||||
(load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
|
||||
&dsi);
|
||||
|
||||
/* Load the initial ramdisk image. */
|
||||
if ( initrd_len != 0 )
|
||||
{
|
||||
for ( i = (vinitrd_start - dsi.v_start);
|
||||
i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
|
||||
{
|
||||
char page[PAGE_SIZE];
|
||||
if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
|
||||
{
|
||||
PERROR("Error reading initrd image, could not");
|
||||
goto error_out;
|
||||
}
|
||||
xc_copy_to_domain_page(xc_handle, dom,
|
||||
page_array[i>>PAGE_SHIFT], page);
|
||||
}
|
||||
}
|
||||
|
||||
if ( load_initrd(xc_handle, dom, initrd,
|
||||
vinitrd_start - dsi.v_start, page_array) )
|
||||
goto error_out;
|
||||
|
||||
*pvke = dsi.v_kernentry;
|
||||
|
||||
@@ -522,11 +553,11 @@ static int setup_guest(int xc_handle,
|
||||
start_info->store_evtchn = store_evtchn;
|
||||
start_info->console_mfn = nr_pages - 1;
|
||||
start_info->console_evtchn = console_evtchn;
|
||||
start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ????
|
||||
if ( initrd_len != 0 )
|
||||
start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ????
|
||||
if ( initrd->len != 0 )
|
||||
{
|
||||
ctxt->initrd.start = vinitrd_start;
|
||||
ctxt->initrd.size = initrd_len;
|
||||
ctxt->initrd.size = initrd->len;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -550,8 +581,8 @@ static int setup_guest(int xc_handle,
|
||||
#else /* x86 */
|
||||
static int setup_guest(int xc_handle,
|
||||
uint32_t dom,
|
||||
char *image, unsigned long image_size,
|
||||
gzFile initrd_gfd, unsigned long initrd_len,
|
||||
const char *image, unsigned long image_size,
|
||||
struct initrd_info *initrd,
|
||||
unsigned long nr_pages,
|
||||
unsigned long *pvsi, unsigned long *pvke,
|
||||
unsigned long *pvss, vcpu_guest_context_t *ctxt,
|
||||
@@ -578,15 +609,11 @@ static int setup_guest(int xc_handle,
|
||||
struct load_funcs load_funcs;
|
||||
struct domain_setup_info dsi;
|
||||
unsigned long vinitrd_start;
|
||||
unsigned long vinitrd_end;
|
||||
unsigned long vphysmap_start;
|
||||
unsigned long vphysmap_end;
|
||||
unsigned long vstartinfo_start;
|
||||
unsigned long vstartinfo_end;
|
||||
unsigned long vstoreinfo_start;
|
||||
unsigned long vstoreinfo_end;
|
||||
unsigned long vconsole_start;
|
||||
unsigned long vconsole_end;
|
||||
unsigned long vsharedinfo_start = 0; /* XXX gcc */
|
||||
unsigned long vstack_start;
|
||||
unsigned long vstack_end;
|
||||
unsigned long vpt_start;
|
||||
@@ -612,6 +639,34 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
/* Parse and validate kernel features. */
|
||||
p = strstr(dsi.xen_guest_string, "FEATURES=");
|
||||
if ( p != NULL )
|
||||
{
|
||||
if ( !parse_features(p + strlen("FEATURES="),
|
||||
supported_features,
|
||||
required_features) )
|
||||
{
|
||||
ERROR("Failed to parse guest kernel features.\n");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
printf("Supported features = { %08x }.\n", supported_features[0]);
|
||||
printf("Required features = { %08x }.\n", required_features[0]);
|
||||
}
|
||||
|
||||
for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
|
||||
{
|
||||
if ( (supported_features[i]&required_features[i]) != required_features[i] )
|
||||
{
|
||||
ERROR("Guest kernel does not support a required feature.\n");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
|
||||
shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap,
|
||||
required_features);
|
||||
|
||||
/*
|
||||
* Why do we need this? The number of page-table frames depends on the
|
||||
* size of the bootstrap address space. But the size of the address space
|
||||
@@ -619,17 +674,22 @@ static int setup_guest(int xc_handle,
|
||||
* read-only). We have a pair of simultaneous equations in two unknowns,
|
||||
* which we solve by exhaustive search.
|
||||
*/
|
||||
vinitrd_start = round_pgup(dsi.v_end);
|
||||
vinitrd_end = vinitrd_start + initrd_len;
|
||||
vphysmap_start = round_pgup(vinitrd_end);
|
||||
vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long));
|
||||
vstartinfo_start = round_pgup(vphysmap_end);
|
||||
vstartinfo_end = vstartinfo_start + PAGE_SIZE;
|
||||
vstoreinfo_start = vstartinfo_end;
|
||||
vstoreinfo_end = vstoreinfo_start + PAGE_SIZE;
|
||||
vconsole_start = vstoreinfo_end;
|
||||
vconsole_end = vconsole_start + PAGE_SIZE;
|
||||
vpt_start = vconsole_end;
|
||||
v_end = round_pgup(dsi.v_end);
|
||||
vinitrd_start = v_end;
|
||||
v_end += round_pgup(initrd->len);
|
||||
vphysmap_start = v_end;
|
||||
v_end += round_pgup(nr_pages * sizeof(unsigned long));
|
||||
vstartinfo_start = v_end;
|
||||
v_end += PAGE_SIZE;
|
||||
vstoreinfo_start = v_end;
|
||||
v_end += PAGE_SIZE;
|
||||
vconsole_start = v_end;
|
||||
v_end += PAGE_SIZE;
|
||||
if ( shadow_mode_enabled ) {
|
||||
vsharedinfo_start = v_end;
|
||||
v_end += PAGE_SIZE;
|
||||
}
|
||||
vpt_start = v_end;
|
||||
|
||||
for ( nr_pt_pages = 2; ; nr_pt_pages++ )
|
||||
{
|
||||
@@ -669,26 +729,22 @@ static int setup_guest(int xc_handle,
|
||||
|
||||
#define _p(a) ((void *) (a))
|
||||
|
||||
printf("VIRTUAL MEMORY ARRANGEMENT:\n"
|
||||
" Loaded kernel: %p->%p\n"
|
||||
" Init. ramdisk: %p->%p\n"
|
||||
" Phys-Mach map: %p->%p\n"
|
||||
" Start info: %p->%p\n"
|
||||
" Store page: %p->%p\n"
|
||||
" Console page: %p->%p\n"
|
||||
" Page tables: %p->%p\n"
|
||||
" Boot stack: %p->%p\n"
|
||||
" TOTAL: %p->%p\n",
|
||||
_p(dsi.v_kernstart), _p(dsi.v_kernend),
|
||||
_p(vinitrd_start), _p(vinitrd_end),
|
||||
_p(vphysmap_start), _p(vphysmap_end),
|
||||
_p(vstartinfo_start), _p(vstartinfo_end),
|
||||
_p(vstoreinfo_start), _p(vstoreinfo_end),
|
||||
_p(vconsole_start), _p(vconsole_end),
|
||||
_p(vpt_start), _p(vpt_end),
|
||||
_p(vstack_start), _p(vstack_end),
|
||||
_p(dsi.v_start), _p(v_end));
|
||||
printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
|
||||
printf("VIRTUAL MEMORY ARRANGEMENT:\n");
|
||||
printf(" Loaded kernel: %p->%p\n", _p(dsi.v_kernstart),
|
||||
_p(dsi.v_kernend));
|
||||
if ( initrd->len )
|
||||
printf(" Initial ramdisk: %p->%p\n", _p(vinitrd_start),
|
||||
_p(vinitrd_start + initrd->len));
|
||||
printf(" Phys-Mach map: %p\n", _p(vphysmap_start));
|
||||
printf(" Start info: %p\n", _p(vstartinfo_start));
|
||||
printf(" Store page: %p\n", _p(vstoreinfo_start));
|
||||
printf(" Console page: %p\n", _p(vconsole_start));
|
||||
if ( shadow_mode_enabled )
|
||||
printf(" Shared Info page: %p\n", _p(vsharedinfo_start));
|
||||
printf(" Page tables: %p\n", _p(vpt_start));
|
||||
printf(" Boot stack: %p\n", _p(vstack_start));
|
||||
printf(" TOTAL: %p->%p\n", _p(dsi.v_start), _p(v_end));
|
||||
printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
|
||||
|
||||
if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
|
||||
{
|
||||
@@ -710,54 +766,13 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
(load_funcs.loadimage)(image, image_size, xc_handle, dom, page_array,
|
||||
(load_funcs.loadimage)(image, image_size,
|
||||
xc_handle, dom, page_array,
|
||||
&dsi);
|
||||
|
||||
/* Parse and validate kernel features. */
|
||||
p = strstr(dsi.xen_guest_string, "FEATURES=");
|
||||
if ( p != NULL )
|
||||
{
|
||||
if ( !parse_features(p + strlen("FEATURES="),
|
||||
supported_features,
|
||||
required_features) )
|
||||
{
|
||||
ERROR("Failed to parse guest kernel features.\n");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Supported features = { %08x }.\n",
|
||||
supported_features[0]);
|
||||
fprintf(stderr, "Required features = { %08x }.\n",
|
||||
required_features[0]);
|
||||
}
|
||||
|
||||
for ( i = 0; i < XENFEAT_NR_SUBMAPS; i++ )
|
||||
{
|
||||
if ( (supported_features[i]&required_features[i]) != required_features[i] )
|
||||
{
|
||||
ERROR("Guest kernel does not support a required feature.\n");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
|
||||
shadow_mode_enabled = test_feature_bit(XENFEAT_auto_translated_physmap, required_features);
|
||||
|
||||
/* Load the initial ramdisk image. */
|
||||
if ( initrd_len != 0 )
|
||||
{
|
||||
for ( i = (vinitrd_start - dsi.v_start);
|
||||
i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
|
||||
{
|
||||
char page[PAGE_SIZE];
|
||||
if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
|
||||
{
|
||||
PERROR("Error reading initrd image, could not");
|
||||
goto error_out;
|
||||
}
|
||||
xc_copy_to_domain_page(xc_handle, dom,
|
||||
page_array[i>>PAGE_SHIFT], page);
|
||||
}
|
||||
}
|
||||
if ( load_initrd(xc_handle, dom, initrd,
|
||||
vinitrd_start - dsi.v_start, page_array) )
|
||||
goto error_out;
|
||||
|
||||
/* setup page tables */
|
||||
#if defined(__i386__)
|
||||
@@ -851,7 +866,7 @@ static int setup_guest(int xc_handle,
|
||||
|
||||
if ( shadow_mode_enabled )
|
||||
{
|
||||
struct xen_reserved_phys_area xrpa;
|
||||
struct xen_add_to_physmap xatp;
|
||||
|
||||
/* Enable shadow translate mode */
|
||||
if ( xc_shadow_control(xc_handle, dom,
|
||||
@@ -862,17 +877,36 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
/* Find the shared info frame. It's guaranteed to be at the
|
||||
start of the PFN hole. */
|
||||
xrpa.domid = dom;
|
||||
xrpa.idx = 0;
|
||||
rc = xc_memory_op(xc_handle, XENMEM_reserved_phys_area, &xrpa);
|
||||
guest_shared_info_mfn = (vsharedinfo_start-dsi.v_start) >> PAGE_SHIFT;
|
||||
|
||||
/* Map shared info frame into guest physmap. */
|
||||
xatp.domid = dom;
|
||||
xatp.space = XENMAPSPACE_shared_info;
|
||||
xatp.idx = 0;
|
||||
xatp.gpfn = guest_shared_info_mfn;
|
||||
rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
PERROR("Cannot find shared info pfn");
|
||||
PERROR("Cannot map shared info pfn");
|
||||
goto error_out;
|
||||
}
|
||||
guest_shared_info_mfn = xrpa.first_gpfn;
|
||||
|
||||
/* Map grant table frames into guest physmap. */
|
||||
for ( i = 0; ; i++ )
|
||||
{
|
||||
xatp.domid = dom;
|
||||
xatp.space = XENMAPSPACE_grant_table;
|
||||
xatp.idx = i;
|
||||
xatp.gpfn = nr_pages + i;
|
||||
rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
if ( errno == EINVAL )
|
||||
break; /* done all grant tables */
|
||||
PERROR("Cannot map grant table pfn");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -914,10 +948,10 @@ static int setup_guest(int xc_handle,
|
||||
start_info->store_evtchn = store_evtchn;
|
||||
start_info->console_mfn = guest_console_mfn;
|
||||
start_info->console_evtchn = console_evtchn;
|
||||
if ( initrd_len != 0 )
|
||||
if ( initrd->len != 0 )
|
||||
{
|
||||
start_info->mod_start = vinitrd_start;
|
||||
start_info->mod_len = initrd_len;
|
||||
start_info->mod_len = initrd->len;
|
||||
}
|
||||
if ( cmdline != NULL )
|
||||
{
|
||||
@@ -970,27 +1004,24 @@ static int setup_guest(int xc_handle,
|
||||
}
|
||||
#endif
|
||||
|
||||
int xc_linux_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *image_name,
|
||||
const char *ramdisk_name,
|
||||
const char *cmdline,
|
||||
const char *features,
|
||||
unsigned long flags,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
static int xc_linux_build_internal(int xc_handle,
|
||||
uint32_t domid,
|
||||
char *image,
|
||||
unsigned long image_size,
|
||||
struct initrd_info *initrd,
|
||||
const char *cmdline,
|
||||
const char *features,
|
||||
unsigned long flags,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
dom0_op_t launch_op;
|
||||
DECLARE_DOM0_OP;
|
||||
int initrd_fd = -1;
|
||||
gzFile initrd_gfd = NULL;
|
||||
int rc, i;
|
||||
vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
|
||||
unsigned long nr_pages;
|
||||
char *image = NULL;
|
||||
unsigned long image_size, initrd_size=0;
|
||||
unsigned long vstartinfo_start, vkern_entry, vstack_start;
|
||||
uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
|
||||
|
||||
@@ -1009,26 +1040,6 @@ int xc_linux_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL )
|
||||
goto error_out;
|
||||
|
||||
if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
|
||||
{
|
||||
if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
|
||||
{
|
||||
PERROR("Could not open the initial ramdisk image");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
initrd_size = xc_get_filesz(initrd_fd);
|
||||
|
||||
if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
|
||||
{
|
||||
PERROR("Could not allocate decompression state for initrd");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VALGRIND
|
||||
memset(&st_ctxt, 0, sizeof(st_ctxt));
|
||||
#endif
|
||||
@@ -1051,7 +1062,8 @@ int xc_linux_build(int xc_handle,
|
||||
memset(ctxt, 0, sizeof(*ctxt));
|
||||
|
||||
if ( setup_guest(xc_handle, domid, image, image_size,
|
||||
initrd_gfd, initrd_size, nr_pages,
|
||||
initrd,
|
||||
nr_pages,
|
||||
&vstartinfo_start, &vkern_entry,
|
||||
&vstack_start, ctxt, cmdline,
|
||||
op.u.getdomaininfo.shared_info_frame,
|
||||
@@ -1063,12 +1075,6 @@ int xc_linux_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( initrd_fd >= 0 )
|
||||
close(initrd_fd);
|
||||
if ( initrd_gfd )
|
||||
gzclose(initrd_gfd);
|
||||
free(image);
|
||||
|
||||
#ifdef __ia64__
|
||||
/* based on new_thread in xen/arch/ia64/domain.c */
|
||||
ctxt->flags = 0;
|
||||
@@ -1154,14 +1160,131 @@ int xc_linux_build(int xc_handle,
|
||||
return rc;
|
||||
|
||||
error_out:
|
||||
if ( initrd_gfd != NULL )
|
||||
gzclose(initrd_gfd);
|
||||
else if ( initrd_fd >= 0 )
|
||||
close(initrd_fd);
|
||||
free(image);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xc_linux_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *image_buffer,
|
||||
unsigned long image_size,
|
||||
const char *initrd,
|
||||
unsigned long initrd_len,
|
||||
const char *cmdline,
|
||||
const char *features,
|
||||
unsigned long flags,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
int sts;
|
||||
char *img_buf;
|
||||
unsigned long img_len;
|
||||
struct initrd_info initrd_info = { .type = INITRD_none };
|
||||
|
||||
/* A kernel buffer is required */
|
||||
if ( (image_buffer == NULL) || (image_size == 0) )
|
||||
{
|
||||
ERROR("kernel image buffer not present");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If it's gzipped, inflate it; otherwise, use as is */
|
||||
/* xc_inflate_buffer may return the same buffer pointer if */
|
||||
/* the buffer is already inflated */
|
||||
img_buf = xc_inflate_buffer(image_buffer, image_size, &img_len);
|
||||
if ( img_buf == NULL )
|
||||
{
|
||||
ERROR("unable to inflate kernel image buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RAM disks are optional; if we get one, inflate it */
|
||||
if ( initrd != NULL )
|
||||
{
|
||||
initrd_info.type = INITRD_mem;
|
||||
initrd_info.u.mem_addr = xc_inflate_buffer(
|
||||
initrd, initrd_len, &initrd_info.len);
|
||||
if ( initrd_info.u.mem_addr == NULL )
|
||||
{
|
||||
ERROR("unable to inflate ram disk buffer");
|
||||
sts = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
sts = xc_linux_build_internal(xc_handle, domid, img_buf, img_len,
|
||||
&initrd_info, cmdline, features, flags,
|
||||
store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
|
||||
out:
|
||||
/* The inflation routines may pass back the same buffer so be */
|
||||
/* sure that we have a buffer and that it's not the one passed in. */
|
||||
/* Don't unnecessarily annoy/surprise/confound the caller */
|
||||
if ( (img_buf != NULL) && (img_buf != image_buffer) )
|
||||
free(img_buf);
|
||||
if ( (initrd_info.u.mem_addr != NULL) &&
|
||||
(initrd_info.u.mem_addr != initrd) )
|
||||
free(initrd_info.u.mem_addr);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
int xc_linux_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *image_name,
|
||||
const char *initrd_name,
|
||||
const char *cmdline,
|
||||
const char *features,
|
||||
unsigned long flags,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn)
|
||||
{
|
||||
char *image = NULL;
|
||||
unsigned long image_size;
|
||||
struct initrd_info initrd_info = { .type = INITRD_none };
|
||||
int fd = -1, sts = -1;
|
||||
|
||||
if ( (image_name == NULL) ||
|
||||
((image = xc_read_image(image_name, &image_size)) == NULL ))
|
||||
return -1;
|
||||
|
||||
if ( (initrd_name != NULL) && (strlen(initrd_name) != 0) )
|
||||
{
|
||||
initrd_info.type = INITRD_file;
|
||||
|
||||
if ( (fd = open(initrd_name, O_RDONLY)) < 0 )
|
||||
{
|
||||
PERROR("Could not open the initial ramdisk image");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
initrd_info.len = xc_get_filesz(fd);
|
||||
if ( (initrd_info.u.file_handle = gzdopen(fd, "rb")) == NULL )
|
||||
{
|
||||
PERROR("Could not allocate decompression state for initrd");
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
|
||||
sts = xc_linux_build_internal(xc_handle, domid, image, image_size,
|
||||
&initrd_info, cmdline, features, flags,
|
||||
store_evtchn, store_mfn,
|
||||
console_evtchn, console_mfn);
|
||||
|
||||
error_out:
|
||||
free(image);
|
||||
if ( fd >= 0 )
|
||||
close(fd);
|
||||
if ( initrd_info.u.file_handle )
|
||||
gzclose(initrd_info.u.file_handle);
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -12,20 +12,19 @@
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
|
||||
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
|
||||
#define KZERO 0x80000000
|
||||
#define KOFFSET(_p) ((_p)&~KZERO)
|
||||
|
||||
static int parseaout9image(char *, unsigned long, struct domain_setup_info *);
|
||||
static int loadaout9image(char *, unsigned long, int, uint32_t, unsigned long *, struct domain_setup_info *);
|
||||
static void copyout(int, uint32_t, unsigned long *, unsigned long, void *, int);
|
||||
struct Exec *get_header(char *, unsigned long, struct Exec *);
|
||||
static int parseaout9image(const char *, unsigned long, struct domain_setup_info *);
|
||||
static int loadaout9image(const char *, unsigned long, int, uint32_t, unsigned long *, struct domain_setup_info *);
|
||||
static void copyout(int, uint32_t, unsigned long *, unsigned long, const char *, int);
|
||||
struct Exec *get_header(const char *, unsigned long, struct Exec *);
|
||||
|
||||
|
||||
int
|
||||
probe_aout9(
|
||||
char *image,
|
||||
const char *image,
|
||||
unsigned long image_size,
|
||||
struct load_funcs *load_funcs)
|
||||
{
|
||||
@@ -43,7 +42,7 @@ probe_aout9(
|
||||
|
||||
static int
|
||||
parseaout9image(
|
||||
char *image,
|
||||
const char *image,
|
||||
unsigned long image_size,
|
||||
struct domain_setup_info *dsi)
|
||||
{
|
||||
@@ -77,7 +76,7 @@ parseaout9image(
|
||||
|
||||
static int
|
||||
loadaout9image(
|
||||
char *image,
|
||||
const char *image,
|
||||
unsigned long image_size,
|
||||
int xch, uint32_t dom,
|
||||
unsigned long *parray,
|
||||
@@ -111,7 +110,7 @@ copyout(
|
||||
int xch, uint32_t dom,
|
||||
unsigned long *parray,
|
||||
unsigned long addr,
|
||||
void *buf,
|
||||
const char *buf,
|
||||
int sz)
|
||||
{
|
||||
unsigned long pgoff, chunksz, off;
|
||||
@@ -143,7 +142,7 @@ copyout(
|
||||
*/
|
||||
struct Exec *
|
||||
get_header(
|
||||
char *image,
|
||||
const char *image,
|
||||
unsigned long image_size,
|
||||
struct Exec *ehdr)
|
||||
{
|
||||
|
||||
+11
-15
@@ -99,23 +99,22 @@ struct xen_bin_image_table
|
||||
#define FLAGS_REQUIRED XEN_REACTOS_FLAG_ADDRSVALID
|
||||
|
||||
static struct xen_bin_image_table *
|
||||
findtable(char *image, unsigned long image_size);
|
||||
findtable(const char *image, unsigned long image_size);
|
||||
static int
|
||||
parsebinimage(
|
||||
char *image, unsigned long image_size, struct domain_setup_info *dsi);
|
||||
const char *image, unsigned long image_size,
|
||||
struct domain_setup_info *dsi);
|
||||
static int
|
||||
loadbinimage(
|
||||
char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
const char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
unsigned long *parray, struct domain_setup_info *dsi);
|
||||
|
||||
int probe_bin(char *image,
|
||||
int probe_bin(const char *image,
|
||||
unsigned long image_size,
|
||||
struct load_funcs *load_funcs)
|
||||
{
|
||||
if ( NULL == findtable(image, image_size) )
|
||||
{
|
||||
if ( findtable(image, image_size) == NULL )
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
load_funcs->parseimage = parsebinimage;
|
||||
load_funcs->loadimage = loadbinimage;
|
||||
@@ -124,7 +123,7 @@ int probe_bin(char *image,
|
||||
}
|
||||
|
||||
static struct xen_bin_image_table *
|
||||
findtable(char *image, unsigned long image_size)
|
||||
findtable(const char *image, unsigned long image_size)
|
||||
{
|
||||
struct xen_bin_image_table *table;
|
||||
unsigned long *probe_ptr;
|
||||
@@ -133,15 +132,12 @@ findtable(char *image, unsigned long image_size)
|
||||
|
||||
/* Don't go outside the image */
|
||||
if ( image_size < sizeof(struct xen_bin_image_table) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
probe_count = image_size;
|
||||
/* Restrict to first 8k */
|
||||
if ( 8192 < probe_count )
|
||||
{
|
||||
if ( probe_count > 8192 )
|
||||
probe_count = 8192;
|
||||
}
|
||||
probe_count = (probe_count - sizeof(struct xen_bin_image_table)) /
|
||||
sizeof(unsigned long);
|
||||
|
||||
@@ -165,7 +161,7 @@ findtable(char *image, unsigned long image_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int parsebinimage(char *image,
|
||||
static int parsebinimage(const char *image,
|
||||
unsigned long image_size,
|
||||
struct domain_setup_info *dsi)
|
||||
{
|
||||
@@ -238,7 +234,7 @@ static int parsebinimage(char *image,
|
||||
|
||||
static int
|
||||
loadbinimage(
|
||||
char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
const char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
unsigned long *parray, struct domain_setup_info *dsi)
|
||||
{
|
||||
unsigned long size;
|
||||
|
||||
+14
-13
@@ -19,26 +19,25 @@
|
||||
|
||||
static int
|
||||
parseelfimage(
|
||||
char *image, unsigned long image_size, struct domain_setup_info *dsi);
|
||||
const char *image, unsigned long image_size,
|
||||
struct domain_setup_info *dsi);
|
||||
static int
|
||||
loadelfimage(
|
||||
char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
const char *image, unsigned long image_size, int xch, uint32_t dom,
|
||||
unsigned long *parray, struct domain_setup_info *dsi);
|
||||
static int
|
||||
loadelfsymtab(
|
||||
char *image, int xch, uint32_t dom, unsigned long *parray,
|
||||
const char *image, int xch, uint32_t dom, unsigned long *parray,
|
||||
struct domain_setup_info *dsi);
|
||||
|
||||
int probe_elf(char *image,
|
||||
int probe_elf(const char *image,
|
||||
unsigned long image_size,
|
||||
struct load_funcs *load_funcs)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
|
||||
|
||||
if ( !IS_ELF(*ehdr) )
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
load_funcs->parseimage = parseelfimage;
|
||||
load_funcs->loadimage = loadelfimage;
|
||||
@@ -52,7 +51,7 @@ static inline int is_loadable_phdr(Elf_Phdr *phdr)
|
||||
((phdr->p_flags & (PF_W|PF_X)) != 0));
|
||||
}
|
||||
|
||||
static int parseelfimage(char *image,
|
||||
static int parseelfimage(const char *image,
|
||||
unsigned long elfsize,
|
||||
struct domain_setup_info *dsi)
|
||||
{
|
||||
@@ -60,7 +59,8 @@ static int parseelfimage(char *image,
|
||||
Elf_Phdr *phdr;
|
||||
Elf_Shdr *shdr;
|
||||
unsigned long kernstart = ~0UL, kernend=0UL;
|
||||
char *shstrtab, *guestinfo=NULL, *p;
|
||||
const char *shstrtab;
|
||||
char *guestinfo=NULL, *p;
|
||||
int h;
|
||||
|
||||
if ( !IS_ELF(*ehdr) )
|
||||
@@ -98,7 +98,7 @@ static int parseelfimage(char *image,
|
||||
if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
|
||||
continue;
|
||||
|
||||
guestinfo = image + shdr->sh_offset;
|
||||
guestinfo = (char *)image + shdr->sh_offset;
|
||||
|
||||
if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
|
||||
(strstr(guestinfo, "GUEST_OS=linux") == NULL) )
|
||||
@@ -171,7 +171,7 @@ static int parseelfimage(char *image,
|
||||
|
||||
static int
|
||||
loadelfimage(
|
||||
char *image, unsigned long elfsize, int xch, uint32_t dom,
|
||||
const char *image, unsigned long elfsize, int xch, uint32_t dom,
|
||||
unsigned long *parray, struct domain_setup_info *dsi)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *)image;
|
||||
@@ -222,7 +222,7 @@ loadelfimage(
|
||||
|
||||
static int
|
||||
loadelfsymtab(
|
||||
char *image, int xch, uint32_t dom, unsigned long *parray,
|
||||
const char *image, int xch, uint32_t dom, unsigned long *parray,
|
||||
struct domain_setup_info *dsi)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *)image, *sym_ehdr;
|
||||
@@ -271,8 +271,9 @@ loadelfsymtab(
|
||||
(shdr[h].sh_type == SHT_SYMTAB) )
|
||||
{
|
||||
if ( parray != NULL )
|
||||
xc_map_memcpy(maxva, image + shdr[h].sh_offset, shdr[h].sh_size,
|
||||
xch, dom, parray, dsi->v_start);
|
||||
xc_map_memcpy(maxva, image + shdr[h].sh_offset,
|
||||
shdr[h].sh_size,
|
||||
xch, dom, parray, dsi->v_start);
|
||||
|
||||
/* Mangled to be based on ELF header location. */
|
||||
shdr[h].sh_offset = maxva - dsi->symtab_addr;
|
||||
|
||||
@@ -231,8 +231,8 @@ int xc_memory_op(int xc_handle,
|
||||
goto out1;
|
||||
}
|
||||
break;
|
||||
case XENMEM_reserved_phys_area:
|
||||
if ( mlock(arg, sizeof(struct xen_reserved_phys_area)) )
|
||||
case XENMEM_add_to_physmap:
|
||||
if ( mlock(arg, sizeof(struct xen_add_to_physmap)) )
|
||||
{
|
||||
PERROR("Could not mlock");
|
||||
goto out1;
|
||||
@@ -277,8 +277,8 @@ int xc_memory_op(int xc_handle,
|
||||
safe_munlock(xmml->extent_start,
|
||||
xmml->max_extents * sizeof(unsigned long));
|
||||
break;
|
||||
case XENMEM_reserved_phys_area:
|
||||
safe_munlock(arg, sizeof(struct xen_reserved_phys_area));
|
||||
case XENMEM_add_to_physmap:
|
||||
safe_munlock(arg, sizeof(struct xen_add_to_physmap));
|
||||
break;
|
||||
case XENMEM_translate_gpfn_list:
|
||||
safe_munlock(trans->mfn_list, trans->nr_gpfns * sizeof(long));
|
||||
@@ -364,7 +364,7 @@ long xc_get_tot_pages(int xc_handle, uint32_t domid)
|
||||
int xc_copy_to_domain_page(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned long dst_pfn,
|
||||
void *src_page)
|
||||
const char *src_page)
|
||||
{
|
||||
void *vaddr = xc_map_foreign_range(
|
||||
xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
|
||||
@@ -410,7 +410,7 @@ unsigned long xc_get_filesz(int fd)
|
||||
return sz;
|
||||
}
|
||||
|
||||
void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
|
||||
void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
|
||||
int xch, uint32_t dom, unsigned long *parray,
|
||||
unsigned long vstart)
|
||||
{
|
||||
|
||||
+30
-1
@@ -1,6 +1,5 @@
|
||||
#define XC_PTRACE_PRIVATE
|
||||
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
@@ -9,6 +8,36 @@
|
||||
#include "xg_private.h"
|
||||
#include "xc_ptrace.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
static char *ptrace_names[] = {
|
||||
"PTRACE_TRACEME",
|
||||
"PTRACE_PEEKTEXT",
|
||||
"PTRACE_PEEKDATA",
|
||||
"PTRACE_PEEKUSER",
|
||||
"PTRACE_POKETEXT",
|
||||
"PTRACE_POKEDATA",
|
||||
"PTRACE_POKEUSER",
|
||||
"PTRACE_CONT",
|
||||
"PTRACE_KILL",
|
||||
"PTRACE_SINGLESTEP",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_GETREGS",
|
||||
"PTRACE_SETREGS",
|
||||
"PTRACE_GETFPREGS",
|
||||
"PTRACE_SETFPREGS",
|
||||
"PTRACE_ATTACH",
|
||||
"PTRACE_DETACH",
|
||||
"PTRACE_GETFPXREGS",
|
||||
"PTRACE_SETFPXREGS",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_SYSCALL",
|
||||
};
|
||||
#endif
|
||||
|
||||
/* XXX application state */
|
||||
static long nr_pages = 0;
|
||||
static unsigned long *page_array = NULL;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#define PDRSHIFT 22
|
||||
#define PSL_T 0x00000100 /* trace enable bit */
|
||||
|
||||
extern const char const * ptrace_names[];
|
||||
|
||||
struct gdb_regs {
|
||||
long ebx; /* 0 */
|
||||
long ecx; /* 4 */
|
||||
|
||||
+24
-6
@@ -139,10 +139,28 @@ int xc_domain_create(int xc_handle,
|
||||
uint32_t *pdomid);
|
||||
|
||||
|
||||
/* Functions to produce a dump of a given domain
|
||||
* xc_domain_dumpcore - produces a dump to a specified file
|
||||
* xc_domain_dumpcore_via_callback - produces a dump, using a specified
|
||||
* callback function
|
||||
*/
|
||||
int xc_domain_dumpcore(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *corename);
|
||||
|
||||
/* Define the callback function type for xc_domain_dumpcore_via_callback.
|
||||
*
|
||||
* This function is called by the coredump code for every "write",
|
||||
* and passes an opaque object for the use of the function and
|
||||
* created by the caller of xc_domain_dumpcore_via_callback.
|
||||
*/
|
||||
typedef int (dumpcore_rtn_t)(void *arg, char *buffer, unsigned int length);
|
||||
|
||||
int xc_domain_dumpcore_via_callback(int xc_handle,
|
||||
uint32_t domid,
|
||||
void *arg,
|
||||
dumpcore_rtn_t dump_rtn);
|
||||
|
||||
/*
|
||||
* This function sets the maximum number of vcpus that a domain may create.
|
||||
*
|
||||
@@ -372,13 +390,13 @@ int xc_domain_memory_increase_reservation(int xc_handle,
|
||||
unsigned long nr_extents,
|
||||
unsigned int extent_order,
|
||||
unsigned int address_bits,
|
||||
unsigned long *extent_start);
|
||||
unsigned long *extent_start);
|
||||
|
||||
int xc_domain_memory_decrease_reservation(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned long nr_extents,
|
||||
unsigned int extent_order,
|
||||
unsigned long *extent_start);
|
||||
unsigned long *extent_start);
|
||||
|
||||
int xc_domain_memory_populate_physmap(int xc_handle,
|
||||
uint32_t domid,
|
||||
@@ -411,7 +429,7 @@ int xc_domain_iomem_permission(int xc_handle,
|
||||
uint8_t allow_access);
|
||||
|
||||
unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
|
||||
unsigned long mfn);
|
||||
unsigned long mfn);
|
||||
|
||||
typedef dom0_perfc_desc_t xc_perfc_desc_t;
|
||||
/* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */
|
||||
@@ -457,7 +475,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
|
||||
* @parm virt the virtual address to translate
|
||||
*/
|
||||
unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
|
||||
int vcpu, unsigned long long virt);
|
||||
int vcpu, unsigned long long virt);
|
||||
|
||||
int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
|
||||
unsigned long max_pfns);
|
||||
@@ -467,7 +485,7 @@ int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid,
|
||||
unsigned int start_page, unsigned int nr_pages);
|
||||
|
||||
int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
|
||||
unsigned long dst_pfn, void *src_page);
|
||||
unsigned long dst_pfn, const char *src_page);
|
||||
|
||||
int xc_clear_domain_page(int xc_handle, uint32_t domid,
|
||||
unsigned long dst_pfn);
|
||||
@@ -478,7 +496,7 @@ int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid,
|
||||
long xc_get_max_pages(int xc_handle, uint32_t domid);
|
||||
|
||||
int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops,
|
||||
domid_t dom);
|
||||
domid_t dom);
|
||||
|
||||
int xc_memory_op(int xc_handle, int cmd, void *arg);
|
||||
|
||||
|
||||
+61
-1
@@ -42,6 +42,22 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom,
|
||||
unsigned long *store_mfn, unsigned int console_evtchn,
|
||||
unsigned long *console_mfn);
|
||||
|
||||
/**
|
||||
* This function will create a domain for a paravirtualized Linux
|
||||
* using file names pointing to kernel and ramdisk
|
||||
*
|
||||
* @parm xc_handle a handle to an open hypervisor interface
|
||||
* @parm domid the id of the domain
|
||||
* @param image_name name of the kernel image file
|
||||
* @param ramdisk_name name of the ramdisk image file
|
||||
* @parm cmdline command line string
|
||||
* @parm flags domain creation flags
|
||||
* @parm store_evtchn the store event channel for this domain to use
|
||||
* @parm store_mfn returned with the mfn of the store page
|
||||
* @parm console_evtchn the console event channel for this domain to use
|
||||
* @parm conole_mfn returned with the mfn of the console page
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_linux_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *image_name,
|
||||
@@ -54,6 +70,38 @@ int xc_linux_build(int xc_handle,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn);
|
||||
|
||||
/**
|
||||
* This function will create a domain for a paravirtualized Linux
|
||||
* using buffers for kernel and initrd
|
||||
*
|
||||
* @param xc_handle a handle to an open hypervisor interface
|
||||
* @param domid the id of the domain
|
||||
* @param image_buffer buffer containing kernel image
|
||||
* @param image_size size of the kernel image buffer
|
||||
* @param initrd_buffer name of the ramdisk image file
|
||||
* @param initrd_size size of the ramdisk buffer
|
||||
* @param cmdline command line string
|
||||
* @param flags domain creation flags
|
||||
* @param store_evtchn the store event channel for this domain to use
|
||||
* @param store_mfn returned with the mfn of the store page
|
||||
* @param console_evtchn the console event channel for this domain to use
|
||||
* @param conole_mfn returned with the mfn of the console page
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_linux_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
const char *image_buffer,
|
||||
unsigned long image_size,
|
||||
const char *initrd_buffer,
|
||||
unsigned long initrd_size,
|
||||
const char *cmdline,
|
||||
const char *features,
|
||||
unsigned long flags,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn,
|
||||
unsigned int console_evtchn,
|
||||
unsigned long *console_mfn);
|
||||
|
||||
int xc_hvm_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
@@ -65,4 +113,16 @@ int xc_hvm_build(int xc_handle,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn);
|
||||
|
||||
#endif // XENGUEST_H
|
||||
int xc_hvm_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
int memsize,
|
||||
const char *image_buffer,
|
||||
unsigned long image_size,
|
||||
unsigned int vcpus,
|
||||
unsigned int pae,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn);
|
||||
|
||||
#endif /* XENGUEST_H */
|
||||
@@ -10,15 +10,15 @@
|
||||
|
||||
#include "xg_private.h"
|
||||
|
||||
char *xc_read_kernel_image(const char *filename, unsigned long *size)
|
||||
char *xc_read_image(const char *filename, unsigned long *size)
|
||||
{
|
||||
int kernel_fd = -1;
|
||||
gzFile kernel_gfd = NULL;
|
||||
char *image = NULL;
|
||||
unsigned int bytes;
|
||||
|
||||
if ( filename == NULL )
|
||||
goto out;
|
||||
if ( (filename == NULL) || (size == NULL) )
|
||||
return NULL;
|
||||
|
||||
if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
|
||||
{
|
||||
@@ -60,6 +60,62 @@ char *xc_read_kernel_image(const char *filename, unsigned long *size)
|
||||
return image;
|
||||
}
|
||||
|
||||
char *xc_inflate_buffer(const char *in_buf, unsigned long in_size,
|
||||
unsigned long *out_size)
|
||||
{
|
||||
int sts;
|
||||
z_stream zStream;
|
||||
unsigned long out_len;
|
||||
char *out_buf;
|
||||
|
||||
/* Not compressed? Then return the original buffer. */
|
||||
if ( ((unsigned char)in_buf[0] != 0x1F) ||
|
||||
((unsigned char)in_buf[1] != 0x8B) )
|
||||
{
|
||||
if ( out_size != NULL )
|
||||
*out_size = in_size;
|
||||
return (char *)in_buf;
|
||||
}
|
||||
|
||||
out_len = in_buf[in_size-4] +
|
||||
(256 * (in_buf[in_size-3] +
|
||||
(256 * (in_buf[in_size-2] +
|
||||
(256 * in_buf[in_size-1])))));
|
||||
bzero(&zStream, sizeof(zStream));
|
||||
out_buf = malloc(out_len + 16); /* Leave a little extra space */
|
||||
if ( out_buf == NULL )
|
||||
{
|
||||
ERROR("Error mallocing buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zStream.next_in = (unsigned char *)in_buf;
|
||||
zStream.avail_in = in_size;
|
||||
zStream.next_out = (unsigned char *)out_buf;
|
||||
zStream.avail_out = out_len+16;
|
||||
sts = inflateInit2(&zStream, (MAX_WBITS+32)); /* +32 means "handle gzip" */
|
||||
if ( sts != Z_OK )
|
||||
{
|
||||
ERROR("inflateInit failed, sts %d\n", sts);
|
||||
free(out_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Inflate in one pass/call */
|
||||
sts = inflate(&zStream, Z_FINISH);
|
||||
if ( sts != Z_STREAM_END )
|
||||
{
|
||||
ERROR("inflate failed, sts %d\n", sts);
|
||||
free(out_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( out_size != NULL )
|
||||
*out_size = out_len;
|
||||
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
/*******************/
|
||||
|
||||
int pin_table(
|
||||
@@ -77,7 +133,7 @@ int pin_table(
|
||||
}
|
||||
|
||||
/* This is shared between save and restore, and may generally be useful. */
|
||||
unsigned long csum_page (void * page)
|
||||
unsigned long csum_page(void *page)
|
||||
{
|
||||
int i;
|
||||
unsigned long *p = page;
|
||||
|
||||
+23
-15
@@ -26,7 +26,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
char *xc_read_kernel_image(const char *filename, unsigned long *size);
|
||||
char *xc_read_image(const char *filename, unsigned long *size);
|
||||
char *xc_inflate_buffer(const char *in_buf,
|
||||
unsigned long in_size,
|
||||
unsigned long *out_size);
|
||||
|
||||
unsigned long csum_page (void * page);
|
||||
|
||||
#define _PAGE_PRESENT 0x001
|
||||
@@ -89,7 +93,7 @@ typedef unsigned long l4_pgentry_t;
|
||||
#define l2_table_offset_pae(_a) \
|
||||
(((_a) >> L2_PAGETABLE_SHIFT_PAE) & (L2_PAGETABLE_ENTRIES_PAE - 1))
|
||||
#define l3_table_offset_pae(_a) \
|
||||
(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
|
||||
(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
|
||||
|
||||
#if defined(__i386__)
|
||||
#define l1_table_offset(_a) \
|
||||
@@ -102,9 +106,9 @@ typedef unsigned long l4_pgentry_t;
|
||||
#define l2_table_offset(_a) \
|
||||
(((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
|
||||
#define l3_table_offset(_a) \
|
||||
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
|
||||
(((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
|
||||
#define l4_table_offset(_a) \
|
||||
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
|
||||
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
|
||||
#endif
|
||||
|
||||
#define ERROR(_m, _a...) \
|
||||
@@ -141,11 +145,12 @@ struct domain_setup_info
|
||||
char *xen_guest_string;
|
||||
};
|
||||
|
||||
typedef int (*parseimagefunc)(char *image, unsigned long image_size,
|
||||
struct domain_setup_info *dsi);
|
||||
typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch,
|
||||
uint32_t dom, unsigned long *parray,
|
||||
struct domain_setup_info *dsi);
|
||||
typedef int (*parseimagefunc)(const char *image, unsigned long image_size,
|
||||
struct domain_setup_info *dsi);
|
||||
typedef int (*loadimagefunc)(const char *image, unsigned long image_size,
|
||||
int xch,
|
||||
uint32_t dom, unsigned long *parray,
|
||||
struct domain_setup_info *dsi);
|
||||
|
||||
struct load_funcs
|
||||
{
|
||||
@@ -167,21 +172,24 @@ typedef struct mfn_mapper {
|
||||
} mfn_mapper_t;
|
||||
|
||||
int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
|
||||
unsigned long dst_pfn, void *src_page);
|
||||
unsigned long dst_pfn, const char *src_page);
|
||||
|
||||
unsigned long xc_get_filesz(int fd);
|
||||
|
||||
void xc_map_memcpy(unsigned long dst, char *src, unsigned long size,
|
||||
void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size,
|
||||
int xch, uint32_t dom, unsigned long *parray,
|
||||
unsigned long vstart);
|
||||
|
||||
int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
|
||||
domid_t dom);
|
||||
domid_t dom);
|
||||
|
||||
/* image loading */
|
||||
int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs);
|
||||
int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs);
|
||||
int probe_aout9(char *image, unsigned long image_size, struct load_funcs *funcs);
|
||||
int probe_elf(const char *image, unsigned long image_size,
|
||||
struct load_funcs *funcs);
|
||||
int probe_bin(const char *image, unsigned long image_size,
|
||||
struct load_funcs *funcs);
|
||||
int probe_aout9(const char *image, unsigned long image_size,
|
||||
struct load_funcs *funcs);
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
XEN_ROOT=../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
CFLAGS += -Wall -Werror -O3
|
||||
CFLAGS += -Werror
|
||||
|
||||
INCLUDES += -I $(XEN_XC)
|
||||
INCLUDES += -I $(XEN_LIBXC)
|
||||
|
||||
@@ -17,8 +17,6 @@ INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
XEN_ROOT=../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
CFLAGS += -Wall -O3
|
||||
|
||||
HDRS = $(wildcard *.h)
|
||||
SRCS = $(wildcard *.c)
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
static int xc_handle;
|
||||
|
||||
void xen_init()
|
||||
void xen_init(void)
|
||||
{
|
||||
if ( (xc_handle = xc_interface_open()) == -1 )
|
||||
{
|
||||
@@ -24,12 +24,12 @@ void xen_init()
|
||||
|
||||
}
|
||||
|
||||
void dom0_wrmsr( int cpu_mask, int msr, unsigned int low, unsigned int high )
|
||||
void dom0_wrmsr(int cpu_mask, int msr, unsigned int low, unsigned int high)
|
||||
{
|
||||
xc_msr_write (xc_handle, cpu_mask, msr, low, high);
|
||||
}
|
||||
|
||||
unsigned long long dom0_rdmsr( int cpu_mask, int msr )
|
||||
unsigned long long dom0_rdmsr(int cpu_mask, int msr)
|
||||
{
|
||||
return xc_msr_read(xc_handle, cpu_mask, msr);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ INSTALL_DATA = $(INSTALL) -m0644
|
||||
XEN_ROOT=../../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
CFLAGS += -Wall -Werror -O3
|
||||
CFLAGS += -Werror
|
||||
|
||||
HDRS = $(wildcard *.h)
|
||||
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
|
||||
Loaded 100 of 254 files, more files were not shown because too many files have changed in this diff.
Show more