2 * Copyright (C) 2001, 2004 Hewlett-Packard Co
3 * David Mosberger-Tang <davidm@hpl.hp.com>
5 * Adapted from arch/i386/kernel/ldt.c
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/string.h>
12 #include <linux/smp.h>
13 #include <linux/vmalloc.h>
15 #include <asm/uaccess.h>
20 * read_ldt() is not really atomic - this is not a problem since synchronization of reads
21 * and writes done to the LDT has to be assured by user-space anyway. Writes are atomic,
22 * to protect the security checks done on new descriptors.
25 read_ldt (void __user *ptr, unsigned long bytecount)
27 unsigned long bytes_left, n;
28 char __user *src, *dst;
29 char buf[256]; /* temporary buffer (don't overflow kernel stack!) */
31 if (bytecount > IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE)
32 bytecount = IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE;
34 bytes_left = bytecount;
36 src = (void __user *) IA32_LDT_OFFSET;
45 * We know we're reading valid memory, but we still must guard against
46 * running out of memory.
48 if (__copy_from_user(buf, src, n))
51 if (copy_to_user(dst, buf, n))
62 read_default_ldt (void __user * ptr, unsigned long bytecount)
67 /* XXX fix me: should return equivalent of default_ldt[0] */
74 if (clear_user(ptr, size))
81 write_ldt (void __user * ptr, unsigned long bytecount, int oldmode)
83 struct ia32_user_desc ldt_info;
87 if (bytecount != sizeof(ldt_info))
89 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
92 if (ldt_info.entry_number >= IA32_LDT_ENTRIES)
94 if (ldt_info.contents == 3) {
97 if (ldt_info.seg_not_present == 0)
101 if (ldt_info.base_addr == 0 && ldt_info.limit == 0
102 && (oldmode || (ldt_info.contents == 0 && ldt_info.read_exec_only == 1
103 && ldt_info.seg_32bit == 0 && ldt_info.limit_in_pages == 0
104 && ldt_info.seg_not_present == 1 && ldt_info.useable == 0)))
105 /* allow LDTs to be cleared by the user */
108 /* we must set the "Accessed" bit as IVE doesn't emulate it */
109 entry = IA32_SEG_DESCRIPTOR(ldt_info.base_addr, ldt_info.limit,
110 (((ldt_info.read_exec_only ^ 1) << 1)
111 | (ldt_info.contents << 2)) | 1,
112 1, 3, ldt_info.seg_not_present ^ 1,
113 (oldmode ? 0 : ldt_info.useable),
115 ldt_info.limit_in_pages);
117 * Install the new entry. We know we're accessing valid (mapped) user-level
118 * memory, but we still need to guard against out-of-memory, hence we must use
121 ret = __put_user(entry, (__u64 __user *) IA32_LDT_OFFSET + ldt_info.entry_number);
122 ia32_load_segment_descriptors(current);
127 sys32_modify_ldt (int func, unsigned int ptr, unsigned int bytecount)
133 ret = read_ldt(compat_ptr(ptr), bytecount);
136 ret = write_ldt(compat_ptr(ptr), bytecount, 1);
139 ret = read_default_ldt(compat_ptr(ptr), bytecount);
142 ret = write_ldt(compat_ptr(ptr), bytecount, 0);