[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID 0699c3eff7a38f315f3a19507050ecbebe79b43f # Parent 066094348f22c27a1aa887b2da96b6d43d81252d # Parent ea457d9d3fb2008e528486e8be89a232c3a91312 merge with xen-unstable.hg --- extras/mini-os/include/x86/spinlock.h | 121 ---- tools/check/check_hotplug | 16 extras/mini-os/Makefile | 6 extras/mini-os/README | 4 extras/mini-os/include/events.h | 2 extras/mini-os/include/sched.h | 3 extras/mini-os/include/spinlock.h | 55 ++ extras/mini-os/include/time.h | 6 extras/mini-os/include/x86/arch_spinlock.h | 93 +++ extras/mini-os/include/x86/os.h | 2 extras/mini-os/include/x86/x86_64/hypercall-x86_64.h | 6 extras/mini-os/kernel.c | 26 - extras/mini-os/mm.c | 7 extras/mini-os/sched.c | 71 ++ extras/mini-os/time.c | 26 - linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c | 1 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c | 2 linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 4 tools/Rules.mk | 5 tools/blktap/drivers/Makefile | 1 tools/blktap/drivers/blktapctrl.c | 67 +- tools/blktap/lib/Makefile | 1 tools/check/check_udev | 16 tools/firmware/hvmloader/Makefile | 6 tools/firmware/hvmloader/acpi/acpi2_0.h | 34 + tools/firmware/hvmloader/acpi/dsdt.asl | 7 tools/firmware/hvmloader/acpi/dsdt.c | 481 +++++++++---------- tools/firmware/hvmloader/acpi_utils.c | 219 +++++--- tools/firmware/hvmloader/util.c | 51 ++ tools/firmware/hvmloader/util.h | 4 tools/ioemu/Makefile.target | 3 tools/ioemu/hw/rtl8139.c | 12 tools/ioemu/xenstore.c | 2 tools/libfsimage/Rules.mk | 2 tools/libfsimage/common/Makefile | 2 tools/libxc/xc_acm.c | 3 tools/libxc/xc_domain.c | 6 tools/libxc/xc_linux_build.c | 53 -- tools/libxc/xc_linux_restore.c | 33 - tools/libxc/xc_tbuf.c | 4 tools/libxc/xenctrl.h | 6 tools/misc/lomount/lomount.c | 2 tools/python/xen/util/security.py | 12 tools/python/xen/xend/XendAPI.py | 7 tools/python/xen/xend/XendConfig.py | 89 +++ tools/python/xen/xend/XendDevices.py | 5 tools/python/xen/xend/XendDomain.py | 49 + tools/python/xen/xend/XendDomainInfo.py | 39 + tools/python/xen/xend/image.py | 7 tools/python/xen/xend/server/pciif.py | 24 tools/python/xen/xm/create.py | 6 tools/python/xen/xm/main.py | 4 tools/xentrace/Makefile | 2 unmodified_drivers/linux-2.6/README | 4 xen/arch/ia64/vmx/vmx_support.c | 3 xen/arch/x86/domain.c | 47 - xen/arch/x86/domain_build.c | 30 - xen/arch/x86/hvm/hvm.c | 73 ++ xen/arch/x86/hvm/i8259.c | 12 xen/arch/x86/hvm/platform.c | 26 - xen/arch/x86/hvm/rtc.c | 92 ++- xen/arch/x86/hvm/svm/svm.c | 39 - xen/arch/x86/hvm/vioapic.c | 4 xen/arch/x86/hvm/vmx/vmcs.c | 2 xen/arch/x86/hvm/vmx/vmx.c | 227 +++----- xen/arch/x86/mm.c | 2 xen/arch/x86/mm/shadow/common.c | 22 xen/arch/x86/mm/shadow/multi.c | 104 ++-- xen/arch/x86/mm/shadow/types.h | 4 xen/arch/x86/oprofile/nmi_int.c | 16 xen/arch/x86/physdev.c | 2 xen/arch/x86/traps.c | 197 +++---- xen/arch/x86/x86_32/entry.S | 27 - xen/arch/x86/x86_64/entry.S | 24 xen/common/domain.c | 14 xen/common/grant_table.c | 11 xen/common/schedule.c | 18 xen/include/asm-x86/domain.h | 4 xen/include/asm-x86/hvm/hvm.h | 4 xen/include/asm-x86/hvm/io.h | 3 xen/include/asm-x86/hvm/vmx/vmcs.h | 30 - xen/include/asm-x86/hvm/vmx/vmx.h | 5 xen/include/asm-x86/hvm/vpt.h | 8 xen/include/asm-x86/mm.h | 28 - xen/include/asm-x86/shadow.h | 57 +- xen/include/asm-x86/x86_32/regs.h | 3 xen/include/asm-x86/x86_64/regs.h | 3 xen/include/public/physdev.h | 3 xen/include/public/vcpu.h | 7 xen/include/public/xen-compat.h | 9 xen/include/public/xen.h | 2 xen/include/xen/iocap.h | 8 xen/include/xen/sched.h | 7 93 files changed, 1640 insertions(+), 1256 deletions(-) diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/Makefile --- a/extras/mini-os/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -122,6 +122,7 @@ clean: rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz rm -f libminios.a find . -type l | xargs rm -f + rm -f tags TAGS %.o: %.c $(HDRS) Makefile $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ @@ -137,4 +138,7 @@ cscope: cscope: $(all_sources) > cscope.files cscope -k -b -q - + +.PHONY: tags +tags: + $(all_sources) | xargs ctags diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/README --- a/extras/mini-os/README Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/README Mon Nov 20 13:11:15 2006 -0700 @@ -26,5 +26,5 @@ Stuff it doesn't show: - to start it do the following in domain0 (assuming xend is running) # xm create domain_config -this starts the kernel and prints out a bunch of stuff and then every -1000 timer interrupts the system time. +this starts the kernel and prints out a bunch of stuff and then once +every second the system time. diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/events.h --- a/extras/mini-os/include/events.h Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/include/events.h Mon Nov 20 13:11:15 2006 -0700 @@ -20,7 +20,7 @@ #define _EVENTS_H_ #include<traps.h> -#include <xen/event_channel.h> +#include<xen/event_channel.h> typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *); diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/sched.h --- a/extras/mini-os/include/sched.h Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/include/sched.h Mon Nov 20 13:11:15 2006 -0700 @@ -2,6 +2,7 @@ #define __SCHED_H__ #include <list.h> +#include <time.h> struct thread { @@ -11,6 +12,7 @@ struct thread unsigned long ip; /* Instruction pointer */ struct list_head thread_list; u32 flags; + s_time_t wakeup_time; }; @@ -36,5 +38,6 @@ static inline struct thread* get_current void wake(struct thread *thread); void block(struct thread *thread); +void sleep(u32 millisecs); #endif /* __SCHED_H__ */ diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/time.h --- a/extras/mini-os/include/time.h Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/include/time.h Mon Nov 20 13:11:15 2006 -0700 @@ -7,8 +7,9 @@ * File: time.h * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) * Changes: Grzegorz Milos (gm281@xxxxxxxxx) + * Robert Kaiser (kaiser@xxxxxxxxxxxxxxxxxxxxxxxxxx) * - * Date: Jul 2003, changesJun 2005 + * Date: Jul 2003, changes: Jun 2005, Sep 2006 * * Environment: Xen Minimal OS * Description: Time and timer functions @@ -57,7 +58,8 @@ void init_time(void); void init_time(void); s_time_t get_s_time(void); s_time_t get_v_time(void); +u64 monotonic_clock(void); void gettimeofday(struct timeval *tv); -void block_domain(u32 millisecs); +void block_domain(s_time_t until); #endif /* _TIME_H_ */ diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/include/x86/os.h Mon Nov 20 13:11:15 2006 -0700 @@ -18,6 +18,8 @@ #ifndef __ASSEMBLY__ #include <types.h> #include <hypervisor.h> + +#define USED __attribute__ ((used)) extern void do_exit(void); #define BUG do_exit diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/x86/x86_64/hypercall-x86_64.h --- a/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/include/x86/x86_64/hypercall-x86_64.h Mon Nov 20 13:11:15 2006 -0700 @@ -235,9 +235,9 @@ HYPERVISOR_update_va_mapping( static inline int HYPERVISOR_event_channel_op( - void *op) -{ - return _hypercall1(int, event_channel_op, op); + int cmd, void *op) +{ + return _hypercall2(int, event_channel_op, cmd, op); } static inline int diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/kernel.c Mon Nov 20 13:11:15 2006 -0700 @@ -6,6 +6,7 @@ * * Copyright (c) 2002-2003, K A Fraser & R Neugebauer * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge + * Copyright (c) 2006, Robert Kaiser, FH Wiesbaden * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -66,11 +67,24 @@ void xenbus_tester(void *p) /* test_xenbus(); */ } +void periodic_thread(void *p) +{ + struct timeval tv; + printk("Periodic thread started.\n"); + for(;;) + { + gettimeofday(&tv); + printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); + sleep(1000); + } +} + /* This should be overridden by the application we are linked against. */ __attribute__((weak)) int app_main(start_info_t *si) { printk("Dummy main: start_info=%p\n", si); create_thread("xenbus_tester", xenbus_tester, si); + create_thread("periodic_thread", periodic_thread, si); return 0; } @@ -87,9 +101,6 @@ void start_kernel(start_info_t *si) trap_init(); - /* ENABLE EVENT DELIVERY. This is disabled at start of day. */ - __sti(); - /* print out some useful information */ printk("Xen Minimal OS!\n"); printk("start_info: %p\n", si); @@ -102,6 +113,12 @@ void start_kernel(start_info_t *si) printk(" cmd_line: %s\n", si->cmd_line ? (const char *)si->cmd_line : "NULL"); + /* Set up events. */ + init_events(); + + /* ENABLE EVENT DELIVERY. This is disabled at start of day. */ + __sti(); + arch_print_info(); setup_xen_features(); @@ -109,9 +126,6 @@ void start_kernel(start_info_t *si) /* Init memory management. */ init_mm(); - /* Set up events. */ - init_events(); - /* Init time and timers. */ init_time(); diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/mm.c --- a/extras/mini-os/mm.c Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/mm.c Mon Nov 20 13:11:15 2006 -0700 @@ -148,7 +148,7 @@ static chunk_head_t free_tail[FREELIST_ * Prints allocation[0/1] for @nr_pages, starting at @start * address (virtual). */ -static void print_allocation(void *start, int nr_pages) +USED static void print_allocation(void *start, int nr_pages) { unsigned long pfn_start = virt_to_pfn(start); int count; @@ -163,7 +163,7 @@ static void print_allocation(void *start * Prints chunks (making them with letters) for @nr_pages starting * at @start (virtual). */ -static void print_chunks(void *start, int nr_pages) +USED static void print_chunks(void *start, int nr_pages) { char chunks[1001], current='A'; int order, count; @@ -408,7 +408,6 @@ void new_pt_frame(unsigned long *pt_pfn, do_exit(); break; } - /* Update the entry */ #if defined(__x86_64__) tab = pte_to_virt(tab[l4_table_offset(pt_page)]); @@ -446,7 +445,6 @@ void new_pt_frame(unsigned long *pt_pfn, printk("ERROR: mmu_update failed\n"); do_exit(); } - *pt_pfn += 1; } @@ -581,7 +579,6 @@ void build_pagetable(unsigned long *star } start_address += PAGE_SIZE; } - *start_pfn = pt_pfn; } diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/sched.c --- a/extras/mini-os/sched.c Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/sched.c Mon Nov 20 13:11:15 2006 -0700 @@ -5,7 +5,7 @@ * * File: sched.c * Author: Grzegorz Milos - * Changes: + * Changes: Robert Kaiser * * Date: Aug 2005 * @@ -142,6 +142,54 @@ void inline print_runqueue(void) printk("\n"); } +/* Find the time when the next timeout expires. If this is more than + 10 seconds from now, return 10 seconds from now. */ +static s_time_t blocking_time(void) +{ + struct thread *thread; + struct list_head *iterator; + s_time_t min_wakeup_time; + unsigned long flags; + local_irq_save(flags); + /* default-block the domain for 10 seconds: */ + min_wakeup_time = NOW() + SECONDS(10); + + /* Thread list needs to be protected */ + list_for_each(iterator, &idle_thread->thread_list) + { + thread = list_entry(iterator, struct thread, thread_list); + if(!is_runnable(thread) && thread->wakeup_time != 0LL) + { + if(thread->wakeup_time < min_wakeup_time) + { + min_wakeup_time = thread->wakeup_time; + } + } + } + local_irq_restore(flags); + return(min_wakeup_time); +} + +/* Wake up all threads with expired timeouts. */ +static void wake_expired(void) +{ + struct thread *thread; + struct list_head *iterator; + s_time_t now = NOW(); + unsigned long flags; + local_irq_save(flags); + /* Thread list needs to be protected */ + list_for_each(iterator, &idle_thread->thread_list) + { + thread = list_entry(iterator, struct thread, thread_list); + if(!is_runnable(thread) && thread->wakeup_time != 0LL) + { + if(thread->wakeup_time <= now) + wake(thread); + } + } + local_irq_restore(flags); +} void schedule(void) { @@ -229,8 +277,9 @@ struct thread* create_thread(char *name, stack_push(thread, (unsigned long) data); thread->ip = (unsigned long) thread_starter; - /* Not runable, not exited */ + /* Not runable, not exited, not sleeping */ thread->flags = 0; + thread->wakeup_time = 0LL; set_runnable(thread); local_irq_save(flags); if(idle_thread != NULL) { @@ -247,20 +296,34 @@ struct thread* create_thread(char *name, void block(struct thread *thread) { + thread->wakeup_time = 0LL; clear_runnable(thread); } +void sleep(u32 millisecs) +{ + struct thread *thread = get_current(); + thread->wakeup_time = NOW() + MILLISECS(millisecs); + clear_runnable(thread); + schedule(); +} + void wake(struct thread *thread) { + thread->wakeup_time = 0LL; set_runnable(thread); } void idle_thread_fn(void *unused) { + s_time_t until; for(;;) { schedule(); - block_domain(10000); + /* block until the next timeout expires, or for 10 secs, whichever comes first */ + until = blocking_time(); + block_domain(until); + wake_expired(); } } @@ -278,7 +341,7 @@ void run_idle_thread(void) "push %1\n\t" "ret" :"=m" (idle_thread->sp) - :"m" (idle_thread->ip)); + :"m" (idle_thread->ip)); #endif } diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/time.c --- a/extras/mini-os/time.c Mon Nov 20 12:14:40 2006 -0700 +++ b/extras/mini-os/time.c Mon Nov 20 13:11:15 2006 -0700 @@ -3,6 +3,7 @@ * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge * (C) 2002-2003 - Keir Fraser - University of Cambridge * (C) 2005 - Grzegorz Milos - Intel Research Cambridge + * (C) 2006 - Robert Kaiser - FH Wiesbaden **************************************************************************** * * File: time.c @@ -194,21 +195,15 @@ void gettimeofday(struct timeval *tv) } -static void print_current_time(void) -{ - struct timeval tv; - - gettimeofday(&tv); - printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); -} - - -void block_domain(u32 millisecs) +void block_domain(s_time_t until) { struct timeval tv; gettimeofday(&tv); - HYPERVISOR_set_timer_op(monotonic_clock() + 1000000LL * (s64) millisecs); - HYPERVISOR_sched_op(SCHEDOP_block, 0); + if(monotonic_clock() < until) + { + HYPERVISOR_set_timer_op(until); + HYPERVISOR_sched_op(SCHEDOP_block, 0); + } } @@ -217,15 +212,8 @@ void block_domain(u32 millisecs) */ static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign) { - static int i; - get_time_values_from_xen(); update_wallclock(); - i++; - if (i >= 1000) { - print_current_time(); - i = 0; - } } diff -r 066094348f22 -r 0699c3eff7a3 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c --- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Mon Nov 20 12:14:40 2006 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c Mon Nov 20 13:11:15 2006 -0700 @@ -716,6 +716,7 @@ irqreturn_t timer_interrupt(int irq, voi rcu_check_callbacks(cpu, user_mode(regs)); scheduler_tick(); run_posix_cpu_timers(current); + profile_tick(CPU_PROFILING, regs); return IRQ_HANDLED; } diff -r 066094348f22 -r 0699c3eff7a3 linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon Nov 20 12:14:40 2006 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon Nov 20 13:11:15 2006 -0700 @@ -1059,9 +1059,9 @@ static int blktap_read_ufe_ring(tap_blki map[offset] = NULL; } fast_flush_area(pending_req, pending_idx, usr_idx, info->minor); + info->idx_map[usr_idx] = INVALID_REQ; make_response(blkif, pending_req->id, res.operation, res.status); - info->idx_map[usr_idx] = INVALID_REQ; blkif_put(pending_req->blkif); free_req(pending_req); } diff -r 066094348f22 -r 0699c3eff7a3 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Nov 20 12:14:40 2006 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Nov 20 13:11:15 2006 -0700 @@ -825,7 +825,9 @@ static void tx_add_credit(netif_t *netif max_burst = max(max_burst, netif->credit_bytes); /* Take care that adding a new chunk of credit doesn't wrap to zero. */ - max_credit = max(netif->remaining_credit + netif->credit_bytes, ~0UL); + max_credit = netif->remaining_credit + netif->credit_bytes; + if (max_credit < netif->remaining_credit) + max_credit = ULONG_MAX; /* wrapped: clamp to ULONG_MAX */ netif->remaining_credit = min(max_credit, max_burst); } diff -r 066094348f22 -r 0699c3eff7a3 tools/Rules.mk --- a/tools/Rules.mk Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/Rules.mk Mon Nov 20 13:11:15 2006 -0700 @@ -13,6 +13,11 @@ X11_LDPATH = -L/usr/X11R6/$(LIBDIR) X11_LDPATH = -L/usr/X11R6/$(LIBDIR) CFLAGS += -D__XEN_TOOLS__ + +# Enable implicit LFS support *and* explicit LFS names. +CFLAGS += $(shell getconf LFS_CFLAGS) +CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE +LDFLAGS += $(shell getconf LFS_LDFLAGS) %.opic: %.c $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< diff -r 066094348f22 -r 0699c3eff7a3 tools/blktap/drivers/Makefile --- a/tools/blktap/drivers/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/blktap/drivers/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -13,7 +13,6 @@ CFLAGS += -fno-strict-aliasing CFLAGS += -fno-strict-aliasing CFLAGS += -I $(XEN_LIBXC) -I $(LIBAIO_DIR) CFLAGS += $(INCLUDES) -I. -I../../xenstore -CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE CFLAGS += -D_GNU_SOURCE # Get gcc to generate the dependencies for us. diff -r 066094348f22 -r 0699c3eff7a3 tools/blktap/drivers/blktapctrl.c --- a/tools/blktap/drivers/blktapctrl.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/blktap/drivers/blktapctrl.c Mon Nov 20 13:11:15 2006 -0700 @@ -167,13 +167,22 @@ static int get_tapdisk_pid(blkif_t *blki return 1; } -static blkif_t *test_path(char *path, char **dev, int *type) +/* Look up the disk specified by path: + * if found, dev points to the device string in the path + * type is the tapdisk driver type id + * blkif is the existing interface if this is a shared driver + * and NULL otherwise. + * return 0 on success, -1 on error. + */ + +static int test_path(char *path, char **dev, int *type, blkif_t *blkif) { char *ptr, handle[10]; - int i, size; + int i, size, found = 0; size = sizeof(dtypes)/sizeof(disk_info_t *); *type = MAX_DISK_TYPES + 1; + blkif = NULL; if ( (ptr = strstr(path, ":"))!=NULL) { memcpy(handle, path, (ptr - path)); @@ -182,25 +191,35 @@ static blkif_t *test_path(char *path, ch *ptr = '\0'; DPRINTF("Detected handle: [%s]\n",handle); - for (i = 0; i < size; i++) { - if (strncmp(handle, dtypes[i]->handle, (ptr - path)) - ==0) { - *type = dtypes[i]->idnum; - - if (dtypes[i]->single_handler == 1) { - /* Check whether tapdisk process - already exists */ - if (active_disks[dtypes[i]->idnum] - == NULL) return NULL; - else - return active_disks[dtypes[i]->idnum]->blkif; - } - } - } - } else *dev = NULL; - - return NULL; -} + for (i = 0; i < size; i++) + if (strncmp(handle, dtypes[i]->handle, + (ptr - path)) ==0) { + found = 1; + break; + } + + if (found) { + *type = dtypes[i]->idnum; + + if (dtypes[i]->single_handler == 1) { + /* Check whether tapdisk process + already exists */ + if (active_disks[dtypes[i]->idnum] == NULL) + blkif = NULL; + else + blkif = active_disks[dtypes[i] + ->idnum]->blkif; + } + return 0; + } + } + + /* Fall-through case, we didn't find a disk driver. */ + DPRINTF("Unknown blktap disk type [%s]!\n",handle); + *dev = NULL; + return -1; +} + static void add_disktype(blkif_t *blkif, int type) { @@ -463,7 +482,11 @@ int blktapctrl_new_blkif(blkif_t *blkif) if (get_new_dev(&major, &minor, blkif)<0) return -1; - exist = test_path(blk->params, &ptr, &type); + if (test_path(blk->params, &ptr, &type, exist) != 0) { + DPRINTF("Error in blktap device string(%s).\n", + blk->params); + return -1; + } blkif->drivertype = type; blkif->cookie = lrand48() % MAX_RAND_VAL; diff -r 066094348f22 -r 0699c3eff7a3 tools/blktap/lib/Makefile --- a/tools/blktap/lib/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/blktap/lib/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -17,7 +17,6 @@ CFLAGS += -Werror CFLAGS += -Werror CFLAGS += -Wno-unused CFLAGS += -fno-strict-aliasing -fPIC -CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE # get asprintf(): CFLAGS += -D _GNU_SOURCE diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -46,16 +46,14 @@ OBJS = $(patsubst %.c,%.o,$(SRCS)) .PHONY: all all: hvmloader -acpi/acpi.bin: - $(MAKE) -C acpi - hvmloader: roms.h $(SRCS) $(CC) $(CFLAGS) -c $(SRCS) $(CC) $(CFLAGS) $(LDFLAGS) -o hvmloader.tmp $(OBJS) $(OBJCOPY) hvmloader.tmp hvmloader rm -f hvmloader.tmp -roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin acpi/acpi.bin +roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin + $(MAKE) -C acpi sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin >> roms.h diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/acpi/acpi2_0.h --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Mon Nov 20 13:11:15 2006 -0700 @@ -34,6 +34,11 @@ typedef signed long int64_t; #include <xen/xen.h> +#define ASCII32(a,b,c,d) \ + (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24)) +#define ASCII64(a,b,c,d,e,f,g,h) \ + (((uint64_t)ASCII32(a,b,c,d)) | (((uint64_t)ASCII32(e,f,g,h)) << 32)) + #pragma pack (1) /* @@ -52,7 +57,7 @@ struct acpi_header { }; #define ACPI_OEM_ID {'I','N','T','E','L',' '} -#define ACPI_OEM_TABLE_ID 0x544244 /* "TBD" */ +#define ACPI_OEM_TABLE_ID ASCII32(' ','T','B','D') #define ACPI_OEM_REVISION 0x00000002 #define ACPI_CREATOR_ID 0x00 /* TBD */ #define ACPI_CREATOR_REVISION 0x00000002 @@ -126,6 +131,20 @@ struct acpi_20_xsdt { uint64_t entry[ACPI_MAX_NUM_TABLES]; }; #define ACPI_2_0_XSDT_REVISION 0x01 + +/* + * TCG Hardware Interface Table (TCPA) + */ + +typedef struct _ACPI_2_0_TCPA_CLIENT { + struct acpi_header header; + uint16_t PlatformClass; + uint32_t LAML; + uint64_t LASA; +} ACPI_2_0_TCPA_CLIENT; + +#define ACPI_2_0_TCPA_REVISION 0x02 +#define ACPI_2_0_TCPA_LAML_SIZE (64*1024) /* * Fixed ACPI Description Table Structure (FADT). @@ -297,12 +316,13 @@ struct acpi_20_madt { /* * Table Signatures. */ -#define ACPI_2_0_RSDP_SIGNATURE 0x2052545020445352LL /* "RSD PTR " */ -#define ACPI_2_0_FACS_SIGNATURE 0x53434146 /* "FACS" */ -#define ACPI_2_0_FADT_SIGNATURE 0x50434146 /* "FADT" */ -#define ACPI_2_0_MADT_SIGNATURE 0x43495041 /* "APIC" */ -#define ACPI_2_0_RSDT_SIGNATURE 0x54445352 /* "RSDT" */ -#define ACPI_2_0_XSDT_SIGNATURE 0x54445358 /* "XSDT" */ +#define ACPI_2_0_RSDP_SIGNATURE ASCII64('R','S','D',' ','P','T','R',' ') +#define ACPI_2_0_FACS_SIGNATURE ASCII32('F','A','C','S') +#define ACPI_2_0_FADT_SIGNATURE ASCII32('F','A','C','P') +#define ACPI_2_0_MADT_SIGNATURE ASCII32('A','P','I','C') +#define ACPI_2_0_RSDT_SIGNATURE ASCII32('R','S','D','T') +#define ACPI_2_0_XSDT_SIGNATURE ASCII32('X','S','D','T') +#define ACPI_2_0_TCPA_SIGNATURE ASCII32('T','C','P','A') #pragma pack () diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/acpi/dsdt.asl --- a/tools/firmware/hvmloader/acpi/dsdt.asl Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Mon Nov 20 13:11:15 2006 -0700 @@ -116,6 +116,13 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, 0xF300) /* reserve memory for pci devices */ + + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00000000, + 0x000A0000, + 0x000BFFFF, + 0x00000000, + 0x00020000) DWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x00000000, diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/acpi/dsdt.c --- a/tools/firmware/hvmloader/acpi/dsdt.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Mon Nov 20 13:11:15 2006 -0700 @@ -1,19 +1,19 @@ /* * * Intel ACPI Component Architecture - * ASL Optimizing Compiler / AML Disassembler version 20050513 [Oct 12 2006] + * ASL Optimizing Compiler / AML Disassembler version 20050513 [Nov 16 2006] * Copyright (C) 2000 - 2005 Intel Corporation * Supports ACPI Specification Revision 3.0 * - * Compilation of "acpi_dsdt.asl" - Thu Oct 12 14:08:49 2006 + * Compilation of "dsdt.asl" - Fri Nov 17 10:00:20 2006 * * C source code output * */ unsigned char AmlCode[] = { - 0x44,0x53,0x44,0x54,0xDA,0x08,0x00,0x00, /* 00000000 "DSDT...." */ - 0x01,0x26,0x49,0x4E,0x54,0x45,0x4C,0x00, /* 00000008 ".&INTEL." */ + 0x44,0x53,0x44,0x54,0xF4,0x08,0x00,0x00, /* 00000000 "DSDT...." */ + 0x01,0x22,0x49,0x4E,0x54,0x45,0x4C,0x00, /* 00000008 "."INTEL." */ 0x69,0x6E,0x74,0x2D,0x78,0x65,0x6E,0x00, /* 00000010 "int-xen." */ 0xD6,0x07,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ 0x13,0x05,0x05,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ @@ -34,7 +34,7 @@ unsigned char AmlCode[] = 0x12,0x08,0x04,0x0A,0x07,0x0A,0x07,0x00, /* 00000098 "........" */ 0x00,0x08,0x50,0x49,0x43,0x44,0x00,0x14, /* 000000A0 "..PICD.." */ 0x0C,0x5F,0x50,0x49,0x43,0x01,0x70,0x68, /* 000000A8 "._PIC.ph" */ - 0x50,0x49,0x43,0x44,0x10,0x45,0x82,0x5F, /* 000000B0 "PICD.E._" */ + 0x50,0x49,0x43,0x44,0x10,0x4F,0x83,0x5F, /* 000000B0 "PICD.O._" */ 0x53,0x42,0x5F,0x5B,0x82,0x49,0x04,0x4D, /* 000000B8 "SB_[.I.M" */ 0x45,0x4D,0x30,0x08,0x5F,0x48,0x49,0x44, /* 000000C0 "EM0._HID" */ 0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43, /* 000000C8 ".A...._C" */ @@ -45,7 +45,7 @@ unsigned char AmlCode[] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000F0 "........" */ 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00, /* 000000F8 "........" */ 0x00,0x00,0x00,0x00,0x79,0x00,0x5B,0x82, /* 00000100 "....y.[." */ - 0x42,0x7D,0x50,0x43,0x49,0x30,0x08,0x5F, /* 00000108 "B}PCI0._" */ + 0x4C,0x7E,0x50,0x43,0x49,0x30,0x08,0x5F, /* 00000108 "L~PCI0._" */ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03, /* 00000110 "HID.A..." */ 0x08,0x5F,0x55,0x49,0x44,0x00,0x08,0x5F, /* 00000118 "._UID.._" */ 0x41,0x44,0x52,0x00,0x08,0x5F,0x42,0x42, /* 00000120 "ADR.._BB" */ @@ -55,9 +55,9 @@ unsigned char AmlCode[] = 0x33,0x03,0x49,0x52,0x51,0x35,0x05,0x49, /* 00000140 "3.IRQ5.I" */ 0x52,0x51,0x37,0x07,0x49,0x52,0x51,0x39, /* 00000148 "RQ7.IRQ9" */ 0x09,0x49,0x52,0x51,0x41,0x0A,0x49,0x52, /* 00000150 ".IRQA.IR" */ - 0x51,0x42,0x0B,0x14,0x4A,0x06,0x5F,0x43, /* 00000158 "QB..J._C" */ + 0x51,0x42,0x0B,0x14,0x44,0x08,0x5F,0x43, /* 00000158 "QB..D._C" */ 0x52,0x53,0x00,0x08,0x50,0x52,0x54,0x30, /* 00000160 "RS..PRT0" */ - 0x11,0x48,0x05,0x0A,0x54,0x88,0x0D,0x00, /* 00000168 ".H..T..." */ + 0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D,0x00, /* 00000168 ".B..n..." */ 0x02,0x0F,0x00,0x00,0x00,0x00,0x00,0xFF, /* 00000170 "........" */ 0x00,0x00,0x00,0x00,0x01,0x47,0x01,0xF8, /* 00000178 ".....G.." */ 0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D,0x00, /* 00000180 "........" */ @@ -65,236 +65,239 @@ unsigned char AmlCode[] = 0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D,0x00, /* 00000190 "........" */ 0x01,0x0C,0x03,0x00,0x00,0x00,0x0D,0xFF, /* 00000198 "........" */ 0xFF,0x00,0x00,0x00,0xF3,0x87,0x17,0x00, /* 000001A0 "........" */ - 0x00,0x0D,0x03,0x00,0x00,0x00,0x00,0x00, /* 000001A8 "........" */ - 0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00, /* 000001B0 "........" */ - 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x79, /* 000001B8 ".......y" */ - 0x00,0xA4,0x50,0x52,0x54,0x30,0x08,0x42, /* 000001C0 "..PRT0.B" */ - 0x55,0x46,0x41,0x11,0x09,0x0A,0x06,0x23, /* 000001C8 "UFA....#" */ - 0xF8,0xDC,0x18,0x79,0x00,0x08,0x42,0x55, /* 000001D0 "...y..BU" */ - 0x46,0x42,0x11,0x09,0x0A,0x06,0x23,0x00, /* 000001D8 "FB....#." */ - 0x00,0x18,0x79,0x00,0x8B,0x42,0x55,0x46, /* 000001E0 "..y..BUF" */ - 0x42,0x01,0x49,0x52,0x51,0x56,0x08,0x42, /* 000001E8 "B.IRQV.B" */ - 0x55,0x46,0x43,0x11,0x07,0x0A,0x04,0x05, /* 000001F0 "UFC....." */ - 0x07,0x0A,0x0B,0x8C,0x42,0x55,0x46,0x43, /* 000001F8 "....BUFC" */ - 0x01,0x50,0x49,0x51,0x41,0x8C,0x42,0x55, /* 00000200 ".PIQA.BU" */ - 0x46,0x43,0x01,0x50,0x49,0x51,0x42,0x8C, /* 00000208 "FC.PIQB." */ - 0x42,0x55,0x46,0x43,0x01,0x50,0x49,0x51, /* 00000210 "BUFC.PIQ" */ - 0x43,0x8C,0x42,0x55,0x46,0x43,0x01,0x50, /* 00000218 "C.BUFC.P" */ - 0x49,0x51,0x44,0x5B,0x82,0x48,0x08,0x4C, /* 00000220 "IQD[.H.L" */ - 0x4E,0x4B,0x41,0x08,0x5F,0x48,0x49,0x44, /* 00000228 "NKA._HID" */ - 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000230 ".A...._U" */ - 0x49,0x44,0x01,0x14,0x1C,0x5F,0x53,0x54, /* 00000238 "ID..._ST" */ - 0x41,0x00,0x7B,0x50,0x49,0x52,0x41,0x0A, /* 00000240 "A.{PIRA." */ - 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000248 ".`...`.." */ - 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000250 "........" */ - 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000258 ".._PRS.." */ - 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000260 "BUFA.._D" */ - 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x41, /* 00000268 "IS.}PIRA" */ - 0x0A,0x80,0x50,0x49,0x52,0x41,0x14,0x1A, /* 00000270 "..PIRA.." */ - 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000278 "_CRS.{PI" */ - 0x52,0x42,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000280 "RB..`y.`" */ - 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000288 "IRQV.BUF" */ - 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000290 "B.._SRS." */ - 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000298 ".h.IRQ1." */ - 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 000002A0 "IRQ1`v`p" */ - 0x60,0x50,0x49,0x52,0x41,0x5B,0x82,0x49, /* 000002A8 "`PIRA[.I" */ - 0x08,0x4C,0x4E,0x4B,0x42,0x08,0x5F,0x48, /* 000002B0 ".LNKB._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000002B8 "ID.A...." */ - 0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x1C, /* 000002C0 "_UID...." */ - 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000002C8 "_STA.{PI" */ - 0x52,0x42,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 000002D0 "RB..`..." */ - 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 000002D8 "`......." */ - 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 000002E0 "....._PR" */ - 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 000002E8 "S..BUFA." */ - 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 000002F0 "._DIS.}P" */ - 0x49,0x52,0x42,0x0A,0x80,0x50,0x49,0x52, /* 000002F8 "IRB..PIR" */ - 0x42,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000300 "B.._CRS." */ - 0x7B,0x50,0x49,0x52,0x42,0x0A,0x0F,0x60, /* 00000308 "{PIRB..`" */ - 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000310 "y.`IRQV." */ - 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000318 "BUFB.._S" */ - 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000320 "RS..h.IR" */ - 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000328 "Q1.IRQ1`" */ - 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x42, /* 00000330 "v`p`PIRB" */ - 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x43, /* 00000338 "[.I.LNKC" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000340 "._HID.A." */ - 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000348 "..._UID." */ - 0x03,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 00000350 "..._STA." */ - 0x7B,0x50,0x49,0x52,0x43,0x0A,0x80,0x60, /* 00000358 "{PIRC..`" */ - 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 00000360 "...`...." */ - 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 00000368 "........" */ - 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 00000370 "_PRS..BU" */ - 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 00000378 "FA.._DIS" */ - 0x00,0x7D,0x50,0x49,0x52,0x43,0x0A,0x80, /* 00000380 ".}PIRC.." */ - 0x50,0x49,0x52,0x43,0x14,0x1A,0x5F,0x43, /* 00000388 "PIRC.._C" */ - 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x43, /* 00000390 "RS.{PIRC" */ - 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 00000398 "..`y.`IR" */ - 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 000003A0 "QV.BUFB." */ - 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 000003A8 "._SRS..h" */ - 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 000003B0 ".IRQ1.IR" */ - 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 000003B8 "Q1`v`p`P" */ - 0x49,0x52,0x43,0x5B,0x82,0x49,0x08,0x4C, /* 000003C0 "IRC[.I.L" */ - 0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,0x44, /* 000003C8 "NKD._HID" */ - 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 000003D0 ".A...._U" */ - 0x49,0x44,0x0A,0x04,0x14,0x1C,0x5F,0x53, /* 000003D8 "ID...._S" */ - 0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x44, /* 000003E0 "TA.{PIRD" */ - 0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A, /* 000003E8 "..`...`." */ - 0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A, /* 000003F0 "........" */ - 0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00, /* 000003F8 "..._PRS." */ - 0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F, /* 00000400 ".BUFA.._" */ - 0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52, /* 00000408 "DIS.}PIR" */ - 0x44,0x0A,0x80,0x50,0x49,0x52,0x44,0x14, /* 00000410 "D..PIRD." */ - 0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50, /* 00000418 "._CRS.{P" */ - 0x49,0x52,0x44,0x0A,0x0F,0x60,0x79,0x01, /* 00000420 "IRD..`y." */ - 0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55, /* 00000428 "`IRQV.BU" */ - 0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 00000430 "FB.._SRS" */ - 0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31, /* 00000438 "..h.IRQ1" */ - 0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60, /* 00000440 ".IRQ1`v`" */ - 0x70,0x60,0x50,0x49,0x52,0x44,0x14,0x16, /* 00000448 "p`PIRD.." */ - 0x5F,0x50,0x52,0x54,0x00,0xA0,0x0A,0x50, /* 00000450 "_PRT...P" */ - 0x49,0x43,0x44,0xA4,0x50,0x52,0x54,0x41, /* 00000458 "ICD.PRTA" */ - 0xA4,0x50,0x52,0x54,0x50,0x08,0x50,0x52, /* 00000460 ".PRTP.PR" */ - 0x54,0x50,0x12,0x4D,0x11,0x14,0x12,0x0B, /* 00000468 "TP.M...." */ - 0x04,0x0B,0xFF,0xFF,0x00,0x4C,0x4E,0x4B, /* 00000470 ".....LNK" */ - 0x41,0x00,0x12,0x0B,0x04,0x0B,0xFF,0xFF, /* 00000478 "A......." */ - 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0C, /* 00000480 ".LNKB..." */ - 0x04,0x0B,0xFF,0xFF,0x0A,0x02,0x4C,0x4E, /* 00000488 "......LN" */ - 0x4B,0x43,0x00,0x12,0x0C,0x04,0x0B,0xFF, /* 00000490 "KC......" */ - 0xFF,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00, /* 00000498 "...LNKD." */ - 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000004A0 "........" */ - 0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000004A8 ".LNKB..." */ - 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01,0x4C, /* 000004B0 ".......L" */ - 0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C, /* 000004B8 "NKC....." */ - 0xFF,0xFF,0x01,0x00,0x0A,0x02,0x4C,0x4E, /* 000004C0 "......LN" */ - 0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004C8 "KD......" */ - 0xFF,0x01,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004D0 ".....LNK" */ - 0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004D8 "A......." */ - 0x02,0x00,0x00,0x4C,0x4E,0x4B,0x43,0x00, /* 000004E0 "...LNKC." */ - 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 000004E8 "........" */ - 0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E, /* 000004F0 ".LNKD..." */ - 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02, /* 000004F8 "........" */ - 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04, /* 00000500 "LNKA...." */ - 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03,0x4C, /* 00000508 ".......L" */ - 0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04,0x0C, /* 00000510 "NKB....." */ - 0xFF,0xFF,0x03,0x00,0x00,0x4C,0x4E,0x4B, /* 00000518 ".....LNK" */ - 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000520 "D......." */ - 0x03,0x00,0x01,0x4C,0x4E,0x4B,0x41,0x00, /* 00000528 "...LNKA." */ - 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000530 "........" */ - 0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000538 "..LNKB.." */ - 0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000540 "........" */ - 0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0D, /* 00000548 ".LNKC..." */ - 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,0x4C, /* 00000550 ".......L" */ - 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000558 "NKA....." */ - 0xFF,0xFF,0x04,0x00,0x01,0x4C,0x4E,0x4B, /* 00000560 ".....LNK" */ - 0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000568 "B......." */ - 0x04,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43, /* 00000570 "....LNKC" */ - 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x04, /* 00000578 "........" */ - 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00, /* 00000580 "...LNKD." */ - 0x08,0x50,0x52,0x54,0x41,0x12,0x32,0x04, /* 00000588 ".PRTA.2." */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000590 "........" */ - 0x00,0x00,0x0A,0x05,0x12,0x0B,0x04,0x0C, /* 00000598 "........" */ - 0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A,0x07, /* 000005A0 "........" */ - 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 000005A8 "........" */ - 0x00,0x00,0x0A,0x0A,0x12,0x0B,0x04,0x0C, /* 000005B0 "........" */ - 0xFF,0xFF,0x04,0x00,0x00,0x00,0x0A,0x0B, /* 000005B8 "........" */ - 0x5B,0x82,0x48,0x31,0x49,0x53,0x41,0x5F, /* 000005C0 "[.H1ISA_" */ - 0x08,0x5F,0x41,0x44,0x52,0x00,0x5B,0x80, /* 000005C8 "._ADR.[." */ - 0x50,0x49,0x52,0x51,0x02,0x0A,0x60,0x0A, /* 000005D0 "PIRQ..`." */ - 0x04,0x10,0x2E,0x5C,0x00,0x5B,0x81,0x29, /* 000005D8 "...\.[.)" */ - 0x5C,0x2F,0x04,0x5F,0x53,0x42,0x5F,0x50, /* 000005E0 "\/._SB_P" */ - 0x43,0x49,0x30,0x49,0x53,0x41,0x5F,0x50, /* 000005E8 "CI0ISA_P" */ - 0x49,0x52,0x51,0x01,0x50,0x49,0x52,0x41, /* 000005F0 "IRQ.PIRA" */ - 0x08,0x50,0x49,0x52,0x42,0x08,0x50,0x49, /* 000005F8 ".PIRB.PI" */ - 0x52,0x43,0x08,0x50,0x49,0x52,0x44,0x08, /* 00000600 "RC.PIRD." */ - 0x5B,0x82,0x46,0x0B,0x53,0x59,0x53,0x52, /* 00000608 "[.F.SYSR" */ - 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000610 "._HID.A." */ - 0x0C,0x02,0x08,0x5F,0x55,0x49,0x44,0x01, /* 00000618 "..._UID." */ - 0x08,0x43,0x52,0x53,0x5F,0x11,0x4E,0x08, /* 00000620 ".CRS_.N." */ - 0x0A,0x8A,0x47,0x01,0x10,0x00,0x10,0x00, /* 00000628 "..G....." */ - 0x00,0x10,0x47,0x01,0x22,0x00,0x22,0x00, /* 00000630 "..G."."." */ - 0x00,0x0C,0x47,0x01,0x30,0x00,0x30,0x00, /* 00000638 "..G.0.0." */ - 0x00,0x10,0x47,0x01,0x44,0x00,0x44,0x00, /* 00000640 "..G.D.D." */ - 0x00,0x1C,0x47,0x01,0x62,0x00,0x62,0x00, /* 00000648 "..G.b.b." */ - 0x00,0x02,0x47,0x01,0x65,0x00,0x65,0x00, /* 00000650 "..G.e.e." */ - 0x00,0x0B,0x47,0x01,0x72,0x00,0x72,0x00, /* 00000658 "..G.r.r." */ - 0x00,0x0E,0x47,0x01,0x80,0x00,0x80,0x00, /* 00000660 "..G....." */ - 0x00,0x01,0x47,0x01,0x84,0x00,0x84,0x00, /* 00000668 "..G....." */ - 0x00,0x03,0x47,0x01,0x88,0x00,0x88,0x00, /* 00000670 "..G....." */ - 0x00,0x01,0x47,0x01,0x8C,0x00,0x8C,0x00, /* 00000678 "..G....." */ - 0x00,0x03,0x47,0x01,0x90,0x00,0x90,0x00, /* 00000680 "..G....." */ - 0x00,0x10,0x47,0x01,0xA2,0x00,0xA2,0x00, /* 00000688 "..G....." */ - 0x00,0x1C,0x47,0x01,0xE0,0x00,0xE0,0x00, /* 00000690 "..G....." */ - 0x00,0x10,0x47,0x01,0xA0,0x08,0xA0,0x08, /* 00000698 "..G....." */ - 0x00,0x04,0x47,0x01,0xC0,0x0C,0xC0,0x0C, /* 000006A0 "..G....." */ - 0x00,0x10,0x47,0x01,0xD0,0x04,0xD0,0x04, /* 000006A8 "..G....." */ - 0x00,0x02,0x79,0x00,0x14,0x0B,0x5F,0x43, /* 000006B0 "..y..._C" */ - 0x52,0x53,0x00,0xA4,0x43,0x52,0x53,0x5F, /* 000006B8 "RS..CRS_" */ - 0x5B,0x82,0x2B,0x50,0x49,0x43,0x5F,0x08, /* 000006C0 "[.+PIC_." */ - 0x5F,0x48,0x49,0x44,0x0B,0x41,0xD0,0x08, /* 000006C8 "_HID.A.." */ - 0x5F,0x43,0x52,0x53,0x11,0x18,0x0A,0x15, /* 000006D0 "_CRS...." */ - 0x47,0x01,0x20,0x00,0x20,0x00,0x01,0x02, /* 000006D8 "G. . ..." */ - 0x47,0x01,0xA0,0x00,0xA0,0x00,0x01,0x02, /* 000006E0 "G......." */ - 0x22,0x04,0x00,0x79,0x00,0x5B,0x82,0x47, /* 000006E8 ""..y.[.G" */ - 0x05,0x44,0x4D,0x41,0x30,0x08,0x5F,0x48, /* 000006F0 ".DMA0._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x02,0x00,0x08, /* 000006F8 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x41,0x04,0x0A, /* 00000700 "_CRS.A.." */ - 0x3D,0x2A,0x10,0x04,0x47,0x01,0x00,0x00, /* 00000708 "=*..G..." */ - 0x00,0x00,0x00,0x10,0x47,0x01,0x81,0x00, /* 00000710 "....G..." */ - 0x81,0x00,0x00,0x03,0x47,0x01,0x87,0x00, /* 00000718 "....G..." */ - 0x87,0x00,0x00,0x01,0x47,0x01,0x89,0x00, /* 00000720 "....G..." */ - 0x89,0x00,0x00,0x03,0x47,0x01,0x8F,0x00, /* 00000728 "....G..." */ - 0x8F,0x00,0x00,0x01,0x47,0x01,0xC0,0x00, /* 00000730 "....G..." */ - 0xC0,0x00,0x00,0x20,0x47,0x01,0x80,0x04, /* 00000738 "... G..." */ - 0x80,0x04,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000740 "....y.[." */ - 0x25,0x54,0x4D,0x52,0x5F,0x08,0x5F,0x48, /* 00000748 "%TMR_._H" */ - 0x49,0x44,0x0C,0x41,0xD0,0x01,0x00,0x08, /* 00000750 "ID.A...." */ - 0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000758 "_CRS...." */ - 0x47,0x01,0x40,0x00,0x40,0x00,0x00,0x04, /* 00000760 "G.@.@..." */ - 0x22,0x01,0x00,0x79,0x00,0x5B,0x82,0x25, /* 00000768 ""..y.[.%" */ - 0x52,0x54,0x43,0x5F,0x08,0x5F,0x48,0x49, /* 00000770 "RTC_._HI" */ - 0x44,0x0C,0x41,0xD0,0x0B,0x00,0x08,0x5F, /* 00000778 "D.A...._" */ - 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 00000780 "CRS....G" */ - 0x01,0x70,0x00,0x70,0x00,0x00,0x02,0x22, /* 00000788 ".p.p..."" */ - 0x00,0x01,0x79,0x00,0x5B,0x82,0x22,0x53, /* 00000790 "..y.[."S" */ - 0x50,0x4B,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000798 "PKR._HID" */ - 0x0C,0x41,0xD0,0x08,0x00,0x08,0x5F,0x43, /* 000007A0 ".A...._C" */ - 0x52,0x53,0x11,0x0D,0x0A,0x0A,0x47,0x01, /* 000007A8 "RS....G." */ - 0x61,0x00,0x61,0x00,0x00,0x01,0x79,0x00, /* 000007B0 "a.a...y." */ - 0x5B,0x82,0x31,0x50,0x53,0x32,0x4D,0x08, /* 000007B8 "[.1PS2M." */ - 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0F, /* 000007C0 "_HID.A.." */ - 0x13,0x08,0x5F,0x43,0x49,0x44,0x0C,0x41, /* 000007C8 ".._CID.A" */ - 0xD0,0x0F,0x13,0x14,0x09,0x5F,0x53,0x54, /* 000007D0 "....._ST" */ - 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 000007D8 "A....._C" */ - 0x52,0x53,0x11,0x08,0x0A,0x05,0x22,0x00, /* 000007E0 "RS...."." */ - 0x10,0x79,0x00,0x5B,0x82,0x42,0x04,0x50, /* 000007E8 ".y.[.B.P" */ - 0x53,0x32,0x4B,0x08,0x5F,0x48,0x49,0x44, /* 000007F0 "S2K._HID" */ - 0x0C,0x41,0xD0,0x03,0x03,0x08,0x5F,0x43, /* 000007F8 ".A...._C" */ - 0x49,0x44,0x0C,0x41,0xD0,0x03,0x0B,0x14, /* 00000800 "ID.A...." */ - 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000808 "._STA..." */ - 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 00000810 ".._CRS.." */ - 0x0A,0x15,0x47,0x01,0x60,0x00,0x60,0x00, /* 00000818 "..G.`.`." */ - 0x00,0x01,0x47,0x01,0x64,0x00,0x64,0x00, /* 00000820 "..G.d.d." */ - 0x00,0x01,0x22,0x02,0x00,0x79,0x00,0x5B, /* 00000828 ".."..y.[" */ - 0x82,0x3A,0x46,0x44,0x43,0x30,0x08,0x5F, /* 00000830 ".:FDC0._" */ - 0x48,0x49,0x44,0x0C,0x41,0xD0,0x07,0x00, /* 00000838 "HID.A..." */ - 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000840 ".._STA.." */ - 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000848 "..._CRS." */ - 0x1B,0x0A,0x18,0x47,0x01,0xF0,0x03,0xF0, /* 00000850 "...G...." */ - 0x03,0x01,0x06,0x47,0x01,0xF7,0x03,0xF7, /* 00000858 "...G...." */ - 0x03,0x01,0x01,0x22,0x40,0x00,0x2A,0x04, /* 00000860 "..."@.*." */ - 0x00,0x79,0x00,0x5B,0x82,0x35,0x55,0x41, /* 00000868 ".y.[.5UA" */ - 0x52,0x31,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000870 "R1._HID." */ - 0x41,0xD0,0x05,0x01,0x08,0x5F,0x55,0x49, /* 00000878 "A...._UI" */ - 0x44,0x01,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000880 "D..._STA" */ - 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000888 "....._CR" */ - 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8, /* 00000890 "S....G.." */ - 0x03,0xF8,0x03,0x01,0x08,0x22,0x10,0x00, /* 00000898 ".....".." */ - 0x79,0x00,0x5B,0x82,0x36,0x4C,0x54,0x50, /* 000008A0 "y.[.6LTP" */ - 0x31,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000008A8 "1._HID.A" */ - 0xD0,0x04,0x00,0x08,0x5F,0x55,0x49,0x44, /* 000008B0 "...._UID" */ - 0x0A,0x02,0x14,0x09,0x5F,0x53,0x54,0x41, /* 000008B8 "...._STA" */ - 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 000008C0 "....._CR" */ - 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x78, /* 000008C8 "S....G.x" */ - 0x03,0x78,0x03,0x08,0x08,0x22,0x80,0x00, /* 000008D0 ".x...".." */ - 0x79,0x00, + 0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, /* 000001A8 "........" */ + 0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00,0x00, /* 000001B0 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x87, /* 000001B8 "........" */ + 0x17,0x00,0x00,0x0D,0x03,0x00,0x00,0x00, /* 000001C0 "........" */ + 0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF, /* 000001C8 "........" */ + 0xF4,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D0 "........" */ + 0x05,0x79,0x00,0xA4,0x50,0x52,0x54,0x30, /* 000001D8 ".y..PRT0" */ + 0x08,0x42,0x55,0x46,0x41,0x11,0x09,0x0A, /* 000001E0 ".BUFA..." */ + 0x06,0x23,0xF8,0xDC,0x18,0x79,0x00,0x08, /* 000001E8 ".#...y.." */ + 0x42,0x55,0x46,0x42,0x11,0x09,0x0A,0x06, /* 000001F0 "BUFB...." */ + 0x23,0x00,0x00,0x18,0x79,0x00,0x8B,0x42, /* 000001F8 "#...y..B" */ + 0x55,0x46,0x42,0x01,0x49,0x52,0x51,0x56, /* 00000200 "UFB.IRQV" */ + 0x08,0x42,0x55,0x46,0x43,0x11,0x07,0x0A, /* 00000208 ".BUFC..." */ + 0x04,0x05,0x07,0x0A,0x0B,0x8C,0x42,0x55, /* 00000210 "......BU" */ + 0x46,0x43,0x01,0x50,0x49,0x51,0x41,0x8C, /* 00000218 "FC.PIQA." */ + 0x42,0x55,0x46,0x43,0x01,0x50,0x49,0x51, /* 00000220 "BUFC.PIQ" */ + 0x42,0x8C,0x42,0x55,0x46,0x43,0x01,0x50, /* 00000228 "B.BUFC.P" */ + 0x49,0x51,0x43,0x8C,0x42,0x55,0x46,0x43, /* 00000230 "IQC.BUFC" */ + 0x01,0x50,0x49,0x51,0x44,0x5B,0x82,0x48, /* 00000238 ".PIQD[.H" */ + 0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48, /* 00000240 ".LNKA._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000248 "ID.A...." */ + 0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F, /* 00000250 "_UID..._" */ + 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 00000258 "STA.{PIR" */ + 0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 00000260 "A..`...`" */ + 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 00000268 "........" */ + 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 00000270 "...._PRS" */ + 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 00000278 "..BUFA.." */ + 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000280 "_DIS.}PI" */ + 0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41, /* 00000288 "RA..PIRA" */ + 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000290 ".._CRS.{" */ + 0x50,0x49,0x52,0x42,0x0A,0x0F,0x60,0x79, /* 00000298 "PIRB..`y" */ + 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 000002A0 ".`IRQV.B" */ + 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 000002A8 "UFB.._SR" */ + 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 000002B0 "S..h.IRQ" */ + 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 000002B8 "1.IRQ1`v" */ + 0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B, /* 000002C0 "`p`PIRA[" */ + 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08, /* 000002C8 ".I.LNKB." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 000002D0 "_HID.A.." */ + 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 000002D8 ".._UID.." */ + 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 000002E0 ".._STA.{" */ + 0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0, /* 000002E8 "PIRB..`." */ + 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 000002F0 "..`....." */ + 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 000002F8 "......._" */ + 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000300 "PRS..BUF" */ + 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000308 "A.._DIS." */ + 0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50, /* 00000310 "}PIRB..P" */ + 0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52, /* 00000318 "IRB.._CR" */ + 0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 00000320 "S.{PIRB." */ + 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 00000328 ".`y.`IRQ" */ + 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 00000330 "V.BUFB.." */ + 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 00000338 "_SRS..h." */ + 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 00000340 "IRQ1.IRQ" */ + 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 00000348 "1`v`p`PI" */ + 0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 00000350 "RB[.I.LN" */ + 0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000358 "KC._HID." */ + 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 00000360 "A...._UI" */ + 0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54, /* 00000368 "D...._ST" */ + 0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 00000370 "A.{PIRC." */ + 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000378 ".`...`.." */ + 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000380 "........" */ + 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000388 ".._PRS.." */ + 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000390 "BUFA.._D" */ + 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43, /* 00000398 "IS.}PIRC" */ + 0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A, /* 000003A0 "..PIRC.." */ + 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 000003A8 "_CRS.{PI" */ + 0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 000003B0 "RC..`y.`" */ + 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 000003B8 "IRQV.BUF" */ + 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 000003C0 "B.._SRS." */ + 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 000003C8 ".h.IRQ1." */ + 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 000003D0 "IRQ1`v`p" */ + 0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49, /* 000003D8 "`PIRC[.I" */ + 0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 000003E0 ".LNKD._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000003E8 "ID.A...." */ + 0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C, /* 000003F0 "_UID...." */ + 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000003F8 "_STA.{PI" */ + 0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000400 "RD..`..." */ + 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000408 "`......." */ + 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000410 "....._PR" */ + 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000418 "S..BUFA." */ + 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000420 "._DIS.}P" */ + 0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52, /* 00000428 "IRD..PIR" */ + 0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000430 "D.._CRS." */ + 0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60, /* 00000438 "{PIRD..`" */ + 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000440 "y.`IRQV." */ + 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000448 "BUFB.._S" */ + 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000450 "RS..h.IR" */ + 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000458 "Q1.IRQ1`" */ + 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44, /* 00000460 "v`p`PIRD" */ + 0x14,0x16,0x5F,0x50,0x52,0x54,0x00,0xA0, /* 00000468 ".._PRT.." */ + 0x0A,0x50,0x49,0x43,0x44,0xA4,0x50,0x52, /* 00000470 ".PICD.PR" */ + 0x54,0x41,0xA4,0x50,0x52,0x54,0x50,0x08, /* 00000478 "TA.PRTP." */ + 0x50,0x52,0x54,0x50,0x12,0x4D,0x11,0x14, /* 00000480 "PRTP.M.." */ + 0x12,0x0B,0x04,0x0B,0xFF,0xFF,0x00,0x4C, /* 00000488 ".......L" */ + 0x4E,0x4B,0x41,0x00,0x12,0x0B,0x04,0x0B, /* 00000490 "NKA....." */ + 0xFF,0xFF,0x01,0x4C,0x4E,0x4B,0x42,0x00, /* 00000498 "...LNKB." */ + 0x12,0x0C,0x04,0x0B,0xFF,0xFF,0x0A,0x02, /* 000004A0 "........" */ + 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0C,0x04, /* 000004A8 "LNKC...." */ + 0x0B,0xFF,0xFF,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004B0 ".....LNK" */ + 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004B8 "D......." */ + 0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000004C0 "...LNKB." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000004C8 "........" */ + 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 000004D0 ".LNKC..." */ + 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 000004D8 "........" */ + 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000004E0 "LNKD...." */ + 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C, /* 000004E8 ".......L" */ + 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000004F0 "NKA....." */ + 0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B, /* 000004F8 ".....LNK" */ + 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000500 "C......." */ + 0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 00000508 "...LNKD." */ + 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000510 "........" */ + 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 00000518 "..LNKA.." */ + 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000520 "........" */ + 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000528 ".LNKB..." */ + 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C, /* 00000530 ".......L" */ + 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000538 "NKD....." */ + 0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B, /* 00000540 ".....LNK" */ + 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000548 "A......." */ + 0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000550 "....LNKB" */ + 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000558 "........" */ + 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000560 "...LNKC." */ + 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000568 "........" */ + 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000570 ".LNKA..." */ + 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C, /* 00000578 ".......L" */ + 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000580 "NKB....." */ + 0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E, /* 00000588 "......LN" */ + 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000590 "KC......" */ + 0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000598 ".....LNK" */ + 0x44,0x00,0x08,0x50,0x52,0x54,0x41,0x12, /* 000005A0 "D..PRTA." */ + 0x32,0x04,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000005A8 "2......." */ + 0x01,0x00,0x00,0x00,0x0A,0x05,0x12,0x0B, /* 000005B0 "........" */ + 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00, /* 000005B8 "........" */ + 0x0A,0x07,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000005C0 "........" */ + 0x03,0x00,0x00,0x00,0x0A,0x0A,0x12,0x0B, /* 000005C8 "........" */ + 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,0x00, /* 000005D0 "........" */ + 0x0A,0x0B,0x5B,0x82,0x48,0x31,0x49,0x53, /* 000005D8 "..[.H1IS" */ + 0x41,0x5F,0x08,0x5F,0x41,0x44,0x52,0x00, /* 000005E0 "A_._ADR." */ + 0x5B,0x80,0x50,0x49,0x52,0x51,0x02,0x0A, /* 000005E8 "[.PIRQ.." */ + 0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00,0x5B, /* 000005F0 "`....\.[" */ + 0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53,0x42, /* 000005F8 ".)\/._SB" */ + 0x5F,0x50,0x43,0x49,0x30,0x49,0x53,0x41, /* 00000600 "_PCI0ISA" */ + 0x5F,0x50,0x49,0x52,0x51,0x01,0x50,0x49, /* 00000608 "_PIRQ.PI" */ + 0x52,0x41,0x08,0x50,0x49,0x52,0x42,0x08, /* 00000610 "RA.PIRB." */ + 0x50,0x49,0x52,0x43,0x08,0x50,0x49,0x52, /* 00000618 "PIRC.PIR" */ + 0x44,0x08,0x5B,0x82,0x46,0x0B,0x53,0x59, /* 00000620 "D.[.F.SY" */ + 0x53,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000628 "SR._HID." */ + 0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49, /* 00000630 "A...._UI" */ + 0x44,0x01,0x08,0x43,0x52,0x53,0x5F,0x11, /* 00000638 "D..CRS_." */ + 0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10,0x00, /* 00000640 "N...G..." */ + 0x10,0x00,0x00,0x10,0x47,0x01,0x22,0x00, /* 00000648 "....G."." */ + 0x22,0x00,0x00,0x0C,0x47,0x01,0x30,0x00, /* 00000650 ""...G.0." */ + 0x30,0x00,0x00,0x10,0x47,0x01,0x44,0x00, /* 00000658 "0...G.D." */ + 0x44,0x00,0x00,0x1C,0x47,0x01,0x62,0x00, /* 00000660 "D...G.b." */ + 0x62,0x00,0x00,0x02,0x47,0x01,0x65,0x00, /* 00000668 "b...G.e." */ + 0x65,0x00,0x00,0x0B,0x47,0x01,0x72,0x00, /* 00000670 "e...G.r." */ + 0x72,0x00,0x00,0x0E,0x47,0x01,0x80,0x00, /* 00000678 "r...G..." */ + 0x80,0x00,0x00,0x01,0x47,0x01,0x84,0x00, /* 00000680 "....G..." */ + 0x84,0x00,0x00,0x03,0x47,0x01,0x88,0x00, /* 00000688 "....G..." */ + 0x88,0x00,0x00,0x01,0x47,0x01,0x8C,0x00, /* 00000690 "....G..." */ + 0x8C,0x00,0x00,0x03,0x47,0x01,0x90,0x00, /* 00000698 "....G..." */ + 0x90,0x00,0x00,0x10,0x47,0x01,0xA2,0x00, /* 000006A0 "....G..." */ + 0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0,0x00, /* 000006A8 "....G..." */ + 0xE0,0x00,0x00,0x10,0x47,0x01,0xA0,0x08, /* 000006B0 "....G..." */ + 0xA0,0x08,0x00,0x04,0x47,0x01,0xC0,0x0C, /* 000006B8 "....G..." */ + 0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0,0x04, /* 000006C0 "....G..." */ + 0xD0,0x04,0x00,0x02,0x79,0x00,0x14,0x0B, /* 000006C8 "....y..." */ + 0x5F,0x43,0x52,0x53,0x00,0xA4,0x43,0x52, /* 000006D0 "_CRS..CR" */ + 0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43, /* 000006D8 "S_[.+PIC" */ + 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41, /* 000006E0 "_._HID.A" */ + 0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 000006E8 ".._CRS.." */ + 0x0A,0x15,0x47,0x01,0x20,0x00,0x20,0x00, /* 000006F0 "..G. . ." */ + 0x01,0x02,0x47,0x01,0xA0,0x00,0xA0,0x00, /* 000006F8 "..G....." */ + 0x01,0x02,0x22,0x04,0x00,0x79,0x00,0x5B, /* 00000700 ".."..y.[" */ + 0x82,0x47,0x05,0x44,0x4D,0x41,0x30,0x08, /* 00000708 ".G.DMA0." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x02, /* 00000710 "_HID.A.." */ + 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x41, /* 00000718 ".._CRS.A" */ + 0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01, /* 00000720 "..=*..G." */ + 0x00,0x00,0x00,0x00,0x00,0x10,0x47,0x01, /* 00000728 "......G." */ + 0x81,0x00,0x81,0x00,0x00,0x03,0x47,0x01, /* 00000730 "......G." */ + 0x87,0x00,0x87,0x00,0x00,0x01,0x47,0x01, /* 00000738 "......G." */ + 0x89,0x00,0x89,0x00,0x00,0x03,0x47,0x01, /* 00000740 "......G." */ + 0x8F,0x00,0x8F,0x00,0x00,0x01,0x47,0x01, /* 00000748 "......G." */ + 0xC0,0x00,0xC0,0x00,0x00,0x20,0x47,0x01, /* 00000750 "..... G." */ + 0x80,0x04,0x80,0x04,0x00,0x10,0x79,0x00, /* 00000758 "......y." */ + 0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F,0x08, /* 00000760 "[.%TMR_." */ + 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 00000768 "_HID.A.." */ + 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000770 ".._CRS.." */ + 0x0A,0x0D,0x47,0x01,0x40,0x00,0x40,0x00, /* 00000778 "..G.@.@." */ + 0x00,0x04,0x22,0x01,0x00,0x79,0x00,0x5B, /* 00000780 ".."..y.[" */ + 0x82,0x25,0x52,0x54,0x43,0x5F,0x08,0x5F, /* 00000788 ".%RTC_._" */ + 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00, /* 00000790 "HID.A..." */ + 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000798 "._CRS..." */ + 0x0D,0x47,0x01,0x70,0x00,0x70,0x00,0x00, /* 000007A0 ".G.p.p.." */ + 0x02,0x22,0x00,0x01,0x79,0x00,0x5B,0x82, /* 000007A8 "."..y.[." */ + 0x22,0x53,0x50,0x4B,0x52,0x08,0x5F,0x48, /* 000007B0 ""SPKR._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x08,0x00,0x08, /* 000007B8 "ID.A...." */ + 0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A, /* 000007C0 "_CRS...." */ + 0x47,0x01,0x61,0x00,0x61,0x00,0x00,0x01, /* 000007C8 "G.a.a..." */ + 0x79,0x00,0x5B,0x82,0x31,0x50,0x53,0x32, /* 000007D0 "y.[.1PS2" */ + 0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000007D8 "M._HID.A" */ + 0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49,0x44, /* 000007E0 "...._CID" */ + 0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F, /* 000007E8 ".A....._" */ + 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 000007F0 "STA....." */ + 0x5F,0x43,0x52,0x53,0x11,0x08,0x0A,0x05, /* 000007F8 "_CRS...." */ + 0x22,0x00,0x10,0x79,0x00,0x5B,0x82,0x42, /* 00000800 ""..y.[.B" */ + 0x04,0x50,0x53,0x32,0x4B,0x08,0x5F,0x48, /* 00000808 ".PS2K._H" */ + 0x49,0x44,0x0C,0x41,0xD0,0x03,0x03,0x08, /* 00000810 "ID.A...." */ + 0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 00000818 "_CID.A.." */ + 0x0B,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000820 "..._STA." */ + 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000828 "...._CRS" */ + 0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00, /* 00000830 "....G.`." */ + 0x60,0x00,0x00,0x01,0x47,0x01,0x64,0x00, /* 00000838 "`...G.d." */ + 0x64,0x00,0x00,0x01,0x22,0x02,0x00,0x79, /* 00000840 "d..."..y" */ + 0x00,0x5B,0x82,0x3A,0x46,0x44,0x43,0x30, /* 00000848 ".[.:FDC0" */ + 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000850 "._HID.A." */ + 0x07,0x00,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000858 "...._STA" */ + 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000860 "....._CR" */ + 0x53,0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0, /* 00000868 "S....G.." */ + 0x03,0xF0,0x03,0x01,0x06,0x47,0x01,0xF7, /* 00000870 ".....G.." */ + 0x03,0xF7,0x03,0x01,0x01,0x22,0x40,0x00, /* 00000878 "....."@." */ + 0x2A,0x04,0x00,0x79,0x00,0x5B,0x82,0x35, /* 00000880 "*..y.[.5" */ + 0x55,0x41,0x52,0x31,0x08,0x5F,0x48,0x49, /* 00000888 "UAR1._HI" */ + 0x44,0x0C,0x41,0xD0,0x05,0x01,0x08,0x5F, /* 00000890 "D.A...._" */ + 0x55,0x49,0x44,0x01,0x14,0x09,0x5F,0x53, /* 00000898 "UID..._S" */ + 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 000008A0 "TA....._" */ + 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 000008A8 "CRS....G" */ + 0x01,0xF8,0x03,0xF8,0x03,0x01,0x08,0x22, /* 000008B0 "......."" */ + 0x10,0x00,0x79,0x00,0x5B,0x82,0x36,0x4C, /* 000008B8 "..y.[.6L" */ + 0x54,0x50,0x31,0x08,0x5F,0x48,0x49,0x44, /* 000008C0 "TP1._HID" */ + 0x0C,0x41,0xD0,0x04,0x00,0x08,0x5F,0x55, /* 000008C8 ".A...._U" */ + 0x49,0x44,0x0A,0x02,0x14,0x09,0x5F,0x53, /* 000008D0 "ID...._S" */ + 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 000008D8 "TA....._" */ + 0x43,0x52,0x53,0x11,0x10,0x0A,0x0D,0x47, /* 000008E0 "CRS....G" */ + 0x01,0x78,0x03,0x78,0x03,0x08,0x08,0x22, /* 000008E8 ".x.x..."" */ + 0x80,0x00,0x79,0x00, }; int DsdtLen=sizeof(AmlCode); diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/acpi_utils.c --- a/tools/firmware/hvmloader/acpi_utils.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/acpi_utils.c Mon Nov 20 13:11:15 2006 -0700 @@ -23,8 +23,11 @@ #include "acpi/acpi2_0.h" #include "acpi_utils.h" #include "util.h" +#include <xen/hvm/e820.h> static int acpi_rsdt_add_entry_pointer(unsigned char *acpi_start, + unsigned char *entry); +static int acpi_xsdt_add_entry_pointer(unsigned char *acpi_start, unsigned char *entry); static unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start, unsigned char **freemem, @@ -34,45 +37,78 @@ static unsigned char *acpi_xsdt_add_entr void set_checksum(void *start, int checksum_offset, int len) { - unsigned char sum = 0; - unsigned char *ptr; - - ptr = start; - ptr[checksum_offset] = 0; - while (len--) - sum += *ptr++; - - ptr = start; - ptr[checksum_offset] = -sum; + unsigned char sum = 0; + unsigned char *ptr; + + ptr = start; + ptr[checksum_offset] = 0; + while ( len-- ) + sum += *ptr++; + + ptr = start; + ptr[checksum_offset] = -sum; } #include "acpi_ssdt_tpm.h" -static int acpi_tpm_tis_probe(unsigned char *acpi_start, - unsigned char **freemem, - unsigned char *limit) -{ - int success = 1; /* not successful means 'out of memory' */ - unsigned char *addr; - /* check TPM_DID, TPM_VID, TPM_RID in ioemu/hw/tpm_tis.c */ - uint16_t tis_did_vid_rid[] = {0x0001, 0x0001, 0x0001}; - - /* probe for TIS interface ... */ - if (memcmp((char *)(0xFED40000 + 0xF00), - tis_did_vid_rid, - sizeof(tis_did_vid_rid)) == 0) { - puts("TIS is available\n"); - addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, - AmlCode_TPM, sizeof(AmlCode_TPM)); - if (addr == NULL) - success = 0; - else { - /* legacy systems need an RSDT entry */ - acpi_rsdt_add_entry_pointer(acpi_start, - addr); - } - } - return success; +static void acpi_tpm_tis_probe(unsigned char *acpi_start, + unsigned char **freemem, + unsigned char *limit) +{ + unsigned char *addr; + ACPI_2_0_TCPA_CLIENT *tcpa; + /* check TPM_DID, TPM_VID, TPM_RID in ioemu/hw/tpm_tis.c */ + uint16_t tis_did_vid_rid[] = {0x0001, 0x0001, 0x0001}; + static const ACPI_2_0_TCPA_CLIENT Tcpa = { + .header = { + .signature = ACPI_2_0_TCPA_SIGNATURE, + .length = sizeof(ACPI_2_0_TCPA_CLIENT), + .revision = ACPI_2_0_TCPA_REVISION, + .oem_id = {'I', 'B', 'M', ' ', ' ', ' '}, + .oem_table_id = ASCII64(' ', ' ', ' ', ' ', ' ', 'x', 'e', 'n'), + .oem_revision = 1, + .creator_id = ASCII32('I', 'B', 'M', ' '), + .creator_revision = 1, + } + }; + + /* probe for TIS interface ... */ + if ( memcmp((char *)(0xFED40000 + 0xF00), + tis_did_vid_rid, + sizeof(tis_did_vid_rid)) != 0 ) + return; + + puts("TIS is available\n"); + addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, + AmlCode_TPM, sizeof(AmlCode_TPM)); + if ( addr == NULL ) + return; + + /* legacy systems need an RSDT entry */ + acpi_rsdt_add_entry_pointer(acpi_start, addr); + + /* add ACPI TCPA table */ + addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, + (unsigned char *)&Tcpa, + sizeof(Tcpa)); + if ( addr == NULL ) + return; + + tcpa = (ACPI_2_0_TCPA_CLIENT *)addr; + tcpa->LASA = e820_malloc( + ACPI_2_0_TCPA_LAML_SIZE, E820_RESERVED, (uint32_t)~0); + if ( tcpa->LASA ) + { + tcpa->LAML = ACPI_2_0_TCPA_LAML_SIZE; + memset((char *)(unsigned long)tcpa->LASA, + 0x0, + tcpa->LAML); + set_checksum(tcpa, + FIELD_OFFSET(struct acpi_header, checksum), + tcpa->header.length); + } + + acpi_rsdt_add_entry_pointer(acpi_start, addr); } @@ -95,17 +131,20 @@ struct acpi_20_rsdt *acpi_rsdt_get(unsig struct acpi_20_rsdt *rsdt; rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if (rsdp->signature != ACPI_2_0_RSDP_SIGNATURE) { + if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) + { puts("Bad RSDP signature\n"); return NULL; } rsdt = (struct acpi_20_rsdt *) (acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS); - if (rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE) { + if ( rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE ) + { puts("Bad RSDT signature\n"); return NULL; } + return rsdt; } @@ -119,17 +158,20 @@ static int acpi_rsdt_add_entry_pointer(u int found = 0; int i = 0; - /* get empty slot in the RSDT table */ - while (i < ACPI_MAX_NUM_TABLES) { - if (rsdt->entry[i] == 0) { - found = 1; - break; - } - i++; - } - - if (found) { - rsdt->entry[i] = (uint64_t)(long)entry; + /* Find an empty slot in the RSDT table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( rsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { + rsdt->entry[i] = (uint64_t)(unsigned long)entry; rsdt->header.length = sizeof(struct acpi_header) + (i + 1) * sizeof(uint64_t); @@ -141,25 +183,62 @@ static int acpi_rsdt_add_entry_pointer(u return found; } -/* Get the XSDT table */ +/* Get the XSDT table. */ struct acpi_20_xsdt *acpi_xsdt_get(unsigned char *acpi_start) { struct acpi_20_rsdp *rsdp; struct acpi_20_xsdt *xsdt; rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if (rsdp->signature != ACPI_2_0_RSDP_SIGNATURE) { + if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) + { puts("Bad RSDP signature\n"); return NULL; } xsdt = (struct acpi_20_xsdt *) (acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS); - if (xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE) { + if ( xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE ) + { puts("Bad XSDT signature\n"); return NULL; } return xsdt; +} + +/* + * Add an entry to the XSDT table given the pointer to the entry. + */ +static int acpi_xsdt_add_entry_pointer(unsigned char *acpi_start, + unsigned char *entry) +{ + struct acpi_20_xsdt *xsdt = acpi_xsdt_get(acpi_start); + int found = 0; + int i = 0; + + /* Find an empty slot in the XSDT table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( xsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { + xsdt->entry[i] = (uint64_t)(unsigned long)entry; + xsdt->header.length = + sizeof(struct acpi_header) + + (i + 1) * sizeof(uint64_t); + set_checksum(xsdt, + FIELD_OFFSET(struct acpi_header, checksum), + xsdt->header.length); + } + + return found; } /* @@ -177,31 +256,29 @@ static unsigned char *acpi_xsdt_add_entr int found = 0, i = 0; unsigned char *addr = NULL; - /* get empty slot in the Xsdt table */ - while (i < ACPI_MAX_NUM_TABLES) { - if (xsdt->entry[i] == 0) { - found = 1; - break; - } - i++; - } - - if (found) { + /* Check for an empty slot in the Xsdt table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( xsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { /* memory below hard limit ? */ if (*freemem + table_size <= limit) { puts("Copying SSDT entry!\n"); addr = *freemem; memcpy(addr, table, table_size); - xsdt->entry[i] = (uint64_t)(long)addr; *freemem += table_size; - /* update the XSDT table */ - xsdt->header.length = - sizeof(struct acpi_header) + - (i + 1) * sizeof(uint64_t); - set_checksum(xsdt, - FIELD_OFFSET(struct acpi_header, checksum), - xsdt->header.length); - } - } + + acpi_xsdt_add_entry_pointer(acpi_start, addr); + } + } + return addr; } diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/util.c Mon Nov 20 13:11:15 2006 -0700 @@ -90,6 +90,23 @@ void *memcpy(void *dest, const void *src return dest; } +void *memmove(void *dest, const void *src, unsigned n) +{ + if ((long)dest > (long)src) { + n--; + while (n > 0) { + ((char *)dest)[n] = ((char *)src)[n]; + n--; + } + } else { + memcpy(dest, src, n); + } + return dest; +} + + + + void puts(const char *s) { while (*s) @@ -229,3 +246,37 @@ uuid_to_string(char *dest, uint8_t *uuid } *p = 0; } + +#include <xen/hvm/e820.h> +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) +#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) +uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask) +{ + uint64_t addr = 0; + int c = *E820_MAP_NR - 1; + struct e820entry *e820entry = (struct e820entry *)E820_MAP; + + while (c >= 0) { + if (e820entry[c].type == E820_RAM && + (e820entry[c].addr & (~mask)) == 0 && + e820entry[c].size >= size) { + addr = e820entry[c].addr; + if (e820entry[c].size != size) { + (*E820_MAP_NR)++; + memmove(&e820entry[c+1], + &e820entry[c], + (*E820_MAP_NR - c) * + sizeof(struct e820entry)); + e820entry[c].size -= size; + addr += e820entry[c].size; + c++; + } + e820entry[c].addr = addr; + e820entry[c].size = size; + e820entry[c].type = type; + break; + } + c--; + } + return addr; +} diff -r 066094348f22 -r 0699c3eff7a3 tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/firmware/hvmloader/util.h Mon Nov 20 13:11:15 2006 -0700 @@ -22,6 +22,7 @@ unsigned strlen(const char *s); unsigned strlen(const char *s); int memcmp(const void *s1, const void *s2, unsigned n); void *memcpy(void *dest, const void *src, unsigned n); +void *memmove(void *dest, const void *src, unsigned n); void *memset(void *s, int c, unsigned n); char *itoa(char *a, unsigned int i); @@ -38,4 +39,7 @@ void uuid_to_string(char *dest, uint8_t /* Debug output */ void puts(const char *s); +/* Allocate region of specified type in the e820 table. */ +uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); + #endif /* __HVMLOADER_UTIL_H__ */ diff -r 066094348f22 -r 0699c3eff7a3 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/ioemu/Makefile.target Mon Nov 20 13:11:15 2006 -0700 @@ -177,7 +177,8 @@ endif ######################################################### -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +DEFINES+=-D_GNU_SOURCE +#-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE LIBS+=-lm LIBS+=-L../../libxc -lxenctrl -lxenguest LIBS+=-L../../xenstore -lxenstore diff -r 066094348f22 -r 0699c3eff7a3 tools/ioemu/hw/rtl8139.c --- a/tools/ioemu/hw/rtl8139.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/ioemu/hw/rtl8139.c Mon Nov 20 13:11:15 2006 -0700 @@ -1999,12 +1999,12 @@ static int rtl8139_cplus_transmit_one(RT DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer allocated space %d\n", s->cplus_txbuffer_len)); } - while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) - { - s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE; - s->cplus_txbuffer = realloc(s->cplus_txbuffer, s->cplus_txbuffer_len); - - DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space changed to %d\n", s->cplus_txbuffer_len)); + if (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len) + { + free(s->cplus_txbuffer); + s->cplus_txbuffer = NULL; + + DEBUG_PRINT(("RTL8139: +++ C+ mode transmission buffer space exceeded: %d\n", s->cplus_txbuffer_offset + txsize)); } if (!s->cplus_txbuffer) diff -r 066094348f22 -r 0699c3eff7a3 tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/ioemu/xenstore.c Mon Nov 20 13:11:15 2006 -0700 @@ -100,7 +100,7 @@ void xenstore_parse_domain_config(int do if (strncmp(dev, "hd", 2) || strlen(dev) != 3) continue; hd_index = dev[2] - 'a'; - if (hd_index > MAX_DISKS) + if (hd_index >= MAX_DISKS) continue; /* read the type of the device */ if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1) diff -r 066094348f22 -r 0699c3eff7a3 tools/libfsimage/Rules.mk --- a/tools/libfsimage/Rules.mk Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libfsimage/Rules.mk Mon Nov 20 13:11:15 2006 -0700 @@ -2,7 +2,7 @@ include $(XEN_ROOT)/tools/Rules.mk DEPS = .*.d -CFLAGS += -I$(XEN_ROOT)/tools/libfsimage/common/ -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wp,-MD,.$(@F).d +CFLAGS += -I$(XEN_ROOT)/tools/libfsimage/common/ -Werror -Wp,-MD,.$(@F).d LDFLAGS += -L../common/ PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y)) diff -r 066094348f22 -r 0699c3eff7a3 tools/libfsimage/common/Makefile --- a/tools/libfsimage/common/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libfsimage/common/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -4,7 +4,7 @@ MAJOR = 1.0 MAJOR = 1.0 MINOR = 0 -CFLAGS += -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wp,-MD,.$(@F).d +CFLAGS += -Werror -Wp,-MD,.$(@F).d DEPS = .*.d LDFLAGS-$(CONFIG_SunOS) = -Wl,-M -Wl,mapfile-SunOS diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xc_acm.c --- a/tools/libxc/xc_acm.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xc_acm.c Mon Nov 20 13:11:15 2006 -0700 @@ -14,8 +14,7 @@ #include "xc_private.h" - -int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size) +int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned long arg_size) { int ret = -1; DECLARE_HYPERCALL; diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xc_domain.c Mon Nov 20 13:11:15 2006 -0700 @@ -352,7 +352,7 @@ int xc_domain_memory_increase_reservatio if ( err >= 0 ) { DPRINTF("Failed allocation for dom %d: " - "%ld pages order %d addr_bits %d\n", + "%ld extents of order %d, addr_bits %d\n", domid, nr_extents, extent_order, address_bits); errno = ENOMEM; err = -1; @@ -390,7 +390,7 @@ int xc_domain_memory_decrease_reservatio if ( err >= 0 ) { - DPRINTF("Failed deallocation for dom %d: %ld pages order %d\n", + DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n", domid, nr_extents, extent_order); errno = EINVAL; err = -1; @@ -421,7 +421,7 @@ int xc_domain_memory_populate_physmap(in if ( err >= 0 ) { - DPRINTF("Failed allocation for dom %d: %ld pages order %d\n", + DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n", domid, nr_extents, extent_order); errno = EBUSY; err = -1; diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xc_linux_build.c Mon Nov 20 13:11:15 2006 -0700 @@ -1106,7 +1106,7 @@ static int xc_linux_build_internal(int x { struct xen_domctl launch_domctl; DECLARE_DOMCTL; - int rc, i; + int rc; struct vcpu_guest_context st_ctxt, *ctxt = &st_ctxt; unsigned long vstartinfo_start, vkern_entry, vstack_start; uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, }; @@ -1120,11 +1120,9 @@ static int xc_linux_build_internal(int x } } -#ifdef VALGRIND - memset(&st_ctxt, 0, sizeof(st_ctxt)); -#endif - - if ( lock_pages(&st_ctxt, sizeof(st_ctxt) ) ) + memset(ctxt, 0, sizeof(*ctxt)); + + if ( lock_pages(ctxt, sizeof(*ctxt) ) ) { PERROR("%s: ctxt lock failed", __func__); return 1; @@ -1138,8 +1136,6 @@ static int xc_linux_build_internal(int x PERROR("Could not get info on domain"); goto error_out; } - - memset(ctxt, 0, sizeof(*ctxt)); if ( setup_guest(xc_handle, domid, image, image_size, initrd, @@ -1157,12 +1153,9 @@ static int xc_linux_build_internal(int x #ifdef __ia64__ /* based on new_thread in xen/arch/ia64/domain.c */ - ctxt->flags = 0; - ctxt->user_regs.cr_ipsr = 0; /* all necessary bits filled by hypervisor */ ctxt->user_regs.cr_iip = vkern_entry; ctxt->user_regs.cr_ifs = 1UL << 63; ctxt->user_regs.ar_fpsr = xc_ia64_fpsr_default(); - i = 0; /* silence unused variable warning */ #else /* x86 */ /* * Initial register values: @@ -1186,43 +1179,11 @@ static int xc_linux_build_internal(int x ctxt->flags = VGCF_IN_KERNEL; - /* FPU is set up to default initial state. */ - memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt)); - - /* Virtual IDT is empty at start-of-day. */ - for ( i = 0; i < 256; i++ ) - { - ctxt->trap_ctxt[i].vector = i; - ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS; - } - - /* No LDT. */ - ctxt->ldt_ents = 0; - - /* Use the default Xen-provided GDT. */ - ctxt->gdt_ents = 0; - - /* Ring 1 stack is the initial stack. */ - ctxt->kernel_ss = FLAT_KERNEL_SS; - ctxt->kernel_sp = vstack_start + PAGE_SIZE; - - /* No debugging. */ - memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg)); - - /* No callback handlers. */ -#if defined(__i386__) - ctxt->event_callback_cs = FLAT_KERNEL_CS; - ctxt->event_callback_eip = 0; - ctxt->failsafe_callback_cs = FLAT_KERNEL_CS; - ctxt->failsafe_callback_eip = 0; -#elif defined(__x86_64__) - ctxt->event_callback_eip = 0; - ctxt->failsafe_callback_eip = 0; - ctxt->syscall_callback_eip = 0; -#endif + ctxt->kernel_ss = ctxt->user_regs.ss; + ctxt->kernel_sp = ctxt->user_regs.esp; #endif /* x86 */ - memset( &launch_domctl, 0, sizeof(launch_domctl) ); + memset(&launch_domctl, 0, sizeof(launch_domctl)); launch_domctl.domain = (domid_t)domid; launch_domctl.u.vcpucontext.vcpu = 0; diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xc_linux_restore.c --- a/tools/libxc/xc_linux_restore.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xc_linux_restore.c Mon Nov 20 13:11:15 2006 -0700 @@ -774,39 +774,6 @@ int xc_linux_restore(int xc_handle, int memcpy(live_p2m, p2m, P2M_SIZE); munmap(live_p2m, P2M_SIZE); - /* - * Safety checking of saved context: - * 1. user_regs is fine, as Xen checks that on context switch. - * 2. fpu_ctxt is fine, as it can't hurt Xen. - * 3. trap_ctxt needs the code selectors checked. - * 4. ldt base must be page-aligned, no more than 8192 ents, ... - * 5. gdt already done, and further checking is done by Xen. - * 6. check that kernel_ss is safe. - * 7. pt_base is already done. - * 8. debugregs are checked by Xen. - * 9. callback code selectors need checking. - */ - for ( i = 0; i < 256; i++ ) { - ctxt.trap_ctxt[i].vector = i; - if ((ctxt.trap_ctxt[i].cs & 3) == 0) - ctxt.trap_ctxt[i].cs = FLAT_KERNEL_CS; - } - if ((ctxt.kernel_ss & 3) == 0) - ctxt.kernel_ss = FLAT_KERNEL_DS; -#if defined(__i386__) - if ((ctxt.event_callback_cs & 3) == 0) - ctxt.event_callback_cs = FLAT_KERNEL_CS; - if ((ctxt.failsafe_callback_cs & 3) == 0) - ctxt.failsafe_callback_cs = FLAT_KERNEL_CS; -#endif - if (((ctxt.ldt_base & (PAGE_SIZE - 1)) != 0) || - (ctxt.ldt_ents > 8192) || - (ctxt.ldt_base > hvirt_start) || - ((ctxt.ldt_base + ctxt.ldt_ents*8) > hvirt_start)) { - ERROR("Bad LDT base or size"); - goto out; - } - DPRINTF("Domain ready to be built.\n"); domctl.cmd = XEN_DOMCTL_setvcpucontext; diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xc_tbuf.c --- a/tools/libxc/xc_tbuf.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xc_tbuf.c Mon Nov 20 13:11:15 2006 -0700 @@ -57,7 +57,7 @@ int xc_tbuf_get_size(int xc_handle, unsi return rc; } -int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn, +int xc_tbuf_enable(int xc_handle, unsigned long pages, unsigned long *mfn, unsigned long *size) { DECLARE_SYSCTL; @@ -68,7 +68,7 @@ int xc_tbuf_enable(int xc_handle, size_t * set (since trace buffers cannot be reallocated). If we really have no * buffers at all then tbuf_enable() will fail, so this is safe. */ - (void)xc_tbuf_set_size(xc_handle, cnt); + (void)xc_tbuf_set_size(xc_handle, pages); if ( tbuf_enable(xc_handle, 1) != 0 ) return -1; diff -r 066094348f22 -r 0699c3eff7a3 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/libxc/xenctrl.h Mon Nov 20 13:11:15 2006 -0700 @@ -556,8 +556,8 @@ long xc_get_tot_pages(int xc_handle, uin * Gets the machine address of the trace pointer area and the size of the * per CPU buffers. */ -int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn, - unsigned long *size); +int xc_tbuf_enable(int xc_handle, unsigned long pages, + unsigned long *mfn, unsigned long *size); /* * Disable tracing buffers. @@ -610,7 +610,7 @@ int xc_add_mmu_update(int xc_handle, xc_ unsigned long long ptr, unsigned long long val); int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu); -int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size); +int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned long arg_size); /* * Return a handle to the event channel driver, or -1 on failure, in which case diff -r 066094348f22 -r 0699c3eff7a3 tools/misc/lomount/lomount.c --- a/tools/misc/lomount/lomount.c Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/misc/lomount/lomount.c Mon Nov 20 13:11:15 2006 -0700 @@ -44,8 +44,6 @@ enum ERR_MOUNT // Other failure of mount command }; -#define _LARGEFILE_SOURCE -#define _FILE_OFFSET_BITS 64 #include <unistd.h> #include <stdio.h> #include <stdlib.h> diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/util/security.py --- a/tools/python/xen/util/security.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/util/security.py Mon Nov 20 13:11:15 2006 -0700 @@ -606,11 +606,17 @@ def unify_resname(resource): # sanity check on resource name try: - (type, resfile) = resource.split(":") + (type, resfile) = resource.split(":", 1) except: err("Resource spec '%s' contains no ':' delimiter" % resource) - if type == "phy": + if type == "tap": + try: + (subtype, resfile) = resfile.split(":") + except: + err("Resource spec '%s' contains no tap subtype" % resource) + + if type in ["phy", "tap"]: if not resfile.startswith("/"): resfile = "/dev/" + resfile @@ -619,6 +625,8 @@ def unify_resname(resource): err("Invalid resource.") # from here on absolute file names with resources + if type == "tap": + type = type + ":" + subtype resource = type + ":" + resfile return resource diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/XendAPI.py Mon Nov 20 13:11:15 2006 -0700 @@ -591,6 +591,7 @@ class XendAPI: 'platform_localtime', 'platform_clock_offset', 'platform_enable_audio', + 'platform_keymap', 'builder', 'boot_method', 'kernel_kernel', @@ -638,6 +639,7 @@ class XendAPI: 'platform_localtime', 'platform_clock_offset', 'platform_enable_audio', + 'platform_keymap', 'builder', 'boot_method', 'kernel_kernel', @@ -781,6 +783,10 @@ class XendAPI: return xen_api_todo() def vm_get_platform_enable_audio(self, session, vm_ref): + dom = XendDomain.instance().get_vm_by_uuid(vm_ref) + return xen_api_todo() + + def vm_get_platform_keymap(self, session, vm_ref): dom = XendDomain.instance().get_vm_by_uuid(vm_ref) return xen_api_todo() @@ -981,6 +987,7 @@ class XendAPI: 'platform_localtime': xeninfo.get_platform_localtime(), 'platform_clock_offset': xeninfo.get_platform_clock_offset(), 'platform_enable_audio': xeninfo.get_platform_enable_audio(), + 'platform_keymap': xeninfo.get_platform_keymap(), 'builder': xeninfo.get_builder(), 'boot_method': xeninfo.get_boot_method(), 'kernel_kernel': xeninfo.get_kernel_image(), diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/XendConfig.py Mon Nov 20 13:11:15 2006 -0700 @@ -17,6 +17,7 @@ import re import time +import types from xen.xend import sxp from xen.xend import uuid @@ -60,6 +61,7 @@ XENAPI_HVM_CFG = { 'platform_serial' : 'serial', 'platform_localtime': 'localtime', 'platform_enable_audio': 'soundhw', + 'platform_keymap' : 'keymap', } XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [ @@ -82,6 +84,7 @@ XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [ 'platform_localtime', 'platform_clock_offset', 'platform_enable_audio', + 'platform_keymap', 'builder', 'grub_cmdline', 'pci_bus', @@ -142,6 +145,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [ ('uuid', str), ('vcpus', int), ('vcpu_avail', int), + ('cpu_cap', int), ('cpu_weight', int), ('memory', int), ('shadow_memory', int), @@ -447,11 +451,36 @@ class XendConfig(dict): for c in sxp.children(parsed, 'backend'): cfg['backend'].append(sxp.name(sxp.child0(c))) + # Parsing the device SXP's. In most cases, the SXP looks + # like this: + # + # [device, [vif, [mac, xx:xx:xx:xx:xx:xx], [ip 1.3.4.5]]] + # + # However, for PCI devices it looks like this: + # + # [device, [pci, [dev, [domain, 0], [bus, 0], [slot, 1]]]] + # + # It seems the reasoning for this difference is because + # pciif.py needs all the PCI device configurations at + # the same time when creating the devices. + # + # To further complicate matters, Xen 2.0 configuration format + # uses the following for pci device configuration: + # + # [device, [pci, [domain, 0], [bus, 0], [dev, 1], [func, 2]]] + # + # Hence we deal with pci device configurations outside of + # the regular device parsing. + cfg['device'] = {} for dev in sxp.children(parsed, 'device'): config = sxp.child0(dev) dev_type = sxp.name(config) dev_info = {} + + if dev_type == 'pci': + continue + for opt, val in config[1:]: dev_info[opt] = val log.debug("XendConfig: reading device: %s" % dev_info) @@ -459,9 +488,34 @@ class XendConfig(dict): dev_uuid = dev_info.get('uuid', uuid.createString()) dev_info['uuid'] = dev_uuid cfg['device'][dev_uuid] = (dev_type, dev_info) - - #cfg['device'].append((sxp.name(config), config)) - + + # deal with PCI device configurations if they exist + for dev in sxp.children(parsed, 'device'): + config = sxp.child0(dev) + dev_type = sxp.name(config) + + if dev_type != 'pci': + continue + + dev_attr = sxp.child_value(config, 'dev') + if isinstance(dev_attr, (types.ListType, types.TupleType)): + for pci_dev in sxp.children(config, 'dev'): + dev_info = {} + for opt, val in pci_dev[1:]: + dev_info[opt] = val + log.debug("XendConfig: reading device: %s" % dev_info) + dev_uuid = dev_info.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid + cfg['device'][dev_uuid] = (dev_type, dev_info) + + else: # Xen 2.0 PCI device configuration + for opt, val in config[1:]: + dev_info[opt] = val + log.debug("XendConfig: reading device: %s" % dev_info) + # create uuid if it doesn't + dev_uuid = dev_info.get('uuid', uuid.createString()) + dev_info['uuid'] = dev_uuid + cfg['device'][dev_uuid] = (dev_type, dev_info) # Extract missing data from configuration entries if 'image' in cfg: @@ -529,7 +583,7 @@ class XendConfig(dict): old_state = sxp.child_value(parsed, 'state') if old_state: for i in range(len(CONFIG_OLD_DOM_STATES)): - cfg[CONFIG_OLD_DOM_STATES[i]] = (old_state[i] != '-') + cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-') # Xen API extra cfgs # ------------------ @@ -726,7 +780,8 @@ class XendConfig(dict): # Verify devices for d_uuid, (d_type, d_info) in self['device'].items(): - if d_type not in XendDevices.valid_devices(): + if d_type not in XendDevices.valid_devices() and \ + d_type not in XendDevices.pseudo_devices(): raise XendConfigError('Invalid device (%s)' % d_type) # Verify restart modes @@ -744,7 +799,8 @@ class XendConfig(dict): self['vtpm_refs'] = [] def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None): - if dev_type not in XendDevices.valid_devices(): + if dev_type not in XendDevices.valid_devices() and \ + dev_type not in XendDevices.pseudo_devices(): raise XendConfigError("XendConfig: %s not a valid device type" % dev_type) @@ -856,10 +912,27 @@ class XendConfig(dict): return sxpr def all_devices_sxpr(self): + """Returns the SXPR for all devices in the current configuration.""" sxprs = [] + pci_devs = [] for dev_type, dev_info in self['device'].values(): - sxpr = self.device_sxpr(dev_type = dev_type, dev_info = dev_info) - sxprs.append((dev_type, sxpr)) + if dev_type == 'pci': # special case for pci devices + pci_devs.append(dev_info) + else: + sxpr = self.device_sxpr(dev_type = dev_type, + dev_info = dev_info) + sxprs.append((dev_type, sxpr)) + + # if we have any pci_devs, we parse them differently into + # one single pci SXP entry. + if pci_devs: + sxpr = ['pci',] + for dev_info in pci_devs: + dev_sxpr = self.device_sxpr(dev_type = 'dev', + dev_info = dev_info) + sxpr.append(dev_sxpr) + sxprs.append(('pci', sxpr)) + return sxprs diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/XendDevices.py --- a/tools/python/xen/xend/XendDevices.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/XendDevices.py Mon Nov 20 13:11:15 2006 -0700 @@ -49,6 +49,11 @@ class XendDevices: valid_devices = classmethod(valid_devices) #@classmethod + def pseudo_devices(cls): + return ['console'] + pseudo_devices = classmethod(pseudo_devices) + + #@classmethod def make_controller(cls, name, domain): """Factory function to make device controllers per domain. diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/XendDomain.py Mon Nov 20 13:11:15 2006 -0700 @@ -33,7 +33,7 @@ from xen.xend import XendRoot, XendCheck from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo from xen.xend.PrettyPrint import prettyprint from xen.xend.XendConfig import XendConfig -from xen.xend.XendError import XendError, XendInvalidDomain +from xen.xend.XendError import XendError, XendInvalidDomain, VmError from xen.xend.XendLogging import log from xen.xend.XendConstants import XS_VMROOT from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_RUNNING @@ -65,7 +65,6 @@ class XendDomain: @type domains_lock: threaading.RLock @ivar _allow_new_domains: Flag to set that allows creating of new domains. @type _allow_new_domains: boolean - """ def __init__(self): @@ -281,9 +280,13 @@ class XendDomain: sxp_cache_file = open(self._managed_config_path(dom_uuid),'w') prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78) sxp_cache_file.close() - except IOError: - log.error("Error occurred saving configuration file to %s" % - domain_config_dir) + except: + log.exception("Error occurred saving configuration file " + + "to %s" % domain_config_dir) + try: + self._managed_domain_remove(dom_uuid) + except: + pass raise XendError("Failed to save configuration file to: %s" % domain_config_dir) else: @@ -374,24 +377,39 @@ class XendDomain: @rtype: None """ + running = self._running_domains() + # Add domains that are not already tracked but running in Xen, + # and update domain state for those that are running and tracked. + for dom in running: + domid = dom['domid'] + if domid in self.domains: + self.domains[domid].update(dom) + elif domid not in self.domains and dom['dying'] != 1: + try: + new_dom = XendDomainInfo.recreate(dom, False) + self._add_domain(new_dom) + except VmError: + log.exception("Unable to recreate domain") + try: + xc.domain_destroy(domid) + except: + log.exception("Hard destruction of domain failed: %d" % + domid) + # update information for all running domains # - like cpu_time, status, dying, etc. - running = self._running_domains() - for dom in running: - domid = dom['domid'] - if domid in self.domains and dom['dying'] != 1: - self.domains[domid].update(dom) - # remove domains that are not running from active domain list. # The list might have changed by now, because the update call may # cause new domains to be added, if the domain has rebooted. We get # the list again. + running = self._running_domains() running_domids = [d['domid'] for d in running if d['dying'] != 1] for domid, dom in self.domains.items(): if domid not in running_domids and domid != DOM0_ID: self._remove_domain(dom, domid) + def _add_domain(self, info): """Add a domain to the list of running domains @@ -409,7 +427,6 @@ class XendDomain: @param info: XendDomainInfo of a domain to be removed. @type info: XendDomainInfo """ - if info: if domid == None: domid = info.getDomid() @@ -948,10 +965,10 @@ class XendDomain: dominfo = self.domain_lookup_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) - + if dominfo.getDomid() == DOM0_ID: + raise XendError("Cannot unpause privileged domain %s" % domid) log.info("Domain %s (%d) unpaused.", dominfo.getName(), int(dominfo.getDomid())) - dominfo.unpause() except XendInvalidDomain: log.exception("domain_unpause") @@ -973,6 +990,8 @@ class XendDomain: dominfo = self.domain_lookup_nr(domid) if not dominfo: raise XendInvalidDomain(str(domid)) + if dominfo.getDomid() == DOM0_ID: + raise XendError("Cannot pause privileged domain %s" % domid) log.info("Domain %s (%d) paused.", dominfo.getName(), int(dominfo.getDomid())) dominfo.pause() @@ -1049,7 +1068,7 @@ class XendDomain: raise XendInvalidDomain(str(domid)) if dominfo.getDomid() == DOM0_ID: - raise XendError("Cannot migrate privileged domain %i" % domid) + raise XendError("Cannot migrate privileged domain %s" % domid) """ The following call may raise a XendError exception """ dominfo.testMigrateDevices(True, dst) diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Nov 20 13:11:15 2006 -0700 @@ -403,7 +403,7 @@ class XendDomainInfo: self.vmWatch = None self.shutdownWatch = None self.shutdownStartTime = None - + self.state = DOM_STATE_HALTED self.state_updated = threading.Condition() self.refresh_shutdown_lock = threading.Condition() @@ -430,7 +430,7 @@ class XendDomainInfo: initialisation if it not started. """ from xen.xend import XendDomain - + if self.state == DOM_STATE_HALTED: try: self._constructDomain() @@ -443,7 +443,6 @@ class XendDomainInfo: # save running configuration if XendDomains believe domain is # persistent - # if is_managed: xendomains = XendDomain.instance() xendomains.managed_config_save(self) @@ -475,6 +474,9 @@ class XendDomainInfo: log.debug('XendDomainInfo.shutdown') if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,): raise XendError('Domain cannot be shutdown') + + if self.domid == 0: + raise XendError('Domain 0 cannot be shutdown') if not reason in DOMAIN_SHUTDOWN_REASONS.values(): raise XendError('Invalid reason: %s' % reason) @@ -920,7 +922,7 @@ class XendDomainInfo: # the VM path now, otherwise we will end up with one # watch for the old domain, and one for the new. self._unwatchVm() - elif reason in ['poweroff', 'reboot']: + elif reason in ('poweroff', 'reboot'): restart_reason = reason else: self.destroy() @@ -1117,8 +1119,9 @@ class XendDomainInfo: @raise: VmError for invalid devices """ for (devclass, config) in self.info.all_devices_sxpr(): - log.info("createDevice: %s : %s" % (devclass, config)) - self._createDevice(devclass, config) + if devclass in XendDevices.valid_devices(): + log.info("createDevice: %s : %s" % (devclass, config)) + self._createDevice(devclass, config) if self.image: self.image.createDeviceModel() @@ -1323,6 +1326,8 @@ class XendDomainInfo: self._stateSet(DOM_STATE_RUNNING) except RuntimeError, exn: log.exception("XendDomainInfo.initDomain: exception occurred") + if self.info['bootloader'] and self.image is not None: + self.image.cleanupBootloading() raise VmError(str(exn)) @@ -1521,6 +1526,14 @@ class XendDomainInfo: def _unwatchVm(self): """Remove the watch on the VM path, if any. Idempotent. Nothrow guarantee.""" + try: + try: + if self.vmWatch: + self.vmWatch.unwatch() + finally: + self.vmWatch = None + except: + log.exception("Unwatching VM path failed.") def testDeviceComplete(self): """ For Block IO migration safety we must ensure that @@ -1659,9 +1672,17 @@ class XendDomainInfo: log.trace("XendDomainInfo.update done on domain %s: %s", str(self.domid), self.info) - def sxpr(self, ignore_devices = False): - return self.info.get_sxp(domain = self, - ignore_devices = ignore_devices) + def sxpr(self, ignore_store = False): + result = self.info.get_sxp(domain = self, + ignore_devices = ignore_store) + + if not ignore_store and self.dompath: + vnc_port = self._readDom('console/vnc-port') + if vnc_port is not None: + result.append(['device', + ['console', ['vnc-port', str(vnc_port)]]]) + + return result # Xen API # ---------------------------------------------------------------- diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/image.py Mon Nov 20 13:11:15 2006 -0700 @@ -309,13 +309,14 @@ class HVMImageHandler(ImageHandler): def parseDeviceModelArgs(self, imageConfig, deviceConfig): dmargs = [ 'boot', 'fda', 'fdb', 'soundhw', 'localtime', 'serial', 'stdvga', 'isa', 'vcpus', - 'acpi', 'usb', 'usbdevice'] + 'acpi', 'usb', 'usbdevice', 'keymap' ] ret = [] for a in dmargs: v = sxp.child_value(imageConfig, a) # python doesn't allow '-' in variable names if a == 'stdvga': a = 'std-vga' + if a == 'keymap': a = 'k' # Handle booleans gracefully if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']: @@ -328,7 +329,7 @@ class HVMImageHandler(ImageHandler): if a in ['fda', 'fdb' ]: if v: - if not os.path.isfile(v): + if not os.path.isabs(v): raise VmError("Floppy file %s does not exist." % v) log.debug("args: %s, val: %s" % (a,v)) @@ -385,8 +386,6 @@ class HVMImageHandler(ImageHandler): else: ret += ['-vnc', '%d' % vncdisplay] - ret += ['-k', 'en-us'] - vnclisten = sxp.child_value(config, 'vnclisten') if not(vnclisten): vnclisten = (xen.xend.XendRoot.instance(). diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xend/server/pciif.py --- a/tools/python/xen/xend/server/pciif.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xend/server/pciif.py Mon Nov 20 13:11:15 2006 -0700 @@ -65,7 +65,7 @@ class PciController(DevController): else: return default - if isinstance(val, types.StringType): + if isinstance(val, types.StringTypes): return int(val, 16) else: return val @@ -79,7 +79,7 @@ class PciController(DevController): back = {} val = sxp.child_value(config, 'dev') - if isinstance(val, list): + if isinstance(val, (types.ListType, types.TupleType)): pcidevid = 0 for dev_config in sxp.children(config, 'dev'): domain = get_param(dev_config, 'domain', 0) @@ -89,7 +89,7 @@ class PciController(DevController): self.setupDevice(domain, bus, slot, func) - back['dev-%i'%(pcidevid)]="%04x:%02x:%02x.%02x"% \ + back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \ (domain, bus, slot, func) pcidevid+=1 @@ -115,19 +115,19 @@ class PciController(DevController): pci_devs = [] for i in range(int(num_devs)): - (dev_config,) = self.readBackend(devid, 'dev-%d'%(i)) - - pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \ - r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \ - r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \ - r"(?P<func>[0-9a-fA-F]{1,2})", dev_config) + dev_config = self.readBackend(devid, 'dev-%d' % i) + + pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + + r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + + r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + + r"(?P<func>[0-9a-fA-F]{1,2})", dev_config) if pci_match!=None: - pci_dev_info = pci_match.groupdict('0') + pci_dev_info = pci_match.groupdict() pci_devs.append({'domain': '0x%(domain)s' % pci_dev_info, 'bus': '0x%(bus)s' % pci_dev_info, - 'slot': '0x(slot)s' % pci_dev_info, - 'func': '0x(func)s' % pci_dev_info}) + 'slot': '0x%(slot)s' % pci_dev_info, + 'func': '0x%(func)s' % pci_dev_info}) result['dev'] = pci_devs return result diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xm/create.py Mon Nov 20 13:11:15 2006 -0700 @@ -386,6 +386,10 @@ gopts.var('localtime', val='no|yes', gopts.var('localtime', val='no|yes', fn=set_bool, default=0, use="Is RTC set to localtime?") + +gopts.var('keymap', val='FILE', + fn=set_value, default='', + use="Set keyboard layout used") gopts.var('usb', val='no|yes', fn=set_bool, default=0, @@ -660,7 +664,7 @@ def configure_hvm(config_image, vals): 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', 'sdl', 'display', 'xauthority', - 'acpi', 'usb', 'usbdevice' ] + 'acpi', 'usb', 'usbdevice', 'keymap' ] for a in args: if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) diff -r 066094348f22 -r 0699c3eff7a3 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/python/xen/xm/main.py Mon Nov 20 13:11:15 2006 -0700 @@ -198,6 +198,10 @@ SUBCOMMAND_OPTIONS = { ), 'network-list': ( ('-l', '--long', 'List resources as SXP'), + ), + 'dump-core': ( + ('-L', '--live', 'Dump core without pausing the domain'), + ('-C', '--crash', 'Crash domain after dumping core'), ), } diff -r 066094348f22 -r 0699c3eff7a3 tools/xentrace/Makefile --- a/tools/xentrace/Makefile Mon Nov 20 12:14:40 2006 -0700 +++ b/tools/xentrace/Makefile Mon Nov 20 13:11:15 2006 -0700 @@ -1,7 +1,7 @@ XEN_ROOT=../.. XEN_ROOT=../.. include $(XEN_ROOT)/tools/Rules.mk -CFLAGS += -Werror -D_LARGEFILE64_SOURCE +CFLAGS += -Werror CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff -r 066094348f22 -r 0699c3eff7a3 unmodified_drivers/linux-2.6/README --- a/unmodified_drivers/linux-2.6/README Mon Nov 20 12:14:40 2006 -0700 +++ b/unmodified_drivers/linux-2.6/README Mon Nov 20 13:11:15 2006 -0700 @@ -2,6 +2,6 @@ To build, run ./mkbuildtree and then make -C /path/to/kernel/source M=$PWD modules -You get four modules, xen-evtchn-pci.ko, xenbus.ko, xen-vbd.ko, and -xen-vnif.ko. Load xen-evtchn-pci first, then xenbus, and then +You get four modules, xen-platform-pci.ko, xenbus.ko, xen-vbd.ko, and +xen-vnif.ko. Load xen-platform-pci first, then xenbus, and then whichever of xen-vbd and xen-vnif you happen to need. diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/ia64/vmx/vmx_support.c --- a/xen/arch/ia64/vmx/vmx_support.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/ia64/vmx/vmx_support.c Mon Nov 20 13:11:15 2006 -0700 @@ -95,8 +95,7 @@ void vmx_send_assist_req(struct vcpu *v) break; } - /* I want to call __enter_scheduler() only */ - do_sched_op_compat(SCHEDOP_yield, 0); + raise_softirq(SCHEDULE_SOFTIRQ); mb(); } diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/domain.c Mon Nov 20 13:11:15 2006 -0700 @@ -294,6 +294,12 @@ int arch_set_info_guest( for ( i = 0; i < 256; i++ ) fixup_guest_code_selector(c->trap_ctxt[i].cs); + + /* LDT safety checks. */ + if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || + (c->ldt_ents > 8192) || + !array_access_ok(c->ldt_base, c->ldt_ents, LDT_ENTRY_SIZE) ) + return -EINVAL; } clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); @@ -396,21 +402,20 @@ arch_do_vcpu_op( if ( copy_from_guest(&area, arg, 1) ) break; - if ( !access_ok(area.addr.v, sizeof(*area.addr.v)) ) + if ( !guest_handle_okay(area.addr.h, 1) ) break; rc = 0; - v->runstate_guest = area.addr.v; + v->runstate_guest = area.addr.h; if ( v == current ) { - __copy_to_user(v->runstate_guest, &v->runstate, - sizeof(v->runstate)); + __copy_to_guest(v->runstate_guest, &v->runstate, 1); } else { vcpu_runstate_get(v, &runstate); - __copy_to_user(v->runstate_guest, &runstate, sizeof(runstate)); + __copy_to_guest(v->runstate_guest, &runstate, 1); } break; @@ -423,33 +428,6 @@ arch_do_vcpu_op( return rc; } - -void new_thread(struct vcpu *d, - unsigned long start_pc, - unsigned long start_stack, - unsigned long start_info) -{ - struct cpu_user_regs *regs = &d->arch.guest_context.user_regs; - - /* - * Initial register values: - * DS,ES,FS,GS = FLAT_KERNEL_DS - * CS:EIP = FLAT_KERNEL_CS:start_pc - * SS:ESP = FLAT_KERNEL_SS:start_stack - * ESI = start_info - * [EAX,EBX,ECX,EDX,EDI,EBP are zero] - */ - regs->ds = regs->es = regs->fs = regs->gs = FLAT_KERNEL_DS; - regs->ss = FLAT_KERNEL_SS; - regs->cs = FLAT_KERNEL_CS; - regs->eip = start_pc; - regs->esp = start_stack; - regs->esi = start_info; - - __save_flags(regs->eflags); - regs->eflags |= X86_EFLAGS_IF; -} - #ifdef __x86_64__ @@ -767,9 +745,8 @@ void context_switch(struct vcpu *prev, s context_saved(prev); /* Update per-VCPU guest runstate shared memory area (if registered). */ - if ( next->runstate_guest != NULL ) - __copy_to_user(next->runstate_guest, &next->runstate, - sizeof(next->runstate)); + if ( !guest_handle_is_null(next->runstate_guest) ) + __copy_to_guest(next->runstate_guest, &next->runstate, 1); schedule_tail(next); BUG(); diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/domain_build.c Mon Nov 20 13:11:15 2006 -0700 @@ -249,6 +249,7 @@ int construct_dom0(struct domain *d, char *cmdline) { int i, rc, dom0_pae, xen_pae, order; + struct cpu_user_regs *regs; unsigned long pfn, mfn; unsigned long nr_pages; unsigned long nr_pt_pages; @@ -441,19 +442,7 @@ int construct_dom0(struct domain *d, mpt_alloc = (vpt_start - dsi.v_start) + (unsigned long)pfn_to_paddr(alloc_spfn); - /* - * We're basically forcing default RPLs to 1, so that our "what privilege - * level are we returning to?" logic works. - */ - v->arch.guest_context.kernel_ss = FLAT_KERNEL_SS; - for ( i = 0; i < 256; i++ ) - v->arch.guest_context.trap_ctxt[i].cs = FLAT_KERNEL_CS; - #if defined(__i386__) - - v->arch.guest_context.failsafe_callback_cs = FLAT_KERNEL_CS; - v->arch.guest_context.event_callback_cs = FLAT_KERNEL_CS; - /* * Protect the lowest 1GB of memory. We use a temporary mapping there * from which we copy the kernel and ramdisk images. @@ -816,7 +805,22 @@ int construct_dom0(struct domain *d, set_bit(_VCPUF_initialised, &v->vcpu_flags); - new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start); + /* + * Initial register values: + * DS,ES,FS,GS = FLAT_KERNEL_DS + * CS:EIP = FLAT_KERNEL_CS:start_pc + * SS:ESP = FLAT_KERNEL_SS:start_stack + * ESI = start_info + * [EAX,EBX,ECX,EDX,EDI,EBP are zero] + */ + regs = &v->arch.guest_context.user_regs; + regs->ds = regs->es = regs->fs = regs->gs = FLAT_KERNEL_DS; + regs->ss = FLAT_KERNEL_SS; + regs->cs = FLAT_KERNEL_CS; + regs->eip = dsi.v_kernentry; + regs->esp = vstack_end; + regs->esi = vstartinfo_start; + regs->eflags = X86_EFLAGS_IF; if ( opt_dom0_shadow ) if ( shadow_test_enable(d) == 0 ) diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/hvm.c Mon Nov 20 13:11:15 2006 -0700 @@ -74,6 +74,44 @@ void hvm_set_guest_time(struct vcpu *v, hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset); } +u64 hvm_get_guest_time(struct vcpu *v) +{ + u64 host_tsc; + + rdtscll(host_tsc); + return host_tsc + v->arch.hvm_vcpu.cache_tsc_offset; +} + +void hvm_freeze_time(struct vcpu *v) +{ + struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; + + if ( pt->enabled && pt->first_injected + && (v->vcpu_id == pt->bind_vcpu) + && !v->arch.hvm_vcpu.guest_time ) { + v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); + if ( !test_bit(_VCPUF_blocked, &v->vcpu_flags) ) + { + stop_timer(&pt->timer); + rtc_freeze(v); + } + } +} + +void hvm_migrate_timers(struct vcpu *v) +{ + struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm; + struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt; + + if ( pt->enabled ) + { + migrate_timer(&pt->timer, v->processor); + } + migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor); + migrate_timer(&vpmt->timer, v->processor); + rtc_migrate_timers(v); +} + void hvm_do_resume(struct vcpu *v) { ioreq_t *p; @@ -91,6 +129,9 @@ void hvm_do_resume(struct vcpu *v) } pickup_deactive_ticks(pt); } + + /* Re-enable the RTC timer if needed */ + rtc_thaw(v); /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */ p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq; @@ -186,7 +227,7 @@ int hvm_vcpu_initialise(struct vcpu *v) pt_timer_fn, v, v->processor); pit_init(v, cpu_khz); rtc_init(v, RTC_PORT(0), RTC_IRQ); - pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); + pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS); /* Init guest TSC to start from zero. */ hvm_set_guest_time(v, 0); @@ -207,14 +248,6 @@ void pic_irq_request(void *data, int lev { int *interrupt_request = data; *interrupt_request = level; -} - -u64 hvm_get_guest_time(struct vcpu *v) -{ - u64 host_tsc; - - rdtscll(host_tsc); - return host_tsc + v->arch.hvm_vcpu.cache_tsc_offset; } int cpu_get_interrupt(struct vcpu *v, int *type) @@ -265,6 +298,28 @@ static void hvm_vcpu_down(void) d->domain_id); domain_shutdown(d, SHUTDOWN_poweroff); } +} + +void hvm_send_assist_req(struct vcpu *v) +{ + ioreq_t *p; + + p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq; + if ( unlikely(p->state != STATE_IOREQ_NONE) ) + { + /* This indicates a bug in the device model. Crash the domain. */ + gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state); + domain_crash_synchronous(); + } + + prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port); + + /* + * Following happens /after/ blocking and setting up ioreq contents. + * prepare_wait_on_xen_event_channel() is an implicit barrier. + */ + p->state = STATE_IOREQ_READY; + notify_via_xen_event_channel(v->arch.hvm_vcpu.xen_port); } void hvm_hlt(unsigned long rflags) diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/i8259.c --- a/xen/arch/x86/hvm/i8259.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/i8259.c Mon Nov 20 13:11:15 2006 -0700 @@ -536,8 +536,6 @@ int is_periodic_irq(struct vcpu *v, int int vec; struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm); - struct RTCState *vrtc = - &(v->domain->arch.hvm_domain.pl_time.vrtc); if (pt->irq == 0) { /* Is it pit irq? */ if (type == APIC_DM_EXTINT) @@ -549,16 +547,6 @@ int is_periodic_irq(struct vcpu *v, int return 1; } - if (pt->irq == 8) { /* Or rtc irq? */ - if (type == APIC_DM_EXTINT) - vec = domain_vpic(v->domain)->pics[1].irq_base; - else - vec = domain_vioapic(v->domain)->redirtbl[8].fields.vector; - - if (irq == vec) - return is_rtc_periodic_irq(vrtc); - } - return 0; } diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/platform.c --- a/xen/arch/x86/hvm/platform.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/platform.c Mon Nov 20 13:11:15 2006 -0700 @@ -346,7 +346,7 @@ static int reg_mem(unsigned char size, u return DECODE_success; } -static int hvm_decode(int realmode, unsigned char *opcode, +static int mmio_decode(int realmode, unsigned char *opcode, struct hvm_io_op *mmio_op, unsigned char *op_size) { unsigned char size_reg = 0; @@ -720,28 +720,6 @@ int inst_copy_from_guest(unsigned char * if ( hvm_copy_from_guest_virt(buf, guest_eip, inst_len) ) return 0; return inst_len; -} - -static void hvm_send_assist_req(struct vcpu *v) -{ - ioreq_t *p; - - p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq; - if ( unlikely(p->state != STATE_IOREQ_NONE) ) - { - /* This indicates a bug in the device model. Crash the domain. */ - gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state); - domain_crash_synchronous(); - } - - prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port); - - /* - * Following happens /after/ blocking and setting up ioreq contents. - * prepare_wait_on_xen_event_channel() is an implicit barrier. - */ - p->state = STATE_IOREQ_READY; - notify_via_xen_event_channel(v->arch.hvm_vcpu.xen_port); } void send_pio_req(unsigned long port, unsigned long count, int size, @@ -927,7 +905,7 @@ void handle_mmio(unsigned long gpa) domain_crash_synchronous(); } - if ( hvm_decode(realmode, inst, mmio_op, &op_size) == DECODE_failure ) { + if ( mmio_decode(realmode, inst, mmio_op, &op_size) == DECODE_failure ) { printk("handle_mmio: failed to decode instruction\n"); printk("mmio opcode: gpa 0x%lx, len %d:", gpa, inst_len); for ( i = 0; i < inst_len; i++ ) diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/rtc.c Mon Nov 20 13:11:15 2006 -0700 @@ -30,40 +30,43 @@ /* #define DEBUG_RTC */ -void rtc_periodic_cb(struct vcpu *v, void *opaque) -{ - RTCState *s = opaque; - s->cmos_data[RTC_REG_C] |= 0xc0; -} - -int is_rtc_periodic_irq(void *opaque) -{ - RTCState *s = opaque; - return !(s->cmos_data[RTC_REG_C] & RTC_AF || - s->cmos_data[RTC_REG_C] & RTC_UF); -} - -static void rtc_timer_update(RTCState *s, int64_t current_time) +/* Callback that fires the RTC's periodic interrupt */ +void rtc_pie_callback(void *opaque) +{ + RTCState *s = opaque; + struct hvm_domain *plat = &s->vcpu->domain->arch.hvm_domain; + struct vpic *pic = &plat->vpic; + /* Record that we have fired */ + s->cmos_data[RTC_REG_C] |= (RTC_IRQF|RTC_PF); /* 0xc0 */ + /* Fire */ + pic_set_irq(pic, s->irq, 1); + /* Remember to fire again */ + s->next_pie = NOW() + s->period; + set_timer(&s->pie_timer, s->next_pie); +} + +/* Enable/configure/disable the periodic timer based on the RTC_PIE and + * RTC_RATE_SELECT settings */ +static void rtc_timer_update(RTCState *s) { int period_code; int period; - period_code = s->cmos_data[RTC_REG_A] & 0x0f; + period_code = s->cmos_data[RTC_REG_A] & RTC_RATE_SELECT; if (period_code != 0 && (s->cmos_data[RTC_REG_B] & RTC_PIE)) { if (period_code <= 2) period_code += 7; period = 1 << (period_code - 1); /* period in 32 Khz cycles */ period = DIV_ROUND((period * 1000000000ULL), 32768); /* period in ns */ - + s->period = period; #ifdef DEBUG_RTC printk("HVM_RTC: period = %uns\n", period); #endif - - s->pt = create_periodic_time(period, RTC_IRQ, 0, rtc_periodic_cb, s); - } else if (s->pt) { - destroy_periodic_time(s->pt); - s->pt = NULL; + s->next_pie = NOW() + s->period; + set_timer(&s->pie_timer, s->next_pie); + } else { + stop_timer(&s->pie_timer); } } @@ -105,7 +108,7 @@ static int rtc_ioport_write(void *opaque /* UIP bit is read only */ s->cmos_data[RTC_REG_A] = (data & ~RTC_UIP) | (s->cmos_data[RTC_REG_A] & RTC_UIP); - rtc_timer_update(s, hvm_get_clock(s->vcpu)); + rtc_timer_update(s); break; case RTC_REG_B: if (data & RTC_SET) { @@ -119,14 +122,14 @@ static int rtc_ioport_write(void *opaque } } s->cmos_data[RTC_REG_B] = data; - rtc_timer_update(s, hvm_get_clock(s->vcpu)); + rtc_timer_update(s); break; case RTC_REG_C: case RTC_REG_D: /* cannot write to them */ break; + } return 1; - } } return 0; } @@ -172,7 +175,7 @@ static void rtc_copy_date(RTCState *s) s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min); - if (s->cmos_data[RTC_REG_B] & 0x02) { + if (s->cmos_data[RTC_REG_B] & RTC_24H) { /* 24 hour format */ s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour); } else { @@ -245,7 +248,7 @@ static void rtc_update_second(void *opaq RTCState *s = opaque; /* if the oscillator is not in normal operation, we do not update */ - if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) { + if ((s->cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ) { s->next_second_time += 1000000000ULL; set_timer(&s->second_timer, s->next_second_time); } else { @@ -361,22 +364,48 @@ static int handle_rtc_io(ioreq_t *p) return 0; } +/* Stop the periodic interrupts from this RTC */ +void rtc_freeze(struct vcpu *v) +{ + RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; + stop_timer(&s->pie_timer); +} + +/* Start them again */ +void rtc_thaw(struct vcpu *v) +{ + RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; + if ( (s->cmos_data[RTC_REG_A] & RTC_RATE_SELECT) /* Period is not zero */ + && (s->cmos_data[RTC_REG_B] & RTC_PIE) ) + set_timer(&s->pie_timer, s->next_pie); +} + +/* Move the RTC timers on to this vcpu's current cpu */ +void rtc_migrate_timers(struct vcpu *v) +{ + RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; + migrate_timer(&s->second_timer, v->processor); + migrate_timer(&s->second_timer2, v->processor); + migrate_timer(&s->pie_timer, v->processor); +} + void rtc_init(struct vcpu *v, int base, int irq) { RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc; s->vcpu = v; s->irq = irq; - s->cmos_data[RTC_REG_A] = 0x26; - s->cmos_data[RTC_REG_B] = 0x02; - s->cmos_data[RTC_REG_C] = 0x00; - s->cmos_data[RTC_REG_D] = 0x80; + s->cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */ + s->cmos_data[RTC_REG_B] = RTC_24H; + s->cmos_data[RTC_REG_C] = 0; + s->cmos_data[RTC_REG_D] = RTC_VRT; s->current_tm = gmtime(get_localtime(v->domain)); rtc_copy_date(s); init_timer(&s->second_timer, rtc_update_second, s, v->processor); init_timer(&s->second_timer2, rtc_update_second2, s, v->processor); + init_timer(&s->pie_timer, rtc_pie_callback, s, v->processor); s->next_second_time = NOW() + 1000000000ULL; set_timer(&s->second_timer2, s->next_second_time); @@ -390,4 +419,5 @@ void rtc_deinit(struct domain *d) kill_timer(&s->second_timer); kill_timer(&s->second_timer2); -} + kill_timer(&s->pie_timer); +} diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Nov 20 13:11:15 2006 -0700 @@ -714,23 +714,9 @@ static void arch_svm_do_launch(struct vc reset_stack_and_jump(svm_asm_do_launch); } -static void svm_freeze_time(struct vcpu *v) -{ - struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - - if ( pt->enabled && pt->first_injected - && (v->vcpu_id == pt->bind_vcpu) - && !v->arch.hvm_vcpu.guest_time ) { - v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); - if ( test_bit(_VCPUF_blocked, &v->vcpu_flags) ) - stop_timer(&pt->timer); - } -} - - static void svm_ctxt_switch_from(struct vcpu *v) { - svm_freeze_time(v); + hvm_freeze_time(v); svm_save_dr(v); } @@ -849,25 +835,6 @@ int start_svm(void) return 1; } - -static void svm_migrate_timers(struct vcpu *v) -{ - struct periodic_time *pt = - &(v->domain->arch.hvm_domain.pl_time.periodic_tm); - struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc; - struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt; - - if ( pt->enabled ) - { - migrate_timer(&pt->timer, v->processor); - } - migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor); - migrate_timer(&vrtc->second_timer, v->processor); - migrate_timer(&vrtc->second_timer2, v->processor); - migrate_timer(&vpmt->timer, v->processor); -} - - void arch_svm_do_resume(struct vcpu *v) { /* pinning VCPU to a different core? */ @@ -880,13 +847,11 @@ void arch_svm_do_resume(struct vcpu *v) printk("VCPU core pinned: %d to %d\n", v->arch.hvm_svm.launch_core, smp_processor_id() ); v->arch.hvm_svm.launch_core = smp_processor_id(); - svm_migrate_timers( v ); + hvm_migrate_timers( v ); hvm_do_resume( v ); reset_stack_and_jump( svm_asm_do_resume ); } } - - static int svm_do_page_fault(unsigned long va, struct cpu_user_regs *regs) { diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/vioapic.c Mon Nov 20 13:11:15 2006 -0700 @@ -471,8 +471,8 @@ void vioapic_set_irq(struct domain *d, i struct vioapic *vioapic = domain_vioapic(d); uint32_t bit; - HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq " - "irq %x level %x\n", irq, level); + HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_set_irq irq %x level %x", + irq, level); if ( (irq < 0) || (irq >= VIOAPIC_NUM_PINS) ) return; diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Mon Nov 20 13:11:15 2006 -0700 @@ -486,7 +486,7 @@ void arch_vmx_do_resume(struct vcpu *v) { vmx_clear_vmcs(v); vmx_load_vmcs(v); - vmx_migrate_timers(v); + hvm_migrate_timers(v); vmx_set_host_env(v); } diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Nov 20 13:11:15 2006 -0700 @@ -78,75 +78,48 @@ static void vmx_vcpu_destroy(struct vcpu #ifdef __x86_64__ -static DEFINE_PER_CPU(struct vmx_msr_state, percpu_msr); - -static u32 msr_data_index[VMX_MSR_COUNT] = +static DEFINE_PER_CPU(struct vmx_msr_state, host_msr_state); + +static u32 msr_index[VMX_MSR_COUNT] = { MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER, }; -static void vmx_save_segments(struct vcpu *v) -{ - rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.msr_content.shadow_gs); -} - -/* - * To avoid MSR save/restore at every VM exit/entry time, we restore - * the x86_64 specific MSRs at domain switch time. Since those MSRs are - * are not modified once set for generic domains, we don't save them, - * but simply reset them to the values set at percpu_traps_init(). - */ -static void vmx_load_msrs(void) -{ - struct vmx_msr_state *host_state = &this_cpu(percpu_msr); +static void vmx_save_host_msrs(void) +{ + struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state); int i; - while ( host_state->flags ) - { - i = find_first_set_bit(host_state->flags); - wrmsrl(msr_data_index[i], host_state->msr_items[i]); - clear_bit(i, &host_state->flags); - } -} - -static void vmx_save_init_msrs(void) -{ - struct vmx_msr_state *host_state = &this_cpu(percpu_msr); - int i; - for ( i = 0; i < VMX_MSR_COUNT; i++ ) - rdmsrl(msr_data_index[i], host_state->msr_items[i]); -} - -#define CASE_READ_MSR(address) \ - case MSR_ ## address: \ - msr_content = msr->msr_items[VMX_INDEX_MSR_ ## address]; \ - break - -#define CASE_WRITE_MSR(address) \ - case MSR_ ## address: \ - { \ - msr->msr_items[VMX_INDEX_MSR_ ## address] = msr_content; \ - if (!test_bit(VMX_INDEX_MSR_ ## address, &msr->flags)) { \ - set_bit(VMX_INDEX_MSR_ ## address, &msr->flags); \ - } \ - wrmsrl(MSR_ ## address, msr_content); \ - set_bit(VMX_INDEX_MSR_ ## address, &host_state->flags); \ - } \ - break + rdmsrl(msr_index[i], host_msr_state->msrs[i]); +} + +#define CASE_READ_MSR(address) \ + case MSR_ ## address: \ + msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_ ## address]; \ + break + +#define CASE_WRITE_MSR(address) \ + case MSR_ ## address: \ + guest_msr_state->msrs[VMX_INDEX_MSR_ ## address] = msr_content; \ + if ( !test_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags) )\ + set_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags); \ + wrmsrl(MSR_ ## address, msr_content); \ + set_bit(VMX_INDEX_MSR_ ## address, &host_msr_state->flags); \ + break #define IS_CANO_ADDRESS(add) 1 static inline int long_mode_do_msr_read(struct cpu_user_regs *regs) { u64 msr_content = 0; struct vcpu *v = current; - struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content; + struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state; switch ( regs->ecx ) { case MSR_EFER: HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content); - msr_content = msr->msr_items[VMX_INDEX_MSR_EFER]; + msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_EFER]; break; case MSR_FS_BASE: @@ -164,7 +137,7 @@ static inline int long_mode_do_msr_read( break; case MSR_SHADOW_GS_BASE: - msr_content = msr->shadow_gs; + msr_content = guest_msr_state->shadow_gs; break; CASE_READ_MSR(STAR); @@ -193,8 +166,8 @@ static inline int long_mode_do_msr_write { u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32); struct vcpu *v = current; - struct vmx_msr_state *msr = &v->arch.hvm_vmx.msr_content; - struct vmx_msr_state *host_state = &this_cpu(percpu_msr); + struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state; + struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state); HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%lx msr_content 0x%"PRIx64"\n", (unsigned long)regs->ecx, msr_content); @@ -211,7 +184,7 @@ static inline int long_mode_do_msr_write } if ( (msr_content & EFER_LME) - && !(msr->msr_items[VMX_INDEX_MSR_EFER] & EFER_LME) ) + && !(guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) ) { if ( unlikely(vmx_paging_enabled(v)) ) { @@ -221,7 +194,7 @@ static inline int long_mode_do_msr_write } } else if ( !(msr_content & EFER_LME) - && (msr->msr_items[VMX_INDEX_MSR_EFER] & EFER_LME) ) + && (guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) ) { if ( unlikely(vmx_paging_enabled(v)) ) { @@ -231,12 +204,12 @@ static inline int long_mode_do_msr_write } } - msr->msr_items[VMX_INDEX_MSR_EFER] = msr_content; + guest_msr_state->msrs[VMX_INDEX_MSR_EFER] = msr_content; break; case MSR_FS_BASE: case MSR_GS_BASE: - if ( !(vmx_long_mode_enabled(v)) ) + if ( !vmx_long_mode_enabled(v) ) goto exit_and_crash; if ( !IS_CANO_ADDRESS(msr_content) ) @@ -257,7 +230,7 @@ static inline int long_mode_do_msr_write if ( !(vmx_long_mode_enabled(v)) ) goto exit_and_crash; - v->arch.hvm_vmx.msr_content.shadow_gs = msr_content; + v->arch.hvm_vmx.msr_state.shadow_gs = msr_content; wrmsrl(MSR_SHADOW_GS_BASE, msr_content); break; @@ -278,40 +251,57 @@ static inline int long_mode_do_msr_write return 1; /* handled */ } -static void vmx_restore_msrs(struct vcpu *v) -{ - int i = 0; - struct vmx_msr_state *guest_state; - struct vmx_msr_state *host_state; - unsigned long guest_flags ; - - guest_state = &v->arch.hvm_vmx.msr_content;; - host_state = &this_cpu(percpu_msr); - - wrmsrl(MSR_SHADOW_GS_BASE, guest_state->shadow_gs); - guest_flags = guest_state->flags; - if (!guest_flags) +/* + * To avoid MSR save/restore at every VM exit/entry time, we restore + * the x86_64 specific MSRs at domain switch time. Since these MSRs + * are not modified once set for para domains, we don't save them, + * but simply reset them to values set in percpu_traps_init(). + */ +static void vmx_restore_host_msrs(void) +{ + struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state); + int i; + + while ( host_msr_state->flags ) + { + i = find_first_set_bit(host_msr_state->flags); + wrmsrl(msr_index[i], host_msr_state->msrs[i]); + clear_bit(i, &host_msr_state->flags); + } +} + +static void vmx_restore_guest_msrs(struct vcpu *v) +{ + struct vmx_msr_state *guest_msr_state, *host_msr_state; + unsigned long guest_flags; + int i; + + guest_msr_state = &v->arch.hvm_vmx.msr_state; + host_msr_state = &this_cpu(host_msr_state); + + wrmsrl(MSR_SHADOW_GS_BASE, guest_msr_state->shadow_gs); + + guest_flags = guest_msr_state->flags; + if ( !guest_flags ) return; - while (guest_flags){ + while ( guest_flags ) { i = find_first_set_bit(guest_flags); HVM_DBG_LOG(DBG_LEVEL_2, - "restore guest's index %d msr %lx with %lx\n", - i, (unsigned long)msr_data_index[i], - (unsigned long)guest_state->msr_items[i]); - set_bit(i, &host_state->flags); - wrmsrl(msr_data_index[i], guest_state->msr_items[i]); + "restore guest's index %d msr %x with value %lx", + i, msr_index[i], guest_msr_state->msrs[i]); + set_bit(i, &host_msr_state->flags); + wrmsrl(msr_index[i], guest_msr_state->msrs[i]); clear_bit(i, &guest_flags); } } #else /* __i386__ */ -#define vmx_save_segments(v) ((void)0) -#define vmx_load_msrs() ((void)0) -#define vmx_restore_msrs(v) ((void)0) -#define vmx_save_init_msrs() ((void)0) +#define vmx_save_host_msrs() ((void)0) +#define vmx_restore_host_msrs() ((void)0) +#define vmx_restore_guest_msrs(v) ((void)0) static inline int long_mode_do_msr_read(struct cpu_user_regs *regs) { @@ -325,9 +315,9 @@ static inline int long_mode_do_msr_write #endif /* __i386__ */ -#define loaddebug(_v,_reg) \ +#define loaddebug(_v,_reg) \ __asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg])) -#define savedebug(_v,_reg) \ +#define savedebug(_v,_reg) \ __asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r" ((_v)->debugreg[_reg])) static inline void vmx_save_dr(struct vcpu *v) @@ -374,30 +364,21 @@ static inline void vmx_restore_dr(struct __restore_debug_registers(v); } -static void vmx_freeze_time(struct vcpu *v) -{ - struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm; - - if ( pt->enabled && pt->first_injected - && (v->vcpu_id == pt->bind_vcpu) - && !v->arch.hvm_vcpu.guest_time ) { - v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); - if ( !test_bit(_VCPUF_blocked, &v->vcpu_flags) ) - stop_timer(&pt->timer); - } -} - static void vmx_ctxt_switch_from(struct vcpu *v) { - vmx_freeze_time(v); - vmx_save_segments(v); - vmx_load_msrs(); + hvm_freeze_time(v); + + /* NB. MSR_SHADOW_GS_BASE may be changed by swapgs instrucion in guest, + * so we must save it. */ + rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.msr_state.shadow_gs); + + vmx_restore_host_msrs(); vmx_save_dr(v); } static void vmx_ctxt_switch_to(struct vcpu *v) { - vmx_restore_msrs(v); + vmx_restore_guest_msrs(v); vmx_restore_dr(v); } @@ -405,24 +386,9 @@ static void stop_vmx(void) { if ( !(read_cr4() & X86_CR4_VMXE) ) return; + __vmxoff(); clear_in_cr4(X86_CR4_VMXE); -} - -void vmx_migrate_timers(struct vcpu *v) -{ - struct periodic_time *pt = &v->domain->arch.hvm_domain.pl_time.periodic_tm; - struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc; - struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt; - - if ( pt->enabled ) - { - migrate_timer(&pt->timer, v->processor); - } - migrate_timer(&vcpu_vlapic(v)->vlapic_timer, v->processor); - migrate_timer(&vrtc->second_timer, v->processor); - migrate_timer(&vrtc->second_timer2, v->processor); - migrate_timer(&vpmt->timer, v->processor); } static void vmx_store_cpu_guest_regs( @@ -718,7 +684,7 @@ int start_vmx(void) printk("VMXON is done\n"); - vmx_save_init_msrs(); + vmx_save_host_msrs(); vmx_setup_hvm_funcs(); @@ -855,14 +821,14 @@ static void vmx_do_cpuid(struct cpu_user if ( vlapic_hw_disabled(vcpu_vlapic(v)) ) clear_bit(X86_FEATURE_APIC, &edx); - + #if CONFIG_PAGING_LEVELS >= 3 if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] ) #endif clear_bit(X86_FEATURE_PAE, &edx); clear_bit(X86_FEATURE_PSE36, &edx); - ebx &= NUM_THREADS_RESET_MASK; + ebx &= NUM_THREADS_RESET_MASK; /* Unsupportable for virtualised CPUs. */ ecx &= ~(bitmaskof(X86_FEATURE_VMXE) | @@ -875,7 +841,7 @@ static void vmx_do_cpuid(struct cpu_user bitmaskof(X86_FEATURE_ACPI) | bitmaskof(X86_FEATURE_ACC) ); } - else if ( ( input == CPUID_LEAF_0x6 ) + else if ( ( input == CPUID_LEAF_0x6 ) || ( input == CPUID_LEAF_0x9 ) || ( input == CPUID_LEAF_0xA )) { @@ -1331,7 +1297,7 @@ static int vmx_assist(struct vcpu *v, in goto error; if ( vmx_world_restore(v, &c) != 0 ) goto error; - v->arch.hvm_vmx.vmxassist_enabled = 1; + v->arch.hvm_vmx.vmxassist_enabled = 1; return 1; } break; @@ -1401,7 +1367,7 @@ static int vmx_set_cr0(unsigned long val mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT); if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) ) { - gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", + gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", v->arch.hvm_vmx.cpu_cr3, mfn); domain_crash(v->domain); return 0; @@ -1416,10 +1382,10 @@ static int vmx_set_cr0(unsigned long val "with EFER.LME set but not CR4.PAE\n"); vmx_inject_hw_exception(v, TRAP_gp_fault, 0); } - else + else { HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode\n"); - v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER] + v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER] |= EFER_LMA; vm_entry_value = __vmread(VM_ENTRY_CONTROLS); vm_entry_value |= VM_ENTRY_IA32E_MODE; @@ -1473,7 +1439,7 @@ static int vmx_set_cr0(unsigned long val */ if ( vmx_long_mode_enabled(v) ) { - v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER] + v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER] &= ~EFER_LMA; vm_entry_value = __vmread(VM_ENTRY_CONTROLS); vm_entry_value &= ~VM_ENTRY_IA32E_MODE; @@ -1506,8 +1472,7 @@ static int vmx_set_cr0(unsigned long val { if ( vmx_long_mode_enabled(v) ) { - v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER] - &= ~EFER_LMA; + v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER] &= ~EFER_LMA; vm_entry_value = __vmread(VM_ENTRY_CONTROLS); vm_entry_value &= ~VM_ENTRY_IA32E_MODE; __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value); @@ -1865,8 +1830,8 @@ static inline void vmx_do_msr_write(stru { struct periodic_time *pt = &(v->domain->arch.hvm_domain.pl_time.periodic_tm); - if ( pt->enabled && pt->first_injected - && v->vcpu_id == pt->bind_vcpu ) + if ( pt->enabled && pt->first_injected + && v->vcpu_id == pt->bind_vcpu ) pt->first_injected = 0; } hvm_set_guest_time(v, msr_content); @@ -1975,7 +1940,7 @@ void store_cpu_user_regs(struct cpu_user regs->es = __vmread(GUEST_ES_SELECTOR); regs->eip = __vmread(GUEST_RIP); } -#endif +#endif #ifdef XEN_DEBUGGER void save_cpu_user_regs(struct cpu_user_regs *regs) diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/mm.c Mon Nov 20 13:11:15 2006 -0700 @@ -2067,7 +2067,7 @@ int do_mmuext_op( { unsigned long vmask; cpumask_t pmask; - if ( unlikely(get_user(vmask, (unsigned long *)op.arg2.vcpumask)) ) + if ( unlikely(copy_from_guest(&vmask, op.arg2.vcpumask, 1)) ) { okay = 0; break; diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/mm/shadow/common.c --- a/xen/arch/x86/mm/shadow/common.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/mm/shadow/common.c Mon Nov 20 13:11:15 2006 -0700 @@ -1047,6 +1047,10 @@ shadow_set_p2m_entry(struct domain *d, u else *p2m_entry = l1e_empty(); + /* Track the highest gfn for which we have ever had a valid mapping */ + if ( valid_mfn(mfn) && (gfn > d->arch.max_mapped_pfn) ) + d->arch.max_mapped_pfn = gfn; + /* The P2M can be shadowed: keep the shadows synced */ if ( d->vcpu[0] != NULL ) (void)__shadow_validate_guest_entry( @@ -1142,12 +1146,9 @@ sh_gfn_to_mfn_foreign(struct domain *d, mfn = pagetable_get_mfn(d->arch.phys_table); -#if CONFIG_PAGING_LEVELS > 2 - if ( gpfn >= (RO_MPT_VIRT_END-RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) - /* This pfn is higher than the p2m map can hold */ + if ( gpfn > d->arch.max_mapped_pfn ) + /* This pfn is higher than the highest the p2m map currently holds */ return _mfn(INVALID_MFN); -#endif - #if CONFIG_PAGING_LEVELS >= 4 { @@ -3333,13 +3334,14 @@ void shadow_audit_p2m(struct domain *d) set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY); } - if ( test_linear ) - { - lp2mfn = get_mfn_from_gpfn(gfn); - if ( lp2mfn != mfn_x(p2mfn) ) + if ( test_linear && (gfn <= d->arch.max_mapped_pfn) ) + { + lp2mfn = gfn_to_mfn_current(gfn); + if ( mfn_x(lp2mfn) != mfn_x(p2mfn) ) { SHADOW_PRINTK("linear mismatch gfn %#lx -> mfn %#lx " - "(!= mfn %#lx)\n", gfn, lp2mfn, p2mfn); + "(!= mfn %#lx)\n", gfn, + mfn_x(lp2mfn), mfn_x(p2mfn)); } } diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/mm/shadow/multi.c Mon Nov 20 13:11:15 2006 -0700 @@ -2798,8 +2798,9 @@ static int sh_page_fault(struct vcpu *v, * We do not emulate user writes. Instead we use them as a hint that the * page is no longer a page table. This behaviour differs from native, but * it seems very unlikely that any OS grants user access to page tables. + * We also disallow guest PTE updates from within Xen. */ - if ( (regs->error_code & PFEC_user_mode) || + if ( (regs->error_code & PFEC_user_mode) || !guest_mode(regs) || x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) ) { SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", @@ -2839,6 +2840,8 @@ static int sh_page_fault(struct vcpu *v, goto done; mmio: + if ( !guest_mode(regs) ) + goto not_a_shadow_fault; perfc_incrc(shadow_fault_mmio); sh_audit_gw(v, &gw); unmap_walk(v, &gw); @@ -3259,9 +3262,25 @@ sh_set_toplevel_shadow(struct vcpu *v, mfn_t gmfn, unsigned int root_type) { - mfn_t smfn = get_shadow_status(v, gmfn, root_type); + mfn_t smfn; struct domain *d = v->domain; - ASSERT(pagetable_is_null(v->arch.shadow_table[slot])); + + /* Decrement the refcount of the old contents of this slot */ + smfn = pagetable_get_mfn(v->arch.shadow_table[slot]); + if ( mfn_x(smfn) ) + sh_put_ref(v, smfn, 0); + + /* Now figure out the new contents: is this a valid guest MFN? */ + if ( !valid_mfn(gmfn) ) + { + SHADOW_PRINTK("%u/%u [%u] invalid gmfn\n", + GUEST_PAGING_LEVELS, SHADOW_PAGING_LEVELS, slot); + v->arch.shadow_table[slot] = pagetable_null(); + return; + } + + /* Guest mfn is valid: shadow it and install the shadow */ + smfn = get_shadow_status(v, gmfn, root_type); if ( valid_mfn(smfn) ) { /* Pull this root shadow to the front of the list of roots. */ @@ -3270,10 +3289,6 @@ sh_set_toplevel_shadow(struct vcpu *v, } else { - /* This guest MFN is a pagetable. Must revoke write access - * (and can't use heuristics because we have no linear map here). */ - if ( shadow_remove_write_access(v, gmfn, 0, 0) != 0 ) - flush_tlb_mask(v->domain->domain_dirty_cpumask); /* Make sure there's enough free shadow memory. */ shadow_prealloc(d, SHADOW_MAX_ORDER); /* Shadow the page. */ @@ -3288,7 +3303,8 @@ sh_set_toplevel_shadow(struct vcpu *v, mfn_to_page(gmfn)->shadow_flags &= ~SHF_unhooked_mappings; #endif - /* Take a ref to this page: it will be released in sh_detach_old_tables. */ + /* Take a ref to this page: it will be released in sh_detach_old_tables() + * or in the next call to sh_set_toplevel_shadow(). */ sh_get_ref(smfn, 0); sh_pin(smfn); @@ -3360,8 +3376,6 @@ sh_update_cr3(struct vcpu *v) #endif gmfn = pagetable_get_mfn(v->arch.guest_table); - sh_detach_old_tables(v); - if ( !is_hvm_domain(d) && !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) { ASSERT(v->arch.cr3 == 0); @@ -3373,10 +3387,16 @@ sh_update_cr3(struct vcpu *v) //// #if GUEST_PAGING_LEVELS == 4 if ( shadow_mode_external(d) || shadow_mode_translate(d) ) + { + if ( v->arch.guest_vtable ) + sh_unmap_domain_page_global(v->arch.guest_vtable); v->arch.guest_vtable = sh_map_domain_page_global(gmfn); + } else v->arch.guest_vtable = __linear_l4_table; #elif GUEST_PAGING_LEVELS == 3 + if ( v->arch.guest_vtable ) + sh_unmap_domain_page_global(v->arch.guest_vtable); if ( shadow_mode_external(d) ) { if ( shadow_vcpu_mode_translate(v) ) @@ -3398,7 +3418,11 @@ sh_update_cr3(struct vcpu *v) v->arch.guest_vtable = sh_map_domain_page_global(gmfn); #elif GUEST_PAGING_LEVELS == 2 if ( shadow_mode_external(d) || shadow_mode_translate(d) ) + { + if ( v->arch.guest_vtable ) + sh_unmap_domain_page_global(v->arch.guest_vtable); v->arch.guest_vtable = sh_map_domain_page_global(gmfn); + } else v->arch.guest_vtable = __linear_l2_table; #else @@ -3414,29 +3438,49 @@ sh_update_cr3(struct vcpu *v) //// vcpu->arch.shadow_table[] //// + /* We revoke write access to the new guest toplevel page(s) before we + * replace the old shadow pagetable(s), so that we can safely use the + * (old) shadow linear maps in the writeable mapping heuristics. */ #if GUEST_PAGING_LEVELS == 2 + if ( shadow_remove_write_access(v, gmfn, 2, 0) != 0 ) + flush_tlb_mask(v->domain->domain_dirty_cpumask); sh_set_toplevel_shadow(v, 0, gmfn, PGC_SH_l2_shadow); #elif GUEST_PAGING_LEVELS == 3 /* PAE guests have four shadow_table entries, based on the * current values of the guest's four l3es. */ { - int i; + int i, flush = 0; + gfn_t gl2gfn; + mfn_t gl2mfn; guest_l3e_t *gl3e = (guest_l3e_t*)v->arch.guest_vtable; - for ( i = 0; i < 4; i++ ) - { - ASSERT(pagetable_is_null(v->arch.shadow_table[i])); + /* First, make all four entries read-only. */ + for ( i = 0; i < 4; i++ ) + { if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) { - gfn_t gl2gfn = guest_l3e_get_gfn(gl3e[i]); - mfn_t gl2mfn = vcpu_gfn_to_mfn(v, gl2gfn); - if ( valid_mfn(gl2mfn) ) - sh_set_toplevel_shadow(v, i, gl2mfn, (i == 3) - ? PGC_SH_l2h_shadow - : PGC_SH_l2_shadow); + gl2gfn = guest_l3e_get_gfn(gl3e[i]); + gl2mfn = vcpu_gfn_to_mfn(v, gl2gfn); + flush |= shadow_remove_write_access(v, gl2mfn, 2, 0); } } + if ( flush ) + flush_tlb_mask(v->domain->domain_dirty_cpumask); + /* Now install the new shadows. */ + for ( i = 0; i < 4; i++ ) + { + if ( guest_l3e_get_flags(gl3e[i]) & _PAGE_PRESENT ) + { + gl2gfn = guest_l3e_get_gfn(gl3e[i]); + gl2mfn = vcpu_gfn_to_mfn(v, gl2gfn); + sh_set_toplevel_shadow(v, i, gl2mfn, (i == 3) + ? PGC_SH_l2h_shadow + : PGC_SH_l2_shadow); + } + } } #elif GUEST_PAGING_LEVELS == 4 + if ( shadow_remove_write_access(v, gmfn, 4, 0) != 0 ) + flush_tlb_mask(v->domain->domain_dirty_cpumask); sh_set_toplevel_shadow(v, 0, gmfn, PGC_SH_l4_shadow); #else #error This should never happen @@ -3524,9 +3568,9 @@ static int sh_guess_wrmap(struct vcpu *v { shadow_l1e_t sl1e, *sl1p; shadow_l2e_t *sl2p; -#if GUEST_PAGING_LEVELS >= 3 +#if SHADOW_PAGING_LEVELS >= 3 shadow_l3e_t *sl3p; -#if GUEST_PAGING_LEVELS >= 4 +#if SHADOW_PAGING_LEVELS >= 4 shadow_l4e_t *sl4p; #endif #endif @@ -3534,14 +3578,14 @@ static int sh_guess_wrmap(struct vcpu *v /* Carefully look in the shadow linear map for the l1e we expect */ -#if GUEST_PAGING_LEVELS >= 4 +#if SHADOW_PAGING_LEVELS >= 4 sl4p = sh_linear_l4_table(v) + shadow_l4_linear_offset(vaddr); if ( !(shadow_l4e_get_flags(*sl4p) & _PAGE_PRESENT) ) return 0; sl3p = sh_linear_l3_table(v) + shadow_l3_linear_offset(vaddr); if ( !(shadow_l3e_get_flags(*sl3p) & _PAGE_PRESENT) ) return 0; -#elif GUEST_PAGING_LEVELS == 3 +#elif SHADOW_PAGING_LEVELS == 3 sl3p = ((shadow_l3e_t *) v->arch.shadow.l3table) + shadow_l3_linear_offset(vaddr); if ( !(shadow_l3e_get_flags(*sl3p) & _PAGE_PRESENT) ) @@ -3828,7 +3872,6 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u sh_unmap_domain_page(addr); shadow_audit_tables(v); - check_for_early_unshadow(v, mfn); return rv; } @@ -3863,7 +3906,6 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, sh_unmap_domain_page(addr); shadow_audit_tables(v); - check_for_early_unshadow(v, mfn); return rv; } @@ -3899,22 +3941,22 @@ static char * sh_audit_flags(struct vcpu return "shadow is present but guest is not present"; if ( (sflags & _PAGE_GLOBAL) && !is_hvm_vcpu(v) ) return "global bit set in PV shadow"; - if ( (level == 1 || (level == 2 && (gflags & _PAGE_PSE))) - && ((sflags & _PAGE_DIRTY) && !(gflags & _PAGE_DIRTY)) ) - return "dirty bit not propagated"; if ( level == 2 && (sflags & _PAGE_PSE) ) return "PS bit set in shadow"; #if SHADOW_PAGING_LEVELS == 3 if ( level == 3 ) return NULL; /* All the other bits are blank in PAEl3 */ #endif + if ( (sflags & _PAGE_PRESENT) && !(gflags & _PAGE_ACCESSED) ) + return "accessed bit not propagated"; + if ( (level == 1 || (level == 2 && (gflags & _PAGE_PSE))) + && ((sflags & _PAGE_RW) && !(gflags & _PAGE_DIRTY)) ) + return "dirty bit not propagated"; if ( (sflags & _PAGE_USER) != (gflags & _PAGE_USER) ) return "user/supervisor bit does not match"; if ( (sflags & _PAGE_NX_BIT) != (gflags & _PAGE_NX_BIT) ) return "NX bit does not match"; if ( (sflags & _PAGE_RW) && !(gflags & _PAGE_RW) ) return "shadow grants write access but guest does not"; - if ( (sflags & _PAGE_ACCESSED) && !(gflags & _PAGE_ACCESSED) ) - return "accessed bit not propagated"; return NULL; } diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/mm/shadow/types.h --- a/xen/arch/x86/mm/shadow/types.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/mm/shadow/types.h Mon Nov 20 13:11:15 2006 -0700 @@ -416,9 +416,7 @@ vcpu_gfn_to_mfn(struct vcpu *v, gfn_t gf { if ( !shadow_vcpu_mode_translate(v) ) return _mfn(gfn_x(gfn)); - if ( likely(current->domain == v->domain) ) - return _mfn(get_mfn_from_gpfn(gfn_x(gfn))); - return sh_gfn_to_mfn_foreign(v->domain, gfn_x(gfn)); + return sh_gfn_to_mfn(v->domain, gfn_x(gfn)); } static inline gfn_t diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/oprofile/nmi_int.c --- a/xen/arch/x86/oprofile/nmi_int.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/oprofile/nmi_int.c Mon Nov 20 13:11:15 2006 -0700 @@ -305,22 +305,24 @@ static int __init ppro_init(char *cpu_ty { __u8 cpu_model = current_cpu_data.x86_model; - if (cpu_model > 0xd) { + if (cpu_model > 15) { printk("xenoprof: Initialization failed. " "Intel processor model %d for P6 class family is not " "supported\n", cpu_model); return 0; } - - if (cpu_model == 9) { + else if (cpu_model == 15) + strncpy (cpu_type, "i386/core_2", XENOPROF_CPU_TYPE_SIZE - 1); + else if (cpu_model == 14) + strncpy (cpu_type, "i386/core", XENOPROF_CPU_TYPE_SIZE - 1); + else if (cpu_model == 9) strncpy (cpu_type, "i386/p6_mobile", XENOPROF_CPU_TYPE_SIZE - 1); - } else if (cpu_model > 5) { + else if (cpu_model > 5) strncpy (cpu_type, "i386/piii", XENOPROF_CPU_TYPE_SIZE - 1); - } else if (cpu_model > 2) { + else if (cpu_model > 2) strncpy (cpu_type, "i386/pii", XENOPROF_CPU_TYPE_SIZE - 1); - } else { + else strncpy (cpu_type, "i386/ppro", XENOPROF_CPU_TYPE_SIZE - 1); - } model = &op_ppro_spec; return 1; diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/physdev.c Mon Nov 20 13:11:15 2006 -0700 @@ -125,7 +125,7 @@ long do_physdev_op(int cmd, XEN_GUEST_HA if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 ) break; ret = -EINVAL; - if ( !access_ok(set_iobitmap.bitmap, IOBMP_BYTES) || + if ( !guest_handle_okay(set_iobitmap.bitmap, IOBMP_BYTES) || (set_iobitmap.nr_ports > 65536) ) break; ret = 0; diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/traps.c Mon Nov 20 13:11:15 2006 -0700 @@ -331,14 +331,9 @@ void show_execution_state(struct cpu_use show_stack(regs); } -/* - * This is called for faults at very unexpected times (e.g., when interrupts - * are disabled). In such situations we can't do much that is safe. We try to - * print out some tracing and then we just spin. - */ -asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs) -{ - static char *trapstr[] = { +char *trapstr(int trapnr) +{ + static char *strings[] = { "divide error", "debug", "nmi", "bkpt", "overflow", "bounds", "invalid opcode", "device not available", "double fault", "coprocessor segment", "invalid tss", "segment not found", @@ -347,6 +342,19 @@ asmlinkage void fatal_trap(int trapnr, s "machine check", "simd error" }; + if ( (trapnr < 0) || (trapnr >= ARRAY_SIZE(strings)) ) + return "???"; + + return strings[trapnr]; +} + +/* + * This is called for faults at very unexpected times (e.g., when interrupts + * are disabled). In such situations we can't do much that is safe. We try to + * print out some tracing and then we just spin. + */ +asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs) +{ watchdog_disable(); console_start_sync(); @@ -361,38 +369,51 @@ asmlinkage void fatal_trap(int trapnr, s panic("FATAL TRAP: vector = %d (%s)\n" "[error_code=%04x] %s\n", - trapnr, trapstr[trapnr], regs->error_code, + trapnr, trapstr(trapnr), regs->error_code, (regs->eflags & X86_EFLAGS_IF) ? "" : ", IN INTERRUPT CONTEXT"); } -static inline int do_trap(int trapnr, char *str, - struct cpu_user_regs *regs, - int use_error_code) +static int do_guest_trap( + int trapnr, const struct cpu_user_regs *regs, int use_error_code) { struct vcpu *v = current; - struct trap_bounce *tb = &v->arch.trap_bounce; - struct trap_info *ti; - unsigned long fixup; - - DEBUGGER_trap_entry(trapnr, regs); - - if ( !guest_mode(regs) ) - goto xen_fault; - - ti = ¤t->arch.guest_context.trap_ctxt[trapnr]; + struct trap_bounce *tb; + const struct trap_info *ti; + + tb = &v->arch.trap_bounce; + ti = &v->arch.guest_context.trap_ctxt[trapnr]; + tb->flags = TBF_EXCEPTION; tb->cs = ti->cs; tb->eip = ti->address; + if ( use_error_code ) { tb->flags |= TBF_EXCEPTION_ERRCODE; tb->error_code = regs->error_code; } + if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; + + if ( unlikely(null_trap_bounce(tb)) ) + gdprintk(XENLOG_WARNING, "Unhandled %s fault/trap [#%d] in " + "domain %d on VCPU %d [ec=%04x]\n", + trapstr(trapnr), trapnr, v->domain->domain_id, v->vcpu_id, + regs->error_code); + return 0; - - xen_fault: +} + +static inline int do_trap( + int trapnr, struct cpu_user_regs *regs, int use_error_code) +{ + unsigned long fixup; + + DEBUGGER_trap_entry(trapnr, regs); + + if ( guest_mode(regs) ) + return do_guest_trap(trapnr, regs, use_error_code); if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) { @@ -407,32 +428,32 @@ static inline int do_trap(int trapnr, ch show_execution_state(regs); panic("FATAL TRAP: vector = %d (%s)\n" "[error_code=%04x]\n", - trapnr, str, regs->error_code); + trapnr, trapstr(trapnr), regs->error_code); return 0; } -#define DO_ERROR_NOCODE(trapnr, str, name) \ +#define DO_ERROR_NOCODE(trapnr, name) \ asmlinkage int do_##name(struct cpu_user_regs *regs) \ { \ - return do_trap(trapnr, str, regs, 0); \ -} - -#define DO_ERROR(trapnr, str, name) \ + return do_trap(trapnr, regs, 0); \ +} + +#define DO_ERROR(trapnr, name) \ asmlinkage int do_##name(struct cpu_user_regs *regs) \ { \ - return do_trap(trapnr, str, regs, 1); \ -} - -DO_ERROR_NOCODE( 0, "divide error", divide_error) -DO_ERROR_NOCODE( 4, "overflow", overflow) -DO_ERROR_NOCODE( 5, "bounds", bounds) -DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun) -DO_ERROR(10, "invalid TSS", invalid_TSS) -DO_ERROR(11, "segment not present", segment_not_present) -DO_ERROR(12, "stack segment", stack_segment) -DO_ERROR_NOCODE(16, "fpu error", coprocessor_error) -DO_ERROR(17, "alignment check", alignment_check) -DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) + return do_trap(trapnr, regs, 1); \ +} + +DO_ERROR_NOCODE(TRAP_divide_error, divide_error) +DO_ERROR_NOCODE(TRAP_overflow, overflow) +DO_ERROR_NOCODE(TRAP_bounds, bounds) +DO_ERROR_NOCODE(TRAP_copro_seg, coprocessor_segment_overrun) +DO_ERROR( TRAP_invalid_tss, invalid_TSS) +DO_ERROR( TRAP_no_segment, segment_not_present) +DO_ERROR( TRAP_stack_error, stack_segment) +DO_ERROR_NOCODE(TRAP_copro_error, coprocessor_error) +DO_ERROR( TRAP_alignment_check, alignment_check) +DO_ERROR_NOCODE(TRAP_simd_error, simd_coprocessor_error) int rdmsr_hypervisor_regs( uint32_t idx, uint32_t *eax, uint32_t *edx) @@ -599,9 +620,6 @@ static int emulate_forced_invalid_op(str asmlinkage int do_invalid_op(struct cpu_user_regs *regs) { - struct vcpu *v = current; - struct trap_bounce *tb = &v->arch.trap_bounce; - struct trap_info *ti; int rc; DEBUGGER_trap_entry(TRAP_invalid_op, regs); @@ -625,22 +643,11 @@ asmlinkage int do_invalid_op(struct cpu_ if ( (rc = emulate_forced_invalid_op(regs)) != 0 ) return rc; - ti = ¤t->arch.guest_context.trap_ctxt[TRAP_invalid_op]; - tb->flags = TBF_EXCEPTION; - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - tb->flags |= TBF_INTERRUPT; - - return 0; + return do_guest_trap(TRAP_invalid_op, regs, 0); } asmlinkage int do_int3(struct cpu_user_regs *regs) { - struct vcpu *v = current; - struct trap_bounce *tb = &v->arch.trap_bounce; - struct trap_info *ti; - DEBUGGER_trap_entry(TRAP_int3, regs); if ( !guest_mode(regs) ) @@ -650,14 +657,7 @@ asmlinkage int do_int3(struct cpu_user_r panic("FATAL TRAP: vector = 3 (Int3)\n"); } - ti = ¤t->arch.guest_context.trap_ctxt[TRAP_int3]; - tb->flags = TBF_EXCEPTION; - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - tb->flags |= TBF_INTERRUPT; - - return 0; + return do_guest_trap(TRAP_int3, regs, 0); } asmlinkage int do_machine_check(struct cpu_user_regs *regs) @@ -687,6 +687,12 @@ void propagate_page_fault(unsigned long tb->eip = ti->address; if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; + if ( unlikely(null_trap_bounce(tb)) ) + { + printk("Unhandled page fault in domain %d on VCPU %d (ec=%04X)\n", + v->domain->domain_id, v->vcpu_id, error_code); + show_page_walk(addr); + } } static int handle_gdt_ldt_mapping_fault( @@ -952,7 +958,6 @@ static inline int guest_io_okay( unsigned int port, unsigned int bytes, struct vcpu *v, struct cpu_user_regs *regs) { - u16 x; #if defined(__x86_64__) /* If in user mode, switch to kernel mode just to read I/O bitmap. */ int user_mode = !(v->arch.flags & TF_kernel_mode); @@ -967,10 +972,23 @@ static inline int guest_io_okay( if ( v->arch.iobmp_limit > (port + bytes) ) { + union { uint8_t bytes[2]; uint16_t mask; } x; + + /* + * Grab permission bytes from guest space. Inaccessible bytes are + * read as 0xff (no access allowed). + */ TOGGLE_MODE(); - __get_user(x, (u16 *)(v->arch.iobmp+(port>>3))); + switch ( __copy_from_guest_offset(&x.bytes[0], v->arch.iobmp, + port>>3, 2) ) + { + default: x.bytes[0] = ~0; + case 1: x.bytes[1] = ~0; + case 0: break; + } TOGGLE_MODE(); - if ( (x & (((1<<bytes)-1) << (port&7))) == 0 ) + + if ( (x.mask & (((1<<bytes)-1) << (port&7))) == 0 ) return 1; } @@ -1469,8 +1487,6 @@ asmlinkage int do_general_protection(str asmlinkage int do_general_protection(struct cpu_user_regs *regs) { struct vcpu *v = current; - struct trap_bounce *tb = &v->arch.trap_bounce; - struct trap_info *ti; unsigned long fixup; DEBUGGER_trap_entry(TRAP_gp_fault, regs); @@ -1504,12 +1520,13 @@ asmlinkage int do_general_protection(str if ( (regs->error_code & 3) == 2 ) { /* This fault must be due to <INT n> instruction. */ - ti = ¤t->arch.guest_context.trap_ctxt[regs->error_code>>3]; + const struct trap_info *ti; + unsigned char vector = regs->error_code >> 3; + ti = &v->arch.guest_context.trap_ctxt[vector]; if ( permit_softint(TI_GET_DPL(ti), v, regs) ) { - tb->flags = TBF_EXCEPTION; regs->eip += 2; - goto finish_propagation; + return do_guest_trap(vector, regs, 0); } } @@ -1526,15 +1543,7 @@ asmlinkage int do_general_protection(str #endif /* Pass on GPF as is. */ - ti = ¤t->arch.guest_context.trap_ctxt[TRAP_gp_fault]; - tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE; - tb->error_code = regs->error_code; - finish_propagation: - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - tb->flags |= TBF_INTERRUPT; - return 0; + return do_guest_trap(TRAP_gp_fault, regs, 1); gp_in_kernel: @@ -1672,22 +1681,11 @@ void unset_nmi_callback(void) asmlinkage int math_state_restore(struct cpu_user_regs *regs) { - struct trap_bounce *tb; - struct trap_info *ti; - setup_fpu(current); if ( current->arch.guest_context.ctrlreg[0] & X86_CR0_TS ) { - tb = ¤t->arch.trap_bounce; - ti = ¤t->arch.guest_context.trap_ctxt[TRAP_no_device]; - - tb->flags = TBF_EXCEPTION; - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - tb->flags |= TBF_INTERRUPT; - + do_guest_trap(TRAP_no_device, regs, 0); current->arch.guest_context.ctrlreg[0] &= ~X86_CR0_TS; } @@ -1698,8 +1696,6 @@ asmlinkage int do_debug(struct cpu_user_ { unsigned long condition; struct vcpu *v = current; - struct trap_bounce *tb = &v->arch.trap_bounce; - struct trap_info *ti; __asm__ __volatile__("mov %%db6,%0" : "=r" (condition)); @@ -1729,12 +1725,7 @@ asmlinkage int do_debug(struct cpu_user_ /* Save debug status register where guest OS can peek at it */ v->arch.guest_context.debugreg[6] = condition; - ti = &v->arch.guest_context.trap_ctxt[TRAP_debug]; - tb->flags = TBF_EXCEPTION; - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - tb->flags |= TBF_INTERRUPT; + return do_guest_trap(TRAP_debug, regs, 0); out: return EXCRET_not_a_fault; diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/x86_32/entry.S Mon Nov 20 13:11:15 2006 -0700 @@ -373,10 +373,11 @@ nvm86_3:/* Rewrite our stack frame and r mov %gs,UREGS_ss+4(%esp) movl %esi,UREGS_esp+4(%esp) movzwl TRAPBOUNCE_cs(%edx),%eax + /* Null selectors (0-3) are not allowed. */ + testl $~3,%eax + jz domain_crash_synchronous movl %eax,UREGS_cs+4(%esp) movl TRAPBOUNCE_eip(%edx),%eax - test %eax,%eax - jz domain_crash_synchronous movl %eax,UREGS_eip+4(%esp) movb $0,TRAPBOUNCE_flags(%edx) ret @@ -596,20 +597,6 @@ ENTRY(setup_vm86_frame) addl $16,%esp ret -do_arch_sched_op_compat: - # Ensure we return success even if we return via schedule_tail() - xorl %eax,%eax - GET_GUEST_REGS(%ecx) - movl %eax,UREGS_eax(%ecx) - jmp do_sched_op_compat - -do_arch_sched_op: - # Ensure we return success even if we return via schedule_tail() - xorl %eax,%eax - GET_GUEST_REGS(%ecx) - movl %eax,UREGS_eax(%ecx) - jmp do_sched_op - .data ENTRY(exception_table) @@ -641,7 +628,7 @@ ENTRY(hypercall_table) .long do_stack_switch .long do_set_callbacks .long do_fpu_taskswitch /* 5 */ - .long do_arch_sched_op_compat + .long do_sched_op_compat .long do_platform_op .long do_set_debugreg .long do_get_debugreg @@ -664,7 +651,7 @@ ENTRY(hypercall_table) .long do_mmuext_op .long do_acm_op .long do_nmi_op - .long do_arch_sched_op + .long do_sched_op .long do_callback_op /* 30 */ .long do_xenoprof_op .long do_event_channel_op @@ -683,7 +670,7 @@ ENTRY(hypercall_args_table) .byte 2 /* do_stack_switch */ .byte 4 /* do_set_callbacks */ .byte 1 /* do_fpu_taskswitch */ /* 5 */ - .byte 2 /* do_arch_sched_op_compat */ + .byte 2 /* do_sched_op_compat */ .byte 1 /* do_platform_op */ .byte 2 /* do_set_debugreg */ .byte 1 /* do_get_debugreg */ @@ -706,7 +693,7 @@ ENTRY(hypercall_args_table) .byte 4 /* do_mmuext_op */ .byte 1 /* do_acm_op */ .byte 2 /* do_nmi_op */ - .byte 2 /* do_arch_sched_op */ + .byte 2 /* do_sched_op */ .byte 2 /* do_callback_op */ /* 30 */ .byte 2 /* do_xenoprof_op */ .byte 2 /* do_event_channel_op */ diff -r 066094348f22 -r 0699c3eff7a3 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/arch/x86/x86_64/entry.S Mon Nov 20 13:11:15 2006 -0700 @@ -497,20 +497,6 @@ nmi_in_hypervisor_mode: call do_nmi jmp ret_from_intr -do_arch_sched_op_compat: - # Ensure we return success even if we return via schedule_tail() - xorl %eax,%eax - GET_GUEST_REGS(%r10) - movq %rax,UREGS_rax(%r10) - jmp do_sched_op_compat - -do_arch_sched_op: - # Ensure we return success even if we return via schedule_tail() - xorl %eax,%eax - GET_GUEST_REGS(%r10) - movq %rax,UREGS_rax(%r10) - jmp do_sched_op - .data ENTRY(exception_table) @@ -542,7 +528,7 @@ ENTRY(hypercall_table) .quad do_stack_switch .quad do_set_callbacks .quad do_fpu_taskswitch /* 5 */ - .quad do_arch_sched_op_compat + .quad do_sched_op_compat .quad do_platform_op .quad do_set_debugreg .quad do_get_debugreg @@ -565,7 +551,7 @@ ENTRY(hypercall_table) .quad do_mmuext_op .quad do_acm_op .quad do_nmi_op - .quad do_arch_sched_op + .quad do_sched_op .quad do_callback_op /* 30 */ .quad do_xenoprof_op .quad do_event_channel_op @@ -584,8 +570,8 @@ ENTRY(hypercall_args_table) .byte 2 /* do_stack_switch */ .byte 3 /* do_set_callbacks */ .byte 1 /* do_fpu_taskswitch */ /* 5 */ - .byte 2 /* do_arch_sched_op_compat */ - .byte 1 /* do_platform_op */ + .byte 2 /* do_sched_op_compat */ + .byte 1 /* do_platform_op */ .byte 2 /* do_set_debugreg */ .byte 1 /* do_get_debugreg */ .byte 2 /* do_update_descriptor */ /* 10 */ @@ -607,7 +593,7 @@ ENTRY(hypercall_args_table) .byte 4 /* do_mmuext_op */ .byte 1 /* do_acm_op */ .byte 2 /* do_nmi_op */ - .byte 2 /* do_arch_sched_op */ + .byte 2 /* do_sched_op */ .byte 2 /* do_callback_op */ /* 30 */ .byte 2 /* do_xenoprof_op */ .byte 2 /* do_event_channel_op */ diff -r 066094348f22 -r 0699c3eff7a3 xen/common/domain.c --- a/xen/common/domain.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/common/domain.c Mon Nov 20 13:11:15 2006 -0700 @@ -258,8 +258,18 @@ void __domain_crash_synchronous(void) { __domain_crash(current->domain); - /* Flush multicall state before dying. */ - this_cpu(mc_state).flags = 0; + /* + * Flush multicall state before dying if a multicall is in progress. + * This shouldn't be necessary, but some architectures are calling + * domain_crash_synchronous() when they really shouldn't (i.e., from + * within hypercall context). + */ + if ( this_cpu(mc_state).flags != 0 ) + { + dprintk(XENLOG_ERR, + "FIXME: synchronous domain crash during a multicall!\n"); + this_cpu(mc_state).flags = 0; + } for ( ; ; ) do_softirq(); diff -r 066094348f22 -r 0699c3eff7a3 xen/common/grant_table.c --- a/xen/common/grant_table.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/common/grant_table.c Mon Nov 20 13:11:15 2006 -0700 @@ -24,6 +24,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <xen/config.h> +#include <xen/iocap.h> #include <xen/lib.h> #include <xen/sched.h> #include <xen/shadow.h> @@ -991,6 +993,9 @@ do_grant_table_op( guest_handle_cast(uop, gnttab_map_grant_ref_t); if ( unlikely(!guest_handle_okay(map, count)) ) goto out; + rc = -EPERM; + if ( unlikely(!grant_operation_permitted(d)) ) + goto out; rc = gnttab_map_grant_ref(map, count); break; } @@ -1000,6 +1005,9 @@ do_grant_table_op( guest_handle_cast(uop, gnttab_unmap_grant_ref_t); if ( unlikely(!guest_handle_okay(unmap, count)) ) goto out; + rc = -EPERM; + if ( unlikely(!grant_operation_permitted(d)) ) + goto out; rc = gnttab_unmap_grant_ref(unmap, count); break; } @@ -1014,6 +1022,9 @@ do_grant_table_op( XEN_GUEST_HANDLE(gnttab_transfer_t) transfer = guest_handle_cast(uop, gnttab_transfer_t); if ( unlikely(!guest_handle_okay(transfer, count)) ) + goto out; + rc = -EPERM; + if ( unlikely(!grant_operation_permitted(d)) ) goto out; rc = gnttab_transfer(transfer, count); break; diff -r 066094348f22 -r 0699c3eff7a3 xen/common/schedule.c --- a/xen/common/schedule.c Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/common/schedule.c Mon Nov 20 13:11:15 2006 -0700 @@ -29,6 +29,7 @@ #include <xen/mm.h> #include <xen/errno.h> #include <xen/guest_access.h> +#include <xen/multicall.h> #include <public/sched.h> extern void arch_getdomaininfo_ctxt(struct vcpu *, @@ -59,8 +60,6 @@ static struct scheduler *schedulers[] = &sched_credit_def, NULL }; - -static void __enter_scheduler(void); static struct scheduler ops; @@ -270,7 +269,7 @@ static long do_block(void) else { TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); } return 0; @@ -315,9 +314,9 @@ static long do_poll(struct sched_poll *s set_timer(&v->poll_timer, sched_poll->timeout); TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id); - __enter_scheduler(); - - stop_timer(&v->poll_timer); + raise_softirq(SCHEDULE_SOFTIRQ); + + return 0; out: clear_bit(_VCPUF_polling, &v->vcpu_flags); @@ -329,7 +328,7 @@ static long do_yield(void) static long do_yield(void) { TRACE_2D(TRC_SCHED_YIELD, current->domain->domain_id, current->vcpu_id); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); return 0; } @@ -540,7 +539,7 @@ long sched_adjust(struct domain *d, stru * - deschedule the current domain (scheduler independent). * - pick a new domain (scheduler dependent). */ -static void __enter_scheduler(void) +static void schedule(void) { struct vcpu *prev = current, *next = NULL; s_time_t now = NOW(); @@ -549,6 +548,7 @@ static void __enter_scheduler(void) s32 r_time; /* time for new dom to run */ ASSERT(!in_irq()); + ASSERT(this_cpu(mc_state).flags == 0); perfc_incrc(sched_run); @@ -679,7 +679,7 @@ void __init scheduler_init(void) { int i; - open_softirq(SCHEDULE_SOFTIRQ, __enter_scheduler); + open_softirq(SCHEDULE_SOFTIRQ, schedule); for_each_cpu ( i ) { diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/domain.h --- a/xen/include/asm-x86/domain.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/domain.h Mon Nov 20 13:11:15 2006 -0700 @@ -111,6 +111,8 @@ struct arch_domain /* Shadow translated domain: P2M mapping */ pagetable_t phys_table; + /* Highest guest frame that's ever been mapped in the p2m */ + unsigned long max_mapped_pfn; } __cacheline_aligned; @@ -169,7 +171,7 @@ struct arch_vcpu struct trap_bounce trap_bounce; /* I/O-port access bitmap. */ - u8 *iobmp; /* Guest kernel virtual address of the bitmap. */ + XEN_GUEST_HANDLE(uint8_t) iobmp; /* Guest kernel virtual address of the bitmap. */ int iobmp_limit; /* Number of ports represented in the bitmap. */ int iopl; /* Current IOPL for this VCPU. */ diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/hvm/hvm.h Mon Nov 20 13:11:15 2006 -0700 @@ -97,6 +97,8 @@ int hvm_vcpu_initialise(struct vcpu *v); int hvm_vcpu_initialise(struct vcpu *v); void hvm_vcpu_destroy(struct vcpu *v); +void hvm_send_assist_req(struct vcpu *v); + static inline void hvm_store_cpu_guest_regs( struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs) @@ -161,6 +163,8 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u void hvm_stts(struct vcpu *v); void hvm_set_guest_time(struct vcpu *v, u64 gtime); +void hvm_freeze_time(struct vcpu *v); +void hvm_migrate_timers(struct vcpu *v); void hvm_do_resume(struct vcpu *v); static inline void diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/hvm/io.h Mon Nov 20 13:11:15 2006 -0700 @@ -151,8 +151,5 @@ extern int cpu_get_interrupt(struct vcpu extern int cpu_get_interrupt(struct vcpu *v, int *type); extern int cpu_has_pending_irq(struct vcpu *v); -// XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame. -#define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT))) - #endif /* __ASM_X86_HVM_IO_H__ */ diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Mon Nov 20 13:11:15 2006 -0700 @@ -41,12 +41,12 @@ enum { VMX_INDEX_MSR_SYSCALL_MASK, VMX_INDEX_MSR_EFER, - VMX_MSR_COUNT, + VMX_MSR_COUNT }; struct vmx_msr_state { unsigned long flags; - unsigned long msr_items[VMX_MSR_COUNT]; + unsigned long msrs[VMX_MSR_COUNT]; unsigned long shadow_gs; }; @@ -76,8 +76,8 @@ struct arch_vmx_struct { unsigned long cpu_shadow_cr4; /* copy of guest read shadow CR4 */ unsigned long cpu_cr2; /* save CR2 */ unsigned long cpu_cr3; - struct vmx_msr_state msr_content; - unsigned long vmxassist_enabled:1; + struct vmx_msr_state msr_state; + unsigned long vmxassist_enabled:1; }; #define vmx_schedule_tail(next) \ @@ -141,10 +141,10 @@ enum vmcs_field { HOST_FS_SELECTOR = 0x00000c08, HOST_GS_SELECTOR = 0x00000c0a, HOST_TR_SELECTOR = 0x00000c0c, - IO_BITMAP_A = 0x00002000, - IO_BITMAP_A_HIGH = 0x00002001, - IO_BITMAP_B = 0x00002002, - IO_BITMAP_B_HIGH = 0x00002003, + IO_BITMAP_A = 0x00002000, + IO_BITMAP_A_HIGH = 0x00002001, + IO_BITMAP_B = 0x00002002, + IO_BITMAP_B_HIGH = 0x00002003, VM_EXIT_MSR_STORE_ADDR = 0x00002006, VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007, VM_EXIT_MSR_LOAD_ADDR = 0x00002008, @@ -160,7 +160,7 @@ enum vmcs_field { GUEST_IA32_DEBUGCTL = 0x00002802, GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, - CPU_BASED_VM_EXEC_CONTROL = 0x00004002, + CPU_BASED_VM_EXEC_CONTROL = 0x00004002, EXCEPTION_BITMAP = 0x00004004, PAGE_FAULT_ERROR_CODE_MASK = 0x00004006, PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008, @@ -177,7 +177,7 @@ enum vmcs_field { SECONDARY_VM_EXEC_CONTROL = 0x0000401e, VM_INSTRUCTION_ERROR = 0x00004400, VM_EXIT_REASON = 0x00004402, - VM_EXIT_INTR_INFO = 0x00004404, + VM_EXIT_INTR_INFO = 0x00004404, VM_EXIT_INTR_ERROR_CODE = 0x00004406, IDT_VECTORING_INFO_FIELD = 0x00004408, IDT_VECTORING_ERROR_CODE = 0x0000440a, @@ -209,10 +209,10 @@ enum vmcs_field { CR4_GUEST_HOST_MASK = 0x00006002, CR0_READ_SHADOW = 0x00006004, CR4_READ_SHADOW = 0x00006006, - CR3_TARGET_VALUE0 = 0x00006008, - CR3_TARGET_VALUE1 = 0x0000600a, - CR3_TARGET_VALUE2 = 0x0000600c, - CR3_TARGET_VALUE3 = 0x0000600e, + CR3_TARGET_VALUE0 = 0x00006008, + CR3_TARGET_VALUE1 = 0x0000600a, + CR3_TARGET_VALUE2 = 0x0000600c, + CR3_TARGET_VALUE3 = 0x0000600e, EXIT_QUALIFICATION = 0x00006400, GUEST_LINEAR_ADDRESS = 0x0000640a, GUEST_CR0 = 0x00006800, @@ -226,7 +226,7 @@ enum vmcs_field { GUEST_GS_BASE = 0x00006810, GUEST_LDTR_BASE = 0x00006812, GUEST_TR_BASE = 0x00006814, - GUEST_GDTR_BASE = 0x00006816, + GUEST_GDTR_BASE = 0x00006816, GUEST_IDTR_BASE = 0x00006818, GUEST_DR7 = 0x0000681a, GUEST_RSP = 0x0000681c, diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Mon Nov 20 13:11:15 2006 -0700 @@ -29,7 +29,6 @@ extern void vmx_asm_vmexit_handler(struc extern void vmx_asm_vmexit_handler(struct cpu_user_regs); extern void vmx_asm_do_vmentry(void); extern void vmx_intr_assist(void); -extern void vmx_migrate_timers(struct vcpu *v); extern void arch_vmx_do_resume(struct vcpu *); extern void set_guest_time(struct vcpu *v, u64 gtime); @@ -263,13 +262,13 @@ static inline int vmx_paging_enabled(str static inline int vmx_long_mode_enabled(struct vcpu *v) { - u64 efer = v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER]; + u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]; return efer & EFER_LMA; } static inline int vmx_lme_is_set(struct vcpu *v) { - u64 efer = v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER]; + u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]; return efer & EFER_LME; } diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/hvm/vpt.h Mon Nov 20 13:11:15 2006 -0700 @@ -67,8 +67,10 @@ typedef struct RTCState { int64_t next_second_time; struct timer second_timer; struct timer second_timer2; + struct timer pie_timer; + int period; + s_time_t next_pie; struct vcpu *vcpu; - struct periodic_time *pt; } RTCState; #define FREQUENCE_PMTIMER 3579545 @@ -143,9 +145,11 @@ void pit_init(struct vcpu *v, unsigned l void pit_init(struct vcpu *v, unsigned long cpu_khz); void rtc_init(struct vcpu *v, int base, int irq); void rtc_deinit(struct domain *d); +void rtc_freeze(struct vcpu *v); +void rtc_thaw(struct vcpu *v); +void rtc_migrate_timers(struct vcpu *v); void pmtimer_init(struct vcpu *v, int base); void pmtimer_deinit(struct domain *d); -int is_rtc_periodic_irq(void *opaque); void pt_timer_fn(void *data); void pit_time_fired(struct vcpu *v, void *priv); diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/mm.h --- a/xen/include/asm-x86/mm.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/mm.h Mon Nov 20 13:11:15 2006 -0700 @@ -304,37 +304,9 @@ int check_descriptor(struct desc_struct #define gmfn_to_mfn(_d, gpfn) mfn_x(sh_gfn_to_mfn(_d, gpfn)) - -/* - * The phys_to_machine_mapping is the reversed mapping of MPT for full - * virtualization. It is only used by shadow_mode_translate()==true - * guests, so we steal the address space that would have normally - * been used by the read-only MPT map. - */ -#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START) #define INVALID_MFN (~0UL) #define VALID_MFN(_mfn) (!((_mfn) & (1U<<31))) -static inline unsigned long get_mfn_from_gpfn(unsigned long pfn) -{ - l1_pgentry_t l1e = l1e_empty(); - int ret; - -#if CONFIG_PAGING_LEVELS > 2 - if ( pfn >= (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t) ) - /* This pfn is higher than the p2m map can hold */ - return INVALID_MFN; -#endif - - ret = __copy_from_user(&l1e, - &phys_to_machine_mapping[pfn], - sizeof(l1e)); - - if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) ) - return l1e_get_pfn(l1e); - - return INVALID_MFN; -} #ifdef MEMORY_GUARD void memguard_init(void); diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/shadow.h --- a/xen/include/asm-x86/shadow.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/shadow.h Mon Nov 20 13:11:15 2006 -0700 @@ -663,12 +663,40 @@ struct shadow_walk_cache { /**************************************************************************/ -/* Guest physmap (p2m) support */ +/* Guest physmap (p2m) support + * + * The phys_to_machine_mapping is the reversed mapping of MPT for full + * virtualization. It is only used by shadow_mode_translate()==true + * guests, so we steal the address space that would have normally + * been used by the read-only MPT map. + */ + +#define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START) + +/* Read the current domain's P2M table. */ +static inline mfn_t sh_gfn_to_mfn_current(unsigned long gfn) +{ + l1_pgentry_t l1e = l1e_empty(); + int ret; + + if ( gfn > current->domain->arch.max_mapped_pfn ) + return _mfn(INVALID_MFN); + + /* Don't read off the end of the p2m table */ + ASSERT(gfn < (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof(l1_pgentry_t)); + + ret = __copy_from_user(&l1e, + &phys_to_machine_mapping[gfn], + sizeof(l1e)); + + if ( (ret == 0) && (l1e_get_flags(l1e) & _PAGE_PRESENT) ) + return _mfn(l1e_get_pfn(l1e)); + + return _mfn(INVALID_MFN); +} /* Walk another domain's P2M table, mapping pages as we go */ -extern mfn_t -sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn); - +extern mfn_t sh_gfn_to_mfn_foreign(struct domain *d, unsigned long gpfn); /* General conversion function from gfn to mfn */ static inline mfn_t @@ -676,12 +704,19 @@ sh_gfn_to_mfn(struct domain *d, unsigned { if ( !shadow_mode_translate(d) ) return _mfn(gfn); - else if ( likely(current->domain == d) ) - return _mfn(get_mfn_from_gpfn(gfn)); - else + if ( likely(current->domain == d) ) + return sh_gfn_to_mfn_current(gfn); + else return sh_gfn_to_mfn_foreign(d, gfn); } +/* Compatibility function for HVM code */ +static inline unsigned long get_mfn_from_gpfn(unsigned long pfn) +{ + return mfn_x(sh_gfn_to_mfn_current(pfn)); +} + +/* General conversion function from mfn to gfn */ static inline unsigned long sh_mfn_to_gfn(struct domain *d, mfn_t mfn) { @@ -689,6 +724,14 @@ sh_mfn_to_gfn(struct domain *d, mfn_t mf return get_gpfn_from_mfn(mfn_x(mfn)); else return mfn_x(mfn); +} + +/* Is this guest address an mmio one? (i.e. not defined in p2m map) */ +static inline int +mmio_space(paddr_t gpa) +{ + unsigned long gfn = gpa >> PAGE_SHIFT; + return !VALID_MFN(mfn_x(sh_gfn_to_mfn_current(gfn))); } static inline l1_pgentry_t diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/x86_32/regs.h --- a/xen/include/asm-x86/x86_32/regs.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/x86_32/regs.h Mon Nov 20 13:11:15 2006 -0700 @@ -16,6 +16,9 @@ #define permit_softint(dpl, v, r) \ ((dpl) >= (vm86_mode(r) ? 3 : ((r)->cs & 3))) +/* Check for null trap callback handler: Is the selector null (0-3)? */ +#define null_trap_bounce(tb) (((tb)->cs & ~3) == 0) + /* Number of bytes of on-stack execution state to be context-switched. */ #define CTXT_SWITCH_STACK_BYTES (sizeof(struct cpu_user_regs)) diff -r 066094348f22 -r 0699c3eff7a3 xen/include/asm-x86/x86_64/regs.h --- a/xen/include/asm-x86/x86_64/regs.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/asm-x86/x86_64/regs.h Mon Nov 20 13:11:15 2006 -0700 @@ -16,6 +16,9 @@ #define permit_softint(dpl, v, r) \ ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3)) +/* Check for null trap callback handler: Is the EIP null? */ +#define null_trap_bounce(tb) ((tb)->eip == 0) + /* Number of bytes of on-stack execution state to be context-switched. */ /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */ #define CTXT_SWITCH_STACK_BYTES (offsetof(struct cpu_user_regs, es)) diff -r 066094348f22 -r 0699c3eff7a3 xen/include/public/physdev.h --- a/xen/include/public/physdev.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/public/physdev.h Mon Nov 20 13:11:15 2006 -0700 @@ -1,4 +1,3 @@ - /* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -82,7 +81,7 @@ DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl #define PHYSDEVOP_set_iobitmap 7 struct physdev_set_iobitmap { /* IN */ - uint8_t *bitmap; + XEN_GUEST_HANDLE_00030205(uint8_t) bitmap; uint32_t nr_ports; }; typedef struct physdev_set_iobitmap physdev_set_iobitmap_t; diff -r 066094348f22 -r 0699c3eff7a3 xen/include/public/vcpu.h --- a/xen/include/public/vcpu.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/public/vcpu.h Mon Nov 20 13:11:15 2006 -0700 @@ -86,6 +86,7 @@ struct vcpu_runstate_info { uint64_t time[4]; }; typedef struct vcpu_runstate_info vcpu_runstate_info_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_t); /* VCPU is currently running on a physical CPU. */ #define RUNSTATE_running 0 @@ -108,8 +109,9 @@ typedef struct vcpu_runstate_info vcpu_r * Register a shared memory area from which the guest may obtain its own * runstate information without needing to execute a hypercall. * Notes: - * 1. The registered address may be virtual or physical, depending on the - * platform. The virtual address should be registered on x86 systems. + * 1. The registered address may be virtual or physical or guest handle, + * depending on the platform. Virtual address or guest handle should be + * registered on x86 systems. * 2. Only one shared area may be registered per VCPU. The shared area is * updated by the hypervisor each time the VCPU is scheduled. Thus * runstate.state will always be RUNSTATE_running and @@ -120,6 +122,7 @@ typedef struct vcpu_runstate_info vcpu_r #define VCPUOP_register_runstate_memory_area 5 struct vcpu_register_runstate_memory_area { union { + XEN_GUEST_HANDLE(vcpu_runstate_info_t) h; struct vcpu_runstate_info *v; uint64_t p; } addr; diff -r 066094348f22 -r 0699c3eff7a3 xen/include/public/xen-compat.h --- a/xen/include/public/xen-compat.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/public/xen-compat.h Mon Nov 20 13:11:15 2006 -0700 @@ -27,7 +27,7 @@ #ifndef __XEN_PUBLIC_XEN_COMPAT_H__ #define __XEN_PUBLIC_XEN_COMPAT_H__ -#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030204 +#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030205 #if defined(__XEN__) || defined(__XEN_TOOLS__) /* Xen is built with matching headers and implements the latest interface. */ @@ -41,4 +41,11 @@ #error "These header files do not support the requested interface version." #endif +/* Fields defined as a Xen guest handle since 0x00030205. */ +#if __XEN_INTERFACE_VERSION__ >= 0x00030205 +#define XEN_GUEST_HANDLE_00030205(type) XEN_GUEST_HANDLE(type) +#else +#define XEN_GUEST_HANDLE_00030205(type) type * +#endif + #endif /* __XEN_PUBLIC_XEN_COMPAT_H__ */ diff -r 066094348f22 -r 0699c3eff7a3 xen/include/public/xen.h --- a/xen/include/public/xen.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/public/xen.h Mon Nov 20 13:11:15 2006 -0700 @@ -246,7 +246,7 @@ struct mmuext_op { /* SET_LDT */ unsigned int nr_ents; /* TLB_FLUSH_MULTI, INVLPG_MULTI */ - void *vcpumask; + XEN_GUEST_HANDLE_00030205(void) vcpumask; } arg2; }; typedef struct mmuext_op mmuext_op_t; diff -r 066094348f22 -r 0699c3eff7a3 xen/include/xen/iocap.h --- a/xen/include/xen/iocap.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/xen/iocap.h Mon Nov 20 13:11:15 2006 -0700 @@ -31,4 +31,12 @@ #define multipage_allocation_permitted(d) \ (!rangeset_is_empty((d)->iomem_caps)) +/* + * Until TLB flushing issues are sorted out we consider it unsafe for + * domains with no hardware-access privileges to perform grant map/transfer + * operations. + */ +#define grant_operation_permitted(d) \ + (!rangeset_is_empty((d)->iomem_caps)) + #endif /* __XEN_IOCAP_H__ */ diff -r 066094348f22 -r 0699c3eff7a3 xen/include/xen/sched.h --- a/xen/include/xen/sched.h Mon Nov 20 12:14:40 2006 -0700 +++ b/xen/include/xen/sched.h Mon Nov 20 13:11:15 2006 -0700 @@ -75,7 +75,7 @@ struct vcpu void *sched_priv; /* scheduler-specific data */ struct vcpu_runstate_info runstate; - struct vcpu_runstate_info *runstate_guest; /* guest address */ + XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */ unsigned long vcpu_flags; @@ -281,11 +281,6 @@ void __domain_crash_synchronous(void) __ printk("domain_crash_sync called from %s:%d\n", __FILE__, __LINE__); \ __domain_crash_synchronous(); \ } while (0) - -void new_thread(struct vcpu *d, - unsigned long start_pc, - unsigned long start_stack, - unsigned long start_info); #define set_current_state(_s) do { current->state = (_s); } while (0) void scheduler_init(void); diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/spinlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/spinlock.h Mon Nov 20 13:11:15 2006 -0700 @@ -0,0 +1,55 @@ +#ifndef __ASM_SPINLOCK_H +#define __ASM_SPINLOCK_H + +#include <lib.h> + +/* + * Your basic SMP spinlocks, allowing only a single CPU anywhere + */ + +typedef struct { + volatile unsigned int slock; +} spinlock_t; + + +#include "arch_spinlock.h" + + +#define SPINLOCK_MAGIC 0xdead4ead + +#define SPIN_LOCK_UNLOCKED ARCH_SPIN_LOCK_UNLOCKED + +#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0) + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +#define spin_is_locked(x) arch_spin_is_locked(x) + +#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) + + +#define _spin_trylock(lock) ({_raw_spin_trylock(lock) ? \ + 1 : ({ 0;});}) + +#define _spin_lock(lock) \ +do { \ + _raw_spin_lock(lock); \ +} while(0) + +#define _spin_unlock(lock) \ +do { \ + _raw_spin_unlock(lock); \ +} while (0) + + +#define spin_lock(lock) _spin_lock(lock) +#define spin_unlock(lock) _spin_unlock(lock) + +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED + +#endif diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/x86/arch_spinlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/x86/arch_spinlock.h Mon Nov 20 13:11:15 2006 -0700 @@ -0,0 +1,93 @@ + + +#ifndef __ARCH_ASM_SPINLOCK_H +#define __ARCH_ASM_SPINLOCK_H + +#include <lib.h> + + +#define ARCH_SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0) +#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) + +#define spin_lock_string \ + "1:\n" \ + LOCK \ + "decb %0\n\t" \ + "jns 3f\n" \ + "2:\t" \ + "rep;nop\n\t" \ + "cmpb $0,%0\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + "3:\n\t" + +#define spin_lock_string_flags \ + "1:\n" \ + LOCK \ + "decb %0\n\t" \ + "jns 4f\n\t" \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 3f\n\t" \ + "#sti\n\t" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "#cli\n\t" \ + "jmp 1b\n" \ + "4:\n\t" + +/* + * This works. Despite all the confusion. + * (except on PPro SMP or if we are using OOSTORE) + * (PPro errata 66, 92) + */ + +#define spin_unlock_string \ + "xchgb %b0, %1" \ + :"=q" (oldval), "=m" (lock->slock) \ + :"0" (oldval) : "memory" + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ + char oldval = 1; + __asm__ __volatile__( + spin_unlock_string + ); +} + +static inline int _raw_spin_trylock(spinlock_t *lock) +{ + char oldval; + __asm__ __volatile__( + "xchgb %b0,%1\n" + :"=q" (oldval), "=m" (lock->slock) + :"0" (0) : "memory"); + return oldval > 0; +} + +static inline void _raw_spin_lock(spinlock_t *lock) +{ + __asm__ __volatile__( + spin_lock_string + :"=m" (lock->slock) : : "memory"); +} + +static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) +{ + __asm__ __volatile__( + spin_lock_string_flags + :"=m" (lock->slock) : "r" (flags) : "memory"); +} + +#endif diff -r 066094348f22 -r 0699c3eff7a3 tools/check/check_udev --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/check/check_udev Mon Nov 20 13:11:15 2006 -0700 @@ -0,0 +1,16 @@ +#!/bin/bash +# CHECK-INSTALL + +function error { + echo + echo ' *** Check for udev/hotplug FAILED' + exit 1 +} +[ -x "$(which udevinfo)" ] && \ + UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/') + +if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then + exit 0 +fi + +which hotplug 1>/dev/null 2>&1 || error diff -r 066094348f22 -r 0699c3eff7a3 extras/mini-os/include/x86/spinlock.h --- a/extras/mini-os/include/x86/spinlock.h Mon Nov 20 12:14:40 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -#ifndef __ASM_SPINLOCK_H -#define __ASM_SPINLOCK_H - -#include <lib.h> - -/* - * Your basic SMP spinlocks, allowing only a single CPU anywhere - */ - -typedef struct { - volatile unsigned int slock; -} spinlock_t; - -#define SPINLOCK_MAGIC 0xdead4ead - -#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } - -#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0) - -/* - * Simple spin lock operations. There are two variants, one clears IRQ's - * on the local processor, one does not. - * - * We make no fairness assumptions. They have a cost. - */ - -#define spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0) -#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) - -#define spin_lock_string \ - "1:\n" \ - LOCK \ - "decb %0\n\t" \ - "jns 3f\n" \ - "2:\t" \ - "rep;nop\n\t" \ - "cmpb $0,%0\n\t" \ - "jle 2b\n\t" \ - "jmp 1b\n" \ - "3:\n\t" - -#define spin_lock_string_flags \ - "1:\n" \ - LOCK \ - "decb %0\n\t" \ - "jns 4f\n\t" \ - "2:\t" \ - "testl $0x200, %1\n\t" \ - "jz 3f\n\t" \ - "#sti\n\t" \ - "3:\t" \ - "rep;nop\n\t" \ - "cmpb $0, %0\n\t" \ - "jle 3b\n\t" \ - "#cli\n\t" \ - "jmp 1b\n" \ - "4:\n\t" - -/* - * This works. Despite all the confusion. - * (except on PPro SMP or if we are using OOSTORE) - * (PPro errata 66, 92) - */ - -#define spin_unlock_string \ - "xchgb %b0, %1" \ - :"=q" (oldval), "=m" (lock->slock) \ - :"0" (oldval) : "memory" - -static inline void _raw_spin_unlock(spinlock_t *lock) -{ - char oldval = 1; - __asm__ __volatile__( - spin_unlock_string - ); -} - -static inline int _raw_spin_trylock(spinlock_t *lock) -{ - char oldval; - __asm__ __volatile__( - "xchgb %b0,%1\n" - :"=q" (oldval), "=m" (lock->slock) - :"0" (0) : "memory"); - return oldval > 0; -} - -static inline void _raw_spin_lock(spinlock_t *lock) -{ - __asm__ __volatile__( - spin_lock_string - :"=m" (lock->slock) : : "memory"); -} - -static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) -{ - __asm__ __volatile__( - spin_lock_string_flags - :"=m" (lock->slock) : "r" (flags) : "memory"); -} - -#define _spin_trylock(lock) ({_raw_spin_trylock(lock) ? \ - 1 : ({ 0;});}) - -#define _spin_lock(lock) \ -do { \ - _raw_spin_lock(lock); \ -} while(0) - -#define _spin_unlock(lock) \ -do { \ - _raw_spin_unlock(lock); \ -} while (0) - - -#define spin_lock(lock) _spin_lock(lock) -#define spin_unlock(lock) _spin_unlock(lock) - -#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED - -#endif diff -r 066094348f22 -r 0699c3eff7a3 tools/check/check_hotplug --- a/tools/check/check_hotplug Mon Nov 20 12:14:40 2006 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#!/bin/bash -# CHECK-INSTALL - -function error { - echo - echo ' *** Check for the hotplug scripts (hotplug) FAILED' - exit 1 -} -[ -x "$(which udevinfo)" ] && \ - UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/') - -if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then - exit 0 -fi - -which hotplug 1>/dev/null 2>&1 || error _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |