diff options
-rw-r--r-- | .rootkeys | 7 | ||||
-rw-r--r-- | extras/mini-os/Makefile | 42 | ||||
-rw-r--r-- | extras/mini-os/h/hypervisor.h | 73 | ||||
-rw-r--r-- | extras/mini-os/h/mm.h | 4 | ||||
-rw-r--r-- | extras/mini-os/h/os.h | 160 | ||||
-rw-r--r-- | extras/mini-os/head.S | 18 | ||||
-rw-r--r-- | extras/mini-os/kernel.c | 17 | ||||
-rw-r--r-- | extras/mini-os/lib/math.c | 4 | ||||
-rw-r--r-- | extras/mini-os/minios-x86_32.lds (renamed from extras/mini-os/minios.lds) | 0 | ||||
-rw-r--r-- | extras/mini-os/minios-x86_64.lds | 54 | ||||
-rw-r--r-- | extras/mini-os/traps.c | 157 | ||||
-rw-r--r-- | extras/mini-os/x86_32.S (renamed from extras/mini-os/entry.S) | 24 | ||||
-rw-r--r-- | extras/mini-os/x86_64.S | 78 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/entry.S | 1 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/entry.S | 13 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_32/regs.h | 3 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/regs.h | 3 | ||||
-rw-r--r-- | xen/include/public/arch-x86_64.h | 9 |
19 files changed, 436 insertions, 233 deletions
@@ -25,7 +25,6 @@ 410144afnSd2Yw68AHGO5gXu2m3y6A docs/src/user.tex 3f815144d1vI2777JI-dO4wk49Iw7g extras/mini-os/Makefile 3f815144zTnCV5591ulIJQrpe5b-5Q extras/mini-os/README -3f815144wiiDekmfMl9LIPIvhR83Uw extras/mini-os/entry.S 3f815144r7AHj8GPvc3Nl1L9OSsWIg extras/mini-os/events.c 3f815144h-Chna6E38yo40jqU95G1Q extras/mini-os/h/events.h 3f8151445bYdgThGHQPeOW49PsrJ_A extras/mini-os/h/hypervisor.h @@ -34,17 +33,19 @@ 3f815144nbSjjT1h4m99-QPbeSWY0Q extras/mini-os/h/os.h 3f815144L1t0AevJt2JDXPegv6JTrw extras/mini-os/h/time.h 3f815144UxddtL0ICCKisN-NDHNFaA extras/mini-os/h/types.h -3f815145W2mamPMclRLOzm5B38vWUQ extras/mini-os/head.S 3f815145LqcH11TCEZbAvcjarckkJw extras/mini-os/hypervisor.c 3f815145vwnmxhCwN7dMRWv_XFtXbg extras/mini-os/kernel.c 3f8151451k5emQAlRe80JdIvfSN4VA extras/mini-os/lib/malloc.c 3f815145Mb9WSKjOPsYTLsPIvPyy4Q extras/mini-os/lib/math.c 3f8151454rEuPjN74V2Bcu65RLnM-Q extras/mini-os/lib/printf.c 3f815145MQZrUJV0iRmTK2KIhwB2wg extras/mini-os/lib/string.c -3f815145AYE58Kpmsj5U7oHDpVDZJA extras/mini-os/minios.lds +3f815145AYE58Kpmsj5U7oHDpVDZJA extras/mini-os/minios-x86_32.lds +420c983dKBm6a2-sM04QzaaTy55crw extras/mini-os/minios-x86_64.lds 3f815145CB8XdPUqsmhAjSDFuwOoqA extras/mini-os/mm.c 3f815145vGYx1WY79voKkZB9yKwJKQ extras/mini-os/time.c 3f815145xlKBAQmal9oces3G_Mvxqw extras/mini-os/traps.c +3f815145W2mamPMclRLOzm5B38vWUQ extras/mini-os/x86_32.S +420c983dAE5qEtJMI6wHAQnHVJ1r2g extras/mini-os/x86_64.S 4187ca95_eQN62ugV1zliQcfzXrHnw install.sh 3e5a4e6589G-U42lFKs43plskXoFxQ linux-2.4.29-xen-sparse/Makefile 3e5a4e65IEPjnWPZ5w3TxS5scV8Ewg linux-2.4.29-xen-sparse/arch/xen/Makefile diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index 606454b6bb..56bc7f9e5f 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -2,31 +2,44 @@ CC := gcc LD := ld -# Linker should relocate monitor to this address -MONITOR_BASE := 0xE0100000 +TARGET_ARCH := $(shell uname -m | sed -e s/i.86/x86_32/) # NB. '-Wcast-qual' is nasty, so I omitted it. -CFLAGS := -fno-builtin -O3 -Wall -Ih/ -Wredundant-decls -CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline -ansi +CFLAGS := -fno-builtin -O3 -Wall -Ih/ -Wredundant-decls -Wno-format +CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline + +ifeq ($(TARGET_ARCH),x86_32) +CFLAGS += -m32 -march=i686 +LDFLAGS := -m elf_i386 +endif + +ifeq ($(TARGET_ARCH),x86_64) +CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks +CFLAGS += -fno-asynchronous-unwind-tables +LDFLAGS := -m elf_x86_64 +endif TARGET := mini-os -LOBJS := lib/malloc.o lib/math.o lib/printf.o lib/string.o -OBJS := entry.o kernel.o traps.o hypervisor.o mm.o events.o time.o ${LOBJS} +OBJS := $(TARGET_ARCH).o +OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) +OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c)) -HINTF := h/xen-public/xen.h -HDRS := h/os.h h/types.h h/hypervisor.h h/mm.h h/events.h h/time.h h/lib.h -HDRS += $(HINTF) +OBJS := $(subst events.o,,$(OBJS)) +OBJS := $(subst hypervisor.o,,$(OBJS)) +OBJS := $(subst time.o,,$(OBJS)) + +HDRS := $(wildcard h/*.h) +HDRS += $(wildcard h/xen-public/*.h) default: $(TARGET) xen-public: - [ -e h/xen-public] || ln -sf ../../../xen/include/public h/xen-public + [ -e h/xen-public ] || ln -sf ../../../xen/include/public h/xen-public -$(TARGET): xen-public head.o $(OBJS) - $(LD) -N -T minios.lds head.o $(OBJS) -o $@.elf - objcopy -R .note -R .comment $@.elf $@ - gzip -f -9 -c $@ >$@.gz +$(TARGET): xen-public $(OBJS) + $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf + gzip -f -9 -c $@.elf >$@.gz clean: find . -type f -name '*.o' | xargs rm -f @@ -38,4 +51,3 @@ clean: %.o: %.S $(HDRS) Makefile $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@ - diff --git a/extras/mini-os/h/hypervisor.h b/extras/mini-os/h/hypervisor.h index 3a127e1290..fee36d5b9c 100644 --- a/extras/mini-os/h/hypervisor.h +++ b/extras/mini-os/h/hypervisor.h @@ -36,13 +36,25 @@ void ack_hypervisor_event(unsigned int ev); * Assembler stubs for hyper-calls. */ +#ifdef __i386__ +#define _a1 "b" +#define _a2 "c" +#define _a3 "d" +#define _a4 "S" +#else +#define _a1 "D" +#define _a2 "S" +#define _a3 "d" +#define _a4 "b" +#endif + static __inline__ int HYPERVISOR_set_trap_table(trap_info_t *table) { int ret; __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table), - "b" (table) : "memory" ); + _a1 (table) : "memory" ); return ret; } @@ -55,7 +67,7 @@ static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), - "b" (req), "c" (count), "d" (success_count) : "memory" ); + _a1 (req), _a2 (count), _a3 (success_count) : "memory" ); return ret; } @@ -66,7 +78,7 @@ static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), - "b" (frame_list), "c" (entries) : "memory" ); + _a1 (frame_list), _a2 (entries) : "memory" ); return ret; @@ -78,11 +90,12 @@ static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long es __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_stack_switch), - "b" (ss), "c" (esp) : "memory" ); + _a1 (ss), _a2 (esp) : "memory" ); return ret; } +#ifdef __i386__ static __inline__ int HYPERVISOR_set_callbacks( unsigned long event_selector, unsigned long event_address, unsigned long failsafe_selector, unsigned long failsafe_address) @@ -91,11 +104,27 @@ static __inline__ int HYPERVISOR_set_callbacks( __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), - "b" (event_selector), "c" (event_address), - "d" (failsafe_selector), "S" (failsafe_address) : "memory" ); + _a1 (event_selector), _a2 (event_address), + _a3 (failsafe_selector), _a4 (failsafe_address) : "memory" ); + + return ret; +} +#else +static __inline__ int HYPERVISOR_set_callbacks( + unsigned long event_address, + unsigned long failsafe_address, + unsigned long syscall_address) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), + _a1 (event_address), _a2 (failsafe_address), + _a3 (syscall_address) : "memory" ); return ret; } +#endif static __inline__ int HYPERVISOR_fpu_taskswitch(void) { @@ -113,7 +142,7 @@ static __inline__ int HYPERVISOR_yield(void) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_yield) : "memory" ); + _a1 (SCHEDOP_yield) : "memory" ); return ret; } @@ -124,7 +153,7 @@ static __inline__ int HYPERVISOR_block(void) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_block) : "memory" ); + _a1 (SCHEDOP_block) : "memory" ); return ret; } @@ -135,7 +164,7 @@ static __inline__ int HYPERVISOR_shutdown(void) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) + _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) : "memory" ); return ret; @@ -147,7 +176,7 @@ static __inline__ int HYPERVISOR_reboot(void) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) + _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) : "memory" ); return ret; @@ -160,7 +189,7 @@ static __inline__ int HYPERVISOR_suspend(unsigned long srec) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), + _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), "S" (srec) : "memory" ); return ret; @@ -172,7 +201,7 @@ static __inline__ long HYPERVISOR_set_timer_op(void *timer_arg) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op), - "b" (timer_arg) : "memory" ); + _a1 (timer_arg) : "memory" ); return ret; } @@ -183,7 +212,7 @@ static __inline__ int HYPERVISOR_dom0_op(void *dom0_op) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), - "b" (dom0_op) : "memory" ); + _a1 (dom0_op) : "memory" ); return ret; } @@ -194,7 +223,7 @@ static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), - "b" (reg), "c" (value) : "memory" ); + _a1 (reg), _a2 (value) : "memory" ); return ret; } @@ -205,7 +234,7 @@ static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), - "b" (reg) : "memory" ); + _a1 (reg) : "memory" ); return ret; } @@ -217,7 +246,7 @@ static __inline__ int HYPERVISOR_update_descriptor( __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), - "b" (pa), "c" (word1), "d" (word2) : "memory" ); + _a1 (pa), _a2 (word1), _a3 (word2) : "memory" ); return ret; } @@ -228,7 +257,7 @@ static __inline__ int HYPERVISOR_set_fast_trap(int idx) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap), - "b" (idx) : "memory" ); + _a1 (idx) : "memory" ); return ret; } @@ -239,7 +268,7 @@ static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), - "b" (dom_mem_op) : "memory" ); + _a1 (dom_mem_op) : "memory" ); return ret; } @@ -250,7 +279,7 @@ static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_multicall), - "b" (call_list), "c" (nr_calls) : "memory" ); + _a1 (call_list), _a2 (nr_calls) : "memory" ); return ret; } @@ -262,7 +291,7 @@ static __inline__ int HYPERVISOR_update_va_mapping( __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), - "b" (page_nr), "c" (new_val), "d" (flags) : "memory" ); + _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" ); return ret; } @@ -273,7 +302,7 @@ static __inline__ int HYPERVISOR_xen_version(int cmd) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_xen_version), - "b" (cmd) : "memory" ); + _a1 (cmd) : "memory" ); return ret; } @@ -284,7 +313,7 @@ static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str) __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_console_io), - "b" (cmd), "c" (count), "d" (str) : "memory" ); + _a1 (cmd), _a2 (count), _a3 (str) : "memory" ); return ret; } diff --git a/extras/mini-os/h/mm.h b/extras/mini-os/h/mm.h index e12b56495d..5c6224db28 100644 --- a/extras/mini-os/h/mm.h +++ b/extras/mini-os/h/mm.h @@ -64,7 +64,11 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine) return phys; } +#ifdef __x86_64__ +#define VIRT_START 0xFFFFFFFF00000000UL +#else #define VIRT_START 0xC0000000UL +#endif #define to_phys(x) ((unsigned long)(x)-VIRT_START) #define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START)) diff --git a/extras/mini-os/h/os.h b/extras/mini-os/h/os.h index cf15d92126..6a0447ca39 100644 --- a/extras/mini-os/h/os.h +++ b/extras/mini-os/h/os.h @@ -9,116 +9,108 @@ #define NULL 0 -/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented - a mechanism by which the user can annotate likely branch directions and - expect the blocks to be reordered appropriately. Define __builtin_expect - to nothing for earlier compilers. */ - #if __GNUC__ == 2 && __GNUC_MINOR__ < 96 #define __builtin_expect(x, expected_value) (x) #endif +#define unlikely(x) __builtin_expect((x),0) -/* - * These are the segment descriptors provided for us by the hypervisor. - * For now, these are hardwired -- guest OSes cannot update the GDT - * or LDT. - * - * It shouldn't be hard to support descriptor-table frobbing -- let me - * know if the BSD or XP ports require flexibility here. - */ - +#define smp_processor_id() 0 +#define preempt_disable() ((void)0) +#define preempt_enable() ((void)0) -/* - * these are also defined in xen-public/xen.h but can't be pulled in as - * they are used in start of day assembly. Need to clean up the .h files - * a bit more... - */ +#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0)) -#ifndef FLAT_RING1_CS -#define FLAT_RING1_CS 0x0819 -#define FLAT_RING1_DS 0x0821 -#define FLAT_RING3_CS 0x082b -#define FLAT_RING3_DS 0x0833 +#ifndef __ASSEMBLY__ +#include <types.h> #endif +#include <xen-public/xen.h> -#define __KERNEL_CS FLAT_RING1_CS -#define __KERNEL_DS FLAT_RING1_DS +#define __KERNEL_CS FLAT_KERNEL_CS +#define __KERNEL_DS FLAT_KERNEL_DS +#define __KERNEL_SS FLAT_KERNEL_SS /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ -#include <types.h> -#include <xen-public/xen.h> +#define pt_regs xen_regs - -/* this struct defines the way the registers are stored on the - stack during an exception or interrupt. */ -struct pt_regs { - long ebx; - long ecx; - long edx; - long esi; - long edi; - long ebp; - long eax; - int xds; - int xes; - long orig_eax; - long eip; - int xcs; - long eflags; - long esp; - int xss; -}; - -/* some function prototypes */ void trap_init(void); void dump_regs(struct pt_regs *regs); - -/* - * STI/CLI equivalents. These basically set and clear the virtual - * event_enable flag in teh shared_info structure. Note that when - * the enable bit is set, there may be pending events to be handled. - * We may therefore call into do_hypervisor_callback() directly. +/* + * The use of 'barrier' in the following reflects their use as local-lock + * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following + * critical operations are executed. All critical operations must complete + * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also + * includes these barriers, for example. */ -#define unlikely(x) __builtin_expect((x),0) -#define __save_flags(x) \ -do { \ - (x) = test_bit(EVENTS_MASTER_ENABLE_BIT, \ - &HYPERVISOR_shared_info->events_mask); \ - barrier(); \ + +#define __cli() \ +do { \ + vcpu_info_t *_vcpu; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu->evtchn_upcall_mask = 1; \ + preempt_enable_no_resched(); \ + barrier(); \ +} while (0) + +#define __sti() \ +do { \ + vcpu_info_t *_vcpu; \ + barrier(); \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + _vcpu->evtchn_upcall_mask = 0; \ + barrier(); /* unmask then check (avoid races) */ \ + if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ + force_evtchn_callback(); \ + preempt_enable(); \ } while (0) -#define __restore_flags(x) \ -do { \ - shared_info_t *_shared = HYPERVISOR_shared_info; \ - if (x) set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \ - barrier(); \ - if ( unlikely(_shared->events) && (x) ) do_hypervisor_callback(NULL); \ +#define __save_flags(x) \ +do { \ + vcpu_info_t *_vcpu; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + (x) = _vcpu->evtchn_upcall_mask; \ } while (0) -#define __cli() \ -do { \ - clear_bit(EVENTS_MASTER_ENABLE_BIT, &HYPERVISOR_shared_info->events_mask);\ - barrier(); \ +#define __restore_flags(x) \ +do { \ + vcpu_info_t *_vcpu; \ + barrier(); \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ + barrier(); /* unmask then check (avoid races) */ \ + if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ + force_evtchn_callback(); \ + preempt_enable(); \ + } else \ + preempt_enable_no_resched(); \ } while (0) -#define __sti() \ -do { \ - shared_info_t *_shared = HYPERVISOR_shared_info; \ - set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \ - barrier(); \ - if ( unlikely(_shared->events) ) do_hypervisor_callback(NULL); \ +#define safe_halt() ((void)0) + +#define __save_and_cli(x) \ +do { \ + vcpu_info_t *_vcpu; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + (x) = _vcpu->evtchn_upcall_mask; \ + _vcpu->evtchn_upcall_mask = 1; \ + preempt_enable_no_resched(); \ + barrier(); \ } while (0) -#define cli() __cli() -#define sti() __sti() -#define save_flags(x) __save_flags(x) -#define restore_flags(x) __restore_flags(x) -#define save_and_cli(x) __save_and_cli(x) -#define save_and_sti(x) __save_and_sti(x) +#define local_irq_save(x) __save_and_cli(x) +#define local_irq_restore(x) __restore_flags(x) +#define local_save_flags(x) __save_flags(x) +#define local_irq_disable() __cli() +#define local_irq_enable() __sti() +#define irqs_disabled() \ + HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask /* This is a barrier for the compiler only, NOT the processor! */ #define barrier() __asm__ __volatile__("": : :"memory") diff --git a/extras/mini-os/head.S b/extras/mini-os/head.S deleted file mode 100644 index 52eae8f818..0000000000 --- a/extras/mini-os/head.S +++ /dev/null @@ -1,18 +0,0 @@ -#include <os.h> - -.globl _start, shared_info - -_start: - cld - lss stack_start,%esp - push %esi - call start_kernel - -stack_start: - .long stack+8192, __KERNEL_DS - - /* Unpleasant -- the PTE that maps this page is actually overwritten */ - /* to map the real shared-info page! :-) */ - .org 0x1000 -shared_info: - .org 0x2000 diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index a9f423c192..a794145e68 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -64,8 +64,8 @@ extern char shared_info[PAGE_SIZE]; static shared_info_t *map_shared_info(unsigned long pa) { - if ( HYPERVISOR_update_va_mapping((unsigned long)shared_info >> PAGE_SHIFT, - pa | 3, UVMF_INVLPG) ) + if ( HYPERVISOR_update_va_mapping( + (unsigned long)shared_info, pa | 3, UVMF_INVLPG) ) { printk("Failed to map shared_info!!\n"); *(int*)0=0; @@ -79,6 +79,9 @@ static shared_info_t *map_shared_info(unsigned long pa) */ void start_kernel(start_info_t *si) { + static char hello[] = "Bootstrapping...\n"; + (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello); + /* Copy the start_info struct to a globally-accessible area. */ memcpy(&start_info, si, sizeof(*si)); @@ -86,9 +89,15 @@ void start_kernel(start_info_t *si) HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); /* Set up event and failsafe callback addresses. */ +#ifdef __i386__ HYPERVISOR_set_callbacks( __KERNEL_CS, (unsigned long)hypervisor_callback, __KERNEL_CS, (unsigned long)failsafe_callback); +#else + HYPERVISOR_set_callbacks( + (unsigned long)hypervisor_callback, + (unsigned long)failsafe_callback, 0); +#endif trap_init(); @@ -117,7 +126,7 @@ void start_kernel(start_info_t *si) init_mm(); /* set up events */ - init_events(); +// init_events(); /* * These need to be replaced with event-channel/control-interface @@ -135,7 +144,7 @@ void start_kernel(start_info_t *si) #endif /* init time and timers */ - init_time(); +// init_time(); /* do nothing */ for ( ; ; ) HYPERVISOR_yield(); diff --git a/extras/mini-os/lib/math.c b/extras/mini-os/lib/math.c index be08740965..8e97be6d18 100644 --- a/extras/mini-os/lib/math.c +++ b/extras/mini-os/lib/math.c @@ -96,14 +96,14 @@ union uu { * (sizeof(long)*CHAR_BIT/2). */ #define HHALF(x) ((x) >> HALF_BITS) -#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1)) +#define LHALF(x) ((x) & ((1UL << HALF_BITS) - 1)) #define LHUP(x) ((x) << HALF_BITS) /* * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed), * section 4.3.1, pp. 257--259. */ -#define B (1 << HALF_BITS) /* digit base */ +#define B (1UL << HALF_BITS) /* digit base */ /* Combine two `digits' to make a single two-digit number. */ #define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b)) diff --git a/extras/mini-os/minios.lds b/extras/mini-os/minios-x86_32.lds index a53504e9a2..a53504e9a2 100644 --- a/extras/mini-os/minios.lds +++ b/extras/mini-os/minios-x86_32.lds diff --git a/extras/mini-os/minios-x86_64.lds b/extras/mini-os/minios-x86_64.lds new file mode 100644 index 0000000000..71b61131b8 --- /dev/null +++ b/extras/mini-os/minios-x86_64.lds @@ -0,0 +1,54 @@ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SECTIONS +{ + . = 0xFFFFFFFF00000000; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.gnu.warning) + } = 0x9090 + + _etext = .; /* End of text section */ + + .rodata : { *(.rodata) *(.rodata.*) } + + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c index c0ef335025..858c54d3f2 100644 --- a/extras/mini-os/traps.c +++ b/extras/mini-os/traps.c @@ -33,38 +33,38 @@ extern void do_exit(void); void dump_regs(struct pt_regs *regs) { - int in_kernel = 1; - unsigned long esp; - unsigned short ss; - - esp = (unsigned long) (®s->esp); - ss = __KERNEL_DS; - if (regs->xcs & 2) { - in_kernel = 0; - esp = regs->esp; - ss = regs->xss & 0xffff; - } - printf("EIP: %04x:[<%08lx>]\n", - 0xffff & regs->xcs, regs->eip); - printf("EFLAGS: %08lx\n",regs->eflags); - printf("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", - regs->eax, regs->ebx, regs->ecx, regs->edx); - printf("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", - regs->esi, regs->edi, regs->ebp, esp); - printf("ds: %04x es: %04x ss: %04x\n", - regs->xds & 0xffff, regs->xes & 0xffff, ss); - printf("\n"); + int in_kernel = 1; + unsigned long esp; + unsigned short ss; + + esp = (unsigned long) (®s->esp); + ss = __KERNEL_DS; + if (regs->cs & 2) { + in_kernel = 0; + esp = regs->esp; + ss = regs->ss & 0xffff; + } + printf("EIP: %04x:[<%p>]\n", + 0xffff & regs->cs , regs->eip); + printf("EFLAGS: %p\n",regs->eflags); + printf("eax: %p ebx: %p ecx: %p edx: %p\n", + regs->eax, regs->ebx, regs->ecx, regs->edx); + printf("esi: %p edi: %p ebp: %p esp: %p\n", + regs->esi, regs->edi, regs->ebp, esp); + printf("ds: %04x es: %04x ss: %04x\n", + regs->ds & 0xffff, regs->es & 0xffff, ss); + printf("\n"); } -static __inline__ void dump_code(unsigned eip) +static __inline__ void dump_code(unsigned long eip) { - unsigned *ptr = (unsigned *)eip; - int x; - - printk("Bytes at eip:\n"); - for (x = -4; x < 5; x++) - printf("%x", ptr[x]); + unsigned *ptr = (unsigned *)eip; + int x; + + printk("Bytes at eip:\n"); + for (x = -4; x < 5; x++) + printf("%p", ptr[x]); } @@ -81,14 +81,14 @@ static __inline__ void dump_code(unsigned eip) */ static void __inline__ do_trap(int trapnr, char *str, - struct pt_regs * regs, long error_code) + struct pt_regs * regs, long error_code) { - printk("FATAL: Unhandled Trap (see mini-os:traps.c)"); - printf("%d %s", trapnr, str); - dump_regs(regs); - dump_code(regs->eip); + printk("FATAL: Unhandled Trap (see mini-os:traps.c)"); + printf("%d %s", trapnr, str); + dump_regs(regs); + dump_code(regs->eip); - do_exit(); + do_exit(); } #define DO_ERROR(trapnr, str, name) \ @@ -104,38 +104,36 @@ void do_##name(struct pt_regs * regs, long error_code) \ } DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip) -DO_ERROR( 3, "int3", int3) -DO_ERROR( 4, "overflow", overflow) -DO_ERROR( 5, "bounds", bounds) -DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) -DO_ERROR( 7, "device not available", device_not_available) -DO_ERROR( 8, "double fault", double_fault) -DO_ERROR( 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_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) -DO_ERROR(18, "machine check", machine_check) - -void do_page_fault(struct pt_regs *regs, long error_code, - unsigned long address) + DO_ERROR( 3, "int3", int3) + DO_ERROR( 4, "overflow", overflow) + DO_ERROR( 5, "bounds", bounds) + DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) + DO_ERROR( 7, "device not available", device_not_available) + DO_ERROR( 8, "double fault", double_fault) + DO_ERROR( 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_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) + DO_ERROR(18, "machine check", machine_check) + + void do_page_fault(struct pt_regs *regs, long error_code, + unsigned long address) { printk("Page fault\n"); - printk("Address: 0x%lx", address); - printk("Error Code: 0x%lx", error_code); - printk("eip: \t 0x%lx", regs->eip); + printk("Address: 0x%p", address); + printk("Error Code: 0x%p", error_code); + printk("eip: \t 0x%p", regs->eip); do_exit(); } void do_general_protection(struct pt_regs * regs, long error_code) { - - HYPERVISOR_shared_info->events_mask = 0; - printk("GPF\n"); - printk("Error Code: 0x%lx", error_code); - dump_regs(regs); - dump_code(regs->eip); - do_exit(); + printk("GPF\n"); + printk("Error Code: 0x%p", error_code); + dump_regs(regs); + dump_code(regs->eip); + do_exit(); } @@ -180,26 +178,29 @@ void do_spurious_interrupt_bug(struct pt_regs * regs, * The 'privilege ring' field specifies the least-privileged ring that * can trap to that vector using a software-interrupt instruction (INT). */ +#ifdef __x86_64__ +#define _P 0, +#endif static trap_info_t trap_table[] = { - { 0, 0, __KERNEL_CS, (unsigned long)divide_error }, - { 1, 0, __KERNEL_CS, (unsigned long)debug }, - { 3, 3, __KERNEL_CS, (unsigned long)int3 }, - { 4, 3, __KERNEL_CS, (unsigned long)overflow }, - { 5, 3, __KERNEL_CS, (unsigned long)bounds }, - { 6, 0, __KERNEL_CS, (unsigned long)invalid_op }, - { 7, 0, __KERNEL_CS, (unsigned long)device_not_available }, - { 8, 0, __KERNEL_CS, (unsigned long)double_fault }, - { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun }, - { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS }, - { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present }, - { 12, 0, __KERNEL_CS, (unsigned long)stack_segment }, - { 13, 0, __KERNEL_CS, (unsigned long)general_protection }, - { 14, 0, __KERNEL_CS, (unsigned long)page_fault }, - { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug }, - { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error }, - { 17, 0, __KERNEL_CS, (unsigned long)alignment_check }, - { 18, 0, __KERNEL_CS, (unsigned long)machine_check }, - { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error }, + { 0, 0, __KERNEL_CS, _P (unsigned long)divide_error }, + { 1, 0, __KERNEL_CS, _P (unsigned long)debug }, + { 3, 3, __KERNEL_CS, _P (unsigned long)int3 }, + { 4, 3, __KERNEL_CS, _P (unsigned long)overflow }, + { 5, 3, __KERNEL_CS, _P (unsigned long)bounds }, + { 6, 0, __KERNEL_CS, _P (unsigned long)invalid_op }, + { 7, 0, __KERNEL_CS, _P (unsigned long)device_not_available }, + { 8, 0, __KERNEL_CS, _P (unsigned long)double_fault }, + { 9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun }, + { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS }, + { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present }, + { 12, 0, __KERNEL_CS, _P (unsigned long)stack_segment }, + { 13, 0, __KERNEL_CS, _P (unsigned long)general_protection }, + { 14, 0, __KERNEL_CS, _P (unsigned long)page_fault }, + { 15, 0, __KERNEL_CS, _P (unsigned long)spurious_interrupt_bug }, + { 16, 0, __KERNEL_CS, _P (unsigned long)coprocessor_error }, + { 17, 0, __KERNEL_CS, _P (unsigned long)alignment_check }, + { 18, 0, __KERNEL_CS, _P (unsigned long)machine_check }, + { 19, 0, __KERNEL_CS, _P (unsigned long)simd_coprocessor_error }, { 0, 0, 0, 0 } }; diff --git a/extras/mini-os/entry.S b/extras/mini-os/x86_32.S index 8565caf745..d193b121bd 100644 --- a/extras/mini-os/entry.S +++ b/extras/mini-os/x86_32.S @@ -1,6 +1,26 @@ - #include <os.h> +.section __xen_guest + .asciz "XEN_VER=2.0,LOADER=generic,PT_MODE_WRITABLE" +.text + +.globl _start, shared_info + +_start: + cld + lss stack_start,%esp + push %esi + call start_kernel + +stack_start: + .long stack+8192, __KERNEL_SS + + /* Unpleasant -- the PTE that maps this page is actually overwritten */ + /* to map the real shared-info page! :-) */ + .org 0x1000 +shared_info: + .org 0x2000 + ES = 0x20 ORIG_EAX = 0x24 EIP = 0x28 @@ -92,7 +112,7 @@ ENTRY(hypervisor_callback) cmpl $ecrit,%eax jb critical_region_fixup 11: push %esp - call do_hypervisor_callback +# call do_hypervisor_callback add $4,%esp movl HYPERVISOR_shared_info,%esi xorl %eax,%eax diff --git a/extras/mini-os/x86_64.S b/extras/mini-os/x86_64.S new file mode 100644 index 0000000000..4a4708ddd5 --- /dev/null +++ b/extras/mini-os/x86_64.S @@ -0,0 +1,78 @@ +#include <os.h> + +.section __xen_guest + .asciz "XEN_VER=2.0,LOADER=generic,PT_MODE_WRITABLE" +.text + +#define ENTRY(X) .globl X ; X : +.globl _start, shared_info + +_start: + cld + movq stack_start(%rip),%rsp + movq %rsi,%rdi + call start_kernel + +stack_start: + .quad stack+8192 + + /* Unpleasant -- the PTE that maps this page is actually overwritten */ + /* to map the real shared-info page! :-) */ + .org 0x1000 +shared_info: + .org 0x2000 + +ENTRY(hypervisor_callback) + +ENTRY(failsafe_callback) + iret + +ENTRY(divide_error) + pushq $0 + +ENTRY(coprocessor_error) + pushq $0 + +ENTRY(simd_coprocessor_error) + pushq $0 + +ENTRY(device_not_available) + iret + +ENTRY(debug) + pushq $0 + +ENTRY(int3) + pushq $0 + +ENTRY(overflow) + pushq $0 + +ENTRY(bounds) + pushq $0 + +ENTRY(invalid_op) + pushq $0 + +ENTRY(coprocessor_segment_overrun) + pushq $0 + +ENTRY(double_fault) + +ENTRY(invalid_TSS) + +ENTRY(segment_not_present) + +ENTRY(stack_segment) + +ENTRY(general_protection) + +ENTRY(alignment_check) + +ENTRY(page_fault) + +ENTRY(machine_check) + pushq $0 + +ENTRY(spurious_interrupt_bug) + pushq $0 diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 53ff190ea8..886e917d03 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -510,7 +510,7 @@ asmlinkage int do_general_protection(struct xen_regs *regs) { /* This fault must be due to <INT n> instruction. */ ti = current->arch.traps + (regs->error_code>>3); - if ( TI_GET_DPL(ti) >= (VM86_MODE(regs) ? 3 : (regs->cs & 3)) ) + if ( PERMIT_SOFTINT(TI_GET_DPL(ti), ed, regs) ) { tb->flags = TBF_EXCEPTION; regs->eip += 2; diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 3e33befc79..68a860eb6d 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -256,6 +256,7 @@ FIX6: pushl %ebx orb $TF_failsafe_return,EDOMAIN_thread_flags(%ebx) pop %ebx jmp FIX5 +.previous .section __pre_ex_table,"a" .long FLT6,FIX6 .previous diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 411bb8dcd8..03301855ec 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -85,6 +85,7 @@ FIX2: pushq %rbx orb $TF_failsafe_return,EDOMAIN_thread_flags(%rbx) popq %rbx jmp FIX1 +.previous .section __pre_ex_table,"a" .quad FLT2,FIX2 .previous @@ -287,8 +288,11 @@ error_code: movq %rsp,%rdi movl XREGS_entry_vector(%rsp),%eax leaq SYMBOL_NAME(exception_table)(%rip),%rdx + GET_CURRENT(%rbx) callq *(%rdx,%rax,8) - jmp restore_all_xen + testb $3,XREGS_cs(%rsp) + jz restore_all_xen + jmp process_guest_exception_and_events exception_with_ints_disabled: testb $3,XREGS_cs(%rsp) # interrupts disabled outside Xen? @@ -299,12 +303,15 @@ exception_with_ints_disabled: testq %rax,%rax # no fixup code for faulting EIP? jz FATAL_exception_with_ints_disabled movq %rax,XREGS_rip(%rsp) + subq $8,XREGS_rsp(%rsp) # add ec/ev to previous stack frame + testb $15,XREGS_rsp(%rsp) # return %rsp is now aligned? + jz 1f # then there is a pad quadword already movq %rsp,%rsi subq $8,%rsp movq %rsp,%rdi movq $XREGS_kernel_sizeof/8,%rcx - rep; movsq # make room for error_code/entry_vector - movq XREGS_error_code(%rsp),%rax # error_code/entry_vector + rep; movsq # make room for ec/ev +1: movq XREGS_error_code(%rsp),%rax # ec/ev movq %rax,XREGS_kernel_sizeof(%rsp) jmp restore_all_xen # return to fixup code diff --git a/xen/include/asm-x86/x86_32/regs.h b/xen/include/asm-x86/x86_32/regs.h index 06991d4cc7..865a385b94 100644 --- a/xen/include/asm-x86/x86_32/regs.h +++ b/xen/include/asm-x86/x86_32/regs.h @@ -12,4 +12,7 @@ #define KERNEL_MODE(_e, _r) (!VM86_MODE(_r) && RING_1(_r)) +#define PERMIT_SOFTINT(_dpl, _e, _r) \ + ((_dpl) >= (VM86_MODE(_r) ? 3 : ((_r)->cs & 3))) + #endif diff --git a/xen/include/asm-x86/x86_64/regs.h b/xen/include/asm-x86/x86_64/regs.h index 5045c29cf1..355e0fa321 100644 --- a/xen/include/asm-x86/x86_64/regs.h +++ b/xen/include/asm-x86/x86_64/regs.h @@ -12,4 +12,7 @@ #define KERNEL_MODE(_e, _r) ((_e)->arch.flags & TF_kernel_mode) +#define PERMIT_SOFTINT(_dpl, _e, _r) \ + ((_dpl) >= (KERNEL_MODE(_e, _r) ? 1 : 3)) + #endif diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index aba053181e..21299c974c 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -115,7 +115,14 @@ typedef unsigned long memory_t; /* Full-sized pointer/address/memory-size. */ typedef unsigned long cpureg_t; /* Full-sized register. */ /* - * Send an array of these to HYPERVISOR_set_trap_table() + * Send an array of these to HYPERVISOR_set_trap_table(). + * N.B. As in x86/32 mode, the privilege level specifies which modes may enter + * a trap via a software interrupt. Since rings 1 and 2 are unavailable, we + * allocate privilege levels as follows: + * Level == 0: Noone may enter + * Level == 1: Kernel may enter + * Level == 2: Kernel may enter + * Level == 3: Everyone may enter */ #define TI_GET_DPL(_ti) ((_ti)->flags & 3) #define TI_GET_IF(_ti) ((_ti)->flags & 4) |