1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#include <sys/asm_linkage.h> 28#include <sys/hypervisor.h> 29#include <sys/privregs.h> 30#include <sys/segments.h> 31#include <sys/traptrace.h> 32#include <sys/trap.h> 33#include <sys/psw.h> 34#include <sys/x86_archext.h> 35#include <sys/asm_misc.h> 36 37#include "assym.h" 38 39 /* 40 * The stack frame for events is exactly that of an x86 hardware 41 * interrupt. 42 * 43 * The stack frame for a failsafe callback is augmented with saved 44 * values for segment registers: 45 * 46 * i386 47 * %ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss ] 48 * 49 * On amd64 the stack frame for events is exactly that of an hardware 50 * interrupt with the addition of rcx and r11. 51 * 52 * The stack frame for a failsafe callback is augmented with saved 53 * values for segment registers: 54 * 55 * amd64 56 * %rcx, %r11, %ds, %es, %fs, %gs, %rip, %cs, %rflags, 57 * [, %oldrsp, %oldss ] 58 * 59 * The hypervisor does this to allow the guest OS to handle returns 60 * to processes which have bad segment registers. 61 * 62 * [See comments in xen/arch/x86/[x86_64,x86_32]/entry.S] 63 * 64 * We will construct a fully fledged 'struct regs' and call trap 65 * with a #gp fault. 66 */ 67 68 ENTRY(xen_failsafe_callback) 69 70 /* 71 * The saved values of rcx and r11 are on the top of the stack. 72 * pop them and let INTR_PUSH save them. We drop ds, es, fs and 73 * gs since the hypervisor will have already loaded these for us. 74 * If any were bad and faulted the hypervisor would have loaded 75 * them with the null selctor. 76 */ 77 XPV_TRAP_POP /* rcx, r11 */ 78 79 /* 80 * XXPV 81 * If the current segregs are provided for us on the stack by 82 * the hypervisor then we should simply move them into their proper 83 * location in the regs struct? 84 */ 85 addq $_CONST(_MUL(4, CLONGSIZE)), %rsp 86 87 /* 88 * XXPV 89 * It would be nice to somehow figure out which selector caused 90 * #gp fault. 91 */ 92 93 pushq $0 /* dummy error */ 94 pushq $T_GPFLT 95 96 INTR_PUSH 97 INTGATE_INIT_KERNEL_FLAGS 98 99 /* 100 * We're here because HYPERVISOR_IRET to userland failed due to a 101 * bad %cs value. Rewrite %cs, %ss and %rip on the stack so trap 102 * will know to handle this with kern_gpfault and kill the currently 103 * running process. 104 */ 105 movq $KCS_SEL, REGOFF_CS(%rsp) 106 movq $KDS_SEL, REGOFF_SS(%rsp) 107 leaq nopop_sys_rtt_syscall(%rip), %rdi 108 movq %rdi, REGOFF_RIP(%rsp) 109 110 TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_EVENT) /* Uses labels 8 and 9 */ 111 TRACE_REGS(%rdi, %rsp, %rbx, %rcx) /* Uses label 9 */ 112 TRACE_STAMP(%rdi) /* Clobbers %eax, %edx, uses 9 */ 113 114 movq %rsp, %rbp 115 116 TRACE_STACK(%rdi) 117 118 movq %rbp, %rdi 119 120 ENABLE_INTR_FLAGS 121 122 movq %rbp, %rdi 123 xorl %esi, %esi 124 movl %gs:CPU_ID, %edx 125 call trap /* trap(rp, addr, cpuid) handles all trap */ 126 jmp _sys_rtt 127 SET_SIZE(xen_failsafe_callback) 128 129 ENTRY(xen_callback) 130 XPV_TRAP_POP 131 132 pushq $0 /* dummy error */ 133 pushq $T_AST 134 135 INTR_PUSH 136 INTGATE_INIT_KERNEL_FLAGS /* (set kernel flag values) */ 137 138 TRACE_PTR(%rdi, %rbx, %ebx, %rcx, $TT_EVENT) /* Uses labels 8 and 9 */ 139 TRACE_REGS(%rdi, %rsp, %rbx, %rcx) /* Uses label 9 */ 140 TRACE_STAMP(%rdi) /* Clobbers %eax, %edx, uses 9 */ 141 142 movq %rsp, %rbp 143 144 TRACE_STACK(%rdi) 145 146 movq %rdi, %rsi /* rsi = trap trace recode pointer */ 147 movq %rbp, %rdi /* rdi = struct regs pointer */ 148 call xen_callback_handler 149 150 jmp _sys_rtt_ints_disabled 151 /*NOTREACHED*/ 152 153 SET_SIZE(xen_callback) 154