All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction
@ 2017-02-08  8:09 ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

rr (http://rr-project.org/), a userspace record-and-replay reverse-
execution debugger, would like to trap and emulate the CPUID instruction.
This would allow us to a) mask away certain hardware features that rr does
not support (e.g. RDRAND) and b) enable trace portability across machines
by providing constant results.

Newer Intel CPUs (Ivy Bridge and later) can fault when CPUID is executed at
CPL > 0. Expose this capability to userspace as a new pair of arch_prctls,
ARCH_GET_CPUID and ARCH_SET_CPUID.

Since v13:
All: rebased on top of tglx's __switch_to_xtra patches
(https://lkml.org/lkml/2016/12/15/432)

Patch 6: x86/arch_prctl: Add ARCH_[GET|SET]_CPUID
- Removed bogus assertion about interrupts

Patch 9: x86/arch_prctl: Rename 'code' argument to 'option'
- New

Three issues were raised last year on the v13 patches. tglx pointed out
that the lock checking assertion in patch 6 was bogus, and it has been
removed. ingo asked that we rename the second argument of arch_prctl to
option, which patch 9 was added to do.

The third issue raised was about performance and code generation. With the
__switch_to_xtra optimizations I suggested in my response that are
implemented in tglx's patches, the extra burden this feature imposes on
context switches that fall into __switch_to_xtra but do not use CPUID faulting
is a single AND and branch.  Compare,

Before:
276:	49 31 dc		xor    %rbx,%r12
279:	41 f7 c4 00 00 00 02 	test   $0x2000000,%r12d
280:	75 43                	jne    2c5 <__switch_to_xtra+0x95>
282:	41 f7 c4 00 00 01 00 	test   $0x10000,%r12d
289:    74 17                   je     2a2 <__switch_to_xtra+0x72>
28b:    65 48 8b 05 00 00 00    mov    %gs:0x0(%rip),%rax        # 293 <__switch_to_xtra+0x63>
292:    00
293:	48 83 f0 04		xor    $0x4,%rax
297:	65 48 89 05 00 00 00 	mov    %rax,%gs:0x0(%rip)        # 29f <__switch_to_xtra+0x6f>
29e:	00
29f:	0f 22 e0		mov    %rax,%cr4

After:
306:	4c 31 e3		xor    %r12,%rbx
309:	f7 c3 00 00 00 02    	test   $0x2000000,%ebx
30f:	0f 85 87 00 00 00    	jne    39c <__switch_to_xtra+0xdc>
315:    f7 c3 00 00 01 00       test   $0x10000,%ebx
31b:    74 17                   je     334 <__switch_to_xtra+0x74>
31d:    65 48 8b 05 00 00 00    mov    %gs:0x0(%rip),%rax        # 325 <__switch_to_xtra+0x65>
324:    00
325:    48 83 f0 04		xor    $0x4,%rax
329:    65 48 89 05 00 00 00 	mov    %rax,%gs:0x0(%rip)        # 331 <__switch_to_xtra+0x71>
330:	00
331:	0f 22 e0		mov    %rax,%cr4
334:    80 e7 80             	and    $0x80,%bh
337:    75 23                   jne    35c <__switch_to_xtra+0x9c>

And this is after the optimizations removed 3 conditional branches from
__switch_to_xtra, so we're still ahead a net 2 branches.

The generated code for set_cpuid_faulting is,

With CONFIG_PARAVIRT=n, inlined into __switch_to_xtra:
35c:    65 48 8b 05 00 00 00	mov    %gs:0x0(%rip),%rax        # 364 <__switch_to_xtra+0xa4>
363:	00
364:	48 83 e0 fe		and    $0xfffffffffffffffe,%rax
368:	b9 40 01 00 00       	mov    $0x140,%ecx
36d:    48 89 c2                mov    %rax,%rdx
370:    4c 89 e0                mov    %r12,%rax
373:    48 c1 e8 0f             shr    $0xf,%rax
377:    83 e0 01                and    $0x1,%eax
37a:    48 09 d0                or     %rdx,%rax
37d:    48 89 c2                mov    %rax,%rdx
380:	65 48 89 05 00 00 00    mov    %rax,%gs:0x0(%rip)        # 388 <__switch_to_xtra+0xc8>
387:	00
388:    48 c1 ea 20		shr    $0x20,%rdx
38c:    0f 30                   wrmsr

With CONFIG_PARAVIRT=y:

in __switch_to_xtra:
354:    80 e7 80                and    $0x80,%bh
357:    74 0f                   je     368 <__switch_to_xtra+0x88>
359:    4c 89 e7                mov    %r12,%rdi
35c:    48 c1 ef 0f             shr    $0xf,%rdi
360:    83 e7 01                and    $0x1,%edi
363:    e8 98 fc ff ff          callq  0 <set_cpuid_faulting>

0000000000000000 <set_cpuid_faulting>:
0:    e8 00 00 00 00          callq  5 <set_cpuid_faulting+0x5>
5:    55                      push   %rbp
6:    65 48 8b 15 00 00 00    mov    %gs:0x0(%rip),%rdx        # e <set_cpuid_faulting+0xe>
d:    00
e:    48 89 d0                mov    %rdx,%rax
11:   40 0f b6 d7             movzbl %dil,%edx
15:   48 89 e5                mov    %rsp,%rbp
18:   48 83 e0 fe             and    $0xfffffffffffffffe,%rax
1c:   bf 40 01 00 00          mov    $0x140,%edi
21:   48 09 c2                or     %rax,%rdx
24:   89 d6                   mov    %edx,%esi
26:   65 48 89 15 00 00 00    mov    %rdx,%gs:0x0(%rip)        # 2e <set_cpuid_faulting+0x2e>
2d:   00
2e:   48 c1 ea 20             shr    $0x20,%rdx
32:   ff 14 25 00 00 00 00    callq  *0x0
39:   5d                      pop    %rbp
3a:   c3                      retq

While these sequences are less efficient than the "load msr from the task struct and wrmsr"
sequence that Ingo's suggestion would produce, this is entirely reasonable code and avoids
taking up 8 bytes in the task_struct that will almost never be used.

As I said last year, obviously I want to get this into the kernel or I wouldn't be here.
So if Ingo or others insist on caching the MSR in the task_struct I'll do it, but I still
think this is a good approach.

- Kyle

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction
@ 2017-02-08  8:09 ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

rr (http://rr-project.org/), a userspace record-and-replay reverse-
execution debugger, would like to trap and emulate the CPUID instruction.
This would allow us to a) mask away certain hardware features that rr does
not support (e.g. RDRAND) and b) enable trace portability across machines
by providing constant results.

Newer Intel CPUs (Ivy Bridge and later) can fault when CPUID is executed at
CPL > 0. Expose this capability to userspace as a new pair of arch_prctls,
ARCH_GET_CPUID and ARCH_SET_CPUID.

Since v13:
All: rebased on top of tglx's __switch_to_xtra patches
(https://lkml.org/lkml/2016/12/15/432)

Patch 6: x86/arch_prctl: Add ARCH_[GET|SET]_CPUID
- Removed bogus assertion about interrupts

Patch 9: x86/arch_prctl: Rename 'code' argument to 'option'
- New

Three issues were raised last year on the v13 patches. tglx pointed out
that the lock checking assertion in patch 6 was bogus, and it has been
removed. ingo asked that we rename the second argument of arch_prctl to
option, which patch 9 was added to do.

The third issue raised was about performance and code generation. With the
__switch_to_xtra optimizations I suggested in my response that are
implemented in tglx's patches, the extra burden this feature imposes on
context switches that fall into __switch_to_xtra but do not use CPUID faulting
is a single AND and branch.  Compare,

Before:
276:	49 31 dc		xor    %rbx,%r12
279:	41 f7 c4 00 00 00 02 	test   $0x2000000,%r12d
280:	75 43                	jne    2c5 <__switch_to_xtra+0x95>
282:	41 f7 c4 00 00 01 00 	test   $0x10000,%r12d
289:    74 17                   je     2a2 <__switch_to_xtra+0x72>
28b:    65 48 8b 05 00 00 00    mov    %gs:0x0(%rip),%rax        # 293 <__switch_to_xtra+0x63>
292:    00
293:	48 83 f0 04		xor    $0x4,%rax
297:	65 48 89 05 00 00 00 	mov    %rax,%gs:0x0(%rip)        # 29f <__switch_to_xtra+0x6f>
29e:	00
29f:	0f 22 e0		mov    %rax,%cr4

After:
306:	4c 31 e3		xor    %r12,%rbx
309:	f7 c3 00 00 00 02    	test   $0x2000000,%ebx
30f:	0f 85 87 00 00 00    	jne    39c <__switch_to_xtra+0xdc>
315:    f7 c3 00 00 01 00       test   $0x10000,%ebx
31b:    74 17                   je     334 <__switch_to_xtra+0x74>
31d:    65 48 8b 05 00 00 00    mov    %gs:0x0(%rip),%rax        # 325 <__switch_to_xtra+0x65>
324:    00
325:    48 83 f0 04		xor    $0x4,%rax
329:    65 48 89 05 00 00 00 	mov    %rax,%gs:0x0(%rip)        # 331 <__switch_to_xtra+0x71>
330:	00
331:	0f 22 e0		mov    %rax,%cr4
334:    80 e7 80             	and    $0x80,%bh
337:    75 23                   jne    35c <__switch_to_xtra+0x9c>

And this is after the optimizations removed 3 conditional branches from
__switch_to_xtra, so we're still ahead a net 2 branches.

The generated code for set_cpuid_faulting is,

With CONFIG_PARAVIRT=n, inlined into __switch_to_xtra:
35c:    65 48 8b 05 00 00 00	mov    %gs:0x0(%rip),%rax        # 364 <__switch_to_xtra+0xa4>
363:	00
364:	48 83 e0 fe		and    $0xfffffffffffffffe,%rax
368:	b9 40 01 00 00       	mov    $0x140,%ecx
36d:    48 89 c2                mov    %rax,%rdx
370:    4c 89 e0                mov    %r12,%rax
373:    48 c1 e8 0f             shr    $0xf,%rax
377:    83 e0 01                and    $0x1,%eax
37a:    48 09 d0                or     %rdx,%rax
37d:    48 89 c2                mov    %rax,%rdx
380:	65 48 89 05 00 00 00    mov    %rax,%gs:0x0(%rip)        # 388 <__switch_to_xtra+0xc8>
387:	00
388:    48 c1 ea 20		shr    $0x20,%rdx
38c:    0f 30                   wrmsr

With CONFIG_PARAVIRT=y:

in __switch_to_xtra:
354:    80 e7 80                and    $0x80,%bh
357:    74 0f                   je     368 <__switch_to_xtra+0x88>
359:    4c 89 e7                mov    %r12,%rdi
35c:    48 c1 ef 0f             shr    $0xf,%rdi
360:    83 e7 01                and    $0x1,%edi
363:    e8 98 fc ff ff          callq  0 <set_cpuid_faulting>

0000000000000000 <set_cpuid_faulting>:
0:    e8 00 00 00 00          callq  5 <set_cpuid_faulting+0x5>
5:    55                      push   %rbp
6:    65 48 8b 15 00 00 00    mov    %gs:0x0(%rip),%rdx        # e <set_cpuid_faulting+0xe>
d:    00
e:    48 89 d0                mov    %rdx,%rax
11:   40 0f b6 d7             movzbl %dil,%edx
15:   48 89 e5                mov    %rsp,%rbp
18:   48 83 e0 fe             and    $0xfffffffffffffffe,%rax
1c:   bf 40 01 00 00          mov    $0x140,%edi
21:   48 09 c2                or     %rax,%rdx
24:   89 d6                   mov    %edx,%esi
26:   65 48 89 15 00 00 00    mov    %rdx,%gs:0x0(%rip)        # 2e <set_cpuid_faulting+0x2e>
2d:   00
2e:   48 c1 ea 20             shr    $0x20,%rdx
32:   ff 14 25 00 00 00 00    callq  *0x0
39:   5d                      pop    %rbp
3a:   c3                      retq

While these sequences are less efficient than the "load msr from the task struct and wrmsr"
sequence that Ingo's suggestion would produce, this is entirely reasonable code and avoids
taking up 8 bytes in the task_struct that will almost never be used.

As I said last year, obviously I want to get this into the kernel or I wouldn't be here.
So if Ingo or others insist on caching the MSR in the task_struct I'll do it, but I still
think this is a good approach.

- Kyle

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 1/9] x86/arch_prctl/64: Use SYSCALL_DEFINE2 to define sys_arch_prctl
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Use the SYSCALL_DEFINE2 macro instead of manually defining it.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/kernel/process_64.c | 3 ++-
 arch/x86/um/syscalls_64.c    | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index a61e141b6891..c0ecc237bd9b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -30,16 +30,17 @@
 #include <linux/ptrace.h>
 #include <linux/notifier.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
 #include <linux/prctl.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/ftrace.h>
+#include <linux/syscalls.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/fpu/internal.h>
 #include <asm/mmu_context.h>
 #include <asm/prctl.h>
 #include <asm/desc.h>
 #include <asm/proto.h>
@@ -614,17 +615,17 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-long sys_arch_prctl(int code, unsigned long addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
 {
 	return do_arch_prctl(current, code, addr);
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index e6552275320b..ab3f7f426279 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -1,16 +1,17 @@
 /*
  * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Copyright 2003 PathScale, Inc.
  *
  * Licensed under the GPL
  */
 
 #include <linux/sched.h>
+#include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
 	unsigned long *ptr = addr, tmp;
 	long ret;
@@ -67,17 +68,17 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 	case ARCH_GET_GS:
 		ret = put_user(tmp, addr);
 		break;
 	}
 
 	return ret;
 }
 
-long sys_arch_prctl(int code, unsigned long addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
 {
 	return arch_prctl(current, code, (unsigned long __user *) addr);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 1/9] x86/arch_prctl/64: Use SYSCALL_DEFINE2 to define sys_arch_prctl
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Use the SYSCALL_DEFINE2 macro instead of manually defining it.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/kernel/process_64.c | 3 ++-
 arch/x86/um/syscalls_64.c    | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index a61e141b6891..c0ecc237bd9b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -30,16 +30,17 @@
 #include <linux/ptrace.h>
 #include <linux/notifier.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
 #include <linux/prctl.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/ftrace.h>
+#include <linux/syscalls.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/fpu/internal.h>
 #include <asm/mmu_context.h>
 #include <asm/prctl.h>
 #include <asm/desc.h>
 #include <asm/proto.h>
@@ -614,17 +615,17 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-long sys_arch_prctl(int code, unsigned long addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
 {
 	return do_arch_prctl(current, code, addr);
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index e6552275320b..ab3f7f426279 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -1,16 +1,17 @@
 /*
  * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Copyright 2003 PathScale, Inc.
  *
  * Licensed under the GPL
  */
 
 #include <linux/sched.h>
+#include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
 	unsigned long *ptr = addr, tmp;
 	long ret;
@@ -67,17 +68,17 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 	case ARCH_GET_GS:
 		ret = put_user(tmp, addr);
 		break;
 	}
 
 	return ret;
 }
 
-long sys_arch_prctl(int code, unsigned long addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
 {
 	return arch_prctl(current, code, (unsigned long __user *) addr);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 2/9] x86/arch_prctl/64: Rename do_arch_prctl to do_arch_prctl_64
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

In order to introduce new arch_prctls that are not 64 bit only, rename the
existing 64 bit implementation to do_arch_prctl_64(). Also rename the second
argument to arch_prctl(), which will no longer always be an address.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: Andy Lutomirski <luto@kernel.org>
---
 arch/um/include/shared/os.h  |  2 +-
 arch/x86/include/asm/proto.h |  3 +--
 arch/x86/kernel/process_64.c | 32 +++++++++++++++++---------------
 arch/x86/kernel/ptrace.c     |  8 ++++----
 arch/x86/um/os-Linux/prctl.c |  4 ++--
 arch/x86/um/syscalls_64.c    | 12 ++++++------
 6 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index de5d572225f3..2b47e0e8d414 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -298,17 +298,17 @@ extern void os_set_ioignore(void);
 
 /* sigio.c */
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
 extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
-extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+extern int os_arch_prctl(int pid, int code, unsigned long *arg2);
 
 /* tty.c */
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
 extern unsigned long os_get_top_address(void);
 
 long syscall(long number, ...);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 9b9b30b19441..f8e9194e100c 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -4,16 +4,17 @@
 #include <asm/ldt.h>
 
 /* misc architecture specific prototypes */
 
 void syscall_init(void);
 
 #ifdef CONFIG_X86_64
 void entry_SYSCALL_64(void);
+long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2);
 #endif
 
 #ifdef CONFIG_X86_32
 void entry_INT80_32(void);
 void entry_SYSENTER_32(void);
 void __begin_SYSENTER_singlestep_region(void);
 void __end_SYSENTER_singlestep_region(void);
 #endif
@@ -25,11 +26,9 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
-long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
-
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c0ecc237bd9b..83e011566db0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -198,17 +198,17 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
 	 */
 	if (clone_flags & CLONE_SETTLS) {
 #ifdef CONFIG_IA32_EMULATION
 		if (in_ia32_syscall())
 			err = do_set_thread_area(p, -1,
 				(struct user_desc __user *)tls, 0);
 		else
 #endif
-			err = do_arch_prctl(p, ARCH_SET_FS, tls);
+			err = do_arch_prctl_64(p, ARCH_SET_FS, tls);
 		if (err)
 			goto out;
 	}
 	err = 0;
 out:
 	if (err && p->thread.io_bitmap_ptr) {
 		kfree(p->thread.io_bitmap_ptr);
 		p->thread.io_bitmap_max = 0;
@@ -541,91 +541,93 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr)
 	ret = map_vdso_once(image, addr);
 	if (ret)
 		return ret;
 
 	return (long)image->size;
 }
 #endif
 
-long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
+long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 {
 	int ret = 0;
 	int doit = task == current;
 	int cpu;
 
 	switch (code) {
 	case ARCH_SET_GS:
-		if (addr >= TASK_SIZE_MAX)
+		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.gsindex = 0;
-		task->thread.gsbase = addr;
+		task->thread.gsbase = arg2;
 		if (doit) {
 			load_gs_index(0);
-			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
+			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, arg2);
 		}
 		put_cpu();
 		break;
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
 		   with gs */
-		if (addr >= TASK_SIZE_MAX)
+		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.fsindex = 0;
-		task->thread.fsbase = addr;
+		task->thread.fsbase = arg2;
 		if (doit) {
 			/* set the selector to 0 to not confuse __switch_to */
 			loadsegment(fs, 0);
-			ret = wrmsrl_safe(MSR_FS_BASE, addr);
+			ret = wrmsrl_safe(MSR_FS_BASE, arg2);
 		}
 		put_cpu();
 		break;
 	case ARCH_GET_FS: {
 		unsigned long base;
+
 		if (doit)
 			rdmsrl(MSR_FS_BASE, base);
 		else
 			base = task->thread.fsbase;
-		ret = put_user(base, (unsigned long __user *)addr);
+		ret = put_user(base, (unsigned long __user *)arg2);
 		break;
 	}
 	case ARCH_GET_GS: {
 		unsigned long base;
+
 		if (doit)
 			rdmsrl(MSR_KERNEL_GS_BASE, base);
 		else
 			base = task->thread.gsbase;
-		ret = put_user(base, (unsigned long __user *)addr);
+		ret = put_user(base, (unsigned long __user *)arg2);
 		break;
 	}
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
 # ifdef CONFIG_X86_X32_ABI
 	case ARCH_MAP_VDSO_X32:
-		return prctl_map_vdso(&vdso_image_x32, addr);
+		return prctl_map_vdso(&vdso_image_x32, arg2);
 # endif
 # if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
 	case ARCH_MAP_VDSO_32:
-		return prctl_map_vdso(&vdso_image_32, addr);
+		return prctl_map_vdso(&vdso_image_32, arg2);
 # endif
 	case ARCH_MAP_VDSO_64:
-		return prctl_map_vdso(&vdso_image_64, addr);
+		return prctl_map_vdso(&vdso_image_64, arg2);
 #endif
 
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return do_arch_prctl(current, code, addr);
+	return do_arch_prctl_64(current, code, arg2);
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 9cc7d5a330ef..7e9996c0058b 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -390,31 +390,31 @@ static int putreg(struct task_struct *child,
 	case offsetof(struct user_regs_struct, flags):
 		return set_flags(child, value);
 
 #ifdef CONFIG_X86_64
 	case offsetof(struct user_regs_struct,fs_base):
 		if (value >= TASK_SIZE_MAX)
 			return -EIO;
 		/*
-		 * When changing the segment base, use do_arch_prctl
+		 * When changing the segment base, use do_arch_prctl_64
 		 * to set either thread.fs or thread.fsindex and the
 		 * corresponding GDT slot.
 		 */
 		if (child->thread.fsbase != value)
-			return do_arch_prctl(child, ARCH_SET_FS, value);
+			return do_arch_prctl_64(child, ARCH_SET_FS, value);
 		return 0;
 	case offsetof(struct user_regs_struct,gs_base):
 		/*
 		 * Exactly the same here as the %fs handling above.
 		 */
 		if (value >= TASK_SIZE_MAX)
 			return -EIO;
 		if (child->thread.gsbase != value)
-			return do_arch_prctl(child, ARCH_SET_GS, value);
+			return do_arch_prctl_64(child, ARCH_SET_GS, value);
 		return 0;
 #endif
 	}
 
 	*pt_regs_access(task_pt_regs(child), offset) = value;
 	return 0;
 }
 
@@ -863,17 +863,17 @@ long arch_ptrace(struct task_struct *child, long request,
 		break;
 #endif
 
 #ifdef CONFIG_X86_64
 		/* normal 64bit interface to access TLS data.
 		   Works just like arch_prctl, except that the arguments
 		   are reversed. */
 	case PTRACE_ARCH_PRCTL:
-		ret = do_arch_prctl(child, data, addr);
+		ret = do_arch_prctl_64(child, data, addr);
 		break;
 #endif
 
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c
index 96eb2bd28832..efc9d7484e72 100644
--- a/arch/x86/um/os-Linux/prctl.c
+++ b/arch/x86/um/os-Linux/prctl.c
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
  * Licensed under the GPL
  */
 
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 
-int os_arch_prctl(int pid, int code, unsigned long *addr)
+int os_arch_prctl(int pid, int code, unsigned long *arg2)
 {
-        return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code);
+	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, code);
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index ab3f7f426279..d472c6b79a90 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -6,19 +6,19 @@
  */
 
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
-long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
+long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 {
-	unsigned long *ptr = addr, tmp;
+	unsigned long *ptr = arg2, tmp;
 	long ret;
 	int pid = task->mm->context.id.u.pid;
 
 	/*
 	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
 	 * be safe), we need to call arch_prctl on the host because
 	 * setting %fs may result in something else happening (like a
 	 * GDT or thread.fs being set instead).  So, we let the host
@@ -58,29 +58,29 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 	case ARCH_SET_FS:
 		current->thread.arch.fs = (unsigned long) ptr;
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_SET_GS:
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_GET_FS:
-		ret = put_user(tmp, addr);
+		ret = put_user(tmp, arg2);
 		break;
 	case ARCH_GET_GS:
-		ret = put_user(tmp, addr);
+		ret = put_user(tmp, arg2);
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return arch_prctl(current, code, (unsigned long __user *) addr);
+	return arch_prctl(current, code, (unsigned long __user *) arg2);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
 
 	arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 2/9] x86/arch_prctl/64: Rename do_arch_prctl to do_arch_prctl_64
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

In order to introduce new arch_prctls that are not 64 bit only, rename the
existing 64 bit implementation to do_arch_prctl_64(). Also rename the second
argument to arch_prctl(), which will no longer always be an address.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: Andy Lutomirski <luto@kernel.org>
---
 arch/um/include/shared/os.h  |  2 +-
 arch/x86/include/asm/proto.h |  3 +--
 arch/x86/kernel/process_64.c | 32 +++++++++++++++++---------------
 arch/x86/kernel/ptrace.c     |  8 ++++----
 arch/x86/um/os-Linux/prctl.c |  4 ++--
 arch/x86/um/syscalls_64.c    | 12 ++++++------
 6 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index de5d572225f3..2b47e0e8d414 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -298,17 +298,17 @@ extern void os_set_ioignore(void);
 
 /* sigio.c */
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
 extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
-extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+extern int os_arch_prctl(int pid, int code, unsigned long *arg2);
 
 /* tty.c */
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
 extern unsigned long os_get_top_address(void);
 
 long syscall(long number, ...);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 9b9b30b19441..f8e9194e100c 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -4,16 +4,17 @@
 #include <asm/ldt.h>
 
 /* misc architecture specific prototypes */
 
 void syscall_init(void);
 
 #ifdef CONFIG_X86_64
 void entry_SYSCALL_64(void);
+long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2);
 #endif
 
 #ifdef CONFIG_X86_32
 void entry_INT80_32(void);
 void entry_SYSENTER_32(void);
 void __begin_SYSENTER_singlestep_region(void);
 void __end_SYSENTER_singlestep_region(void);
 #endif
@@ -25,11 +26,9 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
-long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
-
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c0ecc237bd9b..83e011566db0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -198,17 +198,17 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
 	 */
 	if (clone_flags & CLONE_SETTLS) {
 #ifdef CONFIG_IA32_EMULATION
 		if (in_ia32_syscall())
 			err = do_set_thread_area(p, -1,
 				(struct user_desc __user *)tls, 0);
 		else
 #endif
-			err = do_arch_prctl(p, ARCH_SET_FS, tls);
+			err = do_arch_prctl_64(p, ARCH_SET_FS, tls);
 		if (err)
 			goto out;
 	}
 	err = 0;
 out:
 	if (err && p->thread.io_bitmap_ptr) {
 		kfree(p->thread.io_bitmap_ptr);
 		p->thread.io_bitmap_max = 0;
@@ -541,91 +541,93 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr)
 	ret = map_vdso_once(image, addr);
 	if (ret)
 		return ret;
 
 	return (long)image->size;
 }
 #endif
 
-long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
+long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 {
 	int ret = 0;
 	int doit = task == current;
 	int cpu;
 
 	switch (code) {
 	case ARCH_SET_GS:
-		if (addr >= TASK_SIZE_MAX)
+		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.gsindex = 0;
-		task->thread.gsbase = addr;
+		task->thread.gsbase = arg2;
 		if (doit) {
 			load_gs_index(0);
-			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
+			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, arg2);
 		}
 		put_cpu();
 		break;
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
 		   with gs */
-		if (addr >= TASK_SIZE_MAX)
+		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.fsindex = 0;
-		task->thread.fsbase = addr;
+		task->thread.fsbase = arg2;
 		if (doit) {
 			/* set the selector to 0 to not confuse __switch_to */
 			loadsegment(fs, 0);
-			ret = wrmsrl_safe(MSR_FS_BASE, addr);
+			ret = wrmsrl_safe(MSR_FS_BASE, arg2);
 		}
 		put_cpu();
 		break;
 	case ARCH_GET_FS: {
 		unsigned long base;
+
 		if (doit)
 			rdmsrl(MSR_FS_BASE, base);
 		else
 			base = task->thread.fsbase;
-		ret = put_user(base, (unsigned long __user *)addr);
+		ret = put_user(base, (unsigned long __user *)arg2);
 		break;
 	}
 	case ARCH_GET_GS: {
 		unsigned long base;
+
 		if (doit)
 			rdmsrl(MSR_KERNEL_GS_BASE, base);
 		else
 			base = task->thread.gsbase;
-		ret = put_user(base, (unsigned long __user *)addr);
+		ret = put_user(base, (unsigned long __user *)arg2);
 		break;
 	}
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
 # ifdef CONFIG_X86_X32_ABI
 	case ARCH_MAP_VDSO_X32:
-		return prctl_map_vdso(&vdso_image_x32, addr);
+		return prctl_map_vdso(&vdso_image_x32, arg2);
 # endif
 # if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
 	case ARCH_MAP_VDSO_32:
-		return prctl_map_vdso(&vdso_image_32, addr);
+		return prctl_map_vdso(&vdso_image_32, arg2);
 # endif
 	case ARCH_MAP_VDSO_64:
-		return prctl_map_vdso(&vdso_image_64, addr);
+		return prctl_map_vdso(&vdso_image_64, arg2);
 #endif
 
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return do_arch_prctl(current, code, addr);
+	return do_arch_prctl_64(current, code, arg2);
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 9cc7d5a330ef..7e9996c0058b 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -390,31 +390,31 @@ static int putreg(struct task_struct *child,
 	case offsetof(struct user_regs_struct, flags):
 		return set_flags(child, value);
 
 #ifdef CONFIG_X86_64
 	case offsetof(struct user_regs_struct,fs_base):
 		if (value >= TASK_SIZE_MAX)
 			return -EIO;
 		/*
-		 * When changing the segment base, use do_arch_prctl
+		 * When changing the segment base, use do_arch_prctl_64
 		 * to set either thread.fs or thread.fsindex and the
 		 * corresponding GDT slot.
 		 */
 		if (child->thread.fsbase != value)
-			return do_arch_prctl(child, ARCH_SET_FS, value);
+			return do_arch_prctl_64(child, ARCH_SET_FS, value);
 		return 0;
 	case offsetof(struct user_regs_struct,gs_base):
 		/*
 		 * Exactly the same here as the %fs handling above.
 		 */
 		if (value >= TASK_SIZE_MAX)
 			return -EIO;
 		if (child->thread.gsbase != value)
-			return do_arch_prctl(child, ARCH_SET_GS, value);
+			return do_arch_prctl_64(child, ARCH_SET_GS, value);
 		return 0;
 #endif
 	}
 
 	*pt_regs_access(task_pt_regs(child), offset) = value;
 	return 0;
 }
 
@@ -863,17 +863,17 @@ long arch_ptrace(struct task_struct *child, long request,
 		break;
 #endif
 
 #ifdef CONFIG_X86_64
 		/* normal 64bit interface to access TLS data.
 		   Works just like arch_prctl, except that the arguments
 		   are reversed. */
 	case PTRACE_ARCH_PRCTL:
-		ret = do_arch_prctl(child, data, addr);
+		ret = do_arch_prctl_64(child, data, addr);
 		break;
 #endif
 
 	default:
 		ret = ptrace_request(child, request, addr, data);
 		break;
 	}
 
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c
index 96eb2bd28832..efc9d7484e72 100644
--- a/arch/x86/um/os-Linux/prctl.c
+++ b/arch/x86/um/os-Linux/prctl.c
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
  * Licensed under the GPL
  */
 
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 
-int os_arch_prctl(int pid, int code, unsigned long *addr)
+int os_arch_prctl(int pid, int code, unsigned long *arg2)
 {
-        return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code);
+	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, code);
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index ab3f7f426279..d472c6b79a90 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -6,19 +6,19 @@
  */
 
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
-long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
+long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 {
-	unsigned long *ptr = addr, tmp;
+	unsigned long *ptr = arg2, tmp;
 	long ret;
 	int pid = task->mm->context.id.u.pid;
 
 	/*
 	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
 	 * be safe), we need to call arch_prctl on the host because
 	 * setting %fs may result in something else happening (like a
 	 * GDT or thread.fs being set instead).  So, we let the host
@@ -58,29 +58,29 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 	case ARCH_SET_FS:
 		current->thread.arch.fs = (unsigned long) ptr;
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_SET_GS:
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_GET_FS:
-		ret = put_user(tmp, addr);
+		ret = put_user(tmp, arg2);
 		break;
 	case ARCH_GET_GS:
-		ret = put_user(tmp, addr);
+		ret = put_user(tmp, arg2);
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, addr)
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return arch_prctl(current, code, (unsigned long __user *) addr);
+	return arch_prctl(current, code, (unsigned long __user *) arg2);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
 
 	arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 3/9] x86/arch_prctl: Add do_arch_prctl_common
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Add do_arch_prctl_common() to handle arch_prctls that are not specific to 64
bit mode. Call it from the syscall entry point, but not any of the other
callsites in the kernel, which all want one of the existing 64 bit only
arch_prctls.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/include/asm/proto.h | 3 +++
 arch/x86/kernel/process.c    | 6 ++++++
 arch/x86/kernel/process_64.c | 8 +++++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index f8e9194e100c..99836d9a893a 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -26,9 +26,12 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
+long do_arch_prctl_common(struct task_struct *task, int code,
+			  unsigned long cpuid_enabled);
+
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4f76b17045cc..edf645e331d0 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -519,8 +519,14 @@ unsigned long get_wchan(struct task_struct *p)
 		}
 		fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
 	} while (count++ < 16 && p->state != TASK_RUNNING);
 
 out:
 	put_task_stack(p);
 	return ret;
 }
+
+long do_arch_prctl_common(struct task_struct *task, int code,
+			  unsigned long cpuid_enabled)
+{
+	return -EINVAL;
+}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 83e011566db0..4db1ebcf18e0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -619,15 +619,21 @@ long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 		break;
 	}
 
 	return ret;
 }
 
 SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return do_arch_prctl_64(current, code, arg2);
+	long ret;
+
+	ret = do_arch_prctl_64(current, code, arg2);
+	if (ret == -EINVAL)
+		ret = do_arch_prctl_common(current, code, arg2);
+
+	return ret;
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 3/9] x86/arch_prctl: Add do_arch_prctl_common
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Add do_arch_prctl_common() to handle arch_prctls that are not specific to 64
bit mode. Call it from the syscall entry point, but not any of the other
callsites in the kernel, which all want one of the existing 64 bit only
arch_prctls.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/include/asm/proto.h | 3 +++
 arch/x86/kernel/process.c    | 6 ++++++
 arch/x86/kernel/process_64.c | 8 +++++++-
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index f8e9194e100c..99836d9a893a 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -26,9 +26,12 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
+long do_arch_prctl_common(struct task_struct *task, int code,
+			  unsigned long cpuid_enabled);
+
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4f76b17045cc..edf645e331d0 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -519,8 +519,14 @@ unsigned long get_wchan(struct task_struct *p)
 		}
 		fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
 	} while (count++ < 16 && p->state != TASK_RUNNING);
 
 out:
 	put_task_stack(p);
 	return ret;
 }
+
+long do_arch_prctl_common(struct task_struct *task, int code,
+			  unsigned long cpuid_enabled)
+{
+	return -EINVAL;
+}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 83e011566db0..4db1ebcf18e0 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -619,15 +619,21 @@ long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 		break;
 	}
 
 	return ret;
 }
 
 SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 {
-	return do_arch_prctl_64(current, code, arg2);
+	long ret;
+
+	ret = do_arch_prctl_64(current, code, arg2);
+	if (ret == -EINVAL)
+		ret = do_arch_prctl_common(current, code, arg2);
+
+	return ret;
 }
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 4/9] x86/syscalls/32: Wire up arch_prctl on x86-32
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Hook up arch_prctl to call do_arch_prctl() on x86-32, and in 32 bit compat
mode on x86-64. This allows us to have arch_prctls that are not specific to
64 bits.

On UML, simply stub out this syscall.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/entry/syscalls/syscall_32.tbl | 1 +
 arch/x86/kernel/process_32.c           | 7 +++++++
 arch/x86/kernel/process_64.c           | 7 +++++++
 arch/x86/um/Makefile                   | 2 +-
 arch/x86/um/syscalls_32.c              | 7 +++++++
 include/linux/compat.h                 | 2 ++
 6 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/um/syscalls_32.c

diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 2b3618542544..d78c6b53e9a2 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -384,8 +384,9 @@
 375	i386	membarrier		sys_membarrier
 376	i386	mlock2			sys_mlock2
 377	i386	copy_file_range		sys_copy_file_range
 378	i386	preadv2			sys_preadv2			compat_sys_preadv2
 379	i386	pwritev2		sys_pwritev2			compat_sys_pwritev2
 380	i386	pkey_mprotect		sys_pkey_mprotect
 381	i386	pkey_alloc		sys_pkey_alloc
 382	i386	pkey_free		sys_pkey_free
+385	i386	arch_prctl		sys_arch_prctl			compat_sys_arch_prctl
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index a0ac3e81518a..c24e72d7ce83 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -30,16 +30,17 @@
 #include <linux/ptrace.h>
 #include <linux/personality.h>
 #include <linux/percpu.h>
 #include <linux/prctl.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/kdebug.h>
+#include <linux/syscalls.h>
 
 #include <asm/pgtable.h>
 #include <asm/ldt.h>
 #include <asm/processor.h>
 #include <asm/fpu/internal.h>
 #include <asm/desc.h>
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
@@ -49,16 +50,17 @@
 
 #include <asm/tlbflush.h>
 #include <asm/cpu.h>
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
 #include <asm/vm86.h>
 #include <asm/intel_rdt.h>
+#include <asm/proto.h>
 
 void __show_regs(struct pt_regs *regs, int all)
 {
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned long sp;
 	unsigned short ss, gs;
 
@@ -297,8 +299,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	this_cpu_write(current_task, next_p);
 
 	/* Load the Intel cache allocation PQR MSR. */
 	intel_rdt_sched_in();
 
 	return prev_p;
 }
+
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return do_arch_prctl_common(current, code, arg2);
+}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4db1ebcf18e0..e67cd9557ff8 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -628,12 +628,19 @@ SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 
 	ret = do_arch_prctl_64(current, code, arg2);
 	if (ret == -EINVAL)
 		ret = do_arch_prctl_common(current, code, arg2);
 
 	return ret;
 }
 
+#ifdef CONFIG_IA32_EMULATION
+COMPAT_SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return do_arch_prctl_common(current, code, arg2);
+}
+#endif
+
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index e7e7055a8658..69f0827d5f53 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -11,17 +11,17 @@ endif
 obj-y = bug.o bugs_$(BITS).o delay.o fault.o ldt.o \
 	ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \
 	stub_$(BITS).o stub_segv.o \
 	sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \
 	mem_$(BITS).o subarch.o os-$(OS)/
 
 ifeq ($(CONFIG_X86_32),y)
 
-obj-y += checksum_32.o
+obj-y += checksum_32.o syscalls_32.o
 obj-$(CONFIG_ELF_CORE) += elfcore.o
 
 subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o
 subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o
 
 else
 
 obj-y += syscalls_64.o vdso/
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c
new file mode 100644
index 000000000000..ccf0598c3fc0
--- /dev/null
+++ b/arch/x86/um/syscalls_32.c
@@ -0,0 +1,7 @@
+#include <linux/syscalls.h>
+#include <os.h>
+
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return -EINVAL;
+}
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 63609398ef9f..0ddfc2ba0d06 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -716,16 +716,18 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 } while (0);
 
 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 						 struct compat_timespec __user *interval);
 
 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
 					    int, const char __user *);
 
+asmlinkage long compat_sys_arch_prctl(int code, unsigned long arg2);
+
 /*
  * For most but not all architectures, "am I in a compat syscall?" and
  * "am I a compat task?" are the same question.  For architectures on which
  * they aren't the same question, arch code can override in_compat_syscall.
  */
 
 #ifndef in_compat_syscall
 static inline bool in_compat_syscall(void) { return is_compat_task(); }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 4/9] x86/syscalls/32: Wire up arch_prctl on x86-32
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Hook up arch_prctl to call do_arch_prctl() on x86-32, and in 32 bit compat
mode on x86-64. This allows us to have arch_prctls that are not specific to
64 bits.

On UML, simply stub out this syscall.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/entry/syscalls/syscall_32.tbl | 1 +
 arch/x86/kernel/process_32.c           | 7 +++++++
 arch/x86/kernel/process_64.c           | 7 +++++++
 arch/x86/um/Makefile                   | 2 +-
 arch/x86/um/syscalls_32.c              | 7 +++++++
 include/linux/compat.h                 | 2 ++
 6 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/um/syscalls_32.c

diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index 2b3618542544..d78c6b53e9a2 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -384,8 +384,9 @@
 375	i386	membarrier		sys_membarrier
 376	i386	mlock2			sys_mlock2
 377	i386	copy_file_range		sys_copy_file_range
 378	i386	preadv2			sys_preadv2			compat_sys_preadv2
 379	i386	pwritev2		sys_pwritev2			compat_sys_pwritev2
 380	i386	pkey_mprotect		sys_pkey_mprotect
 381	i386	pkey_alloc		sys_pkey_alloc
 382	i386	pkey_free		sys_pkey_free
+385	i386	arch_prctl		sys_arch_prctl			compat_sys_arch_prctl
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index a0ac3e81518a..c24e72d7ce83 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -30,16 +30,17 @@
 #include <linux/ptrace.h>
 #include <linux/personality.h>
 #include <linux/percpu.h>
 #include <linux/prctl.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/kdebug.h>
+#include <linux/syscalls.h>
 
 #include <asm/pgtable.h>
 #include <asm/ldt.h>
 #include <asm/processor.h>
 #include <asm/fpu/internal.h>
 #include <asm/desc.h>
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
@@ -49,16 +50,17 @@
 
 #include <asm/tlbflush.h>
 #include <asm/cpu.h>
 #include <asm/syscalls.h>
 #include <asm/debugreg.h>
 #include <asm/switch_to.h>
 #include <asm/vm86.h>
 #include <asm/intel_rdt.h>
+#include <asm/proto.h>
 
 void __show_regs(struct pt_regs *regs, int all)
 {
 	unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
 	unsigned long d0, d1, d2, d3, d6, d7;
 	unsigned long sp;
 	unsigned short ss, gs;
 
@@ -297,8 +299,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	this_cpu_write(current_task, next_p);
 
 	/* Load the Intel cache allocation PQR MSR. */
 	intel_rdt_sched_in();
 
 	return prev_p;
 }
+
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return do_arch_prctl_common(current, code, arg2);
+}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4db1ebcf18e0..e67cd9557ff8 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -628,12 +628,19 @@ SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
 
 	ret = do_arch_prctl_64(current, code, arg2);
 	if (ret == -EINVAL)
 		ret = do_arch_prctl_common(current, code, arg2);
 
 	return ret;
 }
 
+#ifdef CONFIG_IA32_EMULATION
+COMPAT_SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return do_arch_prctl_common(current, code, arg2);
+}
+#endif
+
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile
index e7e7055a8658..69f0827d5f53 100644
--- a/arch/x86/um/Makefile
+++ b/arch/x86/um/Makefile
@@ -11,17 +11,17 @@ endif
 obj-y = bug.o bugs_$(BITS).o delay.o fault.o ldt.o \
 	ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \
 	stub_$(BITS).o stub_segv.o \
 	sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \
 	mem_$(BITS).o subarch.o os-$(OS)/
 
 ifeq ($(CONFIG_X86_32),y)
 
-obj-y += checksum_32.o
+obj-y += checksum_32.o syscalls_32.o
 obj-$(CONFIG_ELF_CORE) += elfcore.o
 
 subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o
 subarch-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += ../lib/rwsem.o
 
 else
 
 obj-y += syscalls_64.o vdso/
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c
new file mode 100644
index 000000000000..ccf0598c3fc0
--- /dev/null
+++ b/arch/x86/um/syscalls_32.c
@@ -0,0 +1,7 @@
+#include <linux/syscalls.h>
+#include <os.h>
+
+SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+{
+	return -EINVAL;
+}
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 63609398ef9f..0ddfc2ba0d06 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -716,16 +716,18 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 } while (0);
 
 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 						 struct compat_timespec __user *interval);
 
 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
 					    int, const char __user *);
 
+asmlinkage long compat_sys_arch_prctl(int code, unsigned long arg2);
+
 /*
  * For most but not all architectures, "am I in a compat syscall?" and
  * "am I a compat task?" are the same question.  For architectures on which
  * they aren't the same question, arch code can override in_compat_syscall.
  */
 
 #ifndef in_compat_syscall
 static inline bool in_compat_syscall(void) { return is_compat_task(); }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 5/9] x86/cpufeature: Detect CPUID faulting support
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Intel supports faulting on the CPUID instruction beginning with Ivy Bridge.
When enabled, the processor will fault on attempts to execute the CPUID
instruction with CPL>0. This will allow a ptracer to emulate the CPUID
instruction.

Bit 31 of MSR_PLATFORM_INFO advertises support for this feature. It is
documented in detail in Section 2.3.2 of
https://bugzilla.kernel.org/attachment.cgi?id=243991

Detect support for this feature and expose it as X86_FEATURE_CPUID_FAULT.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/include/asm/msr-index.h   |  2 ++
 arch/x86/kernel/cpu/intel.c        | 12 ++++++++++++
 3 files changed, 15 insertions(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index eafee3161d1c..c70cab24f648 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -182,16 +182,17 @@
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
  * CPUID levels like 0x6, 0xA etc, word 7.
  *
  * Reuse free bits when adding new feature flags!
  */
 
+#define X86_FEATURE_CPUID_FAULT ( 7*32+ 0) /* Intel CPUID faulting */
 #define X86_FEATURE_CPB		( 7*32+ 2) /* AMD Core Performance Boost */
 #define X86_FEATURE_EPB		( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
 #define X86_FEATURE_CAT_L3	( 7*32+ 4) /* Cache Allocation Technology L3 */
 #define X86_FEATURE_CAT_L2	( 7*32+ 5) /* Cache Allocation Technology L2 */
 #define X86_FEATURE_CDP_L3	( 7*32+ 6) /* Code and Data Prioritization L3 */
 
 #define X86_FEATURE_HW_PSTATE	( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 710273c617b8..8192b3111c84 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -40,16 +40,18 @@
 
 #define MSR_PPIN_CTL			0x0000004e
 #define MSR_PPIN			0x0000004f
 
 #define MSR_IA32_PERFCTR0		0x000000c1
 #define MSR_IA32_PERFCTR1		0x000000c2
 #define MSR_FSB_FREQ			0x000000cd
 #define MSR_PLATFORM_INFO		0x000000ce
+#define MSR_PLATFORM_INFO_CPUID_FAULT_BIT	31
+#define MSR_PLATFORM_INFO_CPUID_FAULT		BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT)
 
 #define MSR_NHM_SNB_PKG_CST_CFG_CTL	0x000000e2
 #define NHM_C3_AUTO_DEMOTE		(1UL << 25)
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
 #define ATM_LNC_C6_AUTO_DEMOTE		(1UL << 25)
 #define SNB_C1_AUTO_UNDEMOTE		(1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE		(1UL << 28)
 
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 203f860d2ab3..3d9e11b2b41a 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -442,16 +442,26 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c)
 {
 	/*
 	 * MSR_IA32_ENERGY_PERF_BIAS is lost across suspend/resume,
 	 * so reinitialize it properly like during bootup:
 	 */
 	init_intel_energy_perf(c);
 }
 
+static void init_intel_misc_features(struct cpuinfo_x86 *c)
+{
+	u64 msr;
+
+	if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) {
+		if (msr & MSR_PLATFORM_INFO_CPUID_FAULT)
+			set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
+	}
+}
+
 static void init_intel(struct cpuinfo_x86 *c)
 {
 	unsigned int l2 = 0;
 
 	early_init_intel(c);
 
 	intel_workarounds(c);
 
@@ -555,16 +565,18 @@ static void init_intel(struct cpuinfo_x86 *c)
 
 	/* Work around errata */
 	srat_detect_node(c);
 
 	if (cpu_has(c, X86_FEATURE_VMX))
 		detect_vmx_virtcap(c);
 
 	init_intel_energy_perf(c);
+
+	init_intel_misc_features(c);
 }
 
 #ifdef CONFIG_X86_32
 static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
 	/*
 	 * Intel PIII Tualatin. This comes in two flavours.
 	 * One has 256kb of cache, the other 512. We have no way
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 5/9] x86/cpufeature: Detect CPUID faulting support
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Intel supports faulting on the CPUID instruction beginning with Ivy Bridge.
When enabled, the processor will fault on attempts to execute the CPUID
instruction with CPL>0. This will allow a ptracer to emulate the CPUID
instruction.

Bit 31 of MSR_PLATFORM_INFO advertises support for this feature. It is
documented in detail in Section 2.3.2 of
https://bugzilla.kernel.org/attachment.cgi?id=243991

Detect support for this feature and expose it as X86_FEATURE_CPUID_FAULT.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/include/asm/msr-index.h   |  2 ++
 arch/x86/kernel/cpu/intel.c        | 12 ++++++++++++
 3 files changed, 15 insertions(+)

diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index eafee3161d1c..c70cab24f648 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -182,16 +182,17 @@
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
  * CPUID levels like 0x6, 0xA etc, word 7.
  *
  * Reuse free bits when adding new feature flags!
  */
 
+#define X86_FEATURE_CPUID_FAULT ( 7*32+ 0) /* Intel CPUID faulting */
 #define X86_FEATURE_CPB		( 7*32+ 2) /* AMD Core Performance Boost */
 #define X86_FEATURE_EPB		( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */
 #define X86_FEATURE_CAT_L3	( 7*32+ 4) /* Cache Allocation Technology L3 */
 #define X86_FEATURE_CAT_L2	( 7*32+ 5) /* Cache Allocation Technology L2 */
 #define X86_FEATURE_CDP_L3	( 7*32+ 6) /* Code and Data Prioritization L3 */
 
 #define X86_FEATURE_HW_PSTATE	( 7*32+ 8) /* AMD HW-PState */
 #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 710273c617b8..8192b3111c84 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -40,16 +40,18 @@
 
 #define MSR_PPIN_CTL			0x0000004e
 #define MSR_PPIN			0x0000004f
 
 #define MSR_IA32_PERFCTR0		0x000000c1
 #define MSR_IA32_PERFCTR1		0x000000c2
 #define MSR_FSB_FREQ			0x000000cd
 #define MSR_PLATFORM_INFO		0x000000ce
+#define MSR_PLATFORM_INFO_CPUID_FAULT_BIT	31
+#define MSR_PLATFORM_INFO_CPUID_FAULT		BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT)
 
 #define MSR_NHM_SNB_PKG_CST_CFG_CTL	0x000000e2
 #define NHM_C3_AUTO_DEMOTE		(1UL << 25)
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
 #define ATM_LNC_C6_AUTO_DEMOTE		(1UL << 25)
 #define SNB_C1_AUTO_UNDEMOTE		(1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE		(1UL << 28)
 
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 203f860d2ab3..3d9e11b2b41a 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -442,16 +442,26 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c)
 {
 	/*
 	 * MSR_IA32_ENERGY_PERF_BIAS is lost across suspend/resume,
 	 * so reinitialize it properly like during bootup:
 	 */
 	init_intel_energy_perf(c);
 }
 
+static void init_intel_misc_features(struct cpuinfo_x86 *c)
+{
+	u64 msr;
+
+	if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) {
+		if (msr & MSR_PLATFORM_INFO_CPUID_FAULT)
+			set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
+	}
+}
+
 static void init_intel(struct cpuinfo_x86 *c)
 {
 	unsigned int l2 = 0;
 
 	early_init_intel(c);
 
 	intel_workarounds(c);
 
@@ -555,16 +565,18 @@ static void init_intel(struct cpuinfo_x86 *c)
 
 	/* Work around errata */
 	srat_detect_node(c);
 
 	if (cpu_has(c, X86_FEATURE_VMX))
 		detect_vmx_virtcap(c);
 
 	init_intel_energy_perf(c);
+
+	init_intel_misc_features(c);
 }
 
 #ifdef CONFIG_X86_32
 static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
 {
 	/*
 	 * Intel PIII Tualatin. This comes in two flavours.
 	 * One has 256kb of cache, the other 512. We have no way
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 6/9] x86/arch_prctl: Add ARCH_[GET|SET]_CPUID
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Intel supports faulting on the CPUID instruction beginning with Ivy Bridge.
When enabled, the processor will fault on attempts to execute the CPUID
instruction with CPL>0. Exposing this feature to userspace will allow a
ptracer to trap and emulate the CPUID instruction.

When supported, this feature is controlled by toggling bit 0 of
MSR_MISC_FEATURES_ENABLES. It is documented in detail in Section 2.3.2 of
https://bugzilla.kernel.org/attachment.cgi?id=243991

Implement a new pair of arch_prctls, available on both x86-32 and x86-64.

ARCH_GET_CPUID: Returns the current CPUID state, either 0 if CPUID faulting
    is enabled (and thus the CPUID instruction is not available) or 1 if
    CPUID faulting is not enabled.

ARCH_SET_CPUID: Set the CPUID state to the second argument. If
    cpuid_enabled is 0 CPUID faulting will be activated, otherwise it will
    be deactivated. Returns ENODEV if CPUID faulting is not supported on
    this system.

The state of the CPUID faulting flag is propagated across forks, but reset
upon exec.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/include/asm/msr-index.h   |  3 ++
 arch/x86/include/asm/processor.h   |  2 +
 arch/x86/include/asm/thread_info.h |  6 ++-
 arch/x86/include/uapi/asm/prctl.h  |  9 +++++
 arch/x86/kernel/cpu/intel.c        |  7 ++++
 arch/x86/kernel/process.c          | 78 ++++++++++++++++++++++++++++++++++++++
 fs/exec.c                          |  1 +
 include/linux/thread_info.h        |  4 ++
 8 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 8192b3111c84..a760e25c3763 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -53,16 +53,19 @@
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
 #define ATM_LNC_C6_AUTO_DEMOTE		(1UL << 25)
 #define SNB_C1_AUTO_UNDEMOTE		(1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE		(1UL << 28)
 
 #define MSR_MTRRcap			0x000000fe
 #define MSR_IA32_BBL_CR_CTL		0x00000119
 #define MSR_IA32_BBL_CR_CTL3		0x0000011e
+#define MSR_MISC_FEATURES_ENABLES	0x00000140
+#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT	0
+#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT		BIT_ULL(MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT)
 
 #define MSR_IA32_SYSENTER_CS		0x00000174
 #define MSR_IA32_SYSENTER_ESP		0x00000175
 #define MSR_IA32_SYSENTER_EIP		0x00000176
 
 #define MSR_IA32_MCG_CAP		0x00000179
 #define MSR_IA32_MCG_STATUS		0x0000017a
 #define MSR_IA32_MCG_CTL		0x0000017b
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index f99d4148d610..ee997cb9f8ba 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -880,16 +880,18 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 
 /* Get/set a process' ability to use the timestamp counter instruction */
 #define GET_TSC_CTL(adr)	get_tsc_mode((adr))
 #define SET_TSC_CTL(val)	set_tsc_mode((val))
 
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
+DECLARE_PER_CPU(u64, msr_misc_features_shadow);
+
 /* Register/unregister a process' MPX related resource */
 #define MPX_ENABLE_MANAGEMENT()	mpx_enable_management()
 #define MPX_DISABLE_MANAGEMENT()	mpx_disable_management()
 
 #ifdef CONFIG_X86_INTEL_MPX
 extern int mpx_enable_management(void);
 extern int mpx_disable_management(void);
 #else
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index ad6f5eb07a95..9fc44b95f7cb 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -82,16 +82,17 @@ struct thread_info {
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* reenable singlestep on user return*/
 #define TIF_SYSCALL_EMU		6	/* syscall emulation active */
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
 #define TIF_UPROBE		12	/* breakpointed or singlestepping */
+#define TIF_NOCPUID		15	/* CPUID is not accessible in userland */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* IA32 compatibility process */
 #define TIF_NOHZ		19	/* in adaptive nohz mode */
 #define TIF_MEMDIE		20	/* is terminating due to OOM killer */
 #define TIF_POLLING_NRFLAG	21	/* idle is polling for TIF_NEED_RESCHED */
 #define TIF_IO_BITMAP		22	/* uses I/O bitmap */
 #define TIF_FORCED_TF		24	/* true if TF in eflags artificially */
 #define TIF_BLOCKSTEP		25	/* set when we want DEBUGCTLMSR_BTF */
@@ -105,16 +106,17 @@ struct thread_info {
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
 #define _TIF_UPROBE		(1 << TIF_UPROBE)
+#define _TIF_NOCPUID		(1 << TIF_NOCPUID)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_NOHZ		(1 << TIF_NOHZ)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
 #define _TIF_BLOCKSTEP		(1 << TIF_BLOCKSTEP)
 #define _TIF_LAZY_MMU_UPDATES	(1 << TIF_LAZY_MMU_UPDATES)
@@ -133,17 +135,17 @@ struct thread_info {
 
 /* work to do on any return to user space */
 #define _TIF_ALLWORK_MASK						\
 	((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT |	\
 	_TIF_NOHZ)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW							\
-	(_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
+	(_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP)
 
 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
 
 #define STACK_WARN		(THREAD_SIZE/8)
 
 /*
  * macros/functions for gaining access to the thread information structure
@@ -234,11 +236,13 @@ static inline int arch_within_stack_frames(const void * const stack,
  * EFLAGS values that other (fast) syscall return instructions
  * are not able to restore properly.
  */
 #define force_iret() set_thread_flag(TIF_NOTIFY_RESUME)
 
 extern void arch_task_cache_init(void);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 extern void arch_release_task_struct(struct task_struct *tsk);
+extern void arch_setup_new_exec(void);
+#define arch_setup_new_exec arch_setup_new_exec
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* _ASM_X86_THREAD_INFO_H */
diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h
index 835aa51c7f6e..5dbbd1be6b97 100644
--- a/arch/x86/include/uapi/asm/prctl.h
+++ b/arch/x86/include/uapi/asm/prctl.h
@@ -1,13 +1,22 @@
 #ifndef _ASM_X86_PRCTL_H
 #define _ASM_X86_PRCTL_H
 
 #define ARCH_SET_GS 0x1001
 #define ARCH_SET_FS 0x1002
 #define ARCH_GET_FS 0x1003
 #define ARCH_GET_GS 0x1004
 
+#define ARCH_GET_CPUID 0x1005
+#define ARCH_SET_CPUID 0x1006
+
 #define ARCH_MAP_VDSO_X32	0x2001
 #define ARCH_MAP_VDSO_32	0x2002
 #define ARCH_MAP_VDSO_64	0x2003
 
+#ifdef CONFIG_CHECKPOINT_RESTORE
+# define ARCH_MAP_VDSO_X32	0x2001
+# define ARCH_MAP_VDSO_32	0x2002
+# define ARCH_MAP_VDSO_64	0x2003
+#endif
+
 #endif /* _ASM_X86_PRCTL_H */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 3d9e11b2b41a..f8ba14cf4a56 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -446,16 +446,23 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c)
 	 */
 	init_intel_energy_perf(c);
 }
 
 static void init_intel_misc_features(struct cpuinfo_x86 *c)
 {
 	u64 msr;
 
+	if (rdmsrl_safe(MSR_MISC_FEATURES_ENABLES, &msr))
+		return;
+
+	msr = 0;
+	wrmsrl(MSR_MISC_FEATURES_ENABLES, msr);
+	this_cpu_write(msr_misc_features_shadow, msr);
+
 	if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) {
 		if (msr & MSR_PLATFORM_INFO_CPUID_FAULT)
 			set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
 	}
 }
 
 static void init_intel(struct cpuinfo_x86 *c)
 {
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index edf645e331d0..1c973b5ea70e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -27,16 +27,17 @@
 #include <asm/mwait.h>
 #include <asm/fpu/internal.h>
 #include <asm/debugreg.h>
 #include <asm/nmi.h>
 #include <asm/tlbflush.h>
 #include <asm/mce.h>
 #include <asm/vm86.h>
 #include <asm/switch_to.h>
+#include <asm/prctl.h>
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
  * no more per-task TSS's. The TSS size is kept cacheline-aligned
  * so they are allowed to end up in the .data..cacheline_aligned
  * section. Since TSS's are completely CPU-local, we want them
  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
  */
@@ -159,16 +160,83 @@ int set_tsc_mode(unsigned int val)
 	else if (val == PR_TSC_ENABLE)
 		enable_TSC();
 	else
 		return -EINVAL;
 
 	return 0;
 }
 
+DEFINE_PER_CPU(u64, msr_misc_features_shadow);
+
+static void set_cpuid_faulting(bool on)
+{
+	u64 msrval;
+
+	msrval = this_cpu_read(msr_misc_features_shadow);
+	msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
+	msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT);
+	this_cpu_write(msr_misc_features_shadow, msrval);
+	wrmsrl(MSR_MISC_FEATURES_ENABLES, msrval);
+}
+
+static void disable_cpuid(void)
+{
+	preempt_disable();
+	if (!test_and_set_thread_flag(TIF_NOCPUID)) {
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOCPUID in the current running context.
+		 */
+		set_cpuid_faulting(true);
+	}
+	preempt_enable();
+}
+
+static void enable_cpuid(void)
+{
+	preempt_disable();
+	if (test_and_clear_thread_flag(TIF_NOCPUID)) {
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOCPUID in the current running context.
+		 */
+		set_cpuid_faulting(false);
+	}
+	preempt_enable();
+}
+
+static int get_cpuid_mode(void)
+{
+	return !test_thread_flag(TIF_NOCPUID);
+}
+
+static int set_cpuid_mode(struct task_struct *task, unsigned long cpuid_enabled)
+{
+	if (!static_cpu_has(X86_FEATURE_CPUID_FAULT))
+		return -ENODEV;
+
+	if (cpuid_enabled)
+		enable_cpuid();
+	else
+		disable_cpuid();
+
+	return 0;
+}
+
+/*
+ * Called immediately after a successful exec.
+ */
+void arch_setup_new_exec(void)
+{
+	/* If cpuid was previously disabled for this task, re-enable it. */
+	if (test_thread_flag(TIF_NOCPUID))
+		enable_cpuid();
+}
+
 static inline void switch_to_bitmap(struct tss_struct *tss,
 				    struct thread_struct *prev,
 				    struct thread_struct *next,
 				    unsigned long tifp, unsigned long tifn)
 {
 	if (tifn & _TIF_IO_BITMAP) {
 		/*
 		 * Copy the relevant range of the IO bitmap.
@@ -199,16 +267,19 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 
 	propagate_user_return_notify(prev_p, next_p);
 
 	if ((tifp ^ tifn) & _TIF_BLOCKSTEP)
 		toggle_debugctlmsr(DEBUGCTLMSR_BTF);
 
 	if ((tifp ^ tifn) & _TIF_NOTSC)
 		cr4_toggle_bits(X86_CR4_TSD);
+
+	if ((tifp ^ tifn) & _TIF_NOCPUID)
+		set_cpuid_faulting(!!(tifn & _TIF_NOCPUID));
 }
 
 /*
  * Idle related variables and functions
  */
 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
 EXPORT_SYMBOL(boot_option_idle_override);
 
@@ -523,10 +594,17 @@ unsigned long get_wchan(struct task_struct *p)
 out:
 	put_task_stack(p);
 	return ret;
 }
 
 long do_arch_prctl_common(struct task_struct *task, int code,
 			  unsigned long cpuid_enabled)
 {
+	switch (code) {
+	case ARCH_GET_CPUID:
+		return get_cpuid_mode();
+	case ARCH_SET_CPUID:
+		return set_cpuid_mode(task, cpuid_enabled);
+	}
+
 	return -EINVAL;
 }
diff --git a/fs/exec.c b/fs/exec.c
index e57946610733..d4f9c6148984 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1310,16 +1310,17 @@ void setup_new_exec(struct linux_binprm * bprm)
 	/* This is the point of no return */
 	current->sas_ss_sp = current->sas_ss_size = 0;
 
 	if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))
 		set_dumpable(current->mm, SUID_DUMP_USER);
 	else
 		set_dumpable(current->mm, suid_dumpable);
 
+	arch_setup_new_exec();
 	perf_event_exec();
 	__set_task_comm(current, kbasename(bprm->filename), true);
 
 	/* Set the new mm task size. We have to do that late because it may
 	 * depend on TIF_32BIT which is only updated in flush_thread() on
 	 * some architectures like powerpc
 	 */
 	current->mm->task_size = TASK_SIZE;
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 58373875e8ee..1539e08757f3 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -96,11 +96,15 @@ static __always_inline void check_object_size(const void *ptr, unsigned long n,
 		__check_object_size(ptr, n, to_user);
 }
 #else
 static inline void check_object_size(const void *ptr, unsigned long n,
 				     bool to_user)
 { }
 #endif /* CONFIG_HARDENED_USERCOPY */
 
+#ifndef arch_setup_new_exec
+static inline void arch_setup_new_exec(void) {}
+#endif
+
 #endif	/* __KERNEL__ */
 
 #endif /* _LINUX_THREAD_INFO_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 6/9] x86/arch_prctl: Add ARCH_[GET|SET]_CPUID
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Intel supports faulting on the CPUID instruction beginning with Ivy Bridge.
When enabled, the processor will fault on attempts to execute the CPUID
instruction with CPL>0. Exposing this feature to userspace will allow a
ptracer to trap and emulate the CPUID instruction.

When supported, this feature is controlled by toggling bit 0 of
MSR_MISC_FEATURES_ENABLES. It is documented in detail in Section 2.3.2 of
https://bugzilla.kernel.org/attachment.cgi?id=243991

Implement a new pair of arch_prctls, available on both x86-32 and x86-64.

ARCH_GET_CPUID: Returns the current CPUID state, either 0 if CPUID faulting
    is enabled (and thus the CPUID instruction is not available) or 1 if
    CPUID faulting is not enabled.

ARCH_SET_CPUID: Set the CPUID state to the second argument. If
    cpuid_enabled is 0 CPUID faulting will be activated, otherwise it will
    be deactivated. Returns ENODEV if CPUID faulting is not supported on
    this system.

The state of the CPUID faulting flag is propagated across forks, but reset
upon exec.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/x86/include/asm/msr-index.h   |  3 ++
 arch/x86/include/asm/processor.h   |  2 +
 arch/x86/include/asm/thread_info.h |  6 ++-
 arch/x86/include/uapi/asm/prctl.h  |  9 +++++
 arch/x86/kernel/cpu/intel.c        |  7 ++++
 arch/x86/kernel/process.c          | 78 ++++++++++++++++++++++++++++++++++++++
 fs/exec.c                          |  1 +
 include/linux/thread_info.h        |  4 ++
 8 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 8192b3111c84..a760e25c3763 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -53,16 +53,19 @@
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
 #define ATM_LNC_C6_AUTO_DEMOTE		(1UL << 25)
 #define SNB_C1_AUTO_UNDEMOTE		(1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE		(1UL << 28)
 
 #define MSR_MTRRcap			0x000000fe
 #define MSR_IA32_BBL_CR_CTL		0x00000119
 #define MSR_IA32_BBL_CR_CTL3		0x0000011e
+#define MSR_MISC_FEATURES_ENABLES	0x00000140
+#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT	0
+#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT		BIT_ULL(MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT)
 
 #define MSR_IA32_SYSENTER_CS		0x00000174
 #define MSR_IA32_SYSENTER_ESP		0x00000175
 #define MSR_IA32_SYSENTER_EIP		0x00000176
 
 #define MSR_IA32_MCG_CAP		0x00000179
 #define MSR_IA32_MCG_STATUS		0x0000017a
 #define MSR_IA32_MCG_CTL		0x0000017b
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index f99d4148d610..ee997cb9f8ba 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -880,16 +880,18 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 
 /* Get/set a process' ability to use the timestamp counter instruction */
 #define GET_TSC_CTL(adr)	get_tsc_mode((adr))
 #define SET_TSC_CTL(val)	set_tsc_mode((val))
 
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
+DECLARE_PER_CPU(u64, msr_misc_features_shadow);
+
 /* Register/unregister a process' MPX related resource */
 #define MPX_ENABLE_MANAGEMENT()	mpx_enable_management()
 #define MPX_DISABLE_MANAGEMENT()	mpx_disable_management()
 
 #ifdef CONFIG_X86_INTEL_MPX
 extern int mpx_enable_management(void);
 extern int mpx_disable_management(void);
 #else
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index ad6f5eb07a95..9fc44b95f7cb 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -82,16 +82,17 @@ struct thread_info {
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* reenable singlestep on user return*/
 #define TIF_SYSCALL_EMU		6	/* syscall emulation active */
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
 #define TIF_UPROBE		12	/* breakpointed or singlestepping */
+#define TIF_NOCPUID		15	/* CPUID is not accessible in userland */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* IA32 compatibility process */
 #define TIF_NOHZ		19	/* in adaptive nohz mode */
 #define TIF_MEMDIE		20	/* is terminating due to OOM killer */
 #define TIF_POLLING_NRFLAG	21	/* idle is polling for TIF_NEED_RESCHED */
 #define TIF_IO_BITMAP		22	/* uses I/O bitmap */
 #define TIF_FORCED_TF		24	/* true if TF in eflags artificially */
 #define TIF_BLOCKSTEP		25	/* set when we want DEBUGCTLMSR_BTF */
@@ -105,16 +106,17 @@ struct thread_info {
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
 #define _TIF_UPROBE		(1 << TIF_UPROBE)
+#define _TIF_NOCPUID		(1 << TIF_NOCPUID)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_NOHZ		(1 << TIF_NOHZ)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_IO_BITMAP		(1 << TIF_IO_BITMAP)
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
 #define _TIF_BLOCKSTEP		(1 << TIF_BLOCKSTEP)
 #define _TIF_LAZY_MMU_UPDATES	(1 << TIF_LAZY_MMU_UPDATES)
@@ -133,17 +135,17 @@ struct thread_info {
 
 /* work to do on any return to user space */
 #define _TIF_ALLWORK_MASK						\
 	((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT |	\
 	_TIF_NOHZ)
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW							\
-	(_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
+	(_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP)
 
 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
 
 #define STACK_WARN		(THREAD_SIZE/8)
 
 /*
  * macros/functions for gaining access to the thread information structure
@@ -234,11 +236,13 @@ static inline int arch_within_stack_frames(const void * const stack,
  * EFLAGS values that other (fast) syscall return instructions
  * are not able to restore properly.
  */
 #define force_iret() set_thread_flag(TIF_NOTIFY_RESUME)
 
 extern void arch_task_cache_init(void);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 extern void arch_release_task_struct(struct task_struct *tsk);
+extern void arch_setup_new_exec(void);
+#define arch_setup_new_exec arch_setup_new_exec
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* _ASM_X86_THREAD_INFO_H */
diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h
index 835aa51c7f6e..5dbbd1be6b97 100644
--- a/arch/x86/include/uapi/asm/prctl.h
+++ b/arch/x86/include/uapi/asm/prctl.h
@@ -1,13 +1,22 @@
 #ifndef _ASM_X86_PRCTL_H
 #define _ASM_X86_PRCTL_H
 
 #define ARCH_SET_GS 0x1001
 #define ARCH_SET_FS 0x1002
 #define ARCH_GET_FS 0x1003
 #define ARCH_GET_GS 0x1004
 
+#define ARCH_GET_CPUID 0x1005
+#define ARCH_SET_CPUID 0x1006
+
 #define ARCH_MAP_VDSO_X32	0x2001
 #define ARCH_MAP_VDSO_32	0x2002
 #define ARCH_MAP_VDSO_64	0x2003
 
+#ifdef CONFIG_CHECKPOINT_RESTORE
+# define ARCH_MAP_VDSO_X32	0x2001
+# define ARCH_MAP_VDSO_32	0x2002
+# define ARCH_MAP_VDSO_64	0x2003
+#endif
+
 #endif /* _ASM_X86_PRCTL_H */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 3d9e11b2b41a..f8ba14cf4a56 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -446,16 +446,23 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c)
 	 */
 	init_intel_energy_perf(c);
 }
 
 static void init_intel_misc_features(struct cpuinfo_x86 *c)
 {
 	u64 msr;
 
+	if (rdmsrl_safe(MSR_MISC_FEATURES_ENABLES, &msr))
+		return;
+
+	msr = 0;
+	wrmsrl(MSR_MISC_FEATURES_ENABLES, msr);
+	this_cpu_write(msr_misc_features_shadow, msr);
+
 	if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) {
 		if (msr & MSR_PLATFORM_INFO_CPUID_FAULT)
 			set_cpu_cap(c, X86_FEATURE_CPUID_FAULT);
 	}
 }
 
 static void init_intel(struct cpuinfo_x86 *c)
 {
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index edf645e331d0..1c973b5ea70e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -27,16 +27,17 @@
 #include <asm/mwait.h>
 #include <asm/fpu/internal.h>
 #include <asm/debugreg.h>
 #include <asm/nmi.h>
 #include <asm/tlbflush.h>
 #include <asm/mce.h>
 #include <asm/vm86.h>
 #include <asm/switch_to.h>
+#include <asm/prctl.h>
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
  * no more per-task TSS's. The TSS size is kept cacheline-aligned
  * so they are allowed to end up in the .data..cacheline_aligned
  * section. Since TSS's are completely CPU-local, we want them
  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
  */
@@ -159,16 +160,83 @@ int set_tsc_mode(unsigned int val)
 	else if (val == PR_TSC_ENABLE)
 		enable_TSC();
 	else
 		return -EINVAL;
 
 	return 0;
 }
 
+DEFINE_PER_CPU(u64, msr_misc_features_shadow);
+
+static void set_cpuid_faulting(bool on)
+{
+	u64 msrval;
+
+	msrval = this_cpu_read(msr_misc_features_shadow);
+	msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
+	msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT);
+	this_cpu_write(msr_misc_features_shadow, msrval);
+	wrmsrl(MSR_MISC_FEATURES_ENABLES, msrval);
+}
+
+static void disable_cpuid(void)
+{
+	preempt_disable();
+	if (!test_and_set_thread_flag(TIF_NOCPUID)) {
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOCPUID in the current running context.
+		 */
+		set_cpuid_faulting(true);
+	}
+	preempt_enable();
+}
+
+static void enable_cpuid(void)
+{
+	preempt_disable();
+	if (test_and_clear_thread_flag(TIF_NOCPUID)) {
+		/*
+		 * Must flip the CPU state synchronously with
+		 * TIF_NOCPUID in the current running context.
+		 */
+		set_cpuid_faulting(false);
+	}
+	preempt_enable();
+}
+
+static int get_cpuid_mode(void)
+{
+	return !test_thread_flag(TIF_NOCPUID);
+}
+
+static int set_cpuid_mode(struct task_struct *task, unsigned long cpuid_enabled)
+{
+	if (!static_cpu_has(X86_FEATURE_CPUID_FAULT))
+		return -ENODEV;
+
+	if (cpuid_enabled)
+		enable_cpuid();
+	else
+		disable_cpuid();
+
+	return 0;
+}
+
+/*
+ * Called immediately after a successful exec.
+ */
+void arch_setup_new_exec(void)
+{
+	/* If cpuid was previously disabled for this task, re-enable it. */
+	if (test_thread_flag(TIF_NOCPUID))
+		enable_cpuid();
+}
+
 static inline void switch_to_bitmap(struct tss_struct *tss,
 				    struct thread_struct *prev,
 				    struct thread_struct *next,
 				    unsigned long tifp, unsigned long tifn)
 {
 	if (tifn & _TIF_IO_BITMAP) {
 		/*
 		 * Copy the relevant range of the IO bitmap.
@@ -199,16 +267,19 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 
 	propagate_user_return_notify(prev_p, next_p);
 
 	if ((tifp ^ tifn) & _TIF_BLOCKSTEP)
 		toggle_debugctlmsr(DEBUGCTLMSR_BTF);
 
 	if ((tifp ^ tifn) & _TIF_NOTSC)
 		cr4_toggle_bits(X86_CR4_TSD);
+
+	if ((tifp ^ tifn) & _TIF_NOCPUID)
+		set_cpuid_faulting(!!(tifn & _TIF_NOCPUID));
 }
 
 /*
  * Idle related variables and functions
  */
 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
 EXPORT_SYMBOL(boot_option_idle_override);
 
@@ -523,10 +594,17 @@ unsigned long get_wchan(struct task_struct *p)
 out:
 	put_task_stack(p);
 	return ret;
 }
 
 long do_arch_prctl_common(struct task_struct *task, int code,
 			  unsigned long cpuid_enabled)
 {
+	switch (code) {
+	case ARCH_GET_CPUID:
+		return get_cpuid_mode();
+	case ARCH_SET_CPUID:
+		return set_cpuid_mode(task, cpuid_enabled);
+	}
+
 	return -EINVAL;
 }
diff --git a/fs/exec.c b/fs/exec.c
index e57946610733..d4f9c6148984 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1310,16 +1310,17 @@ void setup_new_exec(struct linux_binprm * bprm)
 	/* This is the point of no return */
 	current->sas_ss_sp = current->sas_ss_size = 0;
 
 	if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))
 		set_dumpable(current->mm, SUID_DUMP_USER);
 	else
 		set_dumpable(current->mm, suid_dumpable);
 
+	arch_setup_new_exec();
 	perf_event_exec();
 	__set_task_comm(current, kbasename(bprm->filename), true);
 
 	/* Set the new mm task size. We have to do that late because it may
 	 * depend on TIF_32BIT which is only updated in flush_thread() on
 	 * some architectures like powerpc
 	 */
 	current->mm->task_size = TASK_SIZE;
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 58373875e8ee..1539e08757f3 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -96,11 +96,15 @@ static __always_inline void check_object_size(const void *ptr, unsigned long n,
 		__check_object_size(ptr, n, to_user);
 }
 #else
 static inline void check_object_size(const void *ptr, unsigned long n,
 				     bool to_user)
 { }
 #endif /* CONFIG_HARDENED_USERCOPY */
 
+#ifndef arch_setup_new_exec
+static inline void arch_setup_new_exec(void) {}
+#endif
+
 #endif	/* __KERNEL__ */
 
 #endif /* _LINUX_THREAD_INFO_H */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 7/9] x86/arch_prctl: Selftest for ARCH_[GET|SET]_CPUID
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Test disabling and reenabling the cpuid instruction via the new arch_prctl
ARCH_SET_CPUID, retrieving the current state via ARCH_GET_CPUID, and the
expected behaviors across fork() and exec().

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 tools/testing/selftests/x86/Makefile      |   4 +-
 tools/testing/selftests/x86/cpuid_fault.c | 251 ++++++++++++++++++++++++++++++
 2 files changed, 253 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/x86/cpuid_fault.c

diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 8c1cb423cfe6..131c5f266d84 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -1,17 +1,17 @@
-all:
+ll:
 
 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 \
-			protection_keys test_vdso
+			protection_keys test_vdso cpuid_fault
 TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
 			test_FCMOV test_FCOMI test_FISTTP \
 			vdso_restorer
 TARGETS_C_64BIT_ONLY := fsgsbase
 
 TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
 TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
 BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
diff --git a/tools/testing/selftests/x86/cpuid_fault.c b/tools/testing/selftests/x86/cpuid_fault.c
new file mode 100644
index 000000000000..d061abde85e8
--- /dev/null
+++ b/tools/testing/selftests/x86/cpuid_fault.c
@@ -0,0 +1,251 @@
+
+/*
+ * Tests for arch_prctl(ARCH_GET_CPUID, ...) / arch_prctl(ARCH_SET_CPUID, ...)
+ *
+ * Basic test to test behaviour of ARCH_GET_CPUID and ARCH_SET_CPUID
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <cpuid.h>
+#include <err.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/*
+#define ARCH_GET_CPUID 0x1005
+#define ARCH_SET_CPUID 0x1006
+#ifdef __x86_64__
+#define SYS_arch_prctl 158
+#else
+#define SYS_arch_prctl 385
+#endif
+*/
+
+const char *cpuid_names[] = {
+	[0] = "[cpuid disabled]",
+	[1] = "[cpuid enabled]",
+};
+
+int arch_prctl(int code, unsigned long arg2)
+{
+	return syscall(SYS_arch_prctl, code, arg2);
+}
+
+int cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
+	  unsigned int *edx)
+{
+	return __get_cpuid(0, eax, ebx, ecx, edx);
+}
+
+int do_child_exec_test(int eax, int ebx, int ecx, int edx)
+{
+	int cpuid_val = 0, child = 0, status = 0;
+
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	if (cpuid_val != 0)
+		errx(1, "How did cpuid get re-enabled on fork?");
+
+	child = fork();
+	if (child == 0) {
+		cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+		if (cpuid_val < 0)
+			errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+		printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+		if (cpuid_val != 0)
+			errx(1, "How did cpuid get re-enabled on fork?");
+
+		printf("exec\n");
+		execl("/proc/self/exe", "cpuid-fault", "-early-return", NULL);
+	}
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Execed child exited abnormally");
+
+	return 0;
+}
+
+int child_received_signal;
+
+void child_sigsegv_cb(int sig)
+{
+	int cpuid_val = 0;
+
+	child_received_signal = 1;
+	printf("[ SIG_SEGV ]\n");
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	printf("arch_prctl(ARCH_SET_CPUID, 1)\n");
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0)
+		exit(errno);
+
+	printf("cpuid() == ");
+}
+
+int do_child_test(void)
+{
+	unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+	signal(SIGSEGV, child_sigsegv_cb);
+
+	/* the child starts out with cpuid disabled, the signal handler
+	 * attempts to enable and retry
+	 */
+	printf("cpuid() == ");
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	return child_received_signal ? 0 : 42;
+}
+
+int signal_count;
+
+void sigsegv_cb(int sig)
+{
+	int cpuid_val = 0;
+
+	signal_count++;
+	printf("[ SIG_SEGV ]\n");
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	printf("arch_prctl(ARC_SET_CPUID, 1)\n");
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	printf("cpuid() == ");
+}
+
+int main(int argc, char **argv)
+{
+	int cpuid_val = 0, child = 0, status = 0;
+	unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+	signal(SIGSEGV, sigsegv_cb);
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0) {
+		if (errno == EINVAL) {
+			printf("ARCH_GET_CPUID is unsupported on this kernel.\n");
+			fflush(stdout);
+			exit(0); /* no ARCH_GET_CPUID on this system */
+		} else if (errno == ENODEV) {
+			printf("ARCH_GET_CPUID is unsupported on this hardware.\n");
+			fflush(stdout);
+			exit(0); /* no ARCH_GET_CPUID on this system */
+		} else {
+			errx(errno, "ARCH_GET_CPUID failed unexpectedly!");
+		}
+	}
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 1)\n");
+
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0) {
+		if (errno == EINVAL) {
+			printf("ARCH_SET_CPUID is unsupported on this kernel.");
+			exit(0); /* no ARCH_SET_CPUID on this system */
+		} else if (errno == ENODEV) {
+			printf("ARCH_SET_CPUID is unsupported on this hardware.");
+			exit(0); /* no ARCH_SET_CPUID on this system */
+		} else {
+			errx(errno, "ARCH_SET_CPUID failed unexpectedly!");
+		}
+	}
+
+
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+	fflush(stdout);
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	printf("cpuid() == ");
+	eax = ebx = ecx = edx = 0;
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+
+	if (signal_count != 1)
+		errx(1, "cpuid didn't fault!");
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	if (argc > 1)
+		exit(0); /* Don't run the whole test again if we were execed */
+
+	printf("do_child_test\n");
+	child = fork();
+	if (child == 0)
+		return do_child_test();
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Child exited abnormally!");
+
+	/* The child enabling cpuid should not have affected us */
+	printf("cpuid() == ");
+	eax = ebx = ecx = edx = 0;
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+
+	if (signal_count != 2)
+		errx(1, "cpuid didn't fault!");
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	/* Our ARCH_CPUID_SIGSEGV should not propagate through exec */
+	printf("do_child_exec_test\n");
+	fflush(stdout);
+
+	child = fork();
+	if (child == 0)
+		return do_child_exec_test(eax, ebx, ecx, edx);
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Child exited abnormally!");
+
+	printf("All tests passed!\n");
+	exit(EXIT_SUCCESS);
+}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 7/9] x86/arch_prctl: Selftest for ARCH_[GET|SET]_CPUID
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Test disabling and reenabling the cpuid instruction via the new arch_prctl
ARCH_SET_CPUID, retrieving the current state via ARCH_GET_CPUID, and the
expected behaviors across fork() and exec().

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 tools/testing/selftests/x86/Makefile      |   4 +-
 tools/testing/selftests/x86/cpuid_fault.c | 251 ++++++++++++++++++++++++++++++
 2 files changed, 253 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/x86/cpuid_fault.c

diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 8c1cb423cfe6..131c5f266d84 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -1,17 +1,17 @@
-all:
+ll:
 
 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 \
-			protection_keys test_vdso
+			protection_keys test_vdso cpuid_fault
 TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
 			test_FCMOV test_FCOMI test_FISTTP \
 			vdso_restorer
 TARGETS_C_64BIT_ONLY := fsgsbase
 
 TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
 TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
 BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
diff --git a/tools/testing/selftests/x86/cpuid_fault.c b/tools/testing/selftests/x86/cpuid_fault.c
new file mode 100644
index 000000000000..d061abde85e8
--- /dev/null
+++ b/tools/testing/selftests/x86/cpuid_fault.c
@@ -0,0 +1,251 @@
+
+/*
+ * Tests for arch_prctl(ARCH_GET_CPUID, ...) / arch_prctl(ARCH_SET_CPUID, ...)
+ *
+ * Basic test to test behaviour of ARCH_GET_CPUID and ARCH_SET_CPUID
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <cpuid.h>
+#include <err.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+
+/*
+#define ARCH_GET_CPUID 0x1005
+#define ARCH_SET_CPUID 0x1006
+#ifdef __x86_64__
+#define SYS_arch_prctl 158
+#else
+#define SYS_arch_prctl 385
+#endif
+*/
+
+const char *cpuid_names[] = {
+	[0] = "[cpuid disabled]",
+	[1] = "[cpuid enabled]",
+};
+
+int arch_prctl(int code, unsigned long arg2)
+{
+	return syscall(SYS_arch_prctl, code, arg2);
+}
+
+int cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
+	  unsigned int *edx)
+{
+	return __get_cpuid(0, eax, ebx, ecx, edx);
+}
+
+int do_child_exec_test(int eax, int ebx, int ecx, int edx)
+{
+	int cpuid_val = 0, child = 0, status = 0;
+
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	if (cpuid_val != 0)
+		errx(1, "How did cpuid get re-enabled on fork?");
+
+	child = fork();
+	if (child == 0) {
+		cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+		if (cpuid_val < 0)
+			errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+		printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+		if (cpuid_val != 0)
+			errx(1, "How did cpuid get re-enabled on fork?");
+
+		printf("exec\n");
+		execl("/proc/self/exe", "cpuid-fault", "-early-return", NULL);
+	}
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Execed child exited abnormally");
+
+	return 0;
+}
+
+int child_received_signal;
+
+void child_sigsegv_cb(int sig)
+{
+	int cpuid_val = 0;
+
+	child_received_signal = 1;
+	printf("[ SIG_SEGV ]\n");
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	printf("arch_prctl(ARCH_SET_CPUID, 1)\n");
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0)
+		exit(errno);
+
+	printf("cpuid() == ");
+}
+
+int do_child_test(void)
+{
+	unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+	signal(SIGSEGV, child_sigsegv_cb);
+
+	/* the child starts out with cpuid disabled, the signal handler
+	 * attempts to enable and retry
+	 */
+	printf("cpuid() == ");
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	return child_received_signal ? 0 : 42;
+}
+
+int signal_count;
+
+void sigsegv_cb(int sig)
+{
+	int cpuid_val = 0;
+
+	signal_count++;
+	printf("[ SIG_SEGV ]\n");
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0)
+		errx(1, "ARCH_GET_CPUID fails now, but not before?");
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	printf("arch_prctl(ARC_SET_CPUID, 1)\n");
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	printf("cpuid() == ");
+}
+
+int main(int argc, char **argv)
+{
+	int cpuid_val = 0, child = 0, status = 0;
+	unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+	signal(SIGSEGV, sigsegv_cb);
+	setvbuf(stdout, NULL, _IONBF, 0);
+
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_GET_CPUID); ");
+
+	cpuid_val = arch_prctl(ARCH_GET_CPUID, 0);
+	if (cpuid_val < 0) {
+		if (errno == EINVAL) {
+			printf("ARCH_GET_CPUID is unsupported on this kernel.\n");
+			fflush(stdout);
+			exit(0); /* no ARCH_GET_CPUID on this system */
+		} else if (errno == ENODEV) {
+			printf("ARCH_GET_CPUID is unsupported on this hardware.\n");
+			fflush(stdout);
+			exit(0); /* no ARCH_GET_CPUID on this system */
+		} else {
+			errx(errno, "ARCH_GET_CPUID failed unexpectedly!");
+		}
+	}
+
+	printf("cpuid_val == %s\n", cpuid_names[cpuid_val]);
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 1)\n");
+
+	if (arch_prctl(ARCH_SET_CPUID, 1) != 0) {
+		if (errno == EINVAL) {
+			printf("ARCH_SET_CPUID is unsupported on this kernel.");
+			exit(0); /* no ARCH_SET_CPUID on this system */
+		} else if (errno == ENODEV) {
+			printf("ARCH_SET_CPUID is unsupported on this hardware.");
+			exit(0); /* no ARCH_SET_CPUID on this system */
+		} else {
+			errx(errno, "ARCH_SET_CPUID failed unexpectedly!");
+		}
+	}
+
+
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("cpuid() == {%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+	fflush(stdout);
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	printf("cpuid() == ");
+	eax = ebx = ecx = edx = 0;
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+
+	if (signal_count != 1)
+		errx(1, "cpuid didn't fault!");
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	if (argc > 1)
+		exit(0); /* Don't run the whole test again if we were execed */
+
+	printf("do_child_test\n");
+	child = fork();
+	if (child == 0)
+		return do_child_test();
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Child exited abnormally!");
+
+	/* The child enabling cpuid should not have affected us */
+	printf("cpuid() == ");
+	eax = ebx = ecx = edx = 0;
+	cpuid(&eax, &ebx, &ecx, &edx);
+	printf("{%x, %x, %x, %x}\n", eax, ebx, ecx, edx);
+	printf("arch_prctl(ARCH_SET_CPUID, 0)\n");
+
+	if (signal_count != 2)
+		errx(1, "cpuid didn't fault!");
+
+	if (arch_prctl(ARCH_SET_CPUID, 0) == -1)
+		errx(1, "ARCH_SET_CPUID failed!");
+
+	/* Our ARCH_CPUID_SIGSEGV should not propagate through exec */
+	printf("do_child_exec_test\n");
+	fflush(stdout);
+
+	child = fork();
+	if (child == 0)
+		return do_child_exec_test(eax, ebx, ecx, edx);
+
+	if (child != waitpid(child, &status, 0))
+		errx(1, "waitpid failed!?");
+
+	if (WEXITSTATUS(status) != 0)
+		errx(1, "Child exited abnormally!");
+
+	printf("All tests passed!\n");
+	exit(EXIT_SUCCESS);
+}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Hardware support for faulting on the cpuid instruction is not required to
emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
cpuid-induced VM exit checks the cpuid faulting state and the CPL.
kvm_require_cpl is even kind enough to inject the GP fault for us.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: David Matlack <dmatlack@google.com>
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/cpuid.c            |  3 +++
 arch/x86/kvm/cpuid.h            | 11 +++++++++++
 arch/x86/kvm/emulate.c          |  7 +++++++
 arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
 5 files changed, 49 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a7066dc1a7e9..a0d6f0c47440 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
 	u64 pat;
 
 	unsigned switch_db_regs;
 	unsigned long db[KVM_NR_DB_REGS];
 	unsigned long dr6;
 	unsigned long dr7;
 	unsigned long eff_db[KVM_NR_DB_REGS];
 	unsigned long guest_debug_dr7;
+	u64 msr_platform_info;
+	u64 msr_misc_features_enables;
 
 	u64 mcg_cap;
 	u64 mcg_status;
 	u64 mcg_ctl;
 	u64 mcg_ext_ctl;
 	u64 *mce_banks;
 
 	/* Cache MMIO info */
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index e85f6bd7b9d5..588ac8ae0a60 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
 	trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
 }
 EXPORT_SYMBOL_GPL(kvm_cpuid);
 
 int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
 {
 	u32 eax, ebx, ecx, edx;
 
+	if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
+		return;
+
 	eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
 	kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
 	kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
 	kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
 	kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
 	kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
 	return kvm_skip_emulated_instruction(vcpu);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index 35058c2c0eea..a6fd40aade7c 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
 
 	best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
 	if (!best)
 		return -1;
 
 	return x86_stepping(best->eax);
 }
 
+static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
+}
+
+static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.msr_misc_features_enables &
+		  MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
+}
+
 #endif
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index cedbba0f3402..8b4b5566c365 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
 	ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
 	ctxt->eflags |= X86_EFLAGS_IF;
 	return X86EMUL_CONTINUE;
 }
 
 static int em_cpuid(struct x86_emulate_ctxt *ctxt)
 {
 	u32 eax, ebx, ecx, edx;
+	u64 msr = 0;
+
+	ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
+	if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
+	    ctxt->ops->cpl(ctxt)) {
+		return emulate_gp(ctxt, 0);
+	}
 
 	eax = reg_read(ctxt, VCPU_REGS_RAX);
 	ecx = reg_read(ctxt, VCPU_REGS_RCX);
 	ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
 	*reg_write(ctxt, VCPU_REGS_RAX) = eax;
 	*reg_write(ctxt, VCPU_REGS_RBX) = ebx;
 	*reg_write(ctxt, VCPU_REGS_RCX) = ecx;
 	*reg_write(ctxt, VCPU_REGS_RDX) = edx;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e52c9088660f..1951b460da47 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
 
 	MSR_IA32_TSC_ADJUST,
 	MSR_IA32_TSCDEADLINE,
 	MSR_IA32_MISC_ENABLE,
 	MSR_IA32_MCG_STATUS,
 	MSR_IA32_MCG_CTL,
 	MSR_IA32_MCG_EXT_CTL,
 	MSR_IA32_SMBASE,
+	MSR_PLATFORM_INFO,
+	MSR_MISC_FEATURES_ENABLES,
 };
 
 static unsigned num_emulated_msrs;
 
 bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
 	if (efer & efer_reserved_bits)
 		return false;
@@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 1;
 		vcpu->arch.osvw.length = data;
 		break;
 	case MSR_AMD64_OSVW_STATUS:
 		if (!guest_cpuid_has_osvw(vcpu))
 			return 1;
 		vcpu->arch.osvw.status = data;
 		break;
+	case MSR_PLATFORM_INFO:
+		if (!msr_info->host_initiated ||
+		    data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
+		    (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
+		     cpuid_fault_enabled(vcpu)))
+			return 1;
+		vcpu->arch.msr_platform_info = data;
+		break;
+	case MSR_MISC_FEATURES_ENABLES:
+		if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
+		    (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
+		     !supports_cpuid_fault(vcpu)))
+			return 1;
+		vcpu->arch.msr_misc_features_enables = data;
+		break;
 	default:
 		if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
 			return xen_hvm_config(vcpu, data);
 		if (kvm_pmu_is_valid_msr(vcpu, msr))
 			return kvm_pmu_set_msr(vcpu, msr_info);
 		if (!ignore_msrs) {
 			vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
 				    msr, data);
@@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 1;
 		msr_info->data = vcpu->arch.osvw.length;
 		break;
 	case MSR_AMD64_OSVW_STATUS:
 		if (!guest_cpuid_has_osvw(vcpu))
 			return 1;
 		msr_info->data = vcpu->arch.osvw.status;
 		break;
+	case MSR_PLATFORM_INFO:
+		msr_info->data = vcpu->arch.msr_platform_info;
+		break;
+	case MSR_MISC_FEATURES_ENABLES:
+		msr_info->data = vcpu->arch.msr_misc_features_enables;
+		break;
 	default:
 		if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
 			return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
 		if (!ignore_msrs) {
 			vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
 					       msr_info->index);
 			return 1;
 		} else {
@@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 
 	kvm_clear_async_pf_completion_queue(vcpu);
 	kvm_async_pf_hash_reset(vcpu);
 	vcpu->arch.apf.halted = false;
 
 	if (!init_event) {
 		kvm_pmu_reset(vcpu);
 		vcpu->arch.smbase = 0x30000;
+
+		vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
+		vcpu->arch.msr_misc_features_enables = 0;
 	}
 
 	memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs));
 	vcpu->arch.regs_avail = ~0;
 	vcpu->arch.regs_dirty = ~0;
 
 	kvm_x86_ops->vcpu_reset(vcpu, init_event);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

Hardware support for faulting on the cpuid instruction is not required to
emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
cpuid-induced VM exit checks the cpuid faulting state and the CPL.
kvm_require_cpl is even kind enough to inject the GP fault for us.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
Reviewed-by: David Matlack <dmatlack@google.com>
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/cpuid.c            |  3 +++
 arch/x86/kvm/cpuid.h            | 11 +++++++++++
 arch/x86/kvm/emulate.c          |  7 +++++++
 arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
 5 files changed, 49 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a7066dc1a7e9..a0d6f0c47440 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
 	u64 pat;
 
 	unsigned switch_db_regs;
 	unsigned long db[KVM_NR_DB_REGS];
 	unsigned long dr6;
 	unsigned long dr7;
 	unsigned long eff_db[KVM_NR_DB_REGS];
 	unsigned long guest_debug_dr7;
+	u64 msr_platform_info;
+	u64 msr_misc_features_enables;
 
 	u64 mcg_cap;
 	u64 mcg_status;
 	u64 mcg_ctl;
 	u64 mcg_ext_ctl;
 	u64 *mce_banks;
 
 	/* Cache MMIO info */
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index e85f6bd7b9d5..588ac8ae0a60 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
 	trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
 }
 EXPORT_SYMBOL_GPL(kvm_cpuid);
 
 int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
 {
 	u32 eax, ebx, ecx, edx;
 
+	if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
+		return;
+
 	eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
 	kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
 	kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
 	kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
 	kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
 	kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
 	return kvm_skip_emulated_instruction(vcpu);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index 35058c2c0eea..a6fd40aade7c 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
 
 	best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
 	if (!best)
 		return -1;
 
 	return x86_stepping(best->eax);
 }
 
+static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
+}
+
+static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.msr_misc_features_enables &
+		  MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
+}
+
 #endif
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index cedbba0f3402..8b4b5566c365 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
 	ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
 	ctxt->eflags |= X86_EFLAGS_IF;
 	return X86EMUL_CONTINUE;
 }
 
 static int em_cpuid(struct x86_emulate_ctxt *ctxt)
 {
 	u32 eax, ebx, ecx, edx;
+	u64 msr = 0;
+
+	ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
+	if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
+	    ctxt->ops->cpl(ctxt)) {
+		return emulate_gp(ctxt, 0);
+	}
 
 	eax = reg_read(ctxt, VCPU_REGS_RAX);
 	ecx = reg_read(ctxt, VCPU_REGS_RCX);
 	ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
 	*reg_write(ctxt, VCPU_REGS_RAX) = eax;
 	*reg_write(ctxt, VCPU_REGS_RBX) = ebx;
 	*reg_write(ctxt, VCPU_REGS_RCX) = ecx;
 	*reg_write(ctxt, VCPU_REGS_RDX) = edx;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e52c9088660f..1951b460da47 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
 
 	MSR_IA32_TSC_ADJUST,
 	MSR_IA32_TSCDEADLINE,
 	MSR_IA32_MISC_ENABLE,
 	MSR_IA32_MCG_STATUS,
 	MSR_IA32_MCG_CTL,
 	MSR_IA32_MCG_EXT_CTL,
 	MSR_IA32_SMBASE,
+	MSR_PLATFORM_INFO,
+	MSR_MISC_FEATURES_ENABLES,
 };
 
 static unsigned num_emulated_msrs;
 
 bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
 	if (efer & efer_reserved_bits)
 		return false;
@@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 1;
 		vcpu->arch.osvw.length = data;
 		break;
 	case MSR_AMD64_OSVW_STATUS:
 		if (!guest_cpuid_has_osvw(vcpu))
 			return 1;
 		vcpu->arch.osvw.status = data;
 		break;
+	case MSR_PLATFORM_INFO:
+		if (!msr_info->host_initiated ||
+		    data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
+		    (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
+		     cpuid_fault_enabled(vcpu)))
+			return 1;
+		vcpu->arch.msr_platform_info = data;
+		break;
+	case MSR_MISC_FEATURES_ENABLES:
+		if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
+		    (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
+		     !supports_cpuid_fault(vcpu)))
+			return 1;
+		vcpu->arch.msr_misc_features_enables = data;
+		break;
 	default:
 		if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
 			return xen_hvm_config(vcpu, data);
 		if (kvm_pmu_is_valid_msr(vcpu, msr))
 			return kvm_pmu_set_msr(vcpu, msr_info);
 		if (!ignore_msrs) {
 			vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
 				    msr, data);
@@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 			return 1;
 		msr_info->data = vcpu->arch.osvw.length;
 		break;
 	case MSR_AMD64_OSVW_STATUS:
 		if (!guest_cpuid_has_osvw(vcpu))
 			return 1;
 		msr_info->data = vcpu->arch.osvw.status;
 		break;
+	case MSR_PLATFORM_INFO:
+		msr_info->data = vcpu->arch.msr_platform_info;
+		break;
+	case MSR_MISC_FEATURES_ENABLES:
+		msr_info->data = vcpu->arch.msr_misc_features_enables;
+		break;
 	default:
 		if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
 			return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
 		if (!ignore_msrs) {
 			vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
 					       msr_info->index);
 			return 1;
 		} else {
@@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 
 	kvm_clear_async_pf_completion_queue(vcpu);
 	kvm_async_pf_hash_reset(vcpu);
 	vcpu->arch.apf.halted = false;
 
 	if (!init_event) {
 		kvm_pmu_reset(vcpu);
 		vcpu->arch.smbase = 0x30000;
+
+		vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
+		vcpu->arch.msr_misc_features_enables = 0;
 	}
 
 	memset(vcpu->arch.regs, 0, sizeof(vcpu->arch.regs));
 	vcpu->arch.regs_avail = ~0;
 	vcpu->arch.regs_dirty = ~0;
 
 	kvm_x86_ops->vcpu_reset(vcpu, init_event);
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 9/9] x86/arch_prctl: Rename 'code' argument to 'option'
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-08  8:09   ` Kyle Huey
  -1 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

arch_prctl arbitrarily changed prctl's 'option' to 'code'. Now that we're
adding additional options, fix that.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/um/include/shared/os.h               |  2 +-
 arch/x86/include/asm/proto.h              |  4 ++--
 arch/x86/kernel/process.c                 |  4 ++--
 arch/x86/kernel/process_32.c              |  4 ++--
 arch/x86/kernel/process_64.c              | 14 +++++++-------
 arch/x86/um/asm/ptrace.h                  |  2 +-
 arch/x86/um/os-Linux/prctl.c              |  4 ++--
 arch/x86/um/syscalls_32.c                 |  2 +-
 arch/x86/um/syscalls_64.c                 | 13 +++++++------
 include/linux/compat.h                    |  2 +-
 tools/testing/selftests/x86/cpuid_fault.c |  4 ++--
 11 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 2b47e0e8d414..fbabca435e7f 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -298,17 +298,17 @@ extern void os_set_ioignore(void);
 
 /* sigio.c */
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
 extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
-extern int os_arch_prctl(int pid, int code, unsigned long *arg2);
+extern int os_arch_prctl(int pid, int option, unsigned long *arg2);
 
 /* tty.c */
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
 extern unsigned long os_get_top_address(void);
 
 long syscall(long number, ...);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 99836d9a893a..8d3964fc5f91 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -4,17 +4,17 @@
 #include <asm/ldt.h>
 
 /* misc architecture specific prototypes */
 
 void syscall_init(void);
 
 #ifdef CONFIG_X86_64
 void entry_SYSCALL_64(void);
-long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2);
+long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2);
 #endif
 
 #ifdef CONFIG_X86_32
 void entry_INT80_32(void);
 void entry_SYSENTER_32(void);
 void __begin_SYSENTER_singlestep_region(void);
 void __end_SYSENTER_singlestep_region(void);
 #endif
@@ -26,12 +26,12 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
-long do_arch_prctl_common(struct task_struct *task, int code,
+long do_arch_prctl_common(struct task_struct *task, int option,
 			  unsigned long cpuid_enabled);
 
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1c973b5ea70e..91c748f3f8cb 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -591,20 +591,20 @@ unsigned long get_wchan(struct task_struct *p)
 		fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
 	} while (count++ < 16 && p->state != TASK_RUNNING);
 
 out:
 	put_task_stack(p);
 	return ret;
 }
 
-long do_arch_prctl_common(struct task_struct *task, int code,
+long do_arch_prctl_common(struct task_struct *task, int option,
 			  unsigned long cpuid_enabled)
 {
-	switch (code) {
+	switch (option) {
 	case ARCH_GET_CPUID:
 		return get_cpuid_mode();
 	case ARCH_SET_CPUID:
 		return set_cpuid_mode(task, cpuid_enabled);
 	}
 
 	return -EINVAL;
 }
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index c24e72d7ce83..d36964ed6d96 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -300,12 +300,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	this_cpu_write(current_task, next_p);
 
 	/* Load the Intel cache allocation PQR MSR. */
 	intel_rdt_sched_in();
 
 	return prev_p;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return do_arch_prctl_common(current, code, arg2);
+	return do_arch_prctl_common(current, option, arg2);
 }
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e67cd9557ff8..bab02cf43439 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -541,23 +541,23 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr)
 	ret = map_vdso_once(image, addr);
 	if (ret)
 		return ret;
 
 	return (long)image->size;
 }
 #endif
 
-long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
+long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
 {
 	int ret = 0;
 	int doit = task == current;
 	int cpu;
 
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_GS:
 		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.gsindex = 0;
 		task->thread.gsbase = arg2;
 		if (doit) {
 			load_gs_index(0);
@@ -617,30 +617,30 @@ long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
 	long ret;
 
-	ret = do_arch_prctl_64(current, code, arg2);
+	ret = do_arch_prctl_64(current, option, arg2);
 	if (ret == -EINVAL)
-		ret = do_arch_prctl_common(current, code, arg2);
+		ret = do_arch_prctl_common(current, option, arg2);
 
 	return ret;
 }
 
 #ifdef CONFIG_IA32_EMULATION
-COMPAT_SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+COMPAT_SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return do_arch_prctl_common(current, code, arg2);
+	return do_arch_prctl_common(current, option, arg2);
 }
 #endif
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index e59eef20647b..b291ca5cf66b 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -73,14 +73,14 @@ static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
 }
 
 static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
                                          struct user_desc __user *user_desc)
 {
         return -ENOSYS;
 }
 
-extern long arch_prctl(struct task_struct *task, int code,
+extern long arch_prctl(struct task_struct *task, int option,
 		       unsigned long __user *addr);
 
 #endif
 #define user_stack_pointer(regs) PT_REGS_SP(regs)
 #endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c
index efc9d7484e72..8431e87ac333 100644
--- a/arch/x86/um/os-Linux/prctl.c
+++ b/arch/x86/um/os-Linux/prctl.c
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
  * Licensed under the GPL
  */
 
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 
-int os_arch_prctl(int pid, int code, unsigned long *arg2)
+int os_arch_prctl(int pid, int option, unsigned long *arg2)
 {
-	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, code);
+	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, option);
 }
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c
index ccf0598c3fc0..627d68836b16 100644
--- a/arch/x86/um/syscalls_32.c
+++ b/arch/x86/um/syscalls_32.c
@@ -1,7 +1,7 @@
 #include <linux/syscalls.h>
 #include <os.h>
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
 	return -EINVAL;
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index d472c6b79a90..da4252e27055 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -6,17 +6,18 @@
  */
 
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
-long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
+long arch_prctl(struct task_struct *task, int option,
+		unsigned long __user *arg2)
 {
 	unsigned long *ptr = arg2, tmp;
 	long ret;
 	int pid = task->mm->context.id.u.pid;
 
 	/*
 	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
 	 * be safe), we need to call arch_prctl on the host because
@@ -25,17 +26,17 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 	 * fiddle the registers and thread struct and restore the
 	 * registers afterwards.
 	 *
 	 * So, the saved registers are stored to the process (this
 	 * needed because a stub may have been the last thing to run),
 	 * arch_prctl is run on the host, then the registers are read
 	 * back.
 	 */
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_FS:
 	case ARCH_SET_GS:
 		ret = restore_registers(pid, &current->thread.regs.regs);
 		if (ret)
 			return ret;
 		break;
 	case ARCH_GET_FS:
 	case ARCH_GET_GS:
@@ -45,21 +46,21 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 		 * given.  If addr isn't valid (because it hasn't been
 		 * faulted in or is just bogus), we want put_user to
 		 * fault it in (or return -EFAULT) instead of having
 		 * the host return -EFAULT.
 		 */
 		ptr = &tmp;
 	}
 
-	ret = os_arch_prctl(pid, code, ptr);
+	ret = os_arch_prctl(pid, option, ptr);
 	if (ret)
 		return ret;
 
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_FS:
 		current->thread.arch.fs = (unsigned long) ptr;
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_SET_GS:
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_GET_FS:
@@ -68,19 +69,19 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 	case ARCH_GET_GS:
 		ret = put_user(tmp, arg2);
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return arch_prctl(current, code, (unsigned long __user *) arg2);
+	return arch_prctl(current, option, (unsigned long __user *) arg2);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
 
 	arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 0ddfc2ba0d06..d64998fa4728 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -716,17 +716,17 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 } while (0);
 
 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 						 struct compat_timespec __user *interval);
 
 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
 					    int, const char __user *);
 
-asmlinkage long compat_sys_arch_prctl(int code, unsigned long arg2);
+asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2);
 
 /*
  * For most but not all architectures, "am I in a compat syscall?" and
  * "am I a compat task?" are the same question.  For architectures on which
  * they aren't the same question, arch code can override in_compat_syscall.
  */
 
 #ifndef in_compat_syscall
diff --git a/tools/testing/selftests/x86/cpuid_fault.c b/tools/testing/selftests/x86/cpuid_fault.c
index d061abde85e8..a1fae06b8324 100644
--- a/tools/testing/selftests/x86/cpuid_fault.c
+++ b/tools/testing/selftests/x86/cpuid_fault.c
@@ -28,19 +28,19 @@
 #endif
 */
 
 const char *cpuid_names[] = {
 	[0] = "[cpuid disabled]",
 	[1] = "[cpuid enabled]",
 };
 
-int arch_prctl(int code, unsigned long arg2)
+int arch_prctl(int option, unsigned long arg2)
 {
-	return syscall(SYS_arch_prctl, code, arg2);
+	return syscall(SYS_arch_prctl, option, arg2);
 }
 
 int cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
 	  unsigned int *edx)
 {
 	return __get_cpuid(0, eax, ebx, ecx, edx);
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v14 9/9] x86/arch_prctl: Rename 'code' argument to 'option'
@ 2017-02-08  8:09   ` Kyle Huey
  0 siblings, 0 replies; 54+ messages in thread
From: Kyle Huey @ 2017-02-08  8:09 UTC (permalink / raw)
  To: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, x86, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack
  Cc: linux-kernel, user-mode-linux-devel, user-mode-linux-user,
	linux-fsdevel, linux-kselftest, kvm

arch_prctl arbitrarily changed prctl's 'option' to 'code'. Now that we're
adding additional options, fix that.

Signed-off-by: Kyle Huey <khuey@kylehuey.com>
---
 arch/um/include/shared/os.h               |  2 +-
 arch/x86/include/asm/proto.h              |  4 ++--
 arch/x86/kernel/process.c                 |  4 ++--
 arch/x86/kernel/process_32.c              |  4 ++--
 arch/x86/kernel/process_64.c              | 14 +++++++-------
 arch/x86/um/asm/ptrace.h                  |  2 +-
 arch/x86/um/os-Linux/prctl.c              |  4 ++--
 arch/x86/um/syscalls_32.c                 |  2 +-
 arch/x86/um/syscalls_64.c                 | 13 +++++++------
 include/linux/compat.h                    |  2 +-
 tools/testing/selftests/x86/cpuid_fault.c |  4 ++--
 11 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 2b47e0e8d414..fbabca435e7f 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -298,17 +298,17 @@ extern void os_set_ioignore(void);
 
 /* sigio.c */
 extern int add_sigio_fd(int fd);
 extern int ignore_sigio_fd(int fd);
 extern void maybe_sigio_broken(int fd, int read);
 extern void sigio_broken(int fd, int read);
 
 /* sys-x86_64/prctl.c */
-extern int os_arch_prctl(int pid, int code, unsigned long *arg2);
+extern int os_arch_prctl(int pid, int option, unsigned long *arg2);
 
 /* tty.c */
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
 extern unsigned long os_get_top_address(void);
 
 long syscall(long number, ...);
diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h
index 99836d9a893a..8d3964fc5f91 100644
--- a/arch/x86/include/asm/proto.h
+++ b/arch/x86/include/asm/proto.h
@@ -4,17 +4,17 @@
 #include <asm/ldt.h>
 
 /* misc architecture specific prototypes */
 
 void syscall_init(void);
 
 #ifdef CONFIG_X86_64
 void entry_SYSCALL_64(void);
-long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2);
+long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2);
 #endif
 
 #ifdef CONFIG_X86_32
 void entry_INT80_32(void);
 void entry_SYSENTER_32(void);
 void __begin_SYSENTER_singlestep_region(void);
 void __end_SYSENTER_singlestep_region(void);
 #endif
@@ -26,12 +26,12 @@ void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
 #endif
 
 void x86_configure_nx(void);
 void x86_report_nx(void);
 
 extern int reboot_force;
 
-long do_arch_prctl_common(struct task_struct *task, int code,
+long do_arch_prctl_common(struct task_struct *task, int option,
 			  unsigned long cpuid_enabled);
 
 #endif /* _ASM_X86_PROTO_H */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1c973b5ea70e..91c748f3f8cb 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -591,20 +591,20 @@ unsigned long get_wchan(struct task_struct *p)
 		fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
 	} while (count++ < 16 && p->state != TASK_RUNNING);
 
 out:
 	put_task_stack(p);
 	return ret;
 }
 
-long do_arch_prctl_common(struct task_struct *task, int code,
+long do_arch_prctl_common(struct task_struct *task, int option,
 			  unsigned long cpuid_enabled)
 {
-	switch (code) {
+	switch (option) {
 	case ARCH_GET_CPUID:
 		return get_cpuid_mode();
 	case ARCH_SET_CPUID:
 		return set_cpuid_mode(task, cpuid_enabled);
 	}
 
 	return -EINVAL;
 }
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index c24e72d7ce83..d36964ed6d96 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -300,12 +300,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	this_cpu_write(current_task, next_p);
 
 	/* Load the Intel cache allocation PQR MSR. */
 	intel_rdt_sched_in();
 
 	return prev_p;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return do_arch_prctl_common(current, code, arg2);
+	return do_arch_prctl_common(current, option, arg2);
 }
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index e67cd9557ff8..bab02cf43439 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -541,23 +541,23 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr)
 	ret = map_vdso_once(image, addr);
 	if (ret)
 		return ret;
 
 	return (long)image->size;
 }
 #endif
 
-long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
+long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2)
 {
 	int ret = 0;
 	int doit = task == current;
 	int cpu;
 
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_GS:
 		if (arg2 >= TASK_SIZE_MAX)
 			return -EPERM;
 		cpu = get_cpu();
 		task->thread.gsindex = 0;
 		task->thread.gsbase = arg2;
 		if (doit) {
 			load_gs_index(0);
@@ -617,30 +617,30 @@ long do_arch_prctl_64(struct task_struct *task, int code, unsigned long arg2)
 	default:
 		ret = -EINVAL;
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
 	long ret;
 
-	ret = do_arch_prctl_64(current, code, arg2);
+	ret = do_arch_prctl_64(current, option, arg2);
 	if (ret == -EINVAL)
-		ret = do_arch_prctl_common(current, code, arg2);
+		ret = do_arch_prctl_common(current, option, arg2);
 
 	return ret;
 }
 
 #ifdef CONFIG_IA32_EMULATION
-COMPAT_SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+COMPAT_SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return do_arch_prctl_common(current, code, arg2);
+	return do_arch_prctl_common(current, option, arg2);
 }
 #endif
 
 unsigned long KSTK_ESP(struct task_struct *task)
 {
 	return task_pt_regs(task)->sp;
 }
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index e59eef20647b..b291ca5cf66b 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -73,14 +73,14 @@ static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
 }
 
 static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
                                          struct user_desc __user *user_desc)
 {
         return -ENOSYS;
 }
 
-extern long arch_prctl(struct task_struct *task, int code,
+extern long arch_prctl(struct task_struct *task, int option,
 		       unsigned long __user *addr);
 
 #endif
 #define user_stack_pointer(regs) PT_REGS_SP(regs)
 #endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c
index efc9d7484e72..8431e87ac333 100644
--- a/arch/x86/um/os-Linux/prctl.c
+++ b/arch/x86/um/os-Linux/prctl.c
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2007 Jeff Dike (jdike@{addtoit.com,linux.intel.com})
  * Licensed under the GPL
  */
 
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 
-int os_arch_prctl(int pid, int code, unsigned long *arg2)
+int os_arch_prctl(int pid, int option, unsigned long *arg2)
 {
-	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, code);
+	return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, option);
 }
diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c
index ccf0598c3fc0..627d68836b16 100644
--- a/arch/x86/um/syscalls_32.c
+++ b/arch/x86/um/syscalls_32.c
@@ -1,7 +1,7 @@
 #include <linux/syscalls.h>
 #include <os.h>
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
 	return -EINVAL;
 }
diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c
index d472c6b79a90..da4252e27055 100644
--- a/arch/x86/um/syscalls_64.c
+++ b/arch/x86/um/syscalls_64.c
@@ -6,17 +6,18 @@
  */
 
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 
-long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
+long arch_prctl(struct task_struct *task, int option,
+		unsigned long __user *arg2)
 {
 	unsigned long *ptr = arg2, tmp;
 	long ret;
 	int pid = task->mm->context.id.u.pid;
 
 	/*
 	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
 	 * be safe), we need to call arch_prctl on the host because
@@ -25,17 +26,17 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 	 * fiddle the registers and thread struct and restore the
 	 * registers afterwards.
 	 *
 	 * So, the saved registers are stored to the process (this
 	 * needed because a stub may have been the last thing to run),
 	 * arch_prctl is run on the host, then the registers are read
 	 * back.
 	 */
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_FS:
 	case ARCH_SET_GS:
 		ret = restore_registers(pid, &current->thread.regs.regs);
 		if (ret)
 			return ret;
 		break;
 	case ARCH_GET_FS:
 	case ARCH_GET_GS:
@@ -45,21 +46,21 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 		 * given.  If addr isn't valid (because it hasn't been
 		 * faulted in or is just bogus), we want put_user to
 		 * fault it in (or return -EFAULT) instead of having
 		 * the host return -EFAULT.
 		 */
 		ptr = &tmp;
 	}
 
-	ret = os_arch_prctl(pid, code, ptr);
+	ret = os_arch_prctl(pid, option, ptr);
 	if (ret)
 		return ret;
 
-	switch (code) {
+	switch (option) {
 	case ARCH_SET_FS:
 		current->thread.arch.fs = (unsigned long) ptr;
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_SET_GS:
 		ret = save_registers(pid, &current->thread.regs.regs);
 		break;
 	case ARCH_GET_FS:
@@ -68,19 +69,19 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *arg2)
 	case ARCH_GET_GS:
 		ret = put_user(tmp, arg2);
 		break;
 	}
 
 	return ret;
 }
 
-SYSCALL_DEFINE2(arch_prctl, int, code, unsigned long, arg2)
+SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2)
 {
-	return arch_prctl(current, code, (unsigned long __user *) arg2);
+	return arch_prctl(current, option, (unsigned long __user *) arg2);
 }
 
 void arch_switch_to(struct task_struct *to)
 {
 	if ((to->thread.arch.fs == 0) || (to->mm == NULL))
 		return;
 
 	arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 0ddfc2ba0d06..d64998fa4728 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -716,17 +716,17 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 } while (0);
 
 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 						 struct compat_timespec __user *interval);
 
 asmlinkage long compat_sys_fanotify_mark(int, unsigned int, __u32, __u32,
 					    int, const char __user *);
 
-asmlinkage long compat_sys_arch_prctl(int code, unsigned long arg2);
+asmlinkage long compat_sys_arch_prctl(int option, unsigned long arg2);
 
 /*
  * For most but not all architectures, "am I in a compat syscall?" and
  * "am I a compat task?" are the same question.  For architectures on which
  * they aren't the same question, arch code can override in_compat_syscall.
  */
 
 #ifndef in_compat_syscall
diff --git a/tools/testing/selftests/x86/cpuid_fault.c b/tools/testing/selftests/x86/cpuid_fault.c
index d061abde85e8..a1fae06b8324 100644
--- a/tools/testing/selftests/x86/cpuid_fault.c
+++ b/tools/testing/selftests/x86/cpuid_fault.c
@@ -28,19 +28,19 @@
 #endif
 */
 
 const char *cpuid_names[] = {
 	[0] = "[cpuid disabled]",
 	[1] = "[cpuid enabled]",
 };
 
-int arch_prctl(int code, unsigned long arg2)
+int arch_prctl(int option, unsigned long arg2)
 {
-	return syscall(SYS_arch_prctl, code, arg2);
+	return syscall(SYS_arch_prctl, option, arg2);
 }
 
 int cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
 	  unsigned int *edx)
 {
 	return __get_cpuid(0, eax, ebx, ecx, edx);
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction
  2017-02-08  8:09 ` Kyle Huey
@ 2017-02-10 13:07   ` Thomas Gleixner
  -1 siblings, 0 replies; 54+ messages in thread
From: Thomas Gleixner @ 2017-02-10 13:07 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Andy Lutomirski, Ingo Molnar,
	H. Peter Anvin, x86, Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, linux-kernel, user-mode-linux-devel,
	user-mode-linux-user, linux-fsdevel, linux-kselftest, kvm

On Wed, 8 Feb 2017, Kyle Huey wrote:

> rr (http://rr-project.org/), a userspace record-and-replay reverse-
> execution debugger, would like to trap and emulate the CPUID instruction.
> This would allow us to a) mask away certain hardware features that rr does
> not support (e.g. RDRAND) and b) enable trace portability across machines
> by providing constant results.
> 
> Newer Intel CPUs (Ivy Bridge and later) can fault when CPUID is executed at
> CPL > 0. Expose this capability to userspace as a new pair of arch_prctls,
> ARCH_GET_CPUID and ARCH_SET_CPUID.
> 
> Since v13:
> All: rebased on top of tglx's __switch_to_xtra patches
> (https://lkml.org/lkml/2016/12/15/432)

That doesn't help because that patchset is stale and it has unresolved
comments. I don't know when I have cycles to revisit it, but if you want to
have a try feel free to do so.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction
@ 2017-02-10 13:07   ` Thomas Gleixner
  0 siblings, 0 replies; 54+ messages in thread
From: Thomas Gleixner @ 2017-02-10 13:07 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Andy Lutomirski, Ingo Molnar,
	H. Peter Anvin, x86, Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit

On Wed, 8 Feb 2017, Kyle Huey wrote:

> rr (http://rr-project.org/), a userspace record-and-replay reverse-
> execution debugger, would like to trap and emulate the CPUID instruction.
> This would allow us to a) mask away certain hardware features that rr does
> not support (e.g. RDRAND) and b) enable trace portability across machines
> by providing constant results.
> 
> Newer Intel CPUs (Ivy Bridge and later) can fault when CPUID is executed at
> CPL > 0. Expose this capability to userspace as a new pair of arch_prctls,
> ARCH_GET_CPUID and ARCH_SET_CPUID.
> 
> Since v13:
> All: rebased on top of tglx's __switch_to_xtra patches
> (https://lkml.org/lkml/2016/12/15/432)

That doesn't help because that patchset is stale and it has unresolved
comments. I don't know when I have cycles to revisit it, but if you want to
have a try feel free to do so.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2017-02-08  8:09   ` Kyle Huey
  (?)
  (?)
@ 2018-07-27 17:15     ` jmattson
  -1 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 17:15 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, the arch/x86 maintainers,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	user-mode-linux-user, linux-fsdevel, linux-kselftest, kvm list

On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
> Reviewed-by: David Matlack <dmatlack@google.com>

I have a couple of concerns about portions of this patch:

1) There are some backward compatibility issues:
  A) Suppose we have an old userspace that doesn't know it needs to
zero MSR_PLATFORM_INFO to preserve existing behavior (to the extent
possible). If a VM starts on a new kernel it could set the bit in
MSR_MISC_FEATURES_ENABLES that enables CPUID faulting. On
live-migration to an old kernel, that bit would be lost.
  B) With either an old userspace or a new userspace, as a VM migrates
between old and new kernels, the behavior of RDMSR with ECX set to
either MSR_PLATFORM_INFO or MSR_MISC_FEATURES_ENABLES will vary
depending on which kernel the VM is currently running on.
  Ideally, I think this new functionality should be guarded by a KVM
capability that has to be enabled from userspace.

2) This doesn't really play well with volume 3 of the SDM, section
18.7.3, where Intel instructs developers to use
MSR_PLATFORM_INFO[15:8] to determine the TSC frequency for a variety
of microarchitectures. When reads of this MSR raised #GP, it was
pretty clear that one couldn't get the TSC frequency that way, but I
don't think many consumers would specifically check for a 0 in that
field when the RDMSR succeeds. If a guest hypervisor used that value
in the computation of the TSC scaling factor for a VMCS12, for
example, it might be surprised to get a #DE.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 17:15     ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: jmattson @ 2018-07-27 17:15 UTC (permalink / raw)


On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me at kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
> Reviewed-by: David Matlack <dmatlack at google.com>

I have a couple of concerns about portions of this patch:

1) There are some backward compatibility issues:
  A) Suppose we have an old userspace that doesn't know it needs to
zero MSR_PLATFORM_INFO to preserve existing behavior (to the extent
possible). If a VM starts on a new kernel it could set the bit in
MSR_MISC_FEATURES_ENABLES that enables CPUID faulting. On
live-migration to an old kernel, that bit would be lost.
  B) With either an old userspace or a new userspace, as a VM migrates
between old and new kernels, the behavior of RDMSR with ECX set to
either MSR_PLATFORM_INFO or MSR_MISC_FEATURES_ENABLES will vary
depending on which kernel the VM is currently running on.
  Ideally, I think this new functionality should be guarded by a KVM
capability that has to be enabled from userspace.

2) This doesn't really play well with volume 3 of the SDM, section
18.7.3, where Intel instructs developers to use
MSR_PLATFORM_INFO[15:8] to determine the TSC frequency for a variety
of microarchitectures. When reads of this MSR raised #GP, it was
pretty clear that one couldn't get the TSC frequency that way, but I
don't think many consumers would specifically check for a 0 in that
field when the RDMSR succeeds. If a guest hypervisor used that value
in the computation of the TSC scaling factor for a VMCS12, for
example, it might be surprised to get a #DE.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 17:15     ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 17:15 UTC (permalink / raw)


On Wed, Feb 8, 2017@12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
> Reviewed-by: David Matlack <dmatlack at google.com>

I have a couple of concerns about portions of this patch:

1) There are some backward compatibility issues:
  A) Suppose we have an old userspace that doesn't know it needs to
zero MSR_PLATFORM_INFO to preserve existing behavior (to the extent
possible). If a VM starts on a new kernel it could set the bit in
MSR_MISC_FEATURES_ENABLES that enables CPUID faulting. On
live-migration to an old kernel, that bit would be lost.
  B) With either an old userspace or a new userspace, as a VM migrates
between old and new kernels, the behavior of RDMSR with ECX set to
either MSR_PLATFORM_INFO or MSR_MISC_FEATURES_ENABLES will vary
depending on which kernel the VM is currently running on.
  Ideally, I think this new functionality should be guarded by a KVM
capability that has to be enabled from userspace.

2) This doesn't really play well with volume 3 of the SDM, section
18.7.3, where Intel instructs developers to use
MSR_PLATFORM_INFO[15:8] to determine the TSC frequency for a variety
of microarchitectures. When reads of this MSR raised #GP, it was
pretty clear that one couldn't get the TSC frequency that way, but I
don't think many consumers would specifically check for a 0 in that
field when the RDMSR succeeds. If a guest hypervisor used that value
in the computation of the TSC scaling factor for a VMCS12, for
example, it might be surprised to get a #DE.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 17:15     ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 17:15 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, the arch/x86 maintainers,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov

On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
> Reviewed-by: David Matlack <dmatlack@google.com>

I have a couple of concerns about portions of this patch:

1) There are some backward compatibility issues:
  A) Suppose we have an old userspace that doesn't know it needs to
zero MSR_PLATFORM_INFO to preserve existing behavior (to the extent
possible). If a VM starts on a new kernel it could set the bit in
MSR_MISC_FEATURES_ENABLES that enables CPUID faulting. On
live-migration to an old kernel, that bit would be lost.
  B) With either an old userspace or a new userspace, as a VM migrates
between old and new kernels, the behavior of RDMSR with ECX set to
either MSR_PLATFORM_INFO or MSR_MISC_FEATURES_ENABLES will vary
depending on which kernel the VM is currently running on.
  Ideally, I think this new functionality should be guarded by a KVM
capability that has to be enabled from userspace.

2) This doesn't really play well with volume 3 of the SDM, section
18.7.3, where Intel instructs developers to use
MSR_PLATFORM_INFO[15:8] to determine the TSC frequency for a variety
of microarchitectures. When reads of this MSR raised #GP, it was
pretty clear that one couldn't get the TSC frequency that way, but I
don't think many consumers would specifically check for a 0 in that
field when the RDMSR succeeds. If a guest hypervisor used that value
in the computation of the TSC scaling factor for a VMCS12, for
example, it might be surprised to get a #DE.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2017-02-08  8:09   ` Kyle Huey
  (?)
  (?)
@ 2018-07-27 19:41     ` luto
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 19:41 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
> Reviewed-by: David Matlack <dmatlack@google.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 ++
>  arch/x86/kvm/cpuid.c            |  3 +++
>  arch/x86/kvm/cpuid.h            | 11 +++++++++++
>  arch/x86/kvm/emulate.c          |  7 +++++++
>  arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
>  5 files changed, 49 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index a7066dc1a7e9..a0d6f0c47440 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
>         u64 pat;
>
>         unsigned switch_db_regs;
>         unsigned long db[KVM_NR_DB_REGS];
>         unsigned long dr6;
>         unsigned long dr7;
>         unsigned long eff_db[KVM_NR_DB_REGS];
>         unsigned long guest_debug_dr7;
> +       u64 msr_platform_info;
> +       u64 msr_misc_features_enables;
>
>         u64 mcg_cap;
>         u64 mcg_status;
>         u64 mcg_ctl;
>         u64 mcg_ext_ctl;
>         u64 *mce_banks;
>
>         /* Cache MMIO info */
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index e85f6bd7b9d5..588ac8ae0a60 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
>         trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
>  }
>  EXPORT_SYMBOL_GPL(kvm_cpuid);
>
>  int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
>  {
>         u32 eax, ebx, ecx, edx;
>
> +       if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
> +               return;
> +
>         eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
>         ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
>         kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
>         kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
>         kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
>         kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
>         kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
>         return kvm_skip_emulated_instruction(vcpu);
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index 35058c2c0eea..a6fd40aade7c 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
>
>         best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
>         if (!best)
>                 return -1;
>
>         return x86_stepping(best->eax);
>  }
>
> +static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
> +}
> +
> +static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_misc_features_enables &
> +                 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
> +}
> +
>  #endif
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index cedbba0f3402..8b4b5566c365 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
>         ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
>         ctxt->eflags |= X86_EFLAGS_IF;
>         return X86EMUL_CONTINUE;
>  }
>
>  static int em_cpuid(struct x86_emulate_ctxt *ctxt)
>  {
>         u32 eax, ebx, ecx, edx;
> +       u64 msr = 0;
> +
> +       ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
> +       if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +           ctxt->ops->cpl(ctxt)) {
> +               return emulate_gp(ctxt, 0);
> +       }

Not strictly a comment on your patch, but why on Earth do there need
to be two copies of this check?

>
>         eax = reg_read(ctxt, VCPU_REGS_RAX);
>         ecx = reg_read(ctxt, VCPU_REGS_RCX);
>         ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
>         *reg_write(ctxt, VCPU_REGS_RAX) = eax;
>         *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
>         *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
>         *reg_write(ctxt, VCPU_REGS_RDX) = edx;
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e52c9088660f..1951b460da47 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
>
>         MSR_IA32_TSC_ADJUST,
>         MSR_IA32_TSCDEADLINE,
>         MSR_IA32_MISC_ENABLE,
>         MSR_IA32_MCG_STATUS,
>         MSR_IA32_MCG_CTL,
>         MSR_IA32_MCG_EXT_CTL,
>         MSR_IA32_SMBASE,
> +       MSR_PLATFORM_INFO,
> +       MSR_MISC_FEATURES_ENABLES,
>  };
>
>  static unsigned num_emulated_msrs;
>
>  bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
>  {
>         if (efer & efer_reserved_bits)
>                 return false;
> @@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 vcpu->arch.osvw.length = data;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 vcpu->arch.osvw.status = data;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               if (!msr_info->host_initiated ||
> +                   data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
> +                   (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
> +                    cpuid_fault_enabled(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_platform_info = data;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> +                   (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +                    !supports_cpuid_fault(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_misc_features_enables = data;
> +               break;
>         default:
>                 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
>                         return xen_hvm_config(vcpu, data);
>                 if (kvm_pmu_is_valid_msr(vcpu, msr))
>                         return kvm_pmu_set_msr(vcpu, msr_info);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
>                                     msr, data);
> @@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.length;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.status;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               msr_info->data = vcpu->arch.msr_platform_info;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               msr_info->data = vcpu->arch.msr_misc_features_enables;
> +               break;
>         default:
>                 if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
>                         return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
>                                                msr_info->index);
>                         return 1;
>                 } else {
> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>
>         kvm_clear_async_pf_completion_queue(vcpu);
>         kvm_async_pf_hash_reset(vcpu);
>         vcpu->arch.apf.halted = false;
>
>         if (!init_event) {
>                 kvm_pmu_reset(vcpu);
>                 vcpu->arch.smbase = 0x30000;
> +
> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
> +               vcpu->arch.msr_misc_features_enables = 0;

Jim, I assume you're worried about this bit?  It seems like
msr_platform_info should maybe be initialized to zero to avoid causing
an unintended migration issue.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 19:41     ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: luto @ 2018-07-27 19:41 UTC (permalink / raw)


On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me at kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
> Reviewed-by: David Matlack <dmatlack at google.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 ++
>  arch/x86/kvm/cpuid.c            |  3 +++
>  arch/x86/kvm/cpuid.h            | 11 +++++++++++
>  arch/x86/kvm/emulate.c          |  7 +++++++
>  arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
>  5 files changed, 49 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index a7066dc1a7e9..a0d6f0c47440 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
>         u64 pat;
>
>         unsigned switch_db_regs;
>         unsigned long db[KVM_NR_DB_REGS];
>         unsigned long dr6;
>         unsigned long dr7;
>         unsigned long eff_db[KVM_NR_DB_REGS];
>         unsigned long guest_debug_dr7;
> +       u64 msr_platform_info;
> +       u64 msr_misc_features_enables;
>
>         u64 mcg_cap;
>         u64 mcg_status;
>         u64 mcg_ctl;
>         u64 mcg_ext_ctl;
>         u64 *mce_banks;
>
>         /* Cache MMIO info */
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index e85f6bd7b9d5..588ac8ae0a60 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
>         trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
>  }
>  EXPORT_SYMBOL_GPL(kvm_cpuid);
>
>  int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
>  {
>         u32 eax, ebx, ecx, edx;
>
> +       if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
> +               return;
> +
>         eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
>         ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
>         kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
>         kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
>         kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
>         kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
>         kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
>         return kvm_skip_emulated_instruction(vcpu);
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index 35058c2c0eea..a6fd40aade7c 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
>
>         best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
>         if (!best)
>                 return -1;
>
>         return x86_stepping(best->eax);
>  }
>
> +static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
> +}
> +
> +static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_misc_features_enables &
> +                 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
> +}
> +
>  #endif
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index cedbba0f3402..8b4b5566c365 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
>         ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
>         ctxt->eflags |= X86_EFLAGS_IF;
>         return X86EMUL_CONTINUE;
>  }
>
>  static int em_cpuid(struct x86_emulate_ctxt *ctxt)
>  {
>         u32 eax, ebx, ecx, edx;
> +       u64 msr = 0;
> +
> +       ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
> +       if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +           ctxt->ops->cpl(ctxt)) {
> +               return emulate_gp(ctxt, 0);
> +       }

Not strictly a comment on your patch, but why on Earth do there need
to be two copies of this check?

>
>         eax = reg_read(ctxt, VCPU_REGS_RAX);
>         ecx = reg_read(ctxt, VCPU_REGS_RCX);
>         ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
>         *reg_write(ctxt, VCPU_REGS_RAX) = eax;
>         *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
>         *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
>         *reg_write(ctxt, VCPU_REGS_RDX) = edx;
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e52c9088660f..1951b460da47 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
>
>         MSR_IA32_TSC_ADJUST,
>         MSR_IA32_TSCDEADLINE,
>         MSR_IA32_MISC_ENABLE,
>         MSR_IA32_MCG_STATUS,
>         MSR_IA32_MCG_CTL,
>         MSR_IA32_MCG_EXT_CTL,
>         MSR_IA32_SMBASE,
> +       MSR_PLATFORM_INFO,
> +       MSR_MISC_FEATURES_ENABLES,
>  };
>
>  static unsigned num_emulated_msrs;
>
>  bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
>  {
>         if (efer & efer_reserved_bits)
>                 return false;
> @@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 vcpu->arch.osvw.length = data;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 vcpu->arch.osvw.status = data;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               if (!msr_info->host_initiated ||
> +                   data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
> +                   (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
> +                    cpuid_fault_enabled(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_platform_info = data;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> +                   (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +                    !supports_cpuid_fault(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_misc_features_enables = data;
> +               break;
>         default:
>                 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
>                         return xen_hvm_config(vcpu, data);
>                 if (kvm_pmu_is_valid_msr(vcpu, msr))
>                         return kvm_pmu_set_msr(vcpu, msr_info);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
>                                     msr, data);
> @@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.length;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.status;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               msr_info->data = vcpu->arch.msr_platform_info;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               msr_info->data = vcpu->arch.msr_misc_features_enables;
> +               break;
>         default:
>                 if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
>                         return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
>                                                msr_info->index);
>                         return 1;
>                 } else {
> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>
>         kvm_clear_async_pf_completion_queue(vcpu);
>         kvm_async_pf_hash_reset(vcpu);
>         vcpu->arch.apf.halted = false;
>
>         if (!init_event) {
>                 kvm_pmu_reset(vcpu);
>                 vcpu->arch.smbase = 0x30000;
> +
> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
> +               vcpu->arch.msr_misc_features_enables = 0;

Jim, I assume you're worried about this bit?  It seems like
msr_platform_info should maybe be initialized to zero to avoid causing
an unintended migration issue.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 19:41     ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 19:41 UTC (permalink / raw)


On Wed, Feb 8, 2017@12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
> Reviewed-by: David Matlack <dmatlack at google.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 ++
>  arch/x86/kvm/cpuid.c            |  3 +++
>  arch/x86/kvm/cpuid.h            | 11 +++++++++++
>  arch/x86/kvm/emulate.c          |  7 +++++++
>  arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
>  5 files changed, 49 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index a7066dc1a7e9..a0d6f0c47440 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
>         u64 pat;
>
>         unsigned switch_db_regs;
>         unsigned long db[KVM_NR_DB_REGS];
>         unsigned long dr6;
>         unsigned long dr7;
>         unsigned long eff_db[KVM_NR_DB_REGS];
>         unsigned long guest_debug_dr7;
> +       u64 msr_platform_info;
> +       u64 msr_misc_features_enables;
>
>         u64 mcg_cap;
>         u64 mcg_status;
>         u64 mcg_ctl;
>         u64 mcg_ext_ctl;
>         u64 *mce_banks;
>
>         /* Cache MMIO info */
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index e85f6bd7b9d5..588ac8ae0a60 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
>         trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
>  }
>  EXPORT_SYMBOL_GPL(kvm_cpuid);
>
>  int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
>  {
>         u32 eax, ebx, ecx, edx;
>
> +       if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
> +               return;
> +
>         eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
>         ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
>         kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
>         kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
>         kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
>         kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
>         kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
>         return kvm_skip_emulated_instruction(vcpu);
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index 35058c2c0eea..a6fd40aade7c 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
>
>         best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
>         if (!best)
>                 return -1;
>
>         return x86_stepping(best->eax);
>  }
>
> +static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
> +}
> +
> +static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_misc_features_enables &
> +                 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
> +}
> +
>  #endif
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index cedbba0f3402..8b4b5566c365 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
>         ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
>         ctxt->eflags |= X86_EFLAGS_IF;
>         return X86EMUL_CONTINUE;
>  }
>
>  static int em_cpuid(struct x86_emulate_ctxt *ctxt)
>  {
>         u32 eax, ebx, ecx, edx;
> +       u64 msr = 0;
> +
> +       ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
> +       if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +           ctxt->ops->cpl(ctxt)) {
> +               return emulate_gp(ctxt, 0);
> +       }

Not strictly a comment on your patch, but why on Earth do there need
to be two copies of this check?

>
>         eax = reg_read(ctxt, VCPU_REGS_RAX);
>         ecx = reg_read(ctxt, VCPU_REGS_RCX);
>         ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
>         *reg_write(ctxt, VCPU_REGS_RAX) = eax;
>         *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
>         *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
>         *reg_write(ctxt, VCPU_REGS_RDX) = edx;
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e52c9088660f..1951b460da47 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
>
>         MSR_IA32_TSC_ADJUST,
>         MSR_IA32_TSCDEADLINE,
>         MSR_IA32_MISC_ENABLE,
>         MSR_IA32_MCG_STATUS,
>         MSR_IA32_MCG_CTL,
>         MSR_IA32_MCG_EXT_CTL,
>         MSR_IA32_SMBASE,
> +       MSR_PLATFORM_INFO,
> +       MSR_MISC_FEATURES_ENABLES,
>  };
>
>  static unsigned num_emulated_msrs;
>
>  bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
>  {
>         if (efer & efer_reserved_bits)
>                 return false;
> @@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 vcpu->arch.osvw.length = data;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 vcpu->arch.osvw.status = data;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               if (!msr_info->host_initiated ||
> +                   data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
> +                   (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
> +                    cpuid_fault_enabled(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_platform_info = data;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> +                   (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +                    !supports_cpuid_fault(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_misc_features_enables = data;
> +               break;
>         default:
>                 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
>                         return xen_hvm_config(vcpu, data);
>                 if (kvm_pmu_is_valid_msr(vcpu, msr))
>                         return kvm_pmu_set_msr(vcpu, msr_info);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
>                                     msr, data);
> @@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.length;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.status;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               msr_info->data = vcpu->arch.msr_platform_info;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               msr_info->data = vcpu->arch.msr_misc_features_enables;
> +               break;
>         default:
>                 if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
>                         return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
>                                                msr_info->index);
>                         return 1;
>                 } else {
> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>
>         kvm_clear_async_pf_completion_queue(vcpu);
>         kvm_async_pf_hash_reset(vcpu);
>         vcpu->arch.apf.halted = false;
>
>         if (!init_event) {
>                 kvm_pmu_reset(vcpu);
>                 vcpu->arch.smbase = 0x30000;
> +
> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
> +               vcpu->arch.msr_misc_features_enables = 0;

Jim, I assume you're worried about this bit?  It seems like
msr_platform_info should maybe be initialized to zero to avoid causing
an unintended migration issue.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 19:41     ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 19:41 UTC (permalink / raw)
  To: Kyle Huey
  Cc: Robert O'Callahan, Thomas Gleixner, Andy Lutomirski,
	Ingo Molnar, H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack

On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
> Hardware support for faulting on the cpuid instruction is not required to
> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
> kvm_require_cpl is even kind enough to inject the GP fault for us.
>
> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
> Reviewed-by: David Matlack <dmatlack@google.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  2 ++
>  arch/x86/kvm/cpuid.c            |  3 +++
>  arch/x86/kvm/cpuid.h            | 11 +++++++++++
>  arch/x86/kvm/emulate.c          |  7 +++++++
>  arch/x86/kvm/x86.c              | 26 ++++++++++++++++++++++++++
>  5 files changed, 49 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index a7066dc1a7e9..a0d6f0c47440 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -601,16 +601,18 @@ struct kvm_vcpu_arch {
>         u64 pat;
>
>         unsigned switch_db_regs;
>         unsigned long db[KVM_NR_DB_REGS];
>         unsigned long dr6;
>         unsigned long dr7;
>         unsigned long eff_db[KVM_NR_DB_REGS];
>         unsigned long guest_debug_dr7;
> +       u64 msr_platform_info;
> +       u64 msr_misc_features_enables;
>
>         u64 mcg_cap;
>         u64 mcg_status;
>         u64 mcg_ctl;
>         u64 mcg_ext_ctl;
>         u64 *mce_banks;
>
>         /* Cache MMIO info */
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index e85f6bd7b9d5..588ac8ae0a60 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -877,16 +877,19 @@ void kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
>         trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx);
>  }
>  EXPORT_SYMBOL_GPL(kvm_cpuid);
>
>  int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
>  {
>         u32 eax, ebx, ecx, edx;
>
> +       if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
> +               return;
> +
>         eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
>         ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
>         kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx);
>         kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
>         kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
>         kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
>         kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
>         return kvm_skip_emulated_instruction(vcpu);
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index 35058c2c0eea..a6fd40aade7c 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -200,9 +200,20 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu *vcpu)
>
>         best = kvm_find_cpuid_entry(vcpu, 0x1, 0);
>         if (!best)
>                 return -1;
>
>         return x86_stepping(best->eax);
>  }
>
> +static inline bool supports_cpuid_fault(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT;
> +}
> +
> +static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
> +{
> +       return vcpu->arch.msr_misc_features_enables &
> +                 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
> +}
> +
>  #endif
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index cedbba0f3402..8b4b5566c365 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -3848,16 +3848,23 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
>         ctxt->interruptibility = KVM_X86_SHADOW_INT_STI;
>         ctxt->eflags |= X86_EFLAGS_IF;
>         return X86EMUL_CONTINUE;
>  }
>
>  static int em_cpuid(struct x86_emulate_ctxt *ctxt)
>  {
>         u32 eax, ebx, ecx, edx;
> +       u64 msr = 0;
> +
> +       ctxt->ops->get_msr(ctxt, MSR_MISC_FEATURES_ENABLES, &msr);
> +       if (msr & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +           ctxt->ops->cpl(ctxt)) {
> +               return emulate_gp(ctxt, 0);
> +       }

Not strictly a comment on your patch, but why on Earth do there need
to be two copies of this check?

>
>         eax = reg_read(ctxt, VCPU_REGS_RAX);
>         ecx = reg_read(ctxt, VCPU_REGS_RCX);
>         ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx);
>         *reg_write(ctxt, VCPU_REGS_RAX) = eax;
>         *reg_write(ctxt, VCPU_REGS_RBX) = ebx;
>         *reg_write(ctxt, VCPU_REGS_RCX) = ecx;
>         *reg_write(ctxt, VCPU_REGS_RDX) = edx;
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e52c9088660f..1951b460da47 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -998,16 +998,18 @@ static u32 emulated_msrs[] = {
>
>         MSR_IA32_TSC_ADJUST,
>         MSR_IA32_TSCDEADLINE,
>         MSR_IA32_MISC_ENABLE,
>         MSR_IA32_MCG_STATUS,
>         MSR_IA32_MCG_CTL,
>         MSR_IA32_MCG_EXT_CTL,
>         MSR_IA32_SMBASE,
> +       MSR_PLATFORM_INFO,
> +       MSR_MISC_FEATURES_ENABLES,
>  };
>
>  static unsigned num_emulated_msrs;
>
>  bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer)
>  {
>         if (efer & efer_reserved_bits)
>                 return false;
> @@ -2285,16 +2287,31 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 vcpu->arch.osvw.length = data;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 vcpu->arch.osvw.status = data;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               if (!msr_info->host_initiated ||
> +                   data & ~MSR_PLATFORM_INFO_CPUID_FAULT ||
> +                   (!(data & MSR_PLATFORM_INFO_CPUID_FAULT) &&
> +                    cpuid_fault_enabled(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_platform_info = data;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT ||
> +                   (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT &&
> +                    !supports_cpuid_fault(vcpu)))
> +                       return 1;
> +               vcpu->arch.msr_misc_features_enables = data;
> +               break;
>         default:
>                 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
>                         return xen_hvm_config(vcpu, data);
>                 if (kvm_pmu_is_valid_msr(vcpu, msr))
>                         return kvm_pmu_set_msr(vcpu, msr_info);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled wrmsr: 0x%x data 0x%llx\n",
>                                     msr, data);
> @@ -2499,16 +2516,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.length;
>                 break;
>         case MSR_AMD64_OSVW_STATUS:
>                 if (!guest_cpuid_has_osvw(vcpu))
>                         return 1;
>                 msr_info->data = vcpu->arch.osvw.status;
>                 break;
> +       case MSR_PLATFORM_INFO:
> +               msr_info->data = vcpu->arch.msr_platform_info;
> +               break;
> +       case MSR_MISC_FEATURES_ENABLES:
> +               msr_info->data = vcpu->arch.msr_misc_features_enables;
> +               break;
>         default:
>                 if (kvm_pmu_is_valid_msr(vcpu, msr_info->index))
>                         return kvm_pmu_get_msr(vcpu, msr_info->index, &msr_info->data);
>                 if (!ignore_msrs) {
>                         vcpu_debug_ratelimited(vcpu, "unhandled rdmsr: 0x%x\n",
>                                                msr_info->index);
>                         return 1;
>                 } else {
> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>
>         kvm_clear_async_pf_completion_queue(vcpu);
>         kvm_async_pf_hash_reset(vcpu);
>         vcpu->arch.apf.halted = false;
>
>         if (!init_event) {
>                 kvm_pmu_reset(vcpu);
>                 vcpu->arch.smbase = 0x30000;
> +
> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
> +               vcpu->arch.msr_misc_features_enables = 0;

Jim, I assume you're worried about this bit?  It seems like
msr_platform_info should maybe be initialized to zero to avoid causing
an unintended migration issue.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 19:41     ` luto
  (?)
  (?)
@ 2018-07-27 20:28       ` jmattson
  -1 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 20:28 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Kyle Huey, Robert O'Callahan, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>> Hardware support for faulting on the cpuid instruction is not required to
>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>
>> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
>> Reviewed-by: David Matlack <dmatlack@google.com>
>> ---
>> ...
>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>
>>         kvm_clear_async_pf_completion_queue(vcpu);
>>         kvm_async_pf_hash_reset(vcpu);
>>         vcpu->arch.apf.halted = false;
>>
>>         if (!init_event) {
>>                 kvm_pmu_reset(vcpu);
>>                 vcpu->arch.smbase = 0x30000;
>> +
>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>> +               vcpu->arch.msr_misc_features_enables = 0;
>
> Jim, I assume you're worried about this bit?  It seems like
> msr_platform_info should maybe be initialized to zero to avoid causing
> an unintended migration issue.

Initializing this bit to zero helps with migration, but then if the
CPUID faulting bits in both MSRs are set, userspace has to take pains
to ensure that MSR_PLATFORM_INFO is restored first, or the
MSR_MISC_FEATURES_ENABLES value will be rejected.

I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
feeding into someone's calculated TSC frequency.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:28       ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: jmattson @ 2018-07-27 20:28 UTC (permalink / raw)


On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto at kernel.org> wrote:
> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me at kylehuey.com> wrote:
>> Hardware support for faulting on the cpuid instruction is not required to
>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>
>> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
>> Reviewed-by: David Matlack <dmatlack at google.com>
>> ---
>> ...
>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>
>>         kvm_clear_async_pf_completion_queue(vcpu);
>>         kvm_async_pf_hash_reset(vcpu);
>>         vcpu->arch.apf.halted = false;
>>
>>         if (!init_event) {
>>                 kvm_pmu_reset(vcpu);
>>                 vcpu->arch.smbase = 0x30000;
>> +
>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>> +               vcpu->arch.msr_misc_features_enables = 0;
>
> Jim, I assume you're worried about this bit?  It seems like
> msr_platform_info should maybe be initialized to zero to avoid causing
> an unintended migration issue.

Initializing this bit to zero helps with migration, but then if the
CPUID faulting bits in both MSRs are set, userspace has to take pains
to ensure that MSR_PLATFORM_INFO is restored first, or the
MSR_MISC_FEATURES_ENABLES value will be rejected.

I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
feeding into someone's calculated TSC frequency.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:28       ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 20:28 UTC (permalink / raw)


On Fri, Jul 27, 2018@12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
> On Wed, Feb 8, 2017@12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>> Hardware support for faulting on the cpuid instruction is not required to
>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>
>> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
>> Reviewed-by: David Matlack <dmatlack at google.com>
>> ---
>> ...
>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>
>>         kvm_clear_async_pf_completion_queue(vcpu);
>>         kvm_async_pf_hash_reset(vcpu);
>>         vcpu->arch.apf.halted = false;
>>
>>         if (!init_event) {
>>                 kvm_pmu_reset(vcpu);
>>                 vcpu->arch.smbase = 0x30000;
>> +
>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>> +               vcpu->arch.msr_misc_features_enables = 0;
>
> Jim, I assume you're worried about this bit?  It seems like
> msr_platform_info should maybe be initialized to zero to avoid causing
> an unintended migration issue.

Initializing this bit to zero helps with migration, but then if the
CPUID faulting bits in both MSRs are set, userspace has to take pains
to ensure that MSR_PLATFORM_INFO is restored first, or the
MSR_MISC_FEATURES_ENABLES value will be rejected.

I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
feeding into someone's calculated TSC frequency.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:28       ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 20:28 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Kyle Huey, Robert O'Callahan, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack

On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>> Hardware support for faulting on the cpuid instruction is not required to
>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>
>> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
>> Reviewed-by: David Matlack <dmatlack@google.com>
>> ---
>> ...
>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>
>>         kvm_clear_async_pf_completion_queue(vcpu);
>>         kvm_async_pf_hash_reset(vcpu);
>>         vcpu->arch.apf.halted = false;
>>
>>         if (!init_event) {
>>                 kvm_pmu_reset(vcpu);
>>                 vcpu->arch.smbase = 0x30000;
>> +
>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>> +               vcpu->arch.msr_misc_features_enables = 0;
>
> Jim, I assume you're worried about this bit?  It seems like
> msr_platform_info should maybe be initialized to zero to avoid causing
> an unintended migration issue.

Initializing this bit to zero helps with migration, but then if the
CPUID faulting bits in both MSRs are set, userspace has to take pains
to ensure that MSR_PLATFORM_INFO is restored first, or the
MSR_MISC_FEATURES_ENABLES value will be rejected.

I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
feeding into someone's calculated TSC frequency.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 20:28       ` jmattson
  (?)
  (?)
@ 2018-07-27 20:46         ` luto
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 20:46 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list



> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
> 
>> On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
>>> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>>> Hardware support for faulting on the cpuid instruction is not required to
>>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>> 
>>> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
>>> Reviewed-by: David Matlack <dmatlack@google.com>
>>> ---
>>> ...
>>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>> 
>>>        kvm_clear_async_pf_completion_queue(vcpu);
>>>        kvm_async_pf_hash_reset(vcpu);
>>>        vcpu->arch.apf.halted = false;
>>> 
>>>        if (!init_event) {
>>>                kvm_pmu_reset(vcpu);
>>>                vcpu->arch.smbase = 0x30000;
>>> +
>>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>>> +               vcpu->arch.msr_misc_features_enables = 0;
>> 
>> Jim, I assume you're worried about this bit?  It seems like
>> msr_platform_info should maybe be initialized to zero to avoid causing
>> an unintended migration issue.
> 
> Initializing this bit to zero helps with migration, but then if the
> CPUID faulting bits in both MSRs are set, userspace has to take pains
> to ensure that MSR_PLATFORM_INFO is restored first, or the
> MSR_MISC_FEATURES_ENABLES value will be rejected.

The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

> 
> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
> feeding into someone's calculated TSC frequency.

Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:46         ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: luto @ 2018-07-27 20:46 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2218 bytes --]



> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson at google.com> wrote:
> 
>> On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto at kernel.org> wrote:
>>> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me at kylehuey.com> wrote:
>>> Hardware support for faulting on the cpuid instruction is not required to
>>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>> 
>>> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
>>> Reviewed-by: David Matlack <dmatlack at google.com>
>>> ---
>>> ...
>>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>> 
>>>        kvm_clear_async_pf_completion_queue(vcpu);
>>>        kvm_async_pf_hash_reset(vcpu);
>>>        vcpu->arch.apf.halted = false;
>>> 
>>>        if (!init_event) {
>>>                kvm_pmu_reset(vcpu);
>>>                vcpu->arch.smbase = 0x30000;
>>> +
>>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>>> +               vcpu->arch.msr_misc_features_enables = 0;
>> 
>> Jim, I assume you're worried about this bit?  It seems like
>> msr_platform_info should maybe be initialized to zero to avoid causing
>> an unintended migration issue.
> 
> Initializing this bit to zero helps with migration, but then if the
> CPUID faulting bits in both MSRs are set, userspace has to take pains
> to ensure that MSR_PLATFORM_INFO is restored first, or the
> MSR_MISC_FEATURES_ENABLES value will be rejected.

The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

> 
> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
> feeding into someone's calculated TSC frequency.

Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:46         ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 20:46 UTC (permalink / raw)




> On Jul 27, 2018,@1:28 PM, Jim Mattson <jmattson@google.com> wrote:
> 
>> On Fri, Jul 27, 2018@12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
>>> On Wed, Feb 8, 2017@12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>>> Hardware support for faulting on the cpuid instruction is not required to
>>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>> 
>>> Signed-off-by: Kyle Huey <khuey at kylehuey.com>
>>> Reviewed-by: David Matlack <dmatlack at google.com>
>>> ---
>>> ...
>>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>> 
>>>        kvm_clear_async_pf_completion_queue(vcpu);
>>>        kvm_async_pf_hash_reset(vcpu);
>>>        vcpu->arch.apf.halted = false;
>>> 
>>>        if (!init_event) {
>>>                kvm_pmu_reset(vcpu);
>>>                vcpu->arch.smbase = 0x30000;
>>> +
>>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>>> +               vcpu->arch.msr_misc_features_enables = 0;
>> 
>> Jim, I assume you're worried about this bit?  It seems like
>> msr_platform_info should maybe be initialized to zero to avoid causing
>> an unintended migration issue.
> 
> Initializing this bit to zero helps with migration, but then if the
> CPUID faulting bits in both MSRs are set, userspace has to take pains
> to ensure that MSR_PLATFORM_INFO is restored first, or the
> MSR_MISC_FEATURES_ENABLES value will be rejected.

The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

> 
> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
> feeding into someone's calculated TSC frequency.

Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 20:46         ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 20:46 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov



> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
> 
>> On Fri, Jul 27, 2018 at 12:41 PM, Andy Lutomirski <luto@kernel.org> wrote:
>>> On Wed, Feb 8, 2017 at 12:09 AM, Kyle Huey <me@kylehuey.com> wrote:
>>> Hardware support for faulting on the cpuid instruction is not required to
>>> emulate it, because cpuid triggers a VM exit anyways. KVM handles the relevant
>>> MSRs (MSR_PLATFORM_INFO and MSR_MISC_FEATURES_ENABLE) and upon a
>>> cpuid-induced VM exit checks the cpuid faulting state and the CPL.
>>> kvm_require_cpl is even kind enough to inject the GP fault for us.
>>> 
>>> Signed-off-by: Kyle Huey <khuey@kylehuey.com>
>>> Reviewed-by: David Matlack <dmatlack@google.com>
>>> ---
>>> ...
>>> @@ -7613,16 +7636,19 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
>>> 
>>>        kvm_clear_async_pf_completion_queue(vcpu);
>>>        kvm_async_pf_hash_reset(vcpu);
>>>        vcpu->arch.apf.halted = false;
>>> 
>>>        if (!init_event) {
>>>                kvm_pmu_reset(vcpu);
>>>                vcpu->arch.smbase = 0x30000;
>>> +
>>> +               vcpu->arch.msr_platform_info = MSR_PLATFORM_INFO_CPUID_FAULT;
>>> +               vcpu->arch.msr_misc_features_enables = 0;
>> 
>> Jim, I assume you're worried about this bit?  It seems like
>> msr_platform_info should maybe be initialized to zero to avoid causing
>> an unintended migration issue.
> 
> Initializing this bit to zero helps with migration, but then if the
> CPUID faulting bits in both MSRs are set, userspace has to take pains
> to ensure that MSR_PLATFORM_INFO is restored first, or the
> MSR_MISC_FEATURES_ENABLES value will be rejected.

The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

> 
> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
> feeding into someone's calculated TSC frequency.

Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 20:46         ` luto
  (?)
  (?)
@ 2018-07-27 21:03           ` jmattson
  -1 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:03 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>> Initializing this bit to zero helps with migration, but then if the
>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>
> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

That would be an improvement, I think.

>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>> feeding into someone's calculated TSC frequency.
>
> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

No. The reason I bring this up is that a customer has code that
expects to be able to derive the TSC frequency from this MSR (per
Intel's instructions in SDM volume 3, section 18.7.3), and they were
surprised to find that the MSR raises #GP on our platform. We're
looking into cherry-picking this support from upstream as a start, but
I know the customer would be unhappy to read zero from bits 15:8.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:03           ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: jmattson @ 2018-07-27 21:03 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1407 bytes --]

On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto at amacapital.net> wrote:
>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson at google.com> wrote:
>> Initializing this bit to zero helps with migration, but then if the
>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>
> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

That would be an improvement, I think.

>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>> feeding into someone's calculated TSC frequency.
>
> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

No. The reason I bring this up is that a customer has code that
expects to be able to derive the TSC frequency from this MSR (per
Intel's instructions in SDM volume 3, section 18.7.3), and they were
surprised to find that the MSR raises #GP on our platform. We're
looking into cherry-picking this support from upstream as a start, but
I know the customer would be unhappy to read zero from bits 15:8.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:03           ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:03 UTC (permalink / raw)


On Fri, Jul 27, 2018@1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>> On Jul 27, 2018,@1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>> Initializing this bit to zero helps with migration, but then if the
>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>
> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

That would be an improvement, I think.

>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>> feeding into someone's calculated TSC frequency.
>
> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

No. The reason I bring this up is that a customer has code that
expects to be able to derive the TSC frequency from this MSR (per
Intel's instructions in SDM volume 3, section 18.7.3), and they were
surprised to find that the MSR raises #GP on our platform. We're
looking into cherry-picking this support from upstream as a start, but
I know the customer would be unhappy to read zero from bits 15:8.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:03           ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:03 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov

On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>> Initializing this bit to zero helps with migration, but then if the
>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>
> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong

That would be an improvement, I think.

>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>> feeding into someone's calculated TSC frequency.
>
> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?

No. The reason I bring this up is that a customer has code that
expects to be able to derive the TSC frequency from this MSR (per
Intel's instructions in SDM volume 3, section 18.7.3), and they were
surprised to find that the MSR raises #GP on our platform. We're
looking into cherry-picking this support from upstream as a start, but
I know the customer would be unhappy to read zero from bits 15:8.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 21:03           ` jmattson
  (?)
  (?)
@ 2018-07-27 21:05             ` luto
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 21:05 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Fri, Jul 27, 2018 at 2:03 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>>> Initializing this bit to zero helps with migration, but then if the
>>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>>
>> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong
>
> That would be an improvement, I think.

I personally don't know enough about the QEMU, kvmtool, etc
architecture to know whether this would be a good idea.

>
>>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>>> feeding into someone's calculated TSC frequency.
>>
>> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?
>
> No. The reason I bring this up is that a customer has code that
> expects to be able to derive the TSC frequency from this MSR (per
> Intel's instructions in SDM volume 3, section 18.7.3), and they were
> surprised to find that the MSR raises #GP on our platform. We're
> looking into cherry-picking this support from upstream as a start, but
> I know the customer would be unhappy to read zero from bits 15:8.

Does KVM *have* a concept of "maximum non-turbo frequency" of the
guest that it would make sense to expose here?  If so, presumably the
right solution is to expose it.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:05             ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: luto @ 2018-07-27 21:05 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On Fri, Jul 27, 2018 at 2:03 PM, Jim Mattson <jmattson at google.com> wrote:
> On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto at amacapital.net> wrote:
>>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson at google.com> wrote:
>>> Initializing this bit to zero helps with migration, but then if the
>>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>>
>> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong
>
> That would be an improvement, I think.

I personally don't know enough about the QEMU, kvmtool, etc
architecture to know whether this would be a good idea.

>
>>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>>> feeding into someone's calculated TSC frequency.
>>
>> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?
>
> No. The reason I bring this up is that a customer has code that
> expects to be able to derive the TSC frequency from this MSR (per
> Intel's instructions in SDM volume 3, section 18.7.3), and they were
> surprised to find that the MSR raises #GP on our platform. We're
> looking into cherry-picking this support from upstream as a start, but
> I know the customer would be unhappy to read zero from bits 15:8.

Does KVM *have* a concept of "maximum non-turbo frequency" of the
guest that it would make sense to expose here?  If so, presumably the
right solution is to expose it.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:05             ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 21:05 UTC (permalink / raw)


On Fri, Jul 27, 2018@2:03 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018@1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>>> On Jul 27, 2018,@1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>>> Initializing this bit to zero helps with migration, but then if the
>>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>>
>> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong
>
> That would be an improvement, I think.

I personally don't know enough about the QEMU, kvmtool, etc
architecture to know whether this would be a good idea.

>
>>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>>> feeding into someone's calculated TSC frequency.
>>
>> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?
>
> No. The reason I bring this up is that a customer has code that
> expects to be able to derive the TSC frequency from this MSR (per
> Intel's instructions in SDM volume 3, section 18.7.3), and they were
> surprised to find that the MSR raises #GP on our platform. We're
> looking into cherry-picking this support from upstream as a start, but
> I know the customer would be unhappy to read zero from bits 15:8.

Does KVM *have* a concept of "maximum non-turbo frequency" of the
guest that it would make sense to expose here?  If so, presumably the
right solution is to expose it.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:05             ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 21:05 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov

On Fri, Jul 27, 2018 at 2:03 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018 at 1:46 PM, Andy Lutomirski <luto@amacapital.net> wrote:
>>> On Jul 27, 2018, at 1:28 PM, Jim Mattson <jmattson@google.com> wrote:
>>> Initializing this bit to zero helps with migration, but then if the
>>> CPUID faulting bits in both MSRs are set, userspace has to take pains
>>> to ensure that MSR_PLATFORM_INFO is restored first, or the
>>> MSR_MISC_FEATURES_ENABLES value will be rejected.
>>
>> The code could drop the constraint and just let the entry possibly fail if the MSRs are set wrong
>
> That would be an improvement, I think.

I personally don't know enough about the QEMU, kvmtool, etc
architecture to know whether this would be a good idea.

>
>>> I'm also concerned about the 0 in the "Maximum Non-Turbo Ratio" field
>>> feeding into someone's calculated TSC frequency.
>>
>> Hmm. I don’t have a good answer to that. Are there any real CPUs that have this MSR but don’t have that field?
>
> No. The reason I bring this up is that a customer has code that
> expects to be able to derive the TSC frequency from this MSR (per
> Intel's instructions in SDM volume 3, section 18.7.3), and they were
> surprised to find that the MSR raises #GP on our platform. We're
> looking into cherry-picking this support from upstream as a start, but
> I know the customer would be unhappy to read zero from bits 15:8.

Does KVM *have* a concept of "maximum non-turbo frequency" of the
guest that it would make sense to expose here?  If so, presumably the
right solution is to expose it.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 21:05             ` luto
  (?)
  (?)
@ 2018-07-27 21:30               ` jmattson
  -1 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:30 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Kyle Huey, Robert O'Callahan, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
> Does KVM *have* a concept of "maximum non-turbo frequency" of the
> guest that it would make sense to expose here?  If so, presumably the
> right solution is to expose it.

KVM has the concept of a guest's invariant TSC frequency. The Maximum
Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
MSR, depending on microarchitecture.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:30               ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: jmattson @ 2018-07-27 21:30 UTC (permalink / raw)


On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto at kernel.org> wrote:
> Does KVM *have* a concept of "maximum non-turbo frequency" of the
> guest that it would make sense to expose here?  If so, presumably the
> right solution is to expose it.

KVM has the concept of a guest's invariant TSC frequency. The Maximum
Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
MSR, depending on microarchitecture.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:30               ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:30 UTC (permalink / raw)


On Fri, Jul 27, 2018@2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
> Does KVM *have* a concept of "maximum non-turbo frequency" of the
> guest that it would make sense to expose here?  If so, presumably the
> right solution is to expose it.

KVM has the concept of a guest's invariant TSC frequency. The Maximum
Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
MSR, depending on microarchitecture.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 21:30               ` jmattson
  0 siblings, 0 replies; 54+ messages in thread
From: Jim Mattson @ 2018-07-27 21:30 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Kyle Huey, Robert O'Callahan, Thomas Gleixner, Ingo Molnar,
	H. Peter Anvin, X86 ML, Paolo Bonzini,
	Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack

On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
> Does KVM *have* a concept of "maximum non-turbo frequency" of the
> guest that it would make sense to expose here?  If so, presumably the
> right solution is to expose it.

KVM has the concept of a guest's invariant TSC frequency. The Maximum
Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
MSR, depending on microarchitecture.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
  2018-07-27 21:30               ` jmattson
  (?)
  (?)
@ 2018-07-27 22:58                 ` luto
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 22:58 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov, David Matlack,
	Nadav Amit, Andi Kleen, LKML, user-mode-linux-devel,
	open list:USER-MODE LINUX (UML),
	Linux FS Devel, open list:KERNEL SELFTEST FRAMEWORK, kvm list

On Fri, Jul 27, 2018 at 2:30 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> Does KVM *have* a concept of "maximum non-turbo frequency" of the
>> guest that it would make sense to expose here?  If so, presumably the
>> right solution is to expose it.
>
> KVM has the concept of a guest's invariant TSC frequency. The Maximum
> Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
> 100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
> MSR, depending on microarchitecture.

Which is problematic, unless KVM wants to start deciding what the base
clock is.  There's MSR_FSB_FREQ, which is supported on Atom only,
IIRC.

I really wish Intel would get its act together.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 22:58                 ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: luto @ 2018-07-27 22:58 UTC (permalink / raw)


On Fri, Jul 27, 2018 at 2:30 PM, Jim Mattson <jmattson at google.com> wrote:
> On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto at kernel.org> wrote:
>> Does KVM *have* a concept of "maximum non-turbo frequency" of the
>> guest that it would make sense to expose here?  If so, presumably the
>> right solution is to expose it.
>
> KVM has the concept of a guest's invariant TSC frequency. The Maximum
> Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
> 100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
> MSR, depending on microarchitecture.

Which is problematic, unless KVM wants to start deciding what the base
clock is.  There's MSR_FSB_FREQ, which is supported on Atom only,
IIRC.

I really wish Intel would get its act together.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 22:58                 ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 22:58 UTC (permalink / raw)


On Fri, Jul 27, 2018@2:30 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018@2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> Does KVM *have* a concept of "maximum non-turbo frequency" of the
>> guest that it would make sense to expose here?  If so, presumably the
>> right solution is to expose it.
>
> KVM has the concept of a guest's invariant TSC frequency. The Maximum
> Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
> 100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
> MSR, depending on microarchitecture.

Which is problematic, unless KVM wants to start deciding what the base
clock is.  There's MSR_FSB_FREQ, which is supported on Atom only,
IIRC.

I really wish Intel would get its act together.
--
To unsubscribe from this list: send the line "unsubscribe linux-kselftest" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting
@ 2018-07-27 22:58                 ` luto
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2018-07-27 22:58 UTC (permalink / raw)
  To: Jim Mattson
  Cc: Andy Lutomirski, Kyle Huey, Robert O'Callahan,
	Thomas Gleixner, Ingo Molnar, H. Peter Anvin, X86 ML,
	Paolo Bonzini, Radim Krčmář,
	Jeff Dike, Richard Weinberger, Alexander Viro, Shuah Khan,
	Dave Hansen, Borislav Petkov, Peter Zijlstra, Boris Ostrovsky,
	Len Brown, Rafael J. Wysocki, Dmitry Safonov

On Fri, Jul 27, 2018 at 2:30 PM, Jim Mattson <jmattson@google.com> wrote:
> On Fri, Jul 27, 2018 at 2:05 PM, Andy Lutomirski <luto@kernel.org> wrote:
>> Does KVM *have* a concept of "maximum non-turbo frequency" of the
>> guest that it would make sense to expose here?  If so, presumably the
>> right solution is to expose it.
>
> KVM has the concept of a guest's invariant TSC frequency. The Maximum
> Non-Turbo Ratio is just some fraction of that. Sadly, the fraction is
> 100 MHz, 133.33MHz, or the "scalable bus frequency" from some other
> MSR, depending on microarchitecture.

Which is problematic, unless KVM wants to start deciding what the base
clock is.  There's MSR_FSB_FREQ, which is supported on Atom only,
IIRC.

I really wish Intel would get its act together.

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2018-07-27 22:58 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-08  8:09 [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction Kyle Huey
2017-02-08  8:09 ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 1/9] x86/arch_prctl/64: Use SYSCALL_DEFINE2 to define sys_arch_prctl Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 2/9] x86/arch_prctl/64: Rename do_arch_prctl to do_arch_prctl_64 Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 3/9] x86/arch_prctl: Add do_arch_prctl_common Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 4/9] x86/syscalls/32: Wire up arch_prctl on x86-32 Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 5/9] x86/cpufeature: Detect CPUID faulting support Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 6/9] x86/arch_prctl: Add ARCH_[GET|SET]_CPUID Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 7/9] x86/arch_prctl: Selftest for ARCH_[GET|SET]_CPUID Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-08  8:09 ` [PATCH v14 8/9] KVM: x86: virtualize cpuid faulting Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2018-07-27 17:15   ` Jim Mattson
2018-07-27 17:15     ` Jim Mattson
2018-07-27 17:15     ` Jim Mattson
2018-07-27 17:15     ` jmattson
2018-07-27 19:41   ` Andy Lutomirski
2018-07-27 19:41     ` Andy Lutomirski
2018-07-27 19:41     ` Andy Lutomirski
2018-07-27 19:41     ` luto
2018-07-27 20:28     ` Jim Mattson
2018-07-27 20:28       ` Jim Mattson
2018-07-27 20:28       ` Jim Mattson
2018-07-27 20:28       ` jmattson
2018-07-27 20:46       ` Andy Lutomirski
2018-07-27 20:46         ` Andy Lutomirski
2018-07-27 20:46         ` Andy Lutomirski
2018-07-27 20:46         ` luto
2018-07-27 21:03         ` Jim Mattson
2018-07-27 21:03           ` Jim Mattson
2018-07-27 21:03           ` Jim Mattson
2018-07-27 21:03           ` jmattson
2018-07-27 21:05           ` Andy Lutomirski
2018-07-27 21:05             ` Andy Lutomirski
2018-07-27 21:05             ` Andy Lutomirski
2018-07-27 21:05             ` luto
2018-07-27 21:30             ` Jim Mattson
2018-07-27 21:30               ` Jim Mattson
2018-07-27 21:30               ` Jim Mattson
2018-07-27 21:30               ` jmattson
2018-07-27 22:58               ` Andy Lutomirski
2018-07-27 22:58                 ` Andy Lutomirski
2018-07-27 22:58                 ` Andy Lutomirski
2018-07-27 22:58                 ` luto
2017-02-08  8:09 ` [PATCH v14 9/9] x86/arch_prctl: Rename 'code' argument to 'option' Kyle Huey
2017-02-08  8:09   ` Kyle Huey
2017-02-10 13:07 ` [PATCH v14 0/9] x86/arch_prctl Add ARCH_[GET|SET]_CPUID for controlling the CPUID instruction Thomas Gleixner
2017-02-10 13:07   ` Thomas Gleixner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.