Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR to previous value.
Tested on Qemu Q35. Needs tests on real hardware.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md M src/cpu/x86/smm/smmhandler.S 2 files changed, 95 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/1
diff --git a/Documentation/arch/x86/index.md b/Documentation/arch/x86/index.md index 462e7e6..b02b879 100644 --- a/Documentation/arch/x86/index.md +++ b/Documentation/arch/x86/index.md @@ -45,6 +45,7 @@ * Add x86_64 exception handlers - *TODO* * Setup page tables for long mode - *DONE* * Add assembly code for long mode - *DONE* +* Add assembly code for SMM - *DONE* * Add assembly code for postcar stage - *TODO* * Add assembly code to return to protected mode - *TODO* * Implement reference code for mainboard `emulation/qemu-q35` - *TODO* diff --git a/src/cpu/x86/smm/smmhandler.S b/src/cpu/x86/smm/smmhandler.S index a2be7f2..fd8af79 100644 --- a/src/cpu/x86/smm/smmhandler.S +++ b/src/cpu/x86/smm/smmhandler.S @@ -20,6 +20,7 @@ */
#include <cpu/x86/lapic_def.h> +#include <cpu/x86/msr.h>
/* * +--------------------------------+ 0xaffff @@ -171,15 +172,104 @@ /* Get SMM revision */ movl $0xa8000 + 0x7efc, %ebx /* core 0 address */ subl %ebp, %ebx /* subtract core X offset */ + +#if defined(__x86_64__) + /* Backup IA32_EFER. Preserves ebx. */ + movl $(IA32_EFER), %ecx + rdmsr + movl %eax, ia32efer_backup + + /* Enable long mode if required. Preserves ebx. */ +#include <cpu/x86/64bit/entry64.inc> + + mov (%ebx), %rdi + +#else movl (%ebx), %eax pushl %eax +#endif
- /* Call 32bit C handler */ + /* Call C handler */ call smi_handler
+#if defined(__x86_64__) + /* + * The only reason to go back to protected mode is that rsm doesn't restore + * MSR registers and IA32_EFER was modified. + * To restore IA32_EFER go back to protected mode. + */ + + /* Ensure cache is clean. */ + invd + + /* Set 32-bit code segment and ss */ + mov $0x08, %rcx + call SetCodeSelector32 + +.code32 + /* Running in 32-bit compatibility mode */ + + /* Use flat data segment */ + movl $0x10, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + + /* Disable paging */ + movl %cr0, %eax + andl $0x7FFFFFFF, %eax + movl %eax, %cr0 + + /* Disable long mode */ + movl $(IA32_EFER), %ecx + rdmsr + andl $(~EFER_LME), %eax + wrmsr + + /* Disable PAE */ + movl %cr4, %eax + andl $(~0x20), %eax + movl %eax, %cr4 + + /* Restore IA32_EFER */ + movl $(IA32_EFER), %ecx + rdmsr + movl ia32efer_backup, %eax + wrmsr +#endif + /* To return, just do rsm. It will "clean up" protected mode */ rsm
+#if defined(__x86_64__) +ia32efer_backup: +.long + +.align 8 +.code64 +SetCodeSelector32: + # pop the return address from stack + pop %rbx + + # save rsp because we need to push it after ss + mov %rsp, %rdx + + # use iret to jump to a 32-bit offset in a new code segment + # iret will pop cs:rip, flags, then ss:rsp + mov %ss, %ax # need to push ss.. + push %rax # push ss instuction not valid in x64 mode, + # so use ax + push %rdx # the rsp to load + pushfq # push rflags + push %rcx # cx is code segment selector from caller + push %rbx # push the IP for the next instruction + + # the iretq will behave like ret, with the new cs/ss value loaded + iretq +#endif + .code16
.align 4, 0xff @@ -202,6 +292,9 @@ .word 0xffff, 0x0000 .byte 0x00, 0x93, 0xcf, 0x00
+ /* gdt selector 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 smm_gdt_end:
Hello Kyösti Mälkki, Aaron Durbin, Stefan Reinauer, Paul Menzel, build bot (Jenkins), Raul Rangel, Patrick Georgi, ron minnich, Rudolf Marek, Lee Leahy, David Hendricks, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#3).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR to previous value.
Tested on Qemu Q35. Needs tests on real hardware.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md M src/cpu/x86/smm/smmhandler.S 2 files changed, 94 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/3
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 5:
(3 comments)
Do you want SMM to rely on a RO component (pagetable)? Wouldn't copying it in ASEG/TSEG be a better idea?
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 198: MSR registers Why can't that MSR be accessed in 64bit mode?
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 219: /* Disable paging */ : movl %cr0, %eax : andl $0x7FFFFFFF, %eax : movl %eax, %cr0 Isn't this covered by the savestate?
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 229: : /* Disable PAE */ : movl %cr4, %eax : andl $(~0x20), %eax : movl %eax, %cr4 Isn't this covered by the savestate?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 5:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 198: MSR registers
Why can't that MSR be accessed in 64bit mode?
it can be accessed, but I don't know what happens if you clear the "LME" Long mode enable-bit when running in long mode. Thus the switch back to protected mode. https://www.amd.com/system/files/TechDocs/24593.pdf doesn't explain this condition.
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 5:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 219: /* Disable paging */ : movl %cr0, %eax : andl $0x7FFFFFFF, %eax : movl %eax, %cr0
Isn't this covered by the savestate?
yes, just standard long mode disable sequence.
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 229: : /* Disable PAE */ : movl %cr4, %eax : andl $(~0x20), %eax : movl %eax, %cr4
Isn't this covered by the savestate?
yes, just standard long mode disable sequence.
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 5:
Patch Set 5:
(3 comments)
Do you want SMM to rely on a RO component (pagetable)? Wouldn't copying it in ASEG/TSEG be a better idea?
yes, as there's not enough space in ASEG, which is used by qemu. Once implemented additional (runtime) pagetables could be installed in RAM.
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 5: Code-Review+1
Patch Set 5:
Patch Set 5:
(3 comments)
Do you want SMM to rely on a RO component (pagetable)? Wouldn't copying it in ASEG/TSEG be a better idea?
yes, as there's not enough space in ASEG, which is used by qemu. Once implemented additional (runtime) pagetables could be installed in RAM.
Ok sounds reasonable. Might be interesting to port over Q35 to CONFIG_SMM_TSEG to have a POC of that too.
Hello Kyösti Mälkki, Aaron Durbin, Arthur Heymans, Stefan Reinauer, Paul Menzel, build bot (Jenkins), Raul Rangel, Patrick Georgi, ron minnich, Rudolf Marek, Lee Leahy, David Hendricks, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#6).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35. Needs tests on real hardware.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md M src/cpu/x86/smm/smmhandler.S 2 files changed, 95 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/6
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 6:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/6//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/6//COMMIT_MSG@10 PS6, Line 10: x86_32 isn't affected from this change. Test this with BUILD_TIMELESS=1?
https://review.coreboot.org/c/coreboot/+/35681/6/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/6/src/cpu/x86/smm/smmhandler.... PS6, Line 247: ia32efer_backup don't you want to place this in the .bss section?
Hello Kyösti Mälkki, Aaron Durbin, Arthur Heymans, Stefan Reinauer, Paul Menzel, build bot (Jenkins), Raul Rangel, Patrick Georgi, ron minnich, Rudolf Marek, Lee Leahy, David Hendricks, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#7).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35. Needs tests on real hardware.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 144 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/7
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 7:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/7/src/cpu/x86/64bit/exit32.in... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/7/src/cpu/x86/64bit/exit32.in... PS7, Line 42: jmp __longmode_compability 'compability' may be misspelled - perhaps 'compatibility'?
https://review.coreboot.org/c/coreboot/+/35681/7/src/cpu/x86/64bit/exit32.in... PS7, Line 68: __longmode_compability: 'compability' may be misspelled - perhaps 'compatibility'?
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 9:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/9/src/cpu/x86/64bit/exit32.in... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/9/src/cpu/x86/64bit/exit32.in... PS9, Line 42: jmp __longmode_compability 'compability' may be misspelled - perhaps 'compatibility'?
https://review.coreboot.org/c/coreboot/+/35681/9/src/cpu/x86/64bit/exit32.in... PS9, Line 68: __longmode_compability: 'compability' may be misspelled - perhaps 'compatibility'?
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 10:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/10/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/10/src/cpu/x86/64bit/exit32.i... PS10, Line 42: jmp __longmode_compability 'compability' may be misspelled - perhaps 'compatibility'?
https://review.coreboot.org/c/coreboot/+/35681/10/src/cpu/x86/64bit/exit32.i... PS10, Line 68: __longmode_compability: 'compability' may be misspelled - perhaps 'compatibility'?
Patrick Rudolph has uploaded a new patch set (#11) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35. Tested on Lenovo T410 with additional x86_64 patches.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 143 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/11
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 11:
(3 comments)
https://review.coreboot.org/c/coreboot/+/35681/11//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/11//COMMIT_MSG@21 PS11, Line 21: Tested on Lenovo T410 with additional x86_64 patches. This code does not use smm entry, so I don't think it makes much sense to mention here.
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... PS11, Line 42: jmp __longmode_compatibility any reason to not place that code here?
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/smm/smmhandler... PS11, Line 215: #if defined(__x86_64__) : ia32efer_backup: : .long : #endif You probably want to put this a different section like .bss?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 11:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... PS11, Line 42: jmp __longmode_compatibility
any reason to not place that code here?
as this file is included by other assembly files there has to be a jmp somewhere to skip SetCodeSelector32, it doesn't matter where it is.
Patrick Rudolph has uploaded a new patch set (#12) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 144 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/12
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 12:
(6 comments)
https://review.coreboot.org/c/coreboot/+/35681/11//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/11//COMMIT_MSG@21 PS11, Line 21: Tested on Lenovo T410 with additional x86_64 patches.
This code does not use smm entry, so I don't think it makes much sense to mention here.
Done
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 198: MSR registers
it can be accessed, but I don't know what happens if you clear the "LME" Long mode enable-bit when r […]
Done
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 219: /* Disable paging */ : movl %cr0, %eax : andl $0x7FFFFFFF, %eax : movl %eax, %cr0
yes, just standard long mode disable sequence.
Moved code to src/cpu/x86/64bit/exit32.inc
https://review.coreboot.org/c/coreboot/+/35681/5/src/cpu/x86/smm/smmhandler.... PS5, Line 229: : /* Disable PAE */ : movl %cr4, %eax : andl $(~0x20), %eax : movl %eax, %cr4
yes, just standard long mode disable sequence.
Moved code to src/cpu/x86/64bit/exit32.inc
https://review.coreboot.org/c/coreboot/+/35681/6/src/cpu/x86/smm/smmhandler.... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/6/src/cpu/x86/smm/smmhandler.... PS6, Line 247: ia32efer_backup
tried that but doesn't compile.
done
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/smm/smmhandler... PS11, Line 215: #if defined(__x86_64__) : ia32efer_backup: : .long : #endif
You probably want to put this a different section like . […]
Done
Raul Rangel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 12: Code-Review+2
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... PS12, Line 25: #if defined(__x86_64__) This file should only be included if __x86_64__ is defined, so don't think you need this check.
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... PS12, Line 55: .. ..?
Hello Kyösti Mälkki, Aaron Durbin, Arthur Heymans, Patrick Rudolph, Stefan Reinauer, Paul Menzel, build bot (Jenkins), Raul Rangel, Patrick Georgi, ron minnich, Rudolf Marek, Lee Leahy, David Hendricks, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#13).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 140 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/13
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 13:
(3 comments)
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/11/src/cpu/x86/64bit/exit32.i... PS11, Line 42: jmp __longmode_compatibility
as this file is included by other assembly files there has to be a jmp somewhere to skip SetCodeSele […]
Done
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... File src/cpu/x86/64bit/exit32.inc:
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... PS12, Line 25: #if defined(__x86_64__)
This file should only be included if __x86_64__ is defined, so don't think you need this check.
Done
https://review.coreboot.org/c/coreboot/+/35681/12/src/cpu/x86/64bit/exit32.i... PS12, Line 55: ..
.. […]
Done
Patrick Rudolph has uploaded a new patch set (#15) to the change originally created by Patrick Rudolph. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected from this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
For now the same page tables as for all other stages are used. If there's enough space in SMM, one could install additional page tables in SMRAM to enable additional features.
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 127 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/15
Raul Rangel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 15:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... PS15, Line 201: rdmsr Why do we need to read it before writing it?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 15:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... PS15, Line 201: rdmsr
Why do we need to read it before writing it?
it initializes edx to a sane value. Should I manually set edx instead?
Raul Rangel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 15:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... PS15, Line 201: rdmsr
it initializes edx to a sane value. […]
Ah, I think it would make the code clearer if you also stored it as part of ia32efer_backup.
Hello build bot (Jenkins), Raul Rangel, Patrick Georgi, Patrick Rudolph, Stefan Reinauer, Paul Menzel, Arthur Heymans, Aaron Durbin, Martin Roth, Lee Leahy, David Hendricks, ron minnich, Rudolf Marek,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#16).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected by this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
NOTE: This commit does NOT introduce a new security model. It uses the same page tables as the remaining firmware does. This can be a security risk if someone is able to manipulate the page tables stored in ROM at runtime. USE FOR TESTING ONLY!
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 130 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/16
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 16: Code-Review+1
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/16//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/16//COMMIT_MSG@16 PS16, Line 16: same Move to the next line
Hello build bot (Jenkins), Raul Rangel, Patrick Georgi, Patrick Rudolph, Stefan Reinauer, Paul Menzel, Angel Pons, Arthur Heymans, Aaron Durbin, Martin Roth, Lee Leahy, David Hendricks, ron minnich, Rudolf Marek,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/35681
to look at the new patch set (#17).
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected by this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
NOTE: This commit does NOT introduce a new security model. It uses the same page tables as the remaining firmware does. This can be a security risk if someone is able to manipulate the page tables stored in ROM at runtime. USE FOR TESTING ONLY!
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 130 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/35681/17
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 16:
(2 comments)
https://review.coreboot.org/c/coreboot/+/35681/16//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/16//COMMIT_MSG@16 PS16, Line 16: same
Move to the next line
Done
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... File src/cpu/x86/smm/smmhandler.S:
https://review.coreboot.org/c/coreboot/+/35681/15/src/cpu/x86/smm/smmhandler... PS15, Line 201: rdmsr
Ah, I think it would make the code clearer if you also stored it as part of ia32efer_backup.
Done
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 17:
(1 comment)
https://review.coreboot.org/c/coreboot/+/35681/6//COMMIT_MSG Commit Message:
https://review.coreboot.org/c/coreboot/+/35681/6//COMMIT_MSG@10 PS6, Line 10: x86_32 isn't affected from this change.
Test this with BUILD_TIMELESS=1?
No as the gdt is extended by an entry using in long mode which would change the resulting binary.
Raul Rangel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
Patch Set 17: Code-Review+2
Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/coreboot/+/35681 )
Change subject: cpu/x86/smm: Add support for long mode ......................................................................
cpu/x86/smm: Add support for long mode
Enable long mode in SMM handler. x86_32 isn't affected by this change.
As the rsm instruction used to leave SMM doesn't restore MSR registers, drop back to protected mode after running the smi_handler and restore IA32_EFER MSR (which enables long mode support) to previous value.
NOTE: This commit does NOT introduce a new security model. It uses the same page tables as the remaining firmware does. This can be a security risk if someone is able to manipulate the page tables stored in ROM at runtime. USE FOR TESTING ONLY!
Tested on Qemu Q35.
Change-Id: I8bba4af4688c723fc079ae905dac95f57ea956f8 Signed-off-by: Patrick Rudolph siro@das-labor.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/35681 Reviewed-by: Raul Rangel rrangel@chromium.org Reviewed-by: Angel Pons th3fanbus@gmail.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M Documentation/arch/x86/index.md A src/cpu/x86/64bit/exit32.inc M src/cpu/x86/smm/smmhandler.S 3 files changed, 130 insertions(+), 1 deletion(-)
Approvals: build bot (Jenkins): Verified Raul Rangel: Looks good to me, approved Angel Pons: Looks good to me, but someone else must approve
diff --git a/Documentation/arch/x86/index.md b/Documentation/arch/x86/index.md index 30dcc10..f5546d1 100644 --- a/Documentation/arch/x86/index.md +++ b/Documentation/arch/x86/index.md @@ -45,6 +45,7 @@ * Add x86_64 exception handlers - *DONE* * Setup page tables for long mode - *DONE* * Add assembly code for long mode - *DONE* +* Add assembly code for SMM - *DONE* * Add assembly code for postcar stage - *TODO* * Add assembly code to return to protected mode - *TODO* * Implement reference code for mainboard `emulation/qemu-q35` - *TODO* diff --git a/src/cpu/x86/64bit/exit32.inc b/src/cpu/x86/64bit/exit32.inc new file mode 100644 index 0000000..48837d9 --- /dev/null +++ b/src/cpu/x86/64bit/exit32.inc @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * For droping from long mode to protected mode. + * + * For reference see "AMD64 ArchitectureProgrammer's Manual Volume 2", + * Document 24593-Rev. 3.31-July 2019 Chapter 5.3 + * + * Clobbers: rax, rbx, rcx, rdx + */ +.code64 + +#include <cpu/x86/msr.h> +#include <cpu/x86/cr.h> +#include <arch/rom_segs.h> + +drop_longmode: + /* Ensure cache is clean. */ + wbinvd + + /* Set 32-bit code segment and ss */ + mov $ROM_CODE_SEG, %rcx + /* SetCodeSelector32 will drop us to protected mode on return */ + call SetCodeSelector32 + + /* Skip SetCodeSelector32 */ +.code32 + jmp __longmode_compatibility + +.align 8 +.code64 +SetCodeSelector32: + # pop the return address from stack + pop %rbx + + # save rsp because we need to push it after ss + mov %rsp, %rdx + + # use iret to jump to a 32-bit offset in a new code segment + # iret will pop cs:rip, flags, then ss:rsp + mov %ss, %ax # need to push ss, but push ss instuction + push %rax # not valid in x64 mode, so use ax + push %rdx # the rsp to load + pushfq # push rflags + push %rcx # cx is code segment selector from caller + push %rbx # push the IP for the next instruction + + # the iretq will behave like ret, with the new cs/ss value loaded + iretq + +.align 4 +.code32 +__longmode_compatibility: + /* Running in 32-bit compatibility mode */ + + /* Use flat data segment */ + movl $ROM_DATA_SEG, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + + /* Disable paging. */ + movl %cr0, %eax + andl $(~CR0_PG), %eax + movl %eax, %cr0 + + /* Disable long mode. */ + movl $(IA32_EFER), %ecx + rdmsr + andl $(~EFER_LME), %eax + wrmsr + + /* Disable PAE. */ + movl %cr4, %eax + andl $(~CR4_PAE), %eax + movl %eax, %cr4 + + /* Clear page table register */ + xor %eax, %eax + movl %eax, %cr3 + +__longmode_exit: diff --git a/src/cpu/x86/smm/smmhandler.S b/src/cpu/x86/smm/smmhandler.S index 036bc83..340840f 100644 --- a/src/cpu/x86/smm/smmhandler.S +++ b/src/cpu/x86/smm/smmhandler.S @@ -8,6 +8,7 @@ */
#include <cpu/x86/lapic_def.h> +#include <cpu/x86/msr.h>
/* * +--------------------------------+ 0xaffff @@ -42,6 +43,14 @@
#define SMM_HANDLER_OFFSET 0x0000
+#if defined(__x86_64__) +.bss +ia32efer_backup_eax: +.long +ia32efer_backup_edx: +.long +#endif + /* initially SMM is some sort of real mode. Let gcc know * how to treat the SMM handler stub */ @@ -159,12 +168,44 @@ /* Get SMM revision */ movl $0xa8000 + 0x7efc, %ebx /* core 0 address */ subl %ebp, %ebx /* subtract core X offset */ + +#if defined(__x86_64__) + /* Backup IA32_EFER. Preserves ebx. */ + movl $(IA32_EFER), %ecx + rdmsr + movl %eax, ia32efer_backup_eax + movl %edx, ia32efer_backup_edx + + /* Enable long mode. Preserves ebx. */ +#include <cpu/x86/64bit/entry64.inc> + + mov (%ebx), %rdi + +#else movl (%ebx), %eax pushl %eax +#endif
- /* Call 32bit C handler */ + /* Call C handler */ call smi_handler
+#if defined(__x86_64__) + /* + * The only reason to go back to protected mode is that RSM doesn't restore + * MSR registers and MSR IA32_EFER was modified by entering long mode. + * Drop to protected mode to safely operate on the IA32_EFER MSR. + */ + + /* Disable long mode. */ + #include <cpu/x86/64bit/exit32.inc> + + /* Restore IA32_EFER as RSM doesn't restore MSRs. */ + movl $(IA32_EFER), %ecx + movl ia32efer_backup_eax, %eax + movl ia32efer_backup_edx, %edx + wrmsr +#endif + /* To return, just do rsm. It will "clean up" protected mode */ rsm
@@ -190,6 +231,9 @@ .word 0xffff, 0x0000 .byte 0x00, 0x93, 0xcf, 0x00
+ /* gdt selector 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 smm_gdt_end: