1 #include <sys/types.h> 2 #include <sys/ioctl.h> 3 #include "qemu-common.h" 4 5 #ifdef CONFIG_KVM_GS_RESTORE 6 7 #define INVALID_GS_REG 0xffff 8 #define KVM_GS_RESTORE_NODETECTED 0x1 9 #define KVM_GS_RESTORE_NO 0x2 10 #define KVM_GS_RESTORE_YES 0x3 11 int initial_gs = INVALID_GS_REG; 12 int gs_need_restore = KVM_GS_RESTORE_NODETECTED; 13 14 static void restoregs(int gs) 15 { 16 asm("movl %0, %%gs"::"r"(gs)); 17 } 18 19 static unsigned int _getgs() 20 { 21 unsigned int gs = 0; 22 asm("movl %%gs,%0" :"=r"(gs):); 23 return gs; 24 } 25 26 /* No fprintf or any system call before the gs is restored successfully */ 27 static void check_and_restore_gs(void) 28 { 29 if (gs_need_restore == KVM_GS_RESTORE_NO) 30 return; 31 32 restoregs(initial_gs); 33 } 34 35 static struct sigaction old_alarm_act, old_gio_act, old_pipe_act,old_usr1_act, old_chld_act; 36 static void temp_sig_handler(int host_signum) 37 { 38 /* !!! must restore gs firstly */ 39 check_and_restore_gs(); 40 switch (host_signum) 41 { 42 case SIGALRM: 43 old_alarm_act.sa_handler(host_signum); 44 break; 45 46 case SIGIO: 47 old_gio_act.sa_handler(host_signum); 48 break; 49 50 case SIGUSR1: 51 old_usr1_act.sa_handler(host_signum); 52 break; 53 54 case SIGPIPE: 55 old_pipe_act.sa_handler(host_signum); 56 break; 57 58 case SIGCHLD: 59 old_chld_act.sa_handler(host_signum); 60 break; 61 62 default: 63 fprintf(stderr, "Not take signal %x!!\n", host_signum); 64 break; 65 } 66 } 67 68 static int sig_taken = 0; 69 static int take_signal_handler(void) 70 { 71 struct sigaction act; 72 int ret; 73 74 if (gs_need_restore == KVM_GS_RESTORE_NO) 75 return 0; 76 if (sig_taken) 77 return 0; 78 79 sig_taken = 1; 80 sigfillset(&act.sa_mask); 81 act.sa_flags = 0; 82 act.sa_handler = temp_sig_handler; 83 /* Did we missed any other signal ? */ 84 sigaction(SIGALRM, &act, &old_alarm_act); 85 sigaction(SIGIO, &act, &old_gio_act); 86 sigaction(SIGUSR1, &act, &old_usr1_act); 87 sigaction(SIGPIPE, &act, &old_pipe_act); 88 act.sa_flags = SA_NOCLDSTOP; 89 sigaction(SIGCHLD, &act, &old_chld_act); 90 return 1; 91 } 92 93 int gs_base_pre_run(void) 94 { 95 if (unlikely(initial_gs == INVALID_GS_REG) ) 96 { 97 initial_gs = _getgs(); 98 /* 99 * As 2.6.35-28 lucid will get correct gs but clobbered GS_BASE 100 * we have to always re-write the gs base 101 */ 102 if (initial_gs == 0x0) 103 gs_need_restore = KVM_GS_RESTORE_NO; 104 else 105 gs_need_restore = KVM_GS_RESTORE_YES; 106 } 107 108 take_signal_handler(); 109 return 0; 110 } 111 112 int gs_base_post_run(void) 113 { 114 check_and_restore_gs(); 115 return 0; 116 } 117 118 /* 119 * ioctl may update errno, which is in thread local storage and 120 * requires gs register, we have to provide our own ioctl 121 * XXX should "call %%gs:$0x10" be replaced with call to vsyscall 122 * page, which is more generic and clean? 123 */ 124 int no_gs_ioctl(int fd, int type, void *arg) 125 { 126 int ret=0; 127 128 asm( 129 "movl %3, %%edx;\n" 130 "movl %2, %%ecx;\n" 131 "movl %1, %%ebx;\n" 132 "movl $0x36, %%eax;\n" 133 "call *%%gs:0x10;\n" 134 "movl %%eax, %0\n" 135 : "=m"(ret) 136 :"m"(fd),"m"(type),"m"(arg) 137 :"%edx","%ecx","%eax","%ebx" 138 ); 139 140 return ret; 141 } 142 143 #endif 144 145