15c48b108SAl Viro /* 25c48b108SAl Viro * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 35c48b108SAl Viro * Licensed under the GPL 45c48b108SAl Viro */ 55c48b108SAl Viro 65c48b108SAl Viro #include <linux/mm.h> 75c48b108SAl Viro #include <linux/sched.h> 85c48b108SAl Viro #include <linux/slab.h> 9da20ab35SDave Hansen #include <linux/syscalls.h> 101d04c8d7SRichard Weinberger #include <linux/uaccess.h> 115c48b108SAl Viro #include <asm/unistd.h> 1237185b33SAl Viro #include <os.h> 1337185b33SAl Viro #include <skas.h> 1437185b33SAl Viro #include <sysdep/tls.h> 155c48b108SAl Viro 1637e81a01SHans-Werner Hilse static inline int modify_ldt (int func, void *ptr, unsigned long bytecount) 1737e81a01SHans-Werner Hilse { 1837e81a01SHans-Werner Hilse return syscall(__NR_modify_ldt, func, ptr, bytecount); 1937e81a01SHans-Werner Hilse } 205c48b108SAl Viro 215c48b108SAl Viro static long write_ldt_entry(struct mm_id *mm_idp, int func, 225c48b108SAl Viro struct user_desc *desc, void **addr, int done) 235c48b108SAl Viro { 245c48b108SAl Viro long res; 255c48b108SAl Viro void *stub_addr; 265c48b108SAl Viro res = syscall_stub_data(mm_idp, (unsigned long *)desc, 275c48b108SAl Viro (sizeof(*desc) + sizeof(long) - 1) & 285c48b108SAl Viro ~(sizeof(long) - 1), 295c48b108SAl Viro addr, &stub_addr); 305c48b108SAl Viro if (!res) { 315c48b108SAl Viro unsigned long args[] = { func, 325c48b108SAl Viro (unsigned long)stub_addr, 335c48b108SAl Viro sizeof(*desc), 345c48b108SAl Viro 0, 0, 0 }; 355c48b108SAl Viro res = run_syscall_stub(mm_idp, __NR_modify_ldt, args, 365c48b108SAl Viro 0, addr, done); 375c48b108SAl Viro } 385c48b108SAl Viro 395c48b108SAl Viro return res; 405c48b108SAl Viro } 415c48b108SAl Viro 425c48b108SAl Viro /* 435c48b108SAl Viro * In skas mode, we hold our own ldt data in UML. 445c48b108SAl Viro * Thus, the code implementing sys_modify_ldt_skas 455c48b108SAl Viro * is very similar to (and mostly stolen from) sys_modify_ldt 465c48b108SAl Viro * for arch/i386/kernel/ldt.c 475c48b108SAl Viro * The routines copied and modified in part are: 485c48b108SAl Viro * - read_ldt 495c48b108SAl Viro * - read_default_ldt 505c48b108SAl Viro * - write_ldt 515c48b108SAl Viro * - sys_modify_ldt_skas 525c48b108SAl Viro */ 535c48b108SAl Viro 545c48b108SAl Viro static int read_ldt(void __user * ptr, unsigned long bytecount) 555c48b108SAl Viro { 565c48b108SAl Viro int i, err = 0; 575c48b108SAl Viro unsigned long size; 58b3ee571eSAl Viro uml_ldt_t *ldt = ¤t->mm->context.arch.ldt; 595c48b108SAl Viro 605c48b108SAl Viro if (!ldt->entry_count) 615c48b108SAl Viro goto out; 625c48b108SAl Viro if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) 635c48b108SAl Viro bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; 645c48b108SAl Viro err = bytecount; 655c48b108SAl Viro 665c48b108SAl Viro mutex_lock(&ldt->lock); 675c48b108SAl Viro if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { 685c48b108SAl Viro size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; 695c48b108SAl Viro if (size > bytecount) 705c48b108SAl Viro size = bytecount; 715c48b108SAl Viro if (copy_to_user(ptr, ldt->u.entries, size)) 725c48b108SAl Viro err = -EFAULT; 735c48b108SAl Viro bytecount -= size; 745c48b108SAl Viro ptr += size; 755c48b108SAl Viro } 765c48b108SAl Viro else { 775c48b108SAl Viro for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; 785c48b108SAl Viro i++) { 795c48b108SAl Viro size = PAGE_SIZE; 805c48b108SAl Viro if (size > bytecount) 815c48b108SAl Viro size = bytecount; 825c48b108SAl Viro if (copy_to_user(ptr, ldt->u.pages[i], size)) { 835c48b108SAl Viro err = -EFAULT; 845c48b108SAl Viro break; 855c48b108SAl Viro } 865c48b108SAl Viro bytecount -= size; 875c48b108SAl Viro ptr += size; 885c48b108SAl Viro } 895c48b108SAl Viro } 905c48b108SAl Viro mutex_unlock(&ldt->lock); 915c48b108SAl Viro 925c48b108SAl Viro if (bytecount == 0 || err == -EFAULT) 935c48b108SAl Viro goto out; 945c48b108SAl Viro 955c48b108SAl Viro if (clear_user(ptr, bytecount)) 965c48b108SAl Viro err = -EFAULT; 975c48b108SAl Viro 985c48b108SAl Viro out: 995c48b108SAl Viro return err; 1005c48b108SAl Viro } 1015c48b108SAl Viro 1025c48b108SAl Viro static int read_default_ldt(void __user * ptr, unsigned long bytecount) 1035c48b108SAl Viro { 1045c48b108SAl Viro int err; 1055c48b108SAl Viro 1065c48b108SAl Viro if (bytecount > 5*LDT_ENTRY_SIZE) 1075c48b108SAl Viro bytecount = 5*LDT_ENTRY_SIZE; 1085c48b108SAl Viro 1095c48b108SAl Viro err = bytecount; 1105c48b108SAl Viro /* 1115c48b108SAl Viro * UML doesn't support lcall7 and lcall27. 1125c48b108SAl Viro * So, we don't really have a default ldt, but emulate 1135c48b108SAl Viro * an empty ldt of common host default ldt size. 1145c48b108SAl Viro */ 1155c48b108SAl Viro if (clear_user(ptr, bytecount)) 1165c48b108SAl Viro err = -EFAULT; 1175c48b108SAl Viro 1185c48b108SAl Viro return err; 1195c48b108SAl Viro } 1205c48b108SAl Viro 1215c48b108SAl Viro static int write_ldt(void __user * ptr, unsigned long bytecount, int func) 1225c48b108SAl Viro { 123b3ee571eSAl Viro uml_ldt_t *ldt = ¤t->mm->context.arch.ldt; 1245c48b108SAl Viro struct mm_id * mm_idp = ¤t->mm->context.id; 1255c48b108SAl Viro int i, err; 1265c48b108SAl Viro struct user_desc ldt_info; 1275c48b108SAl Viro struct ldt_entry entry0, *ldt_p; 1285c48b108SAl Viro void *addr = NULL; 1295c48b108SAl Viro 1305c48b108SAl Viro err = -EINVAL; 1315c48b108SAl Viro if (bytecount != sizeof(ldt_info)) 1325c48b108SAl Viro goto out; 1335c48b108SAl Viro err = -EFAULT; 1345c48b108SAl Viro if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) 1355c48b108SAl Viro goto out; 1365c48b108SAl Viro 1375c48b108SAl Viro err = -EINVAL; 1385c48b108SAl Viro if (ldt_info.entry_number >= LDT_ENTRIES) 1395c48b108SAl Viro goto out; 1405c48b108SAl Viro if (ldt_info.contents == 3) { 1415c48b108SAl Viro if (func == 1) 1425c48b108SAl Viro goto out; 1435c48b108SAl Viro if (ldt_info.seg_not_present == 0) 1445c48b108SAl Viro goto out; 1455c48b108SAl Viro } 1465c48b108SAl Viro 1475c48b108SAl Viro mutex_lock(&ldt->lock); 1485c48b108SAl Viro 1495c48b108SAl Viro err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); 1505c48b108SAl Viro if (err) 1515c48b108SAl Viro goto out_unlock; 1525c48b108SAl Viro 1535c48b108SAl Viro if (ldt_info.entry_number >= ldt->entry_count && 1545c48b108SAl Viro ldt_info.entry_number >= LDT_DIRECT_ENTRIES) { 1555c48b108SAl Viro for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; 1565c48b108SAl Viro i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; 1575c48b108SAl Viro i++) { 1585c48b108SAl Viro if (i == 0) 1595c48b108SAl Viro memcpy(&entry0, ldt->u.entries, 1605c48b108SAl Viro sizeof(entry0)); 1615c48b108SAl Viro ldt->u.pages[i] = (struct ldt_entry *) 1625c48b108SAl Viro __get_free_page(GFP_KERNEL|__GFP_ZERO); 1635c48b108SAl Viro if (!ldt->u.pages[i]) { 1645c48b108SAl Viro err = -ENOMEM; 1655c48b108SAl Viro /* Undo the change in host */ 1665c48b108SAl Viro memset(&ldt_info, 0, sizeof(ldt_info)); 1675c48b108SAl Viro write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); 1685c48b108SAl Viro goto out_unlock; 1695c48b108SAl Viro } 1705c48b108SAl Viro if (i == 0) { 1715c48b108SAl Viro memcpy(ldt->u.pages[0], &entry0, 1725c48b108SAl Viro sizeof(entry0)); 1735c48b108SAl Viro memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, 1745c48b108SAl Viro sizeof(entry0)*(LDT_DIRECT_ENTRIES-1)); 1755c48b108SAl Viro } 1765c48b108SAl Viro ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; 1775c48b108SAl Viro } 1785c48b108SAl Viro } 1795c48b108SAl Viro if (ldt->entry_count <= ldt_info.entry_number) 1805c48b108SAl Viro ldt->entry_count = ldt_info.entry_number + 1; 1815c48b108SAl Viro 1825c48b108SAl Viro if (ldt->entry_count <= LDT_DIRECT_ENTRIES) 1835c48b108SAl Viro ldt_p = ldt->u.entries + ldt_info.entry_number; 1845c48b108SAl Viro else 1855c48b108SAl Viro ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + 1865c48b108SAl Viro ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; 1875c48b108SAl Viro 1885c48b108SAl Viro if (ldt_info.base_addr == 0 && ldt_info.limit == 0 && 1895c48b108SAl Viro (func == 1 || LDT_empty(&ldt_info))) { 1905c48b108SAl Viro ldt_p->a = 0; 1915c48b108SAl Viro ldt_p->b = 0; 1925c48b108SAl Viro } 1935c48b108SAl Viro else{ 1945c48b108SAl Viro if (func == 1) 1955c48b108SAl Viro ldt_info.useable = 0; 1965c48b108SAl Viro ldt_p->a = LDT_entry_a(&ldt_info); 1975c48b108SAl Viro ldt_p->b = LDT_entry_b(&ldt_info); 1985c48b108SAl Viro } 1995c48b108SAl Viro err = 0; 2005c48b108SAl Viro 2015c48b108SAl Viro out_unlock: 2025c48b108SAl Viro mutex_unlock(&ldt->lock); 2035c48b108SAl Viro out: 2045c48b108SAl Viro return err; 2055c48b108SAl Viro } 2065c48b108SAl Viro 2075c48b108SAl Viro static long do_modify_ldt_skas(int func, void __user *ptr, 2085c48b108SAl Viro unsigned long bytecount) 2095c48b108SAl Viro { 2105c48b108SAl Viro int ret = -ENOSYS; 2115c48b108SAl Viro 2125c48b108SAl Viro switch (func) { 2135c48b108SAl Viro case 0: 2145c48b108SAl Viro ret = read_ldt(ptr, bytecount); 2155c48b108SAl Viro break; 2165c48b108SAl Viro case 1: 2175c48b108SAl Viro case 0x11: 2185c48b108SAl Viro ret = write_ldt(ptr, bytecount, func); 2195c48b108SAl Viro break; 2205c48b108SAl Viro case 2: 2215c48b108SAl Viro ret = read_default_ldt(ptr, bytecount); 2225c48b108SAl Viro break; 2235c48b108SAl Viro } 2245c48b108SAl Viro return ret; 2255c48b108SAl Viro } 2265c48b108SAl Viro 2275c48b108SAl Viro static DEFINE_SPINLOCK(host_ldt_lock); 2285c48b108SAl Viro static short dummy_list[9] = {0, -1}; 2295c48b108SAl Viro static short * host_ldt_entries = NULL; 2305c48b108SAl Viro 2315c48b108SAl Viro static void ldt_get_host_info(void) 2325c48b108SAl Viro { 2335c48b108SAl Viro long ret; 2345c48b108SAl Viro struct ldt_entry * ldt; 2355c48b108SAl Viro short *tmp; 2365c48b108SAl Viro int i, size, k, order; 2375c48b108SAl Viro 2385c48b108SAl Viro spin_lock(&host_ldt_lock); 2395c48b108SAl Viro 2405c48b108SAl Viro if (host_ldt_entries != NULL) { 2415c48b108SAl Viro spin_unlock(&host_ldt_lock); 2425c48b108SAl Viro return; 2435c48b108SAl Viro } 2445c48b108SAl Viro host_ldt_entries = dummy_list+1; 2455c48b108SAl Viro 2465c48b108SAl Viro spin_unlock(&host_ldt_lock); 2475c48b108SAl Viro 2485c48b108SAl Viro for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++) 2495c48b108SAl Viro ; 2505c48b108SAl Viro 2515c48b108SAl Viro ldt = (struct ldt_entry *) 2525c48b108SAl Viro __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); 2535c48b108SAl Viro if (ldt == NULL) { 2545c48b108SAl Viro printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer " 2555c48b108SAl Viro "for host ldt\n"); 2565c48b108SAl Viro return; 2575c48b108SAl Viro } 2585c48b108SAl Viro 2595c48b108SAl Viro ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); 2605c48b108SAl Viro if (ret < 0) { 2615c48b108SAl Viro printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n"); 2625c48b108SAl Viro goto out_free; 2635c48b108SAl Viro } 2645c48b108SAl Viro if (ret == 0) { 2655c48b108SAl Viro /* default_ldt is active, simply write an empty entry 0 */ 2665c48b108SAl Viro host_ldt_entries = dummy_list; 2675c48b108SAl Viro goto out_free; 2685c48b108SAl Viro } 2695c48b108SAl Viro 2705c48b108SAl Viro for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) { 2715c48b108SAl Viro if (ldt[i].a != 0 || ldt[i].b != 0) 2725c48b108SAl Viro size++; 2735c48b108SAl Viro } 2745c48b108SAl Viro 2755c48b108SAl Viro if (size < ARRAY_SIZE(dummy_list)) 2765c48b108SAl Viro host_ldt_entries = dummy_list; 2775c48b108SAl Viro else { 2785c48b108SAl Viro size = (size + 1) * sizeof(dummy_list[0]); 2795c48b108SAl Viro tmp = kmalloc(size, GFP_KERNEL); 2805c48b108SAl Viro if (tmp == NULL) { 2815c48b108SAl Viro printk(KERN_ERR "ldt_get_host_info: couldn't allocate " 2825c48b108SAl Viro "host ldt list\n"); 2835c48b108SAl Viro goto out_free; 2845c48b108SAl Viro } 2855c48b108SAl Viro host_ldt_entries = tmp; 2865c48b108SAl Viro } 2875c48b108SAl Viro 2885c48b108SAl Viro for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) { 2895c48b108SAl Viro if (ldt[i].a != 0 || ldt[i].b != 0) 2905c48b108SAl Viro host_ldt_entries[k++] = i; 2915c48b108SAl Viro } 2925c48b108SAl Viro host_ldt_entries[k] = -1; 2935c48b108SAl Viro 2945c48b108SAl Viro out_free: 2955c48b108SAl Viro free_pages((unsigned long)ldt, order); 2965c48b108SAl Viro } 2975c48b108SAl Viro 2985c48b108SAl Viro long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm) 2995c48b108SAl Viro { 3005c48b108SAl Viro struct user_desc desc; 3015c48b108SAl Viro short * num_p; 3025c48b108SAl Viro int i; 3035c48b108SAl Viro long page, err=0; 3045c48b108SAl Viro void *addr = NULL; 3055c48b108SAl Viro 3065c48b108SAl Viro 307b3ee571eSAl Viro mutex_init(&new_mm->arch.ldt.lock); 3085c48b108SAl Viro 3095c48b108SAl Viro if (!from_mm) { 3105c48b108SAl Viro memset(&desc, 0, sizeof(desc)); 3115c48b108SAl Viro /* 3125c48b108SAl Viro * Now we try to retrieve info about the ldt, we 3135c48b108SAl Viro * inherited from the host. All ldt-entries found 3145c48b108SAl Viro * will be reset in the following loop 3155c48b108SAl Viro */ 3165c48b108SAl Viro ldt_get_host_info(); 3175c48b108SAl Viro for (num_p=host_ldt_entries; *num_p != -1; num_p++) { 3185c48b108SAl Viro desc.entry_number = *num_p; 3195c48b108SAl Viro err = write_ldt_entry(&new_mm->id, 1, &desc, 3205c48b108SAl Viro &addr, *(num_p + 1) == -1); 3215c48b108SAl Viro if (err) 3225c48b108SAl Viro break; 3235c48b108SAl Viro } 324b3ee571eSAl Viro new_mm->arch.ldt.entry_count = 0; 3255c48b108SAl Viro 3265c48b108SAl Viro goto out; 3275c48b108SAl Viro } 3285c48b108SAl Viro 3295c48b108SAl Viro /* 3305c48b108SAl Viro * Our local LDT is used to supply the data for 3315c48b108SAl Viro * modify_ldt(READLDT), if PTRACE_LDT isn't available, 3325c48b108SAl Viro * i.e., we have to use the stub for modify_ldt, which 3335c48b108SAl Viro * can't handle the big read buffer of up to 64kB. 3345c48b108SAl Viro */ 335b3ee571eSAl Viro mutex_lock(&from_mm->arch.ldt.lock); 336b3ee571eSAl Viro if (from_mm->arch.ldt.entry_count <= LDT_DIRECT_ENTRIES) 337b3ee571eSAl Viro memcpy(new_mm->arch.ldt.u.entries, from_mm->arch.ldt.u.entries, 338b3ee571eSAl Viro sizeof(new_mm->arch.ldt.u.entries)); 3395c48b108SAl Viro else { 340b3ee571eSAl Viro i = from_mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE; 3415c48b108SAl Viro while (i-->0) { 3425c48b108SAl Viro page = __get_free_page(GFP_KERNEL|__GFP_ZERO); 3435c48b108SAl Viro if (!page) { 3445c48b108SAl Viro err = -ENOMEM; 3455c48b108SAl Viro break; 3465c48b108SAl Viro } 347b3ee571eSAl Viro new_mm->arch.ldt.u.pages[i] = 3485c48b108SAl Viro (struct ldt_entry *) page; 349b3ee571eSAl Viro memcpy(new_mm->arch.ldt.u.pages[i], 350b3ee571eSAl Viro from_mm->arch.ldt.u.pages[i], PAGE_SIZE); 3515c48b108SAl Viro } 3525c48b108SAl Viro } 353b3ee571eSAl Viro new_mm->arch.ldt.entry_count = from_mm->arch.ldt.entry_count; 354b3ee571eSAl Viro mutex_unlock(&from_mm->arch.ldt.lock); 3555c48b108SAl Viro 3565c48b108SAl Viro out: 3575c48b108SAl Viro return err; 3585c48b108SAl Viro } 3595c48b108SAl Viro 3605c48b108SAl Viro 3615c48b108SAl Viro void free_ldt(struct mm_context *mm) 3625c48b108SAl Viro { 3635c48b108SAl Viro int i; 3645c48b108SAl Viro 365d0b5e15fSRichard Weinberger if (mm->arch.ldt.entry_count > LDT_DIRECT_ENTRIES) { 366b3ee571eSAl Viro i = mm->arch.ldt.entry_count / LDT_ENTRIES_PER_PAGE; 3675c48b108SAl Viro while (i-- > 0) 368b3ee571eSAl Viro free_page((long) mm->arch.ldt.u.pages[i]); 3695c48b108SAl Viro } 370b3ee571eSAl Viro mm->arch.ldt.entry_count = 0; 3715c48b108SAl Viro } 3725c48b108SAl Viro 373da20ab35SDave Hansen SYSCALL_DEFINE3(modify_ldt, int , func , void __user * , ptr , 374da20ab35SDave Hansen unsigned long , bytecount) 3755c48b108SAl Viro { 376da20ab35SDave Hansen /* See non-um modify_ldt() for why we do this cast */ 377da20ab35SDave Hansen return (unsigned int)do_modify_ldt_skas(func, ptr, bytecount); 3785c48b108SAl Viro } 379