From 9ea03e01a0ef2fa4cf62b7ab4de52d76db979e2a Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Thu, 24 Dec 2015 21:04:27 +0000 Subject: [PATCH] Setup for common PV userspace execution * Implement and use hypercall_stack_switch(). * Implement {read,write}_[cdefgs]s() wrappers. * Use __USER_DS for the regular data segment selectors. Signed-off-by: Andrew Cooper --- arch/x86/pv/traps.c | 11 ++++++ include/arch/x86/lib.h | 79 +++++++++++++++++++++++++++++++++++++++++ include/xtf/hypercall.h | 5 +++ 3 files changed, 95 insertions(+) diff --git a/arch/x86/pv/traps.c b/arch/x86/pv/traps.c index fda8285..3612872 100644 --- a/arch/x86/pv/traps.c +++ b/arch/x86/pv/traps.c @@ -52,10 +52,21 @@ struct xen_trap_info pv_default_trap_info[] = void arch_init_traps(void) { + /* PV equivalent of `lidt`. */ int rc = hypercall_set_trap_table(pv_default_trap_info); if ( rc ) panic("Failed to set trap table: %d\n", rc); + + /* PV equivalent of setting tss.{esp0,ss0}. */ + rc = hypercall_stack_switch(__KERN_DS, &boot_stack[2 * PAGE_SIZE]); + if ( rc ) + panic("Failed to set kernel stack: %d\n", rc); + + write_ds(__USER_DS); + write_es(__USER_DS); + write_fs(__USER_DS); + write_gs(__USER_DS); } void __noreturn arch_crash_hard(void) diff --git a/include/arch/x86/lib.h b/include/arch/x86/lib.h index 458e25f..7951695 100644 --- a/include/arch/x86/lib.h +++ b/include/arch/x86/lib.h @@ -79,6 +79,85 @@ static inline void outl(uint32_t val, uint16_t port) asm volatile("outl %k0, %w1": : "a" (val), "Nd" (port)); } +static inline unsigned int read_cs(void) +{ + unsigned int cs; + + asm volatile ("mov %%cs, %0" : "=r" (cs)); + + return cs; +} + +static inline unsigned int read_ds(void) +{ + unsigned int ds; + + asm volatile ("mov %%ds, %0" : "=r" (ds)); + + return ds; +} + +static inline unsigned int read_es(void) +{ + unsigned int es; + + asm volatile ("mov %%es, %0" : "=r" (es)); + + return es; +} + +static inline unsigned int read_fs(void) +{ + unsigned int fs; + + asm volatile ("mov %%fs, %0" : "=r" (fs)); + + return fs; +} + +static inline unsigned int read_gs(void) +{ + unsigned int gs; + + asm volatile ("mov %%gs, %0" : "=r" (gs)); + + return gs; +} + +static inline unsigned int read_ss(void) +{ + unsigned int ss; + + asm volatile ("mov %%ss, %0" : "=r" (ss)); + + return ss; +} + +static inline void write_ds(unsigned int ds) +{ + asm volatile ("mov %0, %%ds" :: "r" (ds)); +} + +static inline void write_es(unsigned int es) +{ + asm volatile ("mov %0, %%es" :: "r" (es)); +} + +static inline void write_fs(unsigned int fs) +{ + asm volatile ("mov %0, %%fs" :: "r" (fs)); +} + +static inline void write_gs(unsigned int gs) +{ + asm volatile ("mov %0, %%gs" :: "r" (gs)); +} + +static inline void write_ss(unsigned int ss) +{ + asm volatile ("mov %0, %%ss" :: "r" (ss)); +} + static inline unsigned long read_dr6(void) { unsigned long val; diff --git a/include/xtf/hypercall.h b/include/xtf/hypercall.h index 124ff6a..7e3bded 100644 --- a/include/xtf/hypercall.h +++ b/include/xtf/hypercall.h @@ -39,6 +39,11 @@ static inline long hypercall_set_trap_table(const struct xen_trap_info *ti) return HYPERCALL1(long, __HYPERVISOR_set_trap_table, ti); } +static inline long hypercall_stack_switch(const unsigned int ss, const void *sp) +{ + return HYPERCALL2(long, __HYPERVISOR_stack_switch, ss, sp); +} + static inline long hypercall_sched_op(unsigned int cmd, void *arg) { return HYPERCALL2(long, __HYPERVISOR_sched_op, cmd, arg); -- 2.39.5