This commit is contained in:
awilliam@xenbuild.aw committed 2006-03-14 13:50:35 -07:00
commit 44784246fc
254 files changed
+4439 -2223

No files matched your search

+21
View File
@@ -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)
+1
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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)
+2
View File
@@ -15,3 +15,5 @@ memory = 32
# A name for your domain. All domains must have different names.
name = "Mini-OS"
on_crash = 'destroy'
+1
View File
@@ -57,6 +57,7 @@
#include <stdarg.h>
/* printing */
#define printk printf
#define kprintf printf
+51 -23
View File
@@ -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);
+2
View File
@@ -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
View File
@@ -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");
}
+24
View File
@@ -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, &ltype);
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;
+9 -4
View File
@@ -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++)
+1 -1
View File
@@ -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);
+9 -15
View File
@@ -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);
/*
+6 -4
View File
@@ -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)
{
+10 -11
View File
@@ -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;
+50 -23
View File
@@ -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;
+22 -23
View File
@@ -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);
+2 -2
View File
@@ -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
+8 -8
View File
@@ -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
View File
@@ -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
-3
View File
@@ -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():
+2 -5
View File
@@ -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)
-3
View File
@@ -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.
+1 -1
View File
@@ -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)
+3 -2
View File
@@ -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;
+1 -3
View File
@@ -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
-1
View File
@@ -20,7 +20,6 @@ INCLUDES += -I ./linux-2.6-module
INCLUDES += -I $(OCAML_ROOT)/lib/ocaml
CFLAGS += $(INCLUDES)
CFLAGS += -Wall
CFLAGS += -Werror
CFLAGS += -g
+10 -11
View File
@@ -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
+1 -1
View File
@@ -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
+11 -11
View File
@@ -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
+4
View File
@@ -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)
+3 -4
View File
@@ -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
View File
@@ -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 */
-4
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
+9 -10
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+6 -6
View File
@@ -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
View File
@@ -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;
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+60 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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)
-2
View File
@@ -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))
+3 -3
View File
@@ -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);
}
+1 -1
View File
@@ -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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.