Skip to content

Commit 111e7b1

Browse files
committed
x86/ioperm: Extend IOPL config to control ioperm() as well
If iopl() is disabled, then providing ioperm() does not make much sense. Rename the config option and disable/enable both syscalls with it. Guard the code with #ifdefs where appropriate. Suggested-by: Andy Lutomirski <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]>
1 parent a24ca99 commit 111e7b1

File tree

7 files changed

+65
-20
lines changed

7 files changed

+65
-20
lines changed

arch/x86/Kconfig

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,10 +1254,13 @@ config X86_VSYSCALL_EMULATION
12541254
Disabling this option saves about 7K of kernel size and
12551255
possibly 4K of additional runtime pagetable memory.
12561256

1257-
config X86_IOPL_EMULATION
1258-
bool "IOPL Emulation"
1257+
config X86_IOPL_IOPERM
1258+
bool "IOPERM and IOPL Emulation"
12591259
default y
12601260
---help---
1261+
This enables the ioperm() and iopl() syscalls which are necessary
1262+
for legacy applications.
1263+
12611264
Legacy IOPL support is an overbroad mechanism which allows user
12621265
space aside of accessing all 65536 I/O ports also to disable
12631266
interrupts. To gain this access the caller needs CAP_SYS_RAWIO

arch/x86/include/asm/io_bitmap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@ struct io_bitmap {
1515

1616
struct task_struct;
1717

18+
#ifdef CONFIG_X86_IOPL_IOPERM
1819
void io_bitmap_share(struct task_struct *tsk);
1920
void io_bitmap_exit(void);
2021

2122
void tss_update_io_bitmap(void);
23+
#else
24+
static inline void io_bitmap_share(struct task_struct *tsk) { }
25+
static inline void io_bitmap_exit(void) { }
26+
static inline void tss_update_io_bitmap(void) { }
27+
#endif
2228

2329
#endif

arch/x86/include/asm/processor.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,18 @@ struct x86_hw_tss {
340340
(offsetof(struct tss_struct, io_bitmap.mapall) - \
341341
offsetof(struct tss_struct, x86_tss))
342342

343+
#ifdef CONFIG_X86_IOPL_IOPERM
343344
/*
344345
* sizeof(unsigned long) coming from an extra "long" at the end of the
345346
* iobitmap. The limit is inclusive, i.e. the last valid byte.
346347
*/
347-
#define __KERNEL_TSS_LIMIT \
348+
# define __KERNEL_TSS_LIMIT \
348349
(IO_BITMAP_OFFSET_VALID_ALL + IO_BITMAP_BYTES + \
349350
sizeof(unsigned long) - 1)
351+
#else
352+
# define __KERNEL_TSS_LIMIT \
353+
(offsetof(struct tss_struct, x86_tss) + sizeof(struct x86_hw_tss) - 1)
354+
#endif
350355

351356
/* Base offset outside of TSS_LIMIT so unpriviledged IO causes #GP */
352357
#define IO_BITMAP_OFFSET_INVALID (__KERNEL_TSS_LIMIT + 1)
@@ -398,7 +403,9 @@ struct tss_struct {
398403
*/
399404
struct x86_hw_tss x86_tss;
400405

406+
#ifdef CONFIG_X86_IOPL_IOPERM
401407
struct x86_io_bitmap io_bitmap;
408+
#endif
402409
} __aligned(PAGE_SIZE);
403410

404411
DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw);

arch/x86/include/asm/thread_info.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,13 @@ struct thread_info {
156156
# define _TIF_WORK_CTXSW (_TIF_WORK_CTXSW_BASE)
157157
#endif
158158

159-
#define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY | \
159+
#ifdef CONFIG_X86_IOPL_IOPERM
160+
# define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY | \
160161
_TIF_IO_BITMAP)
162+
#else
163+
# define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY)
164+
#endif
165+
161166
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
162167

163168
#define STACK_WARN (THREAD_SIZE/8)

arch/x86/kernel/cpu/common.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,22 @@ static inline void gdt_setup_doublefault_tss(int cpu)
18041804
}
18051805
#endif /* !CONFIG_X86_64 */
18061806

1807+
static inline void tss_setup_io_bitmap(struct tss_struct *tss)
1808+
{
1809+
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
1810+
1811+
#ifdef CONFIG_X86_IOPL_IOPERM
1812+
tss->io_bitmap.prev_max = 0;
1813+
tss->io_bitmap.prev_sequence = 0;
1814+
memset(tss->io_bitmap.bitmap, 0xff, sizeof(tss->io_bitmap.bitmap));
1815+
/*
1816+
* Invalidate the extra array entry past the end of the all
1817+
* permission bitmap as required by the hardware.
1818+
*/
1819+
tss->io_bitmap.mapall[IO_BITMAP_LONGS] = ~0UL;
1820+
#endif
1821+
}
1822+
18071823
/*
18081824
* cpu_init() initializes state that is per-CPU. Some data is already
18091825
* initialized (naturally) in the bootstrap process, such as the GDT
@@ -1860,15 +1876,7 @@ void cpu_init(void)
18601876

18611877
/* Initialize the TSS. */
18621878
tss_setup_ist(tss);
1863-
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
1864-
tss->io_bitmap.prev_max = 0;
1865-
tss->io_bitmap.prev_sequence = 0;
1866-
memset(tss->io_bitmap.bitmap, 0xff, sizeof(tss->io_bitmap.bitmap));
1867-
/*
1868-
* Invalidate the extra array entry past the end of the all
1869-
* permission bitmap as required by the hardware.
1870-
*/
1871-
tss->io_bitmap.mapall[IO_BITMAP_LONGS] = ~0UL;
1879+
tss_setup_io_bitmap(tss);
18721880
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
18731881

18741882
load_TR_desc();

arch/x86/kernel/ioport.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <asm/io_bitmap.h>
1515
#include <asm/desc.h>
1616

17+
#ifdef CONFIG_X86_IOPL_IOPERM
18+
1719
static atomic64_t io_bitmap_sequence;
1820

1921
void io_bitmap_share(struct task_struct *tsk)
@@ -172,13 +174,6 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
172174
struct thread_struct *t = &current->thread;
173175
unsigned int old;
174176

175-
/*
176-
* Careful: the IOPL bits in regs->flags are undefined under Xen PV
177-
* and changing them has no effect.
178-
*/
179-
if (IS_ENABLED(CONFIG_X86_IOPL_NONE))
180-
return -ENOSYS;
181-
182177
if (level > 3)
183178
return -EINVAL;
184179

@@ -200,3 +195,20 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
200195

201196
return 0;
202197
}
198+
199+
#else /* CONFIG_X86_IOPL_IOPERM */
200+
201+
long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
202+
{
203+
return -ENOSYS;
204+
}
205+
SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
206+
{
207+
return -ENOSYS;
208+
}
209+
210+
SYSCALL_DEFINE1(iopl, unsigned int, level)
211+
{
212+
return -ENOSYS;
213+
}
214+
#endif

arch/x86/kernel/process.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ void arch_setup_new_exec(void)
322322
}
323323
}
324324

325+
#ifdef CONFIG_X86_IOPL_IOPERM
325326
static inline void tss_invalidate_io_bitmap(struct tss_struct *tss)
326327
{
327328
/*
@@ -409,6 +410,9 @@ void tss_update_io_bitmap(void)
409410
tss_invalidate_io_bitmap(tss);
410411
}
411412
}
413+
#else /* CONFIG_X86_IOPL_IOPERM */
414+
static inline void switch_to_bitmap(unsigned long tifp) { }
415+
#endif
412416

413417
#ifdef CONFIG_SMP
414418

0 commit comments

Comments
 (0)