Re: [tip:x86/urgent] x86, AMD: Disable wrongly set X86_FEATURE_LAHF_LM CPUID bit

H. Peter Anvin
2009-08-24T20:34:40Z

On 08/22/2009 09:37 AM, Borislav Petkov wrote:
> On Fri, Aug 21, 2009 at 10:40:18AM -0700, H. Peter Anvin wrote:
>> If we're going to modify the paravirt_crap for yet another MSR
>> operation, then let's at least make it something like "write_msr_edi"
>> and have it take a parameter for the EDI value. Perhaps we should let
>> it set EBX and ESI as well (and the same for the read operation, even
>> though it already exists.)
>
> Ok, how about making all rdmsr* variants indirectly call into a
> native_read_msr_safe_reg() helper which takes esi and edi as additional
> arguments. There was no room for ebx since paravirt has a PVOP_CALL4
> macro which takes the largest number of args - 4 and I am lazy, of
> course, to implement a PVOP_CALL5 thing :o)
>
> The wrmsr variants could be done similarly.
>
> Suggestions, comments?
>

Looks reasonable... although part of me wonders if having a pointer to
an array containing the entire register file in and out is even better,
of if I'm just overengineering at this point.

Note that the only difference between "rdmsr" and "wrmsr" is the actual
opcode being executed at this point...

/*
* int native_rdmsr_safe_regs(u32 gprs[8]);
*
* 32-bit implementation
*
*/
ENTRY(native_rdmsr_safe_regs)
push %ebx
push %ebp
push %esi
push %edi
push $0 /* Return value */
push %eax
movl 4(%eax), %ecx
movl 8(%eax), %edx
movl 12(%eax), %ebx
movl 20(%eax), %ebp
movl 24(%eax), %esi
movl 28(%eax), %edi
movl (%eax), %eax
1: rdmsr
2: push %eax
movl 4(%esp), %eax
pop (%eax)
addl $4, %esp
movl %ecx, 4(%eax)
movl %edx, 8(%eax)
movl %ebx, 12(%eax)
movl %ebp, 20(%eax)
movl %esi, 24(%eax)
movl %edi, 28(%eax)
pop %eax
pop %edi
pop %esi
pop %ebp
pop %ebx
ret
3:
movl $-EIO, 4(%esp)
jmp 2b
__ASM_EX_SEC
.balign 4
.long 1b, 3b
.previous
EXIT(native_rdmsr_safe_regs)

/*
* int native_rdmsr_safe_regs(u32 gprs[8]);
*
* 64-bit implementation
*
*/
ENTRY(native_rdmsr_safe_regs)
push %rbx
push %rbp
push $0 /* Return value */
push %rdi
movl (%rdi), %eax
movl 4(%rdi), %ecx
movl 8(%rdi), %edx
movl 12(%rdi), %ebx
movl 20(%rdi), %ebp
movl 24(%rdi), %esi
movl 28(%rdi), %edi
1: rdmsr
2: movl %edi, %r10
pop %rdi
movl %eax, (%rdi)
movl %ecx, 4(%rdi)
movl %edx, 8(%rdi)
movl %ebx, 12(%rdi)
movl %ebp, 20(%rdi)
movl %esi, 24(%rdi)
movl %r10d, 28(%rdi)
pop %rax
pop %rbp
pop %rbx
ret
3:
movq $-EIO, 8(%esp)
jmp 2b
__ASM_EX_SEC
.balign 4
.long 1b, 3b
.previous
EXIT(native_rdmsr_safe_regs)