summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2016-10-31 18:18:46 -0400
committerIngo Molnar <mingo@kernel.org>2016-11-01 02:47:54 -0400
commitcd95ea81f25608c403052d0508ee5c9b32e2bc7d (patch)
treeb5901aa76a2882cf4e722faa33b430945455d1dc
parent04ac88abaf758bd76edcc3be5549003a017e7963 (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.h1
-rw-r--r--arch/x86/lguest/boot.c17
-rw-r--r--drivers/lguest/hypercalls.c4
-rw-r--r--drivers/lguest/lg.h1
-rw-r--r--drivers/lguest/x86/core.c19
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 */
511static unsigned long current_cr0;
512static void lguest_write_cr0(unsigned long val) 511static 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
518static unsigned long lguest_read_cr0(void) 515static 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)
247void lguest_arch_run_guest(struct lg_cpu *cpu) 247void 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. */