diff options
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 36 |
1 files changed, 9 insertions, 27 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 646da41a620..a59314e877f 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -248,11 +248,8 @@ void exit_thread(void) | |||
248 | /* | 248 | /* |
249 | * Careful, clear this in the TSS too: | 249 | * Careful, clear this in the TSS too: |
250 | */ | 250 | */ |
251 | memset(tss->io_bitmap, 0xff, tss->io_bitmap_max); | 251 | memset(tss->io_bitmap, 0xff, t->io_bitmap_max); |
252 | t->io_bitmap_max = 0; | 252 | t->io_bitmap_max = 0; |
253 | tss->io_bitmap_owner = NULL; | ||
254 | tss->io_bitmap_max = 0; | ||
255 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | ||
256 | put_cpu(); | 253 | put_cpu(); |
257 | } | 254 | } |
258 | 255 | ||
@@ -458,34 +455,19 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
458 | hard_enable_TSC(); | 455 | hard_enable_TSC(); |
459 | } | 456 | } |
460 | 457 | ||
461 | if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 458 | if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |
462 | /* | 459 | /* |
463 | * Disable the bitmap via an invalid offset. We still cache | 460 | * Copy the relevant range of the IO bitmap. |
464 | * the previous bitmap owner and the IO bitmap contents: | 461 | * Normally this is 128 bytes or less: |
465 | */ | 462 | */ |
466 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; | 463 | memcpy(tss->io_bitmap, next->io_bitmap_ptr, |
467 | return; | 464 | max(prev->io_bitmap_max, next->io_bitmap_max)); |
468 | } | 465 | } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { |
469 | |||
470 | if (likely(next == tss->io_bitmap_owner)) { | ||
471 | /* | 466 | /* |
472 | * Previous owner of the bitmap (hence the bitmap content) | 467 | * Clear any possible leftover bits: |
473 | * matches the next task, we dont have to do anything but | ||
474 | * to set a valid offset in the TSS: | ||
475 | */ | 468 | */ |
476 | tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; | 469 | memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); |
477 | return; | ||
478 | } | 470 | } |
479 | /* | ||
480 | * Lazy TSS's I/O bitmap copy. We set an invalid offset here | ||
481 | * and we let the task to get a GPF in case an I/O instruction | ||
482 | * is performed. The handler of the GPF will verify that the | ||
483 | * faulting task has a valid I/O bitmap and, it true, does the | ||
484 | * real copy and restart the instruction. This will save us | ||
485 | * redundant copies when the currently switched task does not | ||
486 | * perform any I/O during its timeslice. | ||
487 | */ | ||
488 | tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; | ||
489 | } | 471 | } |
490 | 472 | ||
491 | /* | 473 | /* |