bitkeeper revision 1.1159.1.477 (41bf20d2wgoxIqhcE0nzBC8W-yFPhg)

sync w/ head.
This commit is contained in:
cl349@arcadians.cl.cam.ac.uk committed 2004-12-14 17:20:18 +00:00
commit df663f9a14
34 files changed
+727 -193

No files matched your search

+5 -1
View File
@@ -705,7 +705,9 @@
40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c
3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c
40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S
41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/x86/x86_64/mm.c
40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
@@ -793,6 +795,7 @@
40715b2dWe0tDhx9LkLXzTQkvD49RA xen/include/asm-x86/acpi.h
3ddb79c3l4IiQtf6MS2jIzcd-hJS8g xen/include/asm-x86/apic.h
3ddb79c3QJYWr8LLGdonLbWmNb9pQQ xen/include/asm-x86/apicdef.h
41bf17171g_hhz2k4B-fN9LQlODDjQ xen/include/asm-x86/asm_defns.h
3ddb79c3OiG9eTsi9Dy3F_OkuRAzKA xen/include/asm-x86/atomic.h
3ddb79c3rM-Ote0Xn6Ytg8Y6YqAG-A xen/include/asm-x86/bitops.h
3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/include/asm-x86/cache.h
@@ -804,7 +807,6 @@
3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h
3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h
40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h
40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/asm-x86/domain.h
3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/domain_page.h
3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h
3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h
@@ -840,6 +842,7 @@
3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h
3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h
404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
@@ -867,6 +870,7 @@
3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h
3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h
3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h
40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/xen/domain.h
3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h
3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h
3ddb79c1W0lQca8gRV7sN6j3iY4Luw xen/include/xen/event.h
@@ -1056,7 +1056,6 @@ void __init trap_init(void)
* default LDT is a single-entry callgate to lcall7 for iBCS
* and a callgate to lcall27 for Solaris/x86 binaries
*/
clear_page(&default_ldt[0]);
set_call_gate(&default_ldt[0],lcall7);
set_call_gate(&default_ldt[4],lcall27);
make_lowmem_page_readonly(&default_ldt[0]);
+9 -8
View File
@@ -9,14 +9,15 @@
#ifndef __XC_H__
#define __XC_H__
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned long long u64;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
typedef signed long long s64;
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
#include <xen/xen.h>
#include <xen/dom0_ops.h>
+4 -3
View File
@@ -6,6 +6,7 @@
* Copyright (c) 2003, K A Fraser.
*/
#include <inttypes.h>
#include <sys/time.h>
#include "xc_private.h"
#include <xen/linux/suspend.h>
@@ -245,7 +246,7 @@ static int print_stats( int xc_handle, u32 domid,
if ( print )
printf("delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, "
"dirtied %dMb/s %ld pages\n",
"dirtied %dMb/s %" PRId32 " pages\n",
wall_delta,
(int)((d0_cpu_delta*100)/wall_delta),
(int)((d1_cpu_delta*100)/wall_delta),
@@ -307,8 +308,8 @@ static int analysis_phase( int xc_handle, u32 domid,
DOM0_SHADOW_CONTROL_OP_PEEK,
NULL, 0, &stats);
printf("now= %lld faults= %ld dirty= %ld dirty_net= %ld "
"dirty_block= %ld\n",
printf("now= %lld faults= %" PRId32 " dirty= %" PRId32
" dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
((now-start)+500)/1000,
stats.fault_count, stats.dirty_count,
stats.dirty_net_count, stats.dirty_block_count);
+2 -2
View File
@@ -1,9 +1,9 @@
# This is the correct place to edit the build version.
# All other places this is stored (eg. compile.h) should be autogenerated.
export XEN_VERSION = 2
export XEN_VERSION = 3
export XEN_SUBVERSION = 0
export XEN_EXTRAVERSION = ""
export XEN_EXTRAVERSION = "-devel"
export BASEDIR := $(shell pwd)
+6 -14
View File
@@ -257,30 +257,22 @@ copy_to_user:
set_intr_gate:
die:
machine_to_phys_mapping:
.globl copy_from_user, show_registers, __set_fixmap, do_iopl, check_descriptor
.globl copy_from_user, show_registers, do_iopl
copy_from_user:
show_registers:
__set_fixmap:
do_iopl:
check_descriptor:
.globl set_gdt, idt_table, copy_user_generic, memcmp, idt_tables, new_thread
set_gdt:
.globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread
idt_table:
copy_user_generic:
memcmp:
idt_tables:
new_thread:
.globl switch_to, continue_nonidle_task, __get_user_1, paging_init, trap_init
.globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init
switch_to:
continue_nonidle_task:
__get_user_1:
paging_init:
trap_init:
.globl __get_user_8, zap_low_mappings, set_debugreg,synchronise_pagetables
__get_user_4:
__get_user_8:
zap_low_mappings:
trap_init:
.globl set_debugreg
set_debugreg:
synchronise_pagetables:
.globl destroy_gdt
destroy_gdt:
+47 -47
View File
@@ -48,35 +48,16 @@
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
#define round_pgdown(_p) ((_p)&PAGE_MASK)
int hlt_counter;
void disable_hlt(void)
{
hlt_counter++;
}
void enable_hlt(void)
{
hlt_counter--;
}
/*
* We use this if we don't have any better
* idle routine..
*/
static void default_idle(void)
{
if ( hlt_counter == 0 )
{
__cli();
if ( !softirq_pending(smp_processor_id()) )
safe_halt();
else
__sti();
}
__cli();
if ( !softirq_pending(smp_processor_id()) )
safe_halt();
else
__sti();
}
void continue_cpu_idle_loop(void)
static void idle_loop(void)
{
int cpu = smp_processor_id();
for ( ; ; )
@@ -102,7 +83,7 @@ void startup_cpu_idle_loop(void)
smp_mb();
init_idle();
continue_cpu_idle_loop();
idle_loop();
}
static long no_idt[2];
@@ -216,23 +197,43 @@ void free_perdomain_pt(struct domain *d)
free_xenheap_page((unsigned long)d->mm_perdomain_pt);
}
void arch_do_createdomain(struct exec_domain *ed)
static void continue_idle_task(struct domain *d)
{
reset_stack_and_jump(idle_loop);
}
static void continue_nonidle_task(struct domain *d)
{
reset_stack_and_jump(ret_from_intr);
}
{
struct domain *d = ed->domain;
d->shared_info = (void *)alloc_xenheap_page();
memset(d->shared_info, 0, PAGE_SIZE);
ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
d->shared_info->arch.mfn_to_pfn_start =
virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
PAGE_SHIFT] = INVALID_P2M_ENTRY;
#ifdef ARCH_HAS_FAST_TRAP
SET_DEFAULT_FAST_TRAP(&d->thread);
#endif
d->mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
memset(d->mm_perdomain_pt, 0, PAGE_SIZE);
machine_to_phys_mapping[virt_to_phys(d->mm_perdomain_pt) >>
PAGE_SHIFT] = INVALID_P2M_ENTRY;
ed->mm.perdomain_ptes = d->mm_perdomain_pt;
if ( d->id == IDLE_DOMAIN_ID )
{
d->thread.schedule_tail = continue_idle_task;
}
else
{
d->thread.schedule_tail = continue_nonidle_task;
d->shared_info = (void *)alloc_xenheap_page();
memset(d->shared_info, 0, PAGE_SIZE);
ed->vcpu_info = &d->shared_info->vcpu_data[ed->eid];
d->shared_info->arch.mfn_to_pfn_start =
virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
machine_to_phys_mapping[virt_to_phys(d->shared_info) >>
PAGE_SHIFT] = INVALID_P2M_ENTRY;
d->mm_perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page();
memset(d->mm_perdomain_pt, 0, PAGE_SIZE);
machine_to_phys_mapping[virt_to_phys(d->mm_perdomain_pt) >>
PAGE_SHIFT] = INVALID_P2M_ENTRY;
}
int arch_final_setup_guestos(struct exec_domain *d, full_execution_context_t *c)
@@ -270,7 +271,6 @@ int arch_final_setup_guestos(struct exec_domain *d, full_execution_context_t *c)
sizeof(d->thread.traps));
#ifdef ARCH_HAS_FAST_TRAP
SET_DEFAULT_FAST_TRAP(&d->thread);
if ( (rc = (int)set_fast_trap(d, c->fast_trap_idx)) != 0 )
return rc;
#endif
@@ -335,9 +335,6 @@ void new_thread(struct exec_domain *d,
__save_flags(ec->eflags);
ec->eflags |= X86_EFLAGS_IF;
/* No fast trap at start of day. */
SET_DEFAULT_FAST_TRAP(&d->thread);
}
@@ -434,6 +431,8 @@ long do_iopl(domid_t domain, unsigned int new_io_pl)
return 0;
}
#endif
unsigned long hypercall_create_continuation(
unsigned int op, unsigned int nr_args, ...)
{
@@ -455,11 +454,15 @@ unsigned long hypercall_create_continuation(
else
{
ec = get_execution_context();
#if defined(__i386__)
ec->eax = op;
ec->eip -= 2; /* re-execute 'int 0x82' */
for ( i = 0, preg = &ec->ebx; i < nr_args; i++, preg++ )
*preg = va_arg(args, unsigned long);
#else
preg = NULL; /* XXX x86/64 */
#endif
}
va_end(args);
@@ -467,9 +470,6 @@ unsigned long hypercall_create_continuation(
return op;
}
#endif
static void relinquish_list(struct domain *d, struct list_head *list)
{
struct list_head *ent;
+2
View File
@@ -328,6 +328,8 @@ void __init start_of_day(void)
sort_exception_tables();
arch_do_createdomain(current);
/* Tell the PCI layer not to allocate too close to the RAM area.. */
low_mem_size = ((max_page << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
if ( low_mem_size > pci_mem_start ) pci_mem_start = low_mem_size;
-4
View File
@@ -665,10 +665,6 @@ static void __init do_boot_cpu (int apicid)
map_cpu_to_boot_apicid(cpu, apicid);
#if defined(__i386__)
SET_DEFAULT_FAST_TRAP(&ed->thread);
#endif
idle_task[cpu] = ed;
/* start_eip had better be page-aligned! */
+6
View File
@@ -998,4 +998,10 @@ unsigned long do_get_debugreg(int reg)
return current->thread.debugreg[reg];
}
#else
asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs)
{
}
#endif /* __i386__ */
+1 -5
View File
@@ -56,7 +56,7 @@
#include <xen/config.h>
#include <xen/errno.h>
#include <xen/softirq.h>
#include <asm/x86_32/asm_defns.h>
#include <asm/asm_defns.h>
#include <public/xen.h>
#define GET_CURRENT(reg) \
@@ -65,10 +65,6 @@
andl $~3,reg; \
movl (reg),reg;
ENTRY(continue_nonidle_task)
GET_CURRENT(%ebx)
jmp test_all_events
ALIGN
restore_all_guest:
testb $TF_failsafe_return,EDOMAIN_thread_flags(%ebx)
+71
View File
@@ -0,0 +1,71 @@
/*
* Generate definitions needed by assembly language modules.
* This code generates raw asm output which is post-processed
* to extract and format the required data.
*/
#include <xen/sched.h>
#define DEFINE(_sym, _val) \
__asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" (_val) )
#define BLANK() \
__asm__ __volatile__ ( "\n->" : : )
#define OFFSET(_sym, _str, _mem) \
DEFINE(_sym, offsetof(_str, _mem));
void __dummy__(void)
{
OFFSET(XREGS_r15, struct xen_regs, r15);
OFFSET(XREGS_r14, struct xen_regs, r14);
OFFSET(XREGS_r13, struct xen_regs, r13);
OFFSET(XREGS_r12, struct xen_regs, r12);
OFFSET(XREGS_rbp, struct xen_regs, rbp);
OFFSET(XREGS_rbx, struct xen_regs, rbx);
OFFSET(XREGS_r11, struct xen_regs, r11);
OFFSET(XREGS_r10, struct xen_regs, r10);
OFFSET(XREGS_r9, struct xen_regs, r9);
OFFSET(XREGS_r8, struct xen_regs, r8);
OFFSET(XREGS_rax, struct xen_regs, rax);
OFFSET(XREGS_rcx, struct xen_regs, rcx);
OFFSET(XREGS_rdx, struct xen_regs, rdx);
OFFSET(XREGS_rsi, struct xen_regs, rsi);
OFFSET(XREGS_rdi, struct xen_regs, rdi);
OFFSET(XREGS_orig_rax, struct xen_regs, orig_rax);
OFFSET(XREGS_rip, struct xen_regs, rip);
OFFSET(XREGS_cs, struct xen_regs, cs);
OFFSET(XREGS_eflags, struct xen_regs, eflags);
OFFSET(XREGS_rsp, struct xen_regs, rsp);
OFFSET(XREGS_ss, struct xen_regs, ss);
BLANK();
OFFSET(DOMAIN_processor, struct domain, processor);
OFFSET(DOMAIN_shared_info, struct domain, shared_info);
OFFSET(DOMAIN_event_sel, struct domain, thread.event_selector);
OFFSET(DOMAIN_event_addr, struct domain, thread.event_address);
OFFSET(DOMAIN_failsafe_sel, struct domain, thread.failsafe_selector);
OFFSET(DOMAIN_failsafe_addr, struct domain, thread.failsafe_address);
OFFSET(DOMAIN_trap_bounce, struct domain, thread.trap_bounce);
OFFSET(DOMAIN_thread_flags, struct domain, thread.flags);
BLANK();
OFFSET(SHINFO_upcall_pending, shared_info_t,
vcpu_data[0].evtchn_upcall_pending);
OFFSET(SHINFO_upcall_mask, shared_info_t,
vcpu_data[0].evtchn_upcall_mask);
BLANK();
OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2);
OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
BLANK();
OFFSET(MULTICALL_op, multicall_entry_t, op);
OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]);
OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]);
OFFSET(MULTICALL_arg2, multicall_entry_t, args[2]);
OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]);
OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]);
OFFSET(MULTICALL_result, multicall_entry_t, args[5]);
}
+455
View File
@@ -0,0 +1,455 @@
/******************************************************************************
* arch/x86/x86_64/mm.c
*
* Modifications to Linux original are copyright (c) 2004, K A Fraser
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <xen/config.h>
#include <xen/lib.h>
#include <xen/init.h>
#include <xen/mm.h>
#include <asm/page.h>
#include <asm/flushtlb.h>
#include <asm/fixmap.h>
#include <asm/domain_page.h>
static inline void set_pte_phys(unsigned long vaddr,
l1_pgentry_t entry)
{
l4_pgentry_t *l4ent;
l3_pgentry_t *l3ent;
l2_pgentry_t *l2ent;
l1_pgentry_t *l1ent;
l4ent = &idle_pg_table[l4_table_offset(vaddr)];
l3ent = l4_pgentry_to_l3(*l4ent) + l3_table_offset(vaddr);
l2ent = l3_pgentry_to_l2(*l3ent) + l2_table_offset(vaddr);
l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr);
*l1ent = entry;
/* It's enough to flush this one mapping. */
__flush_tlb_one(vaddr);
}
void __set_fixmap(enum fixed_addresses idx,
l1_pgentry_t entry)
{
unsigned long address = fix_to_virt(idx);
if ( likely(idx < __end_of_fixed_addresses) )
set_pte_phys(address, entry);
else
printk("Invalid __set_fixmap\n");
}
void __init paging_init(void)
{
void *ioremap_pt;
int i;
/* Create page table for ioremap(). */
ioremap_pt = (void *)alloc_xenheap_page();
clear_page(ioremap_pt);
idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR);
/* Create read-only mapping of MPT for guest-OS use. */
idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(l2_pgentry_val(
idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]) &
~_PAGE_RW);
/* Set up mapping cache for domain pages. */
mapcache = (unsigned long *)alloc_xenheap_page();
clear_page(mapcache);
idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR);
/* Set up linear page table mapping. */
idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR);
}
void __init zap_low_mappings(void)
{
idle_pg_table[0] = 0;
}
/*
* Allows shooting down of borrowed page-table use on specific CPUs.
* Specifically, we borrow page tables when running the idle domain.
*/
static void __synchronise_pagetables(void *mask)
{
struct domain *d = current;
if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) )
write_ptbase(&d->mm);
}
void synchronise_pagetables(unsigned long cpu_mask)
{
__synchronise_pagetables((void *)cpu_mask);
smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1);
}
long do_stack_switch(unsigned long ss, unsigned long esp)
{
int nr = smp_processor_id();
struct tss_struct *t = &init_tss[nr];
/* We need to do this check as we load and use SS on guest's behalf. */
if ( (ss & 3) == 0 )
return -EPERM;
current->thread.guestos_ss = ss;
current->thread.guestos_sp = esp;
t->ss1 = ss;
t->esp1 = esp;
return 0;
}
/* Returns TRUE if given descriptor is valid for GDT or LDT. */
int check_descriptor(unsigned long *d)
{
unsigned long base, limit, a = d[0], b = d[1];
/* A not-present descriptor will always fault, so is safe. */
if ( !(b & _SEGMENT_P) )
goto good;
/*
* We don't allow a DPL of zero. There is no legitimate reason for
* specifying DPL==0, and it gets rather dangerous if we also accept call
* gates (consider a call gate pointing at another guestos descriptor with
* DPL 0 -- this would get the OS ring-0 privileges).
*/
if ( (b & _SEGMENT_DPL) == 0 )
goto bad;
if ( !(b & _SEGMENT_S) )
{
/*
* System segment:
* 1. Don't allow interrupt or trap gates as they belong in the IDT.
* 2. Don't allow TSS descriptors or task gates as we don't
* virtualise x86 tasks.
* 3. Don't allow LDT descriptors because they're unnecessary and
* I'm uneasy about allowing an LDT page to contain LDT
* descriptors. In any case, Xen automatically creates the
* required descriptor when reloading the LDT register.
* 4. We allow call gates but they must not jump to a private segment.
*/
/* Disallow everything but call gates. */
if ( (b & _SEGMENT_TYPE) != 0xc00 )
goto bad;
/* Can't allow far jump to a Xen-private segment. */
if ( !VALID_CODESEL(a>>16) )
goto bad;
/* Reserved bits must be zero. */
if ( (b & 0xe0) != 0 )
goto bad;
/* No base/limit check is needed for a call gate. */
goto good;
}
/* Check that base is at least a page away from Xen-private area. */
base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16);
if ( base >= (PAGE_OFFSET - PAGE_SIZE) )
goto bad;
/* Check and truncate the limit if necessary. */
limit = (b&0xf0000) | (a&0xffff);
limit++; /* We add one because limit is inclusive. */
if ( (b & _SEGMENT_G) )
limit <<= 12;
if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC )
{
/*
* Grows-down limit check.
* NB. limit == 0xFFFFF provides no access (if G=1).
* limit == 0x00000 provides 4GB-4kB access (if G=1).
*/
if ( (base + limit) > base )
{
limit = -(base & PAGE_MASK);
goto truncate;
}
}
else
{
/*
* Grows-up limit check.
* NB. limit == 0xFFFFF provides 4GB access (if G=1).
* limit == 0x00000 provides 4kB access (if G=1).
*/
if ( ((base + limit) <= base) ||
((base + limit) > PAGE_OFFSET) )
{
limit = PAGE_OFFSET - base;
truncate:
if ( !(b & _SEGMENT_G) )
goto bad; /* too dangerous; too hard to work out... */
limit = (limit >> 12) - 1;
d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff;
d[1] &= ~0xf0000; d[1] |= limit & 0xf0000;
}
}
good:
return 1;
bad:
return 0;
}
void destroy_gdt(struct domain *d)
{
int i;
unsigned long pfn;
for ( i = 0; i < 16; i++ )
{
if ( (pfn = l1_pgentry_to_pagenr(d->mm.perdomain_pt[i])) != 0 )
put_page_and_type(&frame_table[pfn]);
d->mm.perdomain_pt[i] = mk_l1_pgentry(0);
}
}
long set_gdt(struct domain *d,
unsigned long *frames,
unsigned int entries)
{
/* NB. There are 512 8-byte entries per GDT page. */
int i = 0, nr_pages = (entries + 511) / 512;
struct desc_struct *vgdt;
unsigned long pfn;
/* Check the first page in the new GDT. */
if ( (pfn = frames[0]) >= max_page )
goto fail;
/* The first page is special because Xen owns a range of entries in it. */
if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
{
/* GDT checks failed: try zapping the Xen reserved entries. */
if ( !get_page_and_type(&frame_table[pfn], d, PGT_writable_page) )
goto fail;
vgdt = map_domain_mem(pfn << PAGE_SHIFT);
memset(vgdt + FIRST_RESERVED_GDT_ENTRY, 0,
NR_RESERVED_GDT_ENTRIES*8);
unmap_domain_mem(vgdt);
put_page_and_type(&frame_table[pfn]);
/* Okay, we zapped the entries. Now try the GDT checks again. */
if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
goto fail;
}
/* Check the remaining pages in the new GDT. */
for ( i = 1; i < nr_pages; i++ )
if ( ((pfn = frames[i]) >= max_page) ||
!get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
goto fail;
/* Copy reserved GDT entries to the new GDT. */
vgdt = map_domain_mem(frames[0] << PAGE_SHIFT);
memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY,
gdt_table + FIRST_RESERVED_GDT_ENTRY,
NR_RESERVED_GDT_ENTRIES*8);
unmap_domain_mem(vgdt);
/* Tear down the old GDT. */
destroy_gdt(d);
/* Install the new GDT. */
for ( i = 0; i < nr_pages; i++ )
d->mm.perdomain_pt[i] =
mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR);
SET_GDT_ADDRESS(d, GDT_VIRT_START);
SET_GDT_ENTRIES(d, entries);
return 0;
fail:
while ( i-- > 0 )
put_page_and_type(&frame_table[frames[i]]);
return -EINVAL;
}
long do_set_gdt(unsigned long *frame_list, unsigned int entries)
{
int nr_pages = (entries + 511) / 512;
unsigned long frames[16];
long ret;
if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) )
return -EINVAL;
if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
return -EFAULT;
if ( (ret = set_gdt(current, frames, entries)) == 0 )
{
local_flush_tlb();
__asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt));
}
return ret;
}
long do_update_descriptor(
unsigned long pa, unsigned long word1, unsigned long word2)
{
unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT, d[2];
struct pfn_info *page;
long ret = -EINVAL;
d[0] = word1;
d[1] = word2;
if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(d) )
return -EINVAL;
page = &frame_table[pfn];
if ( unlikely(!get_page(page, current)) )
return -EINVAL;
/* Check if the given frame is in use in an unsafe context. */
switch ( page->u.inuse.type_info & PGT_type_mask )
{
case PGT_gdt_page:
/* Disallow updates of Xen-reserved descriptors in the current GDT. */
if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) &&
(((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) &&
(((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) )
goto out;
if ( unlikely(!get_page_type(page, PGT_gdt_page)) )
goto out;
break;
case PGT_ldt_page:
if ( unlikely(!get_page_type(page, PGT_ldt_page)) )
goto out;
break;
default:
if ( unlikely(!get_page_type(page, PGT_writable_page)) )
goto out;
break;
}
/* All is good so make the update. */
gdt_pent = map_domain_mem(pa);
memcpy(gdt_pent, d, 8);
unmap_domain_mem(gdt_pent);
put_page_type(page);
ret = 0; /* success */
out:
put_page(page);
return ret;
}
#ifdef MEMORY_GUARD
void *memguard_init(void *heap_start)
{
l1_pgentry_t *l1;
int i, j;
/* Round the allocation pointer up to a page boundary. */
heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) &
PAGE_MASK);
/* Memory guarding is incompatible with super pages. */
for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
{
l1 = (l1_pgentry_t *)heap_start;
heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ )
l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) |
(j << L1_PAGETABLE_SHIFT) |
__PAGE_HYPERVISOR);
idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] =
mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR);
}
return heap_start;
}
static void __memguard_change_range(void *p, unsigned long l, int guard)
{
l1_pgentry_t *l1;
l2_pgentry_t *l2;
unsigned long _p = (unsigned long)p;
unsigned long _l = (unsigned long)l;
/* Ensure we are dealing with a page-aligned whole number of pages. */
ASSERT((_p&PAGE_MASK) != 0);
ASSERT((_l&PAGE_MASK) != 0);
ASSERT((_p&~PAGE_MASK) == 0);
ASSERT((_l&~PAGE_MASK) == 0);
while ( _l != 0 )
{
l2 = &idle_pg_table[l2_table_offset(_p)];
l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
if ( guard )
*l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT);
else
*l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT);
_p += PAGE_SIZE;
_l -= PAGE_SIZE;
}
}
void memguard_guard_range(void *p, unsigned long l)
{
__memguard_change_range(p, l, 1);
local_flush_tlb();
}
void memguard_unguard_range(void *p, unsigned long l)
{
__memguard_change_range(p, l, 0);
}
int memguard_is_guarded(void *p)
{
l1_pgentry_t *l1;
l2_pgentry_t *l2;
unsigned long _p = (unsigned long)p;
l2 = &idle_pg_table[l2_table_offset(_p)];
l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p);
return !(l1_pgentry_val(*l1) & _PAGE_PRESENT);
}
#endif
+5
View File
@@ -28,6 +28,11 @@ SECTIONS
__ex_table : { *(__ex_table) } :text
__stop___ex_table = .;
. = ALIGN(16); /* Pre-exception table */
__start___pre_ex_table = .;
__pre_ex_table : { *(__pre_ex_table) } :text
__stop___pre_ex_table = .;
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) } :text
__stop___ksymtab = .;
+12 -15
View File
@@ -55,20 +55,21 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
/* Per-domain PCI-device list. */
spin_lock_init(&d->pcidev_lock);
INIT_LIST_HEAD(&d->pcidev_list);
if ( (d->id != IDLE_DOMAIN_ID) &&
((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) )
{
destroy_event_channels(d);
free_domain_struct(d);
return NULL;
}
arch_do_createdomain(ed);
sched_add_domain(ed);
if ( d->id != IDLE_DOMAIN_ID )
{
if ( (init_event_channels(d) != 0) || (grant_table_create(d) != 0) )
{
destroy_event_channels(d);
free_domain_struct(d);
return NULL;
}
arch_do_createdomain(ed);
sched_add_domain(ed);
write_lock(&domlist_lock);
pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */
for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list )
@@ -80,10 +81,6 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
domain_hash[DOMAIN_HASH(dom_id)] = d;
write_unlock(&domlist_lock);
}
else
{
sched_add_domain(ed);
}
return d;
}
+2 -1
View File
@@ -758,7 +758,8 @@ void physdev_init_dom0(struct domain *p)
*
* In Linux2.6 we set pcibios_scan_all_fns().
*/
if ( dev->hdr_type != PCI_HEADER_TYPE_NORMAL )
if ( (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) &&
(dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) )
continue;
pdev = xmalloc(sizeof(phys_dev_t));
pdev->dev = dev;
+18
View File
@@ -0,0 +1,18 @@
#ifndef __X86_ASM_DEFNS_H__
#define __X86_ASM_DEFNS_H__
/* NB. Auto-generated from arch/.../asm-offsets.c */
#include <asm/asm-offsets.h>
#include <asm/processor.h>
#define __STR(x) #x
#define STR(x) __STR(x)
#ifdef __x86_64__
#include <asm/x86_64/asm_defns.h>
#else
#include <asm/x86_32/asm_defns.h>
#endif
#endif /* __X86_ASM_DEFNS_H__ */
+1 -1
View File
@@ -5,7 +5,7 @@
#include <xen/config.h>
#include <asm/atomic.h>
#include <asm/x86_32/asm_defns.h>
#include <asm/asm_defns.h>
extern void disable_irq(unsigned int);
extern void disable_irq_nosync(unsigned int);
+9 -1
View File
@@ -5,7 +5,13 @@
#ifndef __ASM_X86_MULTICALL_H__
#define __ASM_X86_MULTICALL_H__
#include <asm-x86/x86_32/asm_defns.h>
#include <asm/asm_defns.h>
#ifdef __x86_64__
#define do_multicall_call(_call) BUG()
#else
#define do_multicall_call(_call) \
do { \
@@ -23,4 +29,6 @@
: : "b" (_call) : "eax", "ecx", "edx" ); \
} while ( 0 )
#endif
#endif /* __ASM_X86_MULTICALL_H__ */
+8 -10
View File
@@ -255,18 +255,18 @@ static inline unsigned int cpuid_edx(unsigned int op)
})
#define write_cr0(x) \
__asm__("mov"__OS" %0,%%cr0": :"r" (x));
__asm__("mov"__OS" %0,%%cr0": :"r" ((unsigned long)x));
#define read_cr4() ({ \
unsigned int __dummy; \
unsigned long __dummy; \
__asm__( \
"movl %%cr4,%0\n\t" \
"mov"__OS" %%cr4,%0\n\t" \
:"=r" (__dummy)); \
__dummy; \
})
#define write_cr4(x) \
__asm__("movl %0,%%cr4": :"r" (x));
__asm__("mov"__OS" %0,%%cr4": :"r" ((unsigned long)x));
/*
* Save the cr4 feature set we're using (ie
@@ -291,7 +291,7 @@ static inline void clear_in_cr4 (unsigned long mask)
mmu_cr4_features &= ~mask;
__asm__("mov"__OS" %%cr4,%%"__OP"ax\n\t"
"and"__OS" %0,%%"__OP"ax\n\t"
"movl"__OS" %%"__OP"ax,%%cr4\n"
"mov"__OS" %%"__OP"ax,%%cr4\n"
: : "irg" (~mask)
:"ax");
}
@@ -400,6 +400,8 @@ struct thread_struct {
/* general user-visible register state */
execution_context_t user_ctxt;
void (*schedule_tail) (struct domain *);
/*
* Return vectors pushed to us by guest OS.
* The stack frame for events is exactly that of an x86 hardware interrupt.
@@ -457,14 +459,10 @@ extern struct desc_struct *idt_tables[];
long set_fast_trap(struct exec_domain *p, int idx);
#define INIT_THREAD { fast_trap_idx: 0x20 }
#elif defined(__x86_64__)
#endif
#define INIT_THREAD { 0 }
#endif /* __x86_64__ */
extern int gpf_emulate_4gb(struct xen_regs *regs);
struct mm_struct {
-7
View File
@@ -271,13 +271,6 @@ static inline int local_irq_is_enabled(void)
return !!(flags & (1<<9)); /* EFLAGS_IF */
}
/*
* disable hlt during certain critical i/o operations
*/
#define HAVE_DISABLE_HLT
void disable_hlt(void);
void enable_hlt(void);
#define BROKEN_ACPI_Sx 0x0001
#define BROKEN_INIT_AFTER_S1 0x0002
+26
View File
@@ -1,6 +1,32 @@
#ifndef __X86_UACCESS_H__
#define __X86_UACCESS_H__
#ifdef __x86_64__
#include <asm/x86_64/uaccess.h>
#else
#include <asm/x86_32/uaccess.h>
#endif
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
extern unsigned long search_exception_table(unsigned long);
extern void sort_exception_tables(void);
#endif /* __X86_UACCESS_H__ */
+3 -10
View File
@@ -1,12 +1,5 @@
#ifndef __ASM_DEFNS_H__
#define __ASM_DEFNS_H__
/* NB. Auto-generated from arch/.../asm-offsets.c */
#include <asm/asm-offsets.h>
#include <asm/processor.h>
#define __STR(x) #x
#define STR(x) __STR(x)
#ifndef __X86_32_ASM_DEFNS_H__
#define __X86_32_ASM_DEFNS_H__
/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
#ifndef __ASSEMBLY__
@@ -85,4 +78,4 @@
#endif
#endif /* __ASM_DEFNS_H__ */
#endif /* __X86_32_ASM_DEFNS_H__ */
+4 -7
View File
@@ -45,14 +45,11 @@ static inline unsigned long get_stack_top(void)
return p;
}
#define schedule_tail(_p) \
#define reset_stack_and_jump(__fn) \
__asm__ __volatile__ ( \
"andl %%esp,%0; addl %2,%0; movl %0,%%esp; jmp *%1" \
: : "r" (~(STACK_SIZE-1)), \
"r" (unlikely(is_idle_task((_p)->domain)) ? \
continue_cpu_idle_loop : \
continue_nonidle_task), \
"i" (STACK_SIZE-STACK_RESERVED) )
"movl %0,%%esp; jmp "STR(__fn) \
: : "r" (get_execution_context()) )
#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d)
#endif /* _X86_CURRENT_H */
-21
View File
@@ -69,27 +69,6 @@ extern struct movsl_mask {
#define array_access_ok(type,addr,count,size) \
(likely(count < (~0UL/size)) && access_ok(type,addr,count*size))
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
extern unsigned long search_exception_table(unsigned long);
extern void sort_exception_tables(void);
/**
* get_user: - Get a simple variable from user space.
* @x: Variable to store result.
+6
View File
@@ -0,0 +1,6 @@
#ifndef __X86_64_ASM_DEFNS_H__
#define __X86_64_ASM_DEFNS_H__
#define SAVE_ALL(_r) ""
#endif /* __X86_64_ASM_DEFNS_H__ */
+4 -7
View File
@@ -40,15 +40,12 @@ static inline unsigned long get_stack_top(void)
return p;
}
#define schedule_tail(_p) \
#define reset_stack_and_jump(__fn) \
__asm__ __volatile__ ( \
"andq %%rsp,%0; addq %2,%0; movq %0,%%rsp; jmp *%1" \
: : "r" (~(STACK_SIZE-1)), \
"r" (unlikely(is_idle_task((_p))) ? \
continue_cpu_idle_loop : \
continue_nonidle_task), \
"i" (STACK_SIZE-STACK_RESERVED) )
"movq %0,%%rsp; jmp "STR(__fn) \
: : "r" (get_execution_context()) )
#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d)
#else
+4 -20
View File
@@ -35,31 +35,15 @@
#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
#define array_access_ok(type,addr,count,size) \
(likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \
access_ok(type,addr,count*size))
extern inline int verify_area(int type, const void __user * addr, unsigned long size)
{
return access_ok(type,addr,size) ? 0 : -EFAULT;
}
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*/
struct exception_table_entry
{
unsigned long insn, fixup;
};
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
+2
View File
@@ -2,6 +2,8 @@
* arch-x86_32.h
*
* Guest OS interface to x86 32-bit Xen.
*
* Copyright (c) 2004, K A Fraser
*/
#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
+2
View File
@@ -2,6 +2,8 @@
* arch-x86_64.h
*
* Guest OS interface to x86 64-bit Xen.
*
* Copyright (c) 2004, K A Fraser
*/
#ifndef __XEN_PUBLIC_ARCH_X86_64_H__
+1 -1
View File
@@ -19,7 +19,7 @@
* This makes sure that old versions of dom0 tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
#define DOM0_INTERFACE_VERSION 0xAAAA001A
#define DOM0_INTERFACE_VERSION 0xAAAA1001
/************************************************************************/
+2
View File
@@ -1,5 +1,7 @@
/******************************************************************************
* trace.h
*
* Mark Williamson, (C) 2004 Intel Research Cambridge
*/
#ifndef __XEN_PUBLIC_TRACE_H__
@@ -1,6 +1,12 @@
#ifndef __ASM_X86_DOMAIN_H__
#define __ASM_X86_DOMAIN_H__
#ifndef __XEN_DOMAIN_H__
#define __XEN_DOMAIN_H__
/*
* Arch-specifics.
*/
extern void arch_do_createdomain(struct exec_domain *d);
@@ -11,4 +17,4 @@ extern void free_perdomain_pt(struct domain *d);
extern void domain_relinquish_memory(struct domain *d);
#endif /* __ASM_X86_DOMAIN_H__ */
#endif /* __XEN_DOMAIN_H__ */
+1 -4
View File
@@ -253,9 +253,6 @@ void domain_init(void);
int idle_cpu(int cpu); /* Is CPU 'cpu' idle right now? */
void startup_cpu_idle_loop(void);
void continue_cpu_idle_loop(void);
void continue_nonidle_task(void);
unsigned long hypercall_create_continuation(
unsigned int op, unsigned int nr_args, ...);
@@ -369,6 +366,6 @@ static inline void domain_unpause_by_systemcontroller(struct domain *d)
#define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist))
#include <xen/slab.h>
#include <asm/domain.h>
#include <xen/domain.h>
#endif /* __SCHED_H__ */
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.