[tip:x86/cpu] x86/cpu: Fix MSR value truncation issue

2015-11-24 Thread tip-bot for Borislav Petkov
Commit-ID:  31ac34ca5636e596485c6e03df1879643bde585e
Gitweb: http://git.kernel.org/tip/31ac34ca5636e596485c6e03df1879643bde585e
Author: Borislav Petkov 
AuthorDate: Mon, 23 Nov 2015 11:12:25 +0100
Committer:  Ingo Molnar 
CommitDate: Tue, 24 Nov 2015 09:15:55 +0100

x86/cpu: Fix MSR value truncation issue

So sparse rightfully complains that the u64 MSR value we're
writing into the STAR MSR, i.e. 0xc081, is being truncated:

./arch/x86/include/asm/msr.h:193:36: warning: cast truncates
bits from constant value (230010 becomes 0)

because the actual value doesn't fit into the unsigned 32-bit
quantity which are the @low and @high wrmsrl() parameters.

This is not a problem, practically, because gcc is actually
being smart enough here and does the right thing:

  .loc 3 87 0
  xorl%esi, %esi# we needz a 32-bit zero
  movl$2293776, %edx# 0x00230010 == (__USER32_CS << 16) | 
__KERNEL_CS go into the high bits
  movl$-1073741695, %ecx# MSR_STAR, i.e., 0xc081
  movl%esi, %eax# low order 32 bits in the MSR which are 0
  #APP
  # 87 "./arch/x86/include/asm/msr.h" 1
  wrmsr

More specifically, MSR_STAR[31:0] is being set to 0. That field
is reserved on Intel and on AMD it is 32-bit SYSCALL Target EIP.

I'd strongly guess because Intel doesn't have SYSCALL in
compat/legacy mode and we're using SYSENTER and INT80 there. And
for compat syscalls in long mode we use CSTAR.

So let's fix the sparse warning by writing SYSRET and SYSCALL CS
and SS into the high 32-bit half of STAR and 0 in the low half
explicitly.

 [ Actually, if we had to be precise, we would have to read what's in
   STAR[31:0] and write it back unchanged on Intel and write 0 on AMD. I
   guess the current writing to 0 is still ok since Intel can apparently
   stomach it. ]

The resulting code is identical to what we have above:

  .loc 3 87 0
  xorl%esi, %esi  # tmp104
  movl$2293776, %eax  #, tmp103
  movl$-1073741695, %ecx  #, tmp102
  movl%esi, %edx  # tmp104, tmp104

  ...

wrmsr

Signed-off-by: Borislav Petkov 
Cc: Andy Lutomirski 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Denys Vlasenko 
Cc: H. Peter Anvin 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Link: http://lkml.kernel.org/r/1448273546-2567-6-git-send-email...@alien8.de
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/cpu/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 0bed416..105da8d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1180,7 +1180,7 @@ void syscall_init(void)
 * They both write to the same internal register. STAR allows to
 * set CS/DS but only a 32bit target. LSTAR sets the 64bit rip.
 */
-   wrmsrl(MSR_STAR,  ((u64)__USER32_CS)<<48  | ((u64)__KERNEL_CS)<<32);
+   wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);
 
 #ifdef CONFIG_IA32_EMULATION
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/cpu] x86/cpu: Fix MSR value truncation issue

2015-11-24 Thread tip-bot for Borislav Petkov
Commit-ID:  31ac34ca5636e596485c6e03df1879643bde585e
Gitweb: http://git.kernel.org/tip/31ac34ca5636e596485c6e03df1879643bde585e
Author: Borislav Petkov 
AuthorDate: Mon, 23 Nov 2015 11:12:25 +0100
Committer:  Ingo Molnar 
CommitDate: Tue, 24 Nov 2015 09:15:55 +0100

x86/cpu: Fix MSR value truncation issue

So sparse rightfully complains that the u64 MSR value we're
writing into the STAR MSR, i.e. 0xc081, is being truncated:

./arch/x86/include/asm/msr.h:193:36: warning: cast truncates
bits from constant value (230010 becomes 0)

because the actual value doesn't fit into the unsigned 32-bit
quantity which are the @low and @high wrmsrl() parameters.

This is not a problem, practically, because gcc is actually
being smart enough here and does the right thing:

  .loc 3 87 0
  xorl%esi, %esi# we needz a 32-bit zero
  movl$2293776, %edx# 0x00230010 == (__USER32_CS << 16) | 
__KERNEL_CS go into the high bits
  movl$-1073741695, %ecx# MSR_STAR, i.e., 0xc081
  movl%esi, %eax# low order 32 bits in the MSR which are 0
  #APP
  # 87 "./arch/x86/include/asm/msr.h" 1
  wrmsr

More specifically, MSR_STAR[31:0] is being set to 0. That field
is reserved on Intel and on AMD it is 32-bit SYSCALL Target EIP.

I'd strongly guess because Intel doesn't have SYSCALL in
compat/legacy mode and we're using SYSENTER and INT80 there. And
for compat syscalls in long mode we use CSTAR.

So let's fix the sparse warning by writing SYSRET and SYSCALL CS
and SS into the high 32-bit half of STAR and 0 in the low half
explicitly.

 [ Actually, if we had to be precise, we would have to read what's in
   STAR[31:0] and write it back unchanged on Intel and write 0 on AMD. I
   guess the current writing to 0 is still ok since Intel can apparently
   stomach it. ]

The resulting code is identical to what we have above:

  .loc 3 87 0
  xorl%esi, %esi  # tmp104
  movl$2293776, %eax  #, tmp103
  movl$-1073741695, %ecx  #, tmp102
  movl%esi, %edx  # tmp104, tmp104

  ...

wrmsr

Signed-off-by: Borislav Petkov 
Cc: Andy Lutomirski 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Denys Vlasenko 
Cc: H. Peter Anvin 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Link: http://lkml.kernel.org/r/1448273546-2567-6-git-send-email...@alien8.de
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/cpu/common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 0bed416..105da8d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1180,7 +1180,7 @@ void syscall_init(void)
 * They both write to the same internal register. STAR allows to
 * set CS/DS but only a 32bit target. LSTAR sets the 64bit rip.
 */
-   wrmsrl(MSR_STAR,  ((u64)__USER32_CS)<<48  | ((u64)__KERNEL_CS)<<32);
+   wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);
 
 #ifdef CONFIG_IA32_EMULATION
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/