Commit 5daa8679 authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] x86 TSS: io bitmap lazy updating

This uses Davide's do_general_protection() fault based io-bitmap lazy update
code and combines it with the ioport-owner cache.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dd826030
...@@ -105,11 +105,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) ...@@ -105,11 +105,11 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
t->io_bitmap_max = bytes; t->io_bitmap_max = bytes;
/* Update the TSS: */ /*
memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated); * Sets the lazy trigger so that the next I/O operation will
tss->io_bitmap_max = bytes; * reload the correct bitmap.
tss->io_bitmap_owner = &current->thread; */
tss->io_bitmap_base = IO_BITMAP_OFFSET; tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
put_cpu(); put_cpu();
......
...@@ -496,17 +496,16 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) ...@@ -496,17 +496,16 @@ handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
return; return;
} }
/* /*
* The IO bitmap in the TSS needs updating: copy the relevant * Lazy TSS's I/O bitmap copy. We set an invalid offset here
* range of the new task's IO bitmap. Normally this is 128 bytes * and we let the task to get a GPF in case an I/O instruction
* or less: * is performed. The handler of the GPF will verify that the
*/ * faulting task has a valid I/O bitmap and, it true, does the
memcpy(tss->io_bitmap, next->io_bitmap_ptr, * real copy and restart the instruction. This will save us
max(tss->io_bitmap_max, next->io_bitmap_max)); * redundant copies when the currently switched task does not
tss->io_bitmap_max = next->io_bitmap_max; * perform any I/O during its timeslice.
tss->io_bitmap_owner = next; */
tss->io_bitmap_base = IO_BITMAP_OFFSET; tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
} }
/* /*
* This special macro can be used to load a debugging register * This special macro can be used to load a debugging register
*/ */
......
...@@ -479,6 +479,36 @@ DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr ...@@ -479,6 +479,36 @@ DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr
asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{ {
int cpu = get_cpu();
struct tss_struct *tss = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &current->thread;
/*
* Perform the lazy TSS's I/O bitmap copy. If the TSS has an
* invalid offset set (the LAZY one) and the faulting thread has
* a valid I/O bitmap pointer, we copy the I/O bitmap in the TSS
* and we set the offset field correctly. Then we let the CPU to
* restart the faulting instruction.
*/
if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY &&
thread->io_bitmap_ptr) {
memcpy(tss->io_bitmap, thread->io_bitmap_ptr,
thread->io_bitmap_max);
/*
* If the previously set map was extending to higher ports
* than the current one, pad extra space with 0xff (no access).
*/
if (thread->io_bitmap_max < tss->io_bitmap_max)
memset((char *) tss->io_bitmap +
thread->io_bitmap_max, 0xff,
tss->io_bitmap_max - thread->io_bitmap_max);
tss->io_bitmap_max = thread->io_bitmap_max;
tss->io_bitmap_base = IO_BITMAP_OFFSET;
put_cpu();
return;
}
put_cpu();
if (regs->eflags & VM_MASK) if (regs->eflags & VM_MASK)
goto gp_in_vm86; goto gp_in_vm86;
......
...@@ -307,6 +307,7 @@ extern unsigned int mca_pentium_flag; ...@@ -307,6 +307,7 @@ extern unsigned int mca_pentium_flag;
#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long)) #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap) #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
#define INVALID_IO_BITMAP_OFFSET 0x8000 #define INVALID_IO_BITMAP_OFFSET 0x8000
#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
struct i387_fsave_struct { struct i387_fsave_struct {
long cwd; long cwd;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment