]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Michael Matz <matz@suse.de> |
2 | Subject: x86/boot: fix clobbered register in vesa_store_edid | |
3 | References: bnc#400487 | |
4 | ||
5 | The only relevant difference that I can detect in the asm (comparing | |
6 | the output of gcc42-4.2.1_20070724-17.1 and gcc43-4.3.3_20081022-1.2) is | |
7 | in vesa_store_edid(), where the constant 0x4f15 is stored in a register | |
8 | which is reused in the second use after an int 0x10 call that could possibly | |
9 | clobber that register. | |
10 | ||
11 | The asm certainly misses a clobber. So, can you try adding one to this | |
12 | asm in vesa_store_edid: | |
13 | ||
14 | /* Note: The VBE DDC spec is different from the main VESA spec; | |
15 | we genuinely have to assume all registers are destroyed here. */ | |
16 | asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" | |
17 | : "+a" (ax), "+b" (bx) | |
18 | : "c" (cx), "D" (di) | |
19 | : "esi"); | |
20 | ||
21 | In particular add "edx" to the clobber list (that's the register used | |
22 | in my case), but the above also misses "ecx", "edi", which have to be added | |
23 | as in/out constraints (i.e. "+c") probably, not as clobbers. | |
24 | ||
25 | Note especially how the comment explicitely warns about assuming that | |
26 | all regs are destroyed, but how the asm makes no try to cater for that. | |
27 | ||
28 | Tested-by: Andreas Schwab <schwab@suse.de> | |
29 | Acked-by: Jeff Mahoney <jeffm@suse.com> | |
30 | --- | |
31 | ||
32 | arch/x86/boot/video-vesa.c | 12 +++++++----- | |
33 | 1 file changed, 7 insertions(+), 5 deletions(-) | |
34 | ||
35 | --- a/arch/x86/boot/video-vesa.c | |
36 | +++ b/arch/x86/boot/video-vesa.c | |
37 | @@ -270,9 +270,10 @@ void vesa_store_edid(void) | |
38 | we genuinely have to assume all registers are destroyed here. */ | |
39 | ||
40 | asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" | |
41 | - : "+a" (ax), "+b" (bx) | |
42 | - : "c" (cx), "D" (di) | |
43 | - : "esi"); | |
44 | + : "+a" (ax), "+b" (bx), | |
45 | + "+c" (cx), "+D" (di) | |
46 | + : | |
47 | + : "esi", "edx"); | |
48 | ||
49 | if (ax != 0x004f) | |
50 | return; /* No EDID */ | |
51 | @@ -286,8 +287,9 @@ void vesa_store_edid(void) | |
52 | dx = 0; /* EDID block number */ | |
53 | di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ | |
54 | asm(INT10 | |
55 | - : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) | |
56 | - : "c" (cx), "D" (di) | |
57 | + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info), | |
58 | + "+c" (cx), "+D" (di) | |
59 | + : | |
60 | : "esi"); | |
61 | #endif /* CONFIG_FIRMWARE_EDID */ | |
62 | } |