summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ioport.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ioport.c')
-rw-r--r--arch/x86/kernel/ioport.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 198beadb3732..f9fc69aeb033 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -16,6 +16,18 @@
static atomic64_t io_bitmap_sequence;
+void io_bitmap_exit(void)
+{
+ struct io_bitmap *iobm = current->thread.io_bitmap;
+
+ current->thread.io_bitmap = NULL;
+ clear_thread_flag(TIF_IO_BITMAP);
+ preempt_disable();
+ tss_update_io_bitmap();
+ preempt_enable();
+ kfree(iobm);
+}
+
/*
* this changes the io permissions bitmap in the current task.
*/
@@ -61,11 +73,16 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
* Search for a (possibly new) maximum. This is simple and stupid,
* to keep it obviously correct:
*/
- max_long = 0;
+ max_long = UINT_MAX;
for (i = 0; i < IO_BITMAP_LONGS; i++) {
if (iobm->bitmap[i] != ~0UL)
max_long = i;
}
+ /* All permissions dropped? */
+ if (max_long == UINT_MAX) {
+ io_bitmap_exit();
+ return 0;
+ }
iobm->max = (max_long + 1) * sizeof(unsigned long);