[flashrom] Patch to fix wrmsr for some toolchains

Mart Raudsepp mart.raudsepp at artecdesign.ee
Tue May 18 14:19:57 CEST 2010


Hello,

On E, 2010-05-17 at 16:20 -0700, ron minnich wrote:
> Hi, I'd like to know a bit more.
> 
> This basic use of the msr device has worked for a very long time. I'm
> not saying there is not a problem, but if there is, it might be best
> to change the struct than to add this code.

Right. This got broken on our toolchains ever since this struct was
introduced to flashrom fater 0.9 release.
I'm not even sure the same thing hit me now and him back in October, but
the same patch fixes it.
It would be weird if this is a new regression in newer GCC version
though, as that would be an ABI break I believe..

Do however note that rdmsr goes through a temporary uint32_t array as
well, just like this patch makes wrmsr. So with this patch it's sort of
uniform that way too.

> Do you have some assembly code showing how it failed?

No I didn't. But now I got some :)
Attached is the physmap.c file from r998 compiled to assembly with all
the same optimization and other flags as the object file is made, just
saved to assembly with -S option. So if anyone can read from that what's
going on, then feel free to; I don't speak assembler well :(

> For example ... certainly, in user mode, why isn't the msr_t just a
> 64-bit number?

Don't really know. All I know is that C language does not really give a
guarantee of structs being tightly packed (are there other rules though,
like for default alignment instead of compiler specific?), unless using
compiler extensions like GCC packed attribute. I have it hard to imagine
why it would be adding alignment padding in there either, if that's what
it is doing per the attached assembler.
However sizeof(msr_t) seem to be returning 8 as desired...


Mart
-------------- next part --------------
	.file	"physmap.c"
	.section	.rodata.str1.1,"aMS", at progbits,1
.LC0:
	.string	"No MSR initialized.\n"
	.text
.globl cleanup_cpu_msr
	.type	cleanup_cpu_msr, @function
cleanup_cpu_msr:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	fd_msr, %eax
	cmpl	$-1, %eax
	jne	.L2
	pushl	%eax
	pushl	%eax
	pushl	$.LC0
	pushl	$1
	call	print
	jmp	.L5
.L2:
	subl	$12, %esp
	pushl	%eax
	call	close
	movl	$-1, fd_msr
.L5:
	addl	$16, %esp
	leave
	ret
	.size	cleanup_cpu_msr, .-cleanup_cpu_msr
	.section	.rodata.str1.1
.LC1:
	.string	"Could not lseek() to MSR"
.LC2:
	.string	"Could not write() MSR"
	.text
.globl wrmsr
	.type	wrmsr, @function
wrmsr:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$12, %esp
	pushl	$0
	pushl	8(%ebp)
	pushl	fd_msr
	call	lseek
	addl	$16, %esp
	incl	%eax
	jne	.L8
	subl	$12, %esp
	pushl	$.LC1
	jmp	.L13
.L8:
	pushl	%ecx
	pushl	$8
	leal	12(%ebp), %eax
	pushl	%eax
	pushl	fd_msr
	call	write
	addl	$16, %esp
	cmpl	$8, %eax
	je	.L9
	call	__errno_location
	cmpl	$5, (%eax)
	je	.L9
	subl	$12, %esp
	pushl	$.LC2
.L13:
	call	perror
	popl	%edx
	pushl	fd_msr
	call	close
	movl	$1, (%esp)
	call	exit
.L9:
	call	__errno_location
	cmpl	$5, (%eax)
	setne	%al
	movzbl	%al, %eax
	decl	%eax
	leave
	ret
	.size	wrmsr, .-wrmsr
	.section	.rodata.str1.1
.LC3:
	.string	"Could not read() MSR"
	.text
.globl rdmsr
	.type	rdmsr, @function
rdmsr:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$24, %esp
	movl	8(%ebp), %ebx
	pushl	$0
	pushl	12(%ebp)
	pushl	fd_msr
	call	lseek
	addl	$16, %esp
	incl	%eax
	jne	.L15
	subl	$12, %esp
	pushl	$.LC1
	jmp	.L20
.L15:
	pushl	%eax
	pushl	$8
	leal	-16(%ebp), %eax
	pushl	%eax
	pushl	fd_msr
	call	read
	addl	$16, %esp
	cmpl	$8, %eax
	jne	.L16
	movl	-16(%ebp), %eax
	movl	%eax, 4(%ebx)
	movl	-12(%ebp), %eax
	movl	%eax, (%ebx)
	jmp	.L14
.L16:
	call	__errno_location
	cmpl	$5, (%eax)
	je	.L18
	subl	$12, %esp
	pushl	$.LC3
.L20:
	call	perror
	popl	%ebx
	pushl	fd_msr
	call	close
	movl	$1, (%esp)
	call	exit
.L18:
	movl	$-1, 4(%ebx)
	movl	$-1, (%ebx)
.L14:
	movl	%ebx, %eax
	movl	-4(%ebp), %ebx
	leave
	ret	$4
	.size	rdmsr, .-rdmsr
	.section	.rodata.str1.1
.LC4:
	.string	"Not unmapping zero size at %p\n"
	.text
.globl physunmap
	.type	physunmap, @function
physunmap:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	8(%ebp), %eax
	movl	12(%ebp), %edx
	testl	%edx, %edx
	jne	.L22
	pushl	%edx
	pushl	%eax
	pushl	$.LC4
	pushl	$3
	call	print
	addl	$16, %esp
	leave
	ret
.L22:
	movl	%edx, 12(%ebp)
	movl	%eax, 8(%ebp)
	leave
	jmp	munmap
	.size	physunmap, .-physunmap
	.section	.rodata.str1.1
.LC5:
	.string	"/dev/mem"
.LC6:
	.string	"Critical error: open(/dev/mem): %s"
	.text
.globl sys_physmap_ro_cached
	.type	sys_physmap_ro_cached, @function
sys_physmap_ro_cached:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	cmpl	$-1, fd_mem_cached
	jne	.L26
	pushl	%eax
	pushl	%eax
	pushl	$2
	pushl	$.LC5
	call	open
	movl	%eax, fd_mem_cached
	addl	$16, %esp
	incl	%eax
	jne	.L26
	call	__errno_location
	subl	$12, %esp
	pushl	(%eax)
	call	strerror
	addl	$12, %esp
	pushl	%eax
	pushl	$.LC6
	pushl	$0
	call	print
	movl	$2, (%esp)
	call	exit
.L26:
	pushl	%ecx
	pushl	%ecx
	pushl	8(%ebp)
	pushl	fd_mem_cached
	pushl	$1
	pushl	$1
	pushl	12(%ebp)
	pushl	$0
	call	mmap
	addl	$32, %esp
	xorl	%edx, %edx
	cmpl	$-1, %eax
	setne	%dl
	negl	%edx
	andl	%edx, %eax
	leave
	ret
	.size	sys_physmap_ro_cached, .-sys_physmap_ro_cached
	.section	.rodata.str1.1
.LC7:
	.string	"Critical error: open(/dev/mem)"
	.text
.globl sys_physmap_rw_uncached
	.type	sys_physmap_rw_uncached, @function
sys_physmap_rw_uncached:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	cmpl	$-1, fd_mem
	jne	.L30
	pushl	%ecx
	pushl	%ecx
	pushl	$4098
	pushl	$.LC5
	call	open
	movl	%eax, fd_mem
	addl	$16, %esp
	incl	%eax
	jne	.L30
	subl	$12, %esp
	pushl	$.LC7
	call	perror
	movl	$2, (%esp)
	call	exit
.L30:
	pushl	%edx
	pushl	%edx
	pushl	8(%ebp)
	pushl	fd_mem
	pushl	$1
	pushl	$3
	pushl	12(%ebp)
	pushl	$0
	call	mmap
	addl	$32, %esp
	xorl	%edx, %edx
	cmpl	$-1, %eax
	setne	%dl
	negl	%edx
	andl	%edx, %eax
	leave
	ret
	.size	sys_physmap_rw_uncached, .-sys_physmap_rw_uncached
	.section	.rodata.str1.1
.LC8:
	.string	"Not mapping %s, zero size at 0x%08lx.\n"
.LC9:
	.string	"Mapping %s at 0x%08lx, unaligned size 0x%lx.\n"
.LC10:
	.string	"Mapping %s, 0x%lx bytes at unaligned 0x%08lx.\n"
.LC11:
	.string	"memory"
.LC12:
	.string	"Error accessing %s, 0x%lx bytes at 0x%08lx\n"
.LC13:
	.string	"/dev/mem mmap failed"
.LC14:
	.string	"In Linux this error can be caused by the CONFIG_NONPROMISC_DEVMEM (<2.6.27),\n"
.LC15:
	.string	"CONFIG_STRICT_DEVMEM (>=2.6.27) and CONFIG_X86_PAT kernel options.\n"
.LC16:
	.string	"Please check if either is enabled in your kernel before reporting a failure.\n"
.LC17:
	.string	"You can override CONFIG_X86_PAT at boot with the nopat kernel parameter but\n"
.LC18:
	.string	"disabling the other option unfortunately requires a kernel recompile. Sorry!\n"
	.text
.globl physmap_common
	.type	physmap_common, @function
physmap_common:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$28, %esp
	movl	8(%ebp), %edi
	movl	12(%ebp), %esi
	movl	16(%ebp), %ebx
	testl	%ebx, %ebx
	jne	.L34
	pushl	%esi
	pushl	%edi
	pushl	$.LC8
	pushl	$3
	call	print
	xorl	%edx, %edx
	addl	$16, %esp
	jmp	.L35
.L34:
	call	getpagesize
	decl	%eax
	movl	%eax, -28(%ebp)
	testl	%ebx, %eax
	je	.L36
	subl	$12, %esp
	pushl	%ebx
	pushl	%esi
	pushl	%edi
	pushl	$.LC9
	pushl	$0
	call	print
	addl	$32, %esp
.L36:
	testl	%esi, -28(%ebp)
	je	.L37
	subl	$12, %esp
	pushl	%esi
	pushl	%ebx
	pushl	%edi
	pushl	$.LC10
	pushl	$0
	call	print
	addl	$32, %esp
.L37:
	cmpl	$0, 24(%ebp)
	je	.L38
	pushl	%edx
	pushl	%edx
	pushl	%ebx
	pushl	%esi
	call	sys_physmap_ro_cached
	jmp	.L43
.L38:
	pushl	%eax
	pushl	%eax
	pushl	%ebx
	pushl	%esi
	call	sys_physmap_rw_uncached
.L43:
	movl	%eax, %edx
	addl	$16, %esp
	testl	%eax, %eax
	jne	.L35
	testl	%edi, %edi
	jne	.L40
	movl	$.LC11, %edi
.L40:
	subl	$12, %esp
	pushl	%esi
	pushl	%ebx
	pushl	%edi
	pushl	$.LC12
	pushl	$0
	movl	%edx, -32(%ebp)
	call	print
	addl	$20, %esp
	pushl	$.LC13
	call	perror
	call	__errno_location
	addl	$16, %esp
	cmpl	$22, (%eax)
	movl	-32(%ebp), %edx
	jne	.L41
	pushl	%edi
	pushl	%edi
	pushl	$.LC14
	pushl	$0
	call	print
	popl	%ebx
	popl	%esi
	pushl	$.LC15
	pushl	$0
	call	print
	popl	%edx
	popl	%ecx
	pushl	$.LC16
	pushl	$0
	call	print
	popl	%edi
	popl	%eax
	pushl	$.LC17
	pushl	$0
	call	print
	popl	%ebx
	popl	%esi
	pushl	$.LC18
	pushl	$0
	call	print
	addl	$16, %esp
	movl	-32(%ebp), %edx
.L41:
	cmpl	$0, 20(%ebp)
	jne	.L35
	subl	$12, %esp
	pushl	$3
	call	exit
.L35:
	movl	%edx, %eax
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
	.size	physmap_common, .-physmap_common
.globl physmap_try_ro
	.type	physmap_try_ro, @function
physmap_try_ro:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	pushl	$1
	pushl	$1
	pushl	16(%ebp)
	pushl	12(%ebp)
	pushl	8(%ebp)
	call	physmap_common
	leave
	ret
	.size	physmap_try_ro, .-physmap_try_ro
.globl physmap
	.type	physmap, @function
physmap:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$20, %esp
	pushl	$0
	pushl	$0
	pushl	16(%ebp)
	pushl	12(%ebp)
	pushl	8(%ebp)
	call	physmap_common
	leave
	ret
	.size	physmap, .-physmap
	.section	.rodata.str1.1
.LC19:
	.string	"/dev/cpu/%d/msr"
.LC20:
	.string	"MSR was already initialized\n"
.LC21:
	.string	"Error while opening /dev/cpu/0/msr"
.LC22:
	.string	"Did you run 'modprobe msr'?\n"
	.text
.globl setup_cpu_msr
	.type	setup_cpu_msr, @function
setup_cpu_msr:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%ebx
	subl	$76, %esp
	cld
	leal	-72(%ebp), %ebx
	movl	$16, %ecx
	xorl	%eax, %eax
	movl	%ebx, %edi
	rep stosl
	pushl	8(%ebp)
	pushl	$.LC19
	pushl	$64
	pushl	$1
	pushl	%ebx
	call	__sprintf_chk
	addl	$32, %esp
	cmpl	$-1, fd_msr
	je	.L49
	pushl	%eax
	pushl	%eax
	pushl	$.LC20
	jmp	.L53
.L49:
	pushl	%edi
	pushl	%edi
	pushl	$2
	pushl	%ebx
	call	open
	movl	%eax, %edx
	movl	%eax, fd_msr
	addl	$16, %esp
	xorl	%eax, %eax
	testl	%edx, %edx
	jns	.L50
	subl	$12, %esp
	pushl	$.LC21
	call	perror
	popl	%ecx
	popl	%ebx
	pushl	$.LC22
.L53:
	pushl	$1
	call	print
	orl	$-1, %eax
	addl	$16, %esp
.L50:
	leal	-8(%ebp), %esp
	popl	%ebx
	popl	%edi
	popl	%ebp
	ret
	.size	setup_cpu_msr, .-setup_cpu_msr
	.data
	.align 4
	.type	fd_msr, @object
	.size	fd_msr, 4
fd_msr:
	.long	-1
	.align 4
	.type	fd_mem_cached, @object
	.size	fd_mem_cached, 4
fd_mem_cached:
	.long	-1
	.align 4
	.type	fd_mem, @object
	.size	fd_mem, 4
fd_mem:
	.long	-1
	.ident	"GCC: (Gentoo 4.4.3 p1.0) 4.4.3"
	.section	.note.GNU-stack,"", at progbits


More information about the flashrom mailing list