[v6,11/14] reboot: Secure Launch SEXIT support on reboot paths

Message ID 20230504145023.835096-12-ross.philipson@oracle.com
State New
Headers
Series x86: Trenchboot secure dynamic launch Linux kernel support |

Commit Message

Ross Philipson May 4, 2023, 2:50 p.m. UTC
  If the MLE kernel is being powered off, rebooted or halted,
then SEXIT must be called. Note that the SEXIT GETSEC leaf
can only be called after a machine_shutdown() has been done on
these paths. The machine_shutdown() is not called on a few paths
like when poweroff action does not have a poweroff callback (into
ACPI code) or when an emergency reset is done. In these cases,
just the TXT registers are finalized but SEXIT is skipped.

Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
---
 arch/x86/kernel/reboot.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
  

Comments

Matthew Garrett May 12, 2023, 11:40 a.m. UTC | #1
On Thu, May 04, 2023 at 02:50:20PM +0000, Ross Philipson wrote:
> If the MLE kernel is being powered off, rebooted or halted,
> then SEXIT must be called. Note that the SEXIT GETSEC leaf
> can only be called after a machine_shutdown() has been done on
> these paths. The machine_shutdown() is not called on a few paths
> like when poweroff action does not have a poweroff callback (into
> ACPI code) or when an emergency reset is done. In these cases,
> just the TXT registers are finalized but SEXIT is skipped.

What are the consequences of SEXIT not being called, and why is it ok to 
skip it in these circumstances?
  
Ross Philipson May 15, 2023, 6:16 p.m. UTC | #2
On 5/12/23 07:40, Matthew Garrett wrote:
> On Thu, May 04, 2023 at 02:50:20PM +0000, Ross Philipson wrote:
>> If the MLE kernel is being powered off, rebooted or halted,
>> then SEXIT must be called. Note that the SEXIT GETSEC leaf
>> can only be called after a machine_shutdown() has been done on
>> these paths. The machine_shutdown() is not called on a few paths
>> like when poweroff action does not have a poweroff callback (into
>> ACPI code) or when an emergency reset is done. In these cases,
>> just the TXT registers are finalized but SEXIT is skipped.
> 
> What are the consequences of SEXIT not being called, and why is it ok to
> skip it in these circumstances?

Well the system is resetting so there are no real consequences. The 
problem on those two paths is that the APs have not been halted with a 
machine_shutdown() and that is a precondition to issuing GETSEC[SEXIT]. 
Only the BSP should be active and SEXIT must be done on it.

Thanks
Ross
  
Daniel P. Smith May 16, 2023, 1:23 a.m. UTC | #3
On 5/15/23 14:16, Ross Philipson wrote:
> On 5/12/23 07:40, Matthew Garrett wrote:
>> On Thu, May 04, 2023 at 02:50:20PM +0000, Ross Philipson wrote:
>>> If the MLE kernel is being powered off, rebooted or halted,
>>> then SEXIT must be called. Note that the SEXIT GETSEC leaf
>>> can only be called after a machine_shutdown() has been done on
>>> these paths. The machine_shutdown() is not called on a few paths
>>> like when poweroff action does not have a poweroff callback (into
>>> ACPI code) or when an emergency reset is done. In these cases,
>>> just the TXT registers are finalized but SEXIT is skipped.
>>
>> What are the consequences of SEXIT not being called, and why is it ok to
>> skip it in these circumstances?
> 
> Well the system is resetting so there are no real consequences. The 
> problem on those two paths is that the APs have not been halted with a 
> machine_shutdown() and that is a precondition to issuing GETSEC[SEXIT]. 
> Only the BSP should be active and SEXIT must be done on it.

To expand on this just a bit further. On all paths we were able to 
identify, the SECRETS bit is cleared, memconfig is unlocked, and the 
private registers are all closed. This makes the system as safe as 
possible to go through a power event and be able to come back up on the 
other side. The clean way is to always go through an SEXIT before a 
power event, but as Ross highlighted this can only be done after the APs 
have been halted.

v/r,
dps
  

Patch

diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 3adbe97..732c81b 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -12,6 +12,7 @@ 
 #include <linux/delay.h>
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
+#include <linux/slaunch.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -720,6 +721,7 @@  static void native_machine_restart(char *__unused)
 
 	if (!reboot_force)
 		machine_shutdown();
+	slaunch_finalize(!reboot_force);
 	__machine_emergency_restart(0);
 }
 
@@ -730,6 +732,9 @@  static void native_machine_halt(void)
 
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 
+	/* SEXIT done after machine_shutdown() to meet TXT requirements */
+	slaunch_finalize(1);
+
 	stop_this_cpu(NULL);
 }
 
@@ -738,8 +743,12 @@  static void native_machine_power_off(void)
 	if (kernel_can_power_off()) {
 		if (!reboot_force)
 			machine_shutdown();
+		slaunch_finalize(!reboot_force);
 		do_kernel_power_off();
+	} else {
+		slaunch_finalize(0);
 	}
+
 	/* A fallback in case there is no PM info available */
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 }
@@ -767,6 +776,7 @@  void machine_shutdown(void)
 
 void machine_emergency_restart(void)
 {
+	slaunch_finalize(0);
 	__machine_emergency_restart(1);
 }