diff options
author | Andy Lutomirski <luto@kernel.org> | 2016-10-31 18:18:46 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-11-01 02:47:54 -0400 |
commit | cd95ea81f25608c403052d0508ee5c9b32e2bc7d (patch) | |
tree | b5901aa76a2882cf4e722faa33b430945455d1dc | |
parent | 04ac88abaf758bd76edcc3be5549003a017e7963 (diff) |
x86/fpu, lguest: Remove CR0.TS support
Now that Linux never sets CR0.TS, lguest doesn't need to support it.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kvm list <kvm@vger.kernel.org>
Link: http://lkml.kernel.org/r/8a7bf2c11231c082258fd67705d0f275639b8475.1477951965.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/include/asm/lguest_hcall.h | 1 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 17 | ||||
-rw-r--r-- | drivers/lguest/hypercalls.c | 4 | ||||
-rw-r--r-- | drivers/lguest/lg.h | 1 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 19 |
5 files changed, 8 insertions, 34 deletions
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index ef01fef3eebc..6c119cfae218 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h | |||
@@ -9,7 +9,6 @@ | |||
9 | #define LHCALL_FLUSH_TLB 5 | 9 | #define LHCALL_FLUSH_TLB 5 |
10 | #define LHCALL_LOAD_IDT_ENTRY 6 | 10 | #define LHCALL_LOAD_IDT_ENTRY 6 |
11 | #define LHCALL_SET_STACK 7 | 11 | #define LHCALL_SET_STACK 7 |
12 | #define LHCALL_TS 8 | ||
13 | #define LHCALL_SET_CLOCKEVENT 9 | 12 | #define LHCALL_SET_CLOCKEVENT 9 |
14 | #define LHCALL_HALT 10 | 13 | #define LHCALL_HALT 10 |
15 | #define LHCALL_SET_PMD 13 | 14 | #define LHCALL_SET_PMD 13 |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 25da5bc8d83d..d74afcdbc580 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -497,27 +497,24 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
497 | * a whole series of functions like read_cr0() and write_cr0(). | 497 | * a whole series of functions like read_cr0() and write_cr0(). |
498 | * | 498 | * |
499 | * We start with cr0. cr0 allows you to turn on and off all kinds of basic | 499 | * We start with cr0. cr0 allows you to turn on and off all kinds of basic |
500 | * features, but Linux only really cares about one: the horrifically-named Task | 500 | * features, but the only cr0 bit that Linux ever used at runtime was the |
501 | * Switched (TS) bit at bit 3 (ie. 8) | 501 | * horrifically-named Task Switched (TS) bit at bit 3 (ie. 8) |
502 | * | 502 | * |
503 | * What does the TS bit do? Well, it causes the CPU to trap (interrupt 7) if | 503 | * What does the TS bit do? Well, it causes the CPU to trap (interrupt 7) if |
504 | * the floating point unit is used. Which allows us to restore FPU state | 504 | * the floating point unit is used. Which allows us to restore FPU state |
505 | * lazily after a task switch, and Linux uses that gratefully, but wouldn't a | 505 | * lazily after a task switch if we wanted to, but wouldn't a name like |
506 | * name like "FPUTRAP bit" be a little less cryptic? | 506 | * "FPUTRAP bit" be a little less cryptic? |
507 | * | 507 | * |
508 | * We store cr0 locally because the Host never changes it. The Guest sometimes | 508 | * Fortunately, Linux keeps it simple and doesn't use TS, so we can ignore |
509 | * wants to read it and we'd prefer not to bother the Host unnecessarily. | 509 | * cr0. |
510 | */ | 510 | */ |
511 | static unsigned long current_cr0; | ||
512 | static void lguest_write_cr0(unsigned long val) | 511 | static void lguest_write_cr0(unsigned long val) |
513 | { | 512 | { |
514 | lazy_hcall1(LHCALL_TS, val & X86_CR0_TS); | ||
515 | current_cr0 = val; | ||
516 | } | 513 | } |
517 | 514 | ||
518 | static unsigned long lguest_read_cr0(void) | 515 | static unsigned long lguest_read_cr0(void) |
519 | { | 516 | { |
520 | return current_cr0; | 517 | return 0; |
521 | } | 518 | } |
522 | 519 | ||
523 | /* | 520 | /* |
diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c index 19a32280731d..601f81c04873 100644 --- a/drivers/lguest/hypercalls.c +++ b/drivers/lguest/hypercalls.c | |||
@@ -109,10 +109,6 @@ static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args) | |||
109 | case LHCALL_SET_CLOCKEVENT: | 109 | case LHCALL_SET_CLOCKEVENT: |
110 | guest_set_clockevent(cpu, args->arg1); | 110 | guest_set_clockevent(cpu, args->arg1); |
111 | break; | 111 | break; |
112 | case LHCALL_TS: | ||
113 | /* This sets the TS flag, as we saw used in run_guest(). */ | ||
114 | cpu->ts = args->arg1; | ||
115 | break; | ||
116 | case LHCALL_HALT: | 112 | case LHCALL_HALT: |
117 | /* Similarly, this sets the halted flag for run_guest(). */ | 113 | /* Similarly, this sets the halted flag for run_guest(). */ |
118 | cpu->halted = 1; | 114 | cpu->halted = 1; |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 69b3814afd2f..2356a2318034 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -43,7 +43,6 @@ struct lg_cpu { | |||
43 | struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ | 43 | struct mm_struct *mm; /* == tsk->mm, but that becomes NULL on exit */ |
44 | 44 | ||
45 | u32 cr2; | 45 | u32 cr2; |
46 | int ts; | ||
47 | u32 esp1; | 46 | u32 esp1; |
48 | u16 ss1; | 47 | u16 ss1; |
49 | 48 | ||
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 6e9042e3d2a9..743253fc638f 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -247,14 +247,6 @@ unsigned long *lguest_arch_regptr(struct lg_cpu *cpu, size_t reg_off, bool any) | |||
247 | void lguest_arch_run_guest(struct lg_cpu *cpu) | 247 | void lguest_arch_run_guest(struct lg_cpu *cpu) |
248 | { | 248 | { |
249 | /* | 249 | /* |
250 | * Remember the awfully-named TS bit? If the Guest has asked to set it | ||
251 | * we set it now, so we can trap and pass that trap to the Guest if it | ||
252 | * uses the FPU. | ||
253 | */ | ||
254 | if (cpu->ts && fpregs_active()) | ||
255 | stts(); | ||
256 | |||
257 | /* | ||
258 | * SYSENTER is an optimized way of doing system calls. We can't allow | 250 | * SYSENTER is an optimized way of doing system calls. We can't allow |
259 | * it because it always jumps to privilege level 0. A normal Guest | 251 | * it because it always jumps to privilege level 0. A normal Guest |
260 | * won't try it because we don't advertise it in CPUID, but a malicious | 252 | * won't try it because we don't advertise it in CPUID, but a malicious |
@@ -282,10 +274,6 @@ void lguest_arch_run_guest(struct lg_cpu *cpu) | |||
282 | if (boot_cpu_has(X86_FEATURE_SEP)) | 274 | if (boot_cpu_has(X86_FEATURE_SEP)) |
283 | wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); | 275 | wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); |
284 | 276 | ||
285 | /* Clear the host TS bit if it was set above. */ | ||
286 | if (cpu->ts && fpregs_active()) | ||
287 | clts(); | ||
288 | |||
289 | /* | 277 | /* |
290 | * If the Guest page faulted, then the cr2 register will tell us the | 278 | * If the Guest page faulted, then the cr2 register will tell us the |
291 | * bad virtual address. We have to grab this now, because once we | 279 | * bad virtual address. We have to grab this now, because once we |
@@ -421,12 +409,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) | |||
421 | kill_guest(cpu, "Writing cr2"); | 409 | kill_guest(cpu, "Writing cr2"); |
422 | break; | 410 | break; |
423 | case 7: /* We've intercepted a Device Not Available fault. */ | 411 | case 7: /* We've intercepted a Device Not Available fault. */ |
424 | /* | 412 | /* No special handling is needed here. */ |
425 | * If the Guest doesn't want to know, we already restored the | ||
426 | * Floating Point Unit, so we just continue without telling it. | ||
427 | */ | ||
428 | if (!cpu->ts) | ||
429 | return; | ||
430 | break; | 413 | break; |
431 | case 32 ... 255: | 414 | case 32 ... 255: |
432 | /* This might be a syscall. */ | 415 | /* This might be a syscall. */ |