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)
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;
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);