1 /* 2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds 3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> 4 * Copyright (C) 2002 Andi Kleen 5 * 6 * This handles calls from both 32bit and 64bit mode. 7 */ 8 9 #include <linux/errno.h> 10 #include <linux/gfp.h> 11 #include <linux/sched.h> 12 #include <linux/string.h> 13 #include <linux/mm.h> 14 #include <linux/smp.h> 15 #include <linux/vmalloc.h> 16 #include <linux/uaccess.h> 17 18 #include <asm/ldt.h> 19 #include <asm/desc.h> 20 #include <asm/mmu_context.h> 21 #include <asm/syscalls.h> 22 23 int sysctl_ldt16 = 0; 24 25 #ifdef CONFIG_SMP 26 static void flush_ldt(void *current_mm) 27 { 28 if (current->active_mm == current_mm) 29 load_LDT(¤t->active_mm->context); 30 } 31 #endif 32 33 static int alloc_ldt(mm_context_t *pc, int mincount, int reload) 34 { 35 void *oldldt, *newldt; 36 int oldsize; 37 38 if (mincount <= pc->size) 39 return 0; 40 oldsize = pc->size; 41 mincount = (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) & 42 (~(PAGE_SIZE / LDT_ENTRY_SIZE - 1)); 43 if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE) 44 newldt = vmalloc(mincount * LDT_ENTRY_SIZE); 45 else 46 newldt = (void *)__get_free_page(GFP_KERNEL); 47 48 if (!newldt) 49 return -ENOMEM; 50 51 if (oldsize) 52 memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE); 53 oldldt = pc->ldt; 54 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, 55 (mincount - oldsize) * LDT_ENTRY_SIZE); 56 57 paravirt_alloc_ldt(newldt, mincount); 58 59 #ifdef CONFIG_X86_64 60 /* CHECKME: Do we really need this ? */ 61 wmb(); 62 #endif 63 pc->ldt = newldt; 64 wmb(); 65 pc->size = mincount; 66 wmb(); 67 68 if (reload) { 69 #ifdef CONFIG_SMP 70 preempt_disable(); 71 load_LDT(pc); 72 if (!cpumask_equal(mm_cpumask(current->mm), 73 cpumask_of(smp_processor_id()))) 74 smp_call_function(flush_ldt, current->mm, 1); 75 preempt_enable(); 76 #else 77 load_LDT(pc); 78 #endif 79 } 80 if (oldsize) { 81 paravirt_free_ldt(oldldt, oldsize); 82 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) 83 vfree(oldldt); 84 else 85 put_page(virt_to_page(oldldt)); 86 } 87 return 0; 88 } 89 90 static inline int copy_ldt(mm_context_t *new, mm_context_t *old) 91 { 92 int err = alloc_ldt(new, old->size, 0); 93 int i; 94 95 if (err < 0) 96 return err; 97 98 for (i = 0; i < old->size; i++) 99 write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); 100 return 0; 101 } 102 103 /* 104 * we do not have to muck with descriptors here, that is 105 * done in switch_mm() as needed. 106 */ 107 int init_new_context(struct task_struct *tsk, struct mm_struct *mm) 108 { 109 struct mm_struct *old_mm; 110 int retval = 0; 111 112 mutex_init(&mm->context.lock); 113 mm->context.size = 0; 114 old_mm = current->mm; 115 if (old_mm && old_mm->context.size > 0) { 116 mutex_lock(&old_mm->context.lock); 117 retval = copy_ldt(&mm->context, &old_mm->context); 118 mutex_unlock(&old_mm->context.lock); 119 } 120 return retval; 121 } 122 123 /* 124 * No need to lock the MM as we are the last user 125 * 126 * 64bit: Don't touch the LDT register - we're already in the next thread. 127 */ 128 void destroy_context(struct mm_struct *mm) 129 { 130 if (mm->context.size) { 131 #ifdef CONFIG_X86_32 132 /* CHECKME: Can this ever happen ? */ 133 if (mm == current->active_mm) 134 clear_LDT(); 135 #endif 136 paravirt_free_ldt(mm->context.ldt, mm->context.size); 137 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) 138 vfree(mm->context.ldt); 139 else 140 put_page(virt_to_page(mm->context.ldt)); 141 mm->context.size = 0; 142 } 143 } 144 145 static int read_ldt(void __user *ptr, unsigned long bytecount) 146 { 147 int err; 148 unsigned long size; 149 struct mm_struct *mm = current->mm; 150 151 if (!mm->context.size) 152 return 0; 153 if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES) 154 bytecount = LDT_ENTRY_SIZE * LDT_ENTRIES; 155 156 mutex_lock(&mm->context.lock); 157 size = mm->context.size * LDT_ENTRY_SIZE; 158 if (size > bytecount) 159 size = bytecount; 160 161 err = 0; 162 if (copy_to_user(ptr, mm->context.ldt, size)) 163 err = -EFAULT; 164 mutex_unlock(&mm->context.lock); 165 if (err < 0) 166 goto error_return; 167 if (size != bytecount) { 168 /* zero-fill the rest */ 169 if (clear_user(ptr + size, bytecount - size) != 0) { 170 err = -EFAULT; 171 goto error_return; 172 } 173 } 174 return bytecount; 175 error_return: 176 return err; 177 } 178 179 static int read_default_ldt(void __user *ptr, unsigned long bytecount) 180 { 181 /* CHECKME: Can we use _one_ random number ? */ 182 #ifdef CONFIG_X86_32 183 unsigned long size = 5 * sizeof(struct desc_struct); 184 #else 185 unsigned long size = 128; 186 #endif 187 if (bytecount > size) 188 bytecount = size; 189 if (clear_user(ptr, bytecount)) 190 return -EFAULT; 191 return bytecount; 192 } 193 194 static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) 195 { 196 struct mm_struct *mm = current->mm; 197 struct desc_struct ldt; 198 int error; 199 struct user_desc ldt_info; 200 201 error = -EINVAL; 202 if (bytecount != sizeof(ldt_info)) 203 goto out; 204 error = -EFAULT; 205 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) 206 goto out; 207 208 error = -EINVAL; 209 if (ldt_info.entry_number >= LDT_ENTRIES) 210 goto out; 211 if (ldt_info.contents == 3) { 212 if (oldmode) 213 goto out; 214 if (ldt_info.seg_not_present == 0) 215 goto out; 216 } 217 218 mutex_lock(&mm->context.lock); 219 if (ldt_info.entry_number >= mm->context.size) { 220 error = alloc_ldt(¤t->mm->context, 221 ldt_info.entry_number + 1, 1); 222 if (error < 0) 223 goto out_unlock; 224 } 225 226 /* Allow LDTs to be cleared by the user. */ 227 if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { 228 if (oldmode || LDT_empty(&ldt_info)) { 229 memset(&ldt, 0, sizeof(ldt)); 230 goto install; 231 } 232 } 233 234 /* 235 * On x86-64 we do not support 16-bit segments due to 236 * IRET leaking the high bits of the kernel stack address. 237 */ 238 #ifdef CONFIG_X86_64 239 if (!ldt_info.seg_32bit && !sysctl_ldt16) { 240 error = -EINVAL; 241 goto out_unlock; 242 } 243 #endif 244 245 fill_ldt(&ldt, &ldt_info); 246 if (oldmode) 247 ldt.avl = 0; 248 249 /* Install the new entry ... */ 250 install: 251 write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt); 252 error = 0; 253 254 out_unlock: 255 mutex_unlock(&mm->context.lock); 256 out: 257 return error; 258 } 259 260 asmlinkage int sys_modify_ldt(int func, void __user *ptr, 261 unsigned long bytecount) 262 { 263 int ret = -ENOSYS; 264 265 switch (func) { 266 case 0: 267 ret = read_ldt(ptr, bytecount); 268 break; 269 case 1: 270 ret = write_ldt(ptr, bytecount, 1); 271 break; 272 case 2: 273 ret = read_default_ldt(ptr, bytecount); 274 break; 275 case 0x11: 276 ret = write_ldt(ptr, bytecount, 0); 277 break; 278 } 279 return ret; 280 } 281