TSS incremental cleanups
cover TSS incremental cleanups
Hi all-
These are incremental improvements. I think they should go through kvm.git since they are functionally KVM improvements and since the code being improved is in kvm.git.
Andy Lutomirski (2):
x86/asm: Tidy up TSS limit code
selftests/x86: Add a basic selftest for ioperm
arch/x86/include/asm/desc.h | 18 ++-- arch/x86/kernel/ioport.c | 8 +- arch/x86/kernel/process.c | 6 +- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/ioperm.c | 171 +++++++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+), 12 deletions(-) create mode 100644 tools/testing/selftests/x86/ioperm.c
Signature · 1 line
2.9.3
PATCH 1/2 x86/asm: Tidy up TSS limit code
In an earlier version of the patch ("x86/kvm/vmx: Defer TR reload after VM exit") that introduced TSS limit validity tracking, I confused which helper was which. On reflection, the names I chose sucked. Rename the helpers to make it more obvious what's going on and add some comments.
While I'm at it, clear __tss_limit_invalid when force-reloading as well as when contitionally reloading, since any TR reload fixes the limit.
--- arch/x86/include/asm/desc.h | 18 +++++++++++------- arch/x86/kernel/ioport.c | 8 +++++++- arch/x86/kernel/process.c | 6 +++--- 3 files changed, 21 insertions(+), 11 deletions(-)
arch/x86/include/asm/desc.h +11 -7
@@ -205,6 +205,8 @@ static inline void native_load_tr_desc(void) asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); } +DECLARE_PER_CPU (bool, __tss_limit_invalid); +static inline void force_reload_TR (void ) {struct desc_struct *d =get_cpu_gdt_table (smp_processor_id ());
@@ -220,18 +222,20 @@ static inline void force_reload_TR(void)write_gdt_entry (d,GDT_ENTRY_TSS , &tss,DESC_TSS );load_TR_desc (); +this_cpu_write (__tss_limit_invalid, false); } -DECLARE_PER_CPU (bool, need_tr_refresh); - -static inline void refresh_TR (void ) +/* +* Call this if you need the TSS limit to be correct, which should be the case +* if and only if you have TIF_IO_BITMAP set or you're switching to a task +* with TIF_IO_BITMAP set. +*/ +static inline void refresh_tss_limit (void ) {DEBUG_LOCKS_WARN_ON (preemptible ()); -if (unlikely (this_cpu_read (need_tr_refresh))) { +if (unlikely (this_cpu_read (__tss_limit_invalid)))force_reload_TR (); -this_cpu_write (need_tr_refresh, false); - } }/*
@@ -250,7 +254,7 @@ static inline void invalidate_tss_limit(void)if (unlikely (test_thread_flag (TIF_IO_BITMAP )))force_reload_TR ();else -this_cpu_write (need_tr_refresh, true); +this_cpu_write (__tss_limit_invalid, true); }static inline void native_load_gdt (const struct desc_ptr *dtr)
arch/x86/kernel/ioport.c +7 -1
@@ -47,8 +47,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) t->io_bitmap_ptr = bitmap;set_thread_flag (TIF_IO_BITMAP ); +/* +* Now that we have an IO bitmap, we need our TSS limit to be +* correct. It's fine if we are preempted after doing this: +* with TIF_IO_BITMAP set, context switches will keep our TSS +* limit correct. +*/ preempt_disable (); -refresh_TR (); +refresh_tss_limit ();preempt_enable (); }
arch/x86/kernel/process.c +3 -3
@@ -65,8 +65,8 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = { };EXPORT_PER_CPU_SYMBOL (cpu_tss); -DEFINE_PER_CPU (bool, need_tr_refresh); -EXPORT_PER_CPU_SYMBOL_GPL (need_tr_refresh); +DEFINE_PER_CPU (bool, __tss_limit_invalid); +EXPORT_PER_CPU_SYMBOL_GPL (__tss_limit_invalid);/* * this gets called so that we can store lazy state into memory and copy the
@@ -218,7 +218,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,* Make sure that the TSS limit is correct for the CPU * to notice the IO bitmap. */ -refresh_TR (); +refresh_tss_limit (); }else if (test_tsk_thread_flag (prev_p,TIF_IO_BITMAP )) {/* * Clear any possible leftover bits:
Signature · 1 line
2.9.3
PATCH 2/2 selftests/x86: Add a basic selftest for ioperm
In reply to Andy LutomirskiThis doesn't fully exercise the interaction between KVM and ioperm(), but it does test basic functionality.
--- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/ioperm.c | 171 +++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/x86/ioperm.c
tools/testing/selftests/x86/Makefile +1 -1
@@ -5,7 +5,7 @@ include ../lib.mk .PHONY: all all_32 all_64 warn_32bit_failure clean TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ - check_initial_reg_state sigreturn ldt_gdt iopl \ + check_initial_reg_state sigreturn ldt_gdt iopl ioperm \ protection_keys test_vdso TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \
tools/testing/selftests/x86/ioperm.c new file +171 -0
171 lines not on this page · raw message
Signature · 1 line
2.9.3