Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-09-20 Thread ross . philipson

On 5/12/23 11:04 AM, Thomas Gleixner wrote:


On Thu, May 04 2023 at 14:50, Ross Philipson wrote:

+
+/* CPUID: leaf 1, ECX, SMX feature bit */
+#define X86_FEATURE_BIT_SMX(1 << 6)
+
+/* Can't include apiddef.h in asm */


Why not? All it needs is a #ifndef __ASSEMBLY__ guard around the C parts.


+#define XAPIC_ENABLE   (1 << 11)
+#define X2APIC_ENABLE  (1 << 10)
+
+/* Can't include traps.h in asm */


NMI_VECTOR is defined in irq_vectors.h which just has a include
 for no real good reason.


+#define X86_TRAP_NMI   2





+/*
+ * See the comment in head_64.S for detailed informatoin on what this macro
+ * is used for.
+ */
+#define rva(X) ((X) - sl_stub_entry)


I'm having a hard time to find that comment in head_64.S. At least it's
not in this patch.


+.Lsl_ap_cs:
+   /* Load the relocated AP IDT */

[ 11 more citation lines. Click/Enter to show. ]

+   lidt(sl_ap_idt_desc - sl_txt_ap_wake_begin)(%ecx)
+
+   /* Fixup MTRRs and misc enable MSR on APs too */
+   callsl_txt_load_regs
+
+   /* Enable SMI with GETSEC[SMCTRL] */
+   GETSEC $(SMX_X86_GETSEC_SMCTRL)
+
+   /* IRET-to-self can be used to enable NMIs which SENTER disabled */
+   lealrva(.Lnmi_enabled_ap)(%ebx), %eax
+   pushfl
+   pushl   $(__SL32_CS)
+   pushl   %eax
+   iret


So from here on any NMI which hits the AP before it can reach the wait
loop will corrupt EDX...


+/* This is the beginning of the relocated AP wake code block */
+   .global sl_txt_ap_wake_begin

[ 10 more citation lines. Click/Enter to show. ]

+sl_txt_ap_wake_begin:
+
+   /*
+* Wait for NMI IPI in the relocated AP wake block which was provided
+* and protected in the memory map by the prelaunch code. Leave all
+* other interrupts masked since we do not expect anything but an NMI.
+*/
+   xorl%edx, %edx
+
+1:
+   hlt
+   testl   %edx, %edx
+   jz  1b


This really makes me nervous. A stray NMI and the AP starts going.

Can't this NMI just bring the AP out of HLT w/o changing any state and
the AP evaluates a memory location which indicates whether it should
start up or not.


I have switched the existing code to use MONITOR/MWAIT and got rid of 
the use of the NMIs here. I am currently using a monitor variable on the 
stack of each AP but I think I may refactor that. The next step is to 
rebase this work on top of your hotplug patchset. Is the code in your 
devel repo on the hotplug branch still the latest bits?


I had a question - more a request for your thoughts on this. I am 
currently assuming a cache line size and alignment of 64b for the 
monitor variable location. Do you think this is sufficient for x86 
platforms or do I need to dynamically find a way to read the CPUID 
information for MONITOR and get my size/alignment values from there?


Thanks
Ross Philipson




+   /*
+* This is the long absolute jump to the 32b Secure Launch protected
+* mode stub code in the rmpiggy. The jump address will be fixed in


Providing an actual name for the stub might spare to rummage through
code to figure out where this is supposed to jump to.


+* the SMP boot code when the first AP is brought up. This whole area
+* is provided and protected in the memory map by the prelaunch code.

[ 2 more citation lines. Click/Enter to show. ]

+*/
+   .byte   0xea
+sl_ap_jmp_offset:
+   .long   0x
+   .word   __SL32_CS


Thanks,

tglx



___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-06-15 Thread Ross Philipson

On 5/15/23 21:45, Matthew Garrett wrote:

On Mon, May 15, 2023 at 09:11:15PM -0400, Daniel P. Smith wrote:

On 5/12/23 12:17, Ross Philipson wrote:

This is a good point. At this point it is really something we
overlooked. We will have to revisit this and figure out the best way to
find the final event log depending on how things booted.


I believe Ross misunderstood what you were asking for here. There are two
reasons this is not possible or desired. The first reason is that on Intel,
the DRTM log is not initialized by TrenchBoot code in the preamble. It is
only responsible for allocating a buffer and recording the location in the
TXT structures. When the SINIT ACM is executed, it will initialize the log
and record the measurement that CPU sent directly to the TPM and then the
measurements the ACM makes of the environment. If you pointed at the SRTM
log, then the ACM would write over existing log, which I don't think you
want. Now if you pointed at the tail end of the SRTM log, you would still
end up with a second, separate log that just happens to be memory adjacent.


Ok. I think it would be clearer if either the function names or some
comments expressly indicated that this refers to the DRTM event log and
that that's a separate entity from the SRTM one, "event log" on its own
is likely to cause people to think of the existing log rather than
associate it with something else.



That can be done, thanks.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-15 Thread Matthew Garrett
On Mon, May 15, 2023 at 09:11:15PM -0400, Daniel P. Smith wrote:
> On 5/12/23 12:17, Ross Philipson wrote:
> > This is a good point. At this point it is really something we
> > overlooked. We will have to revisit this and figure out the best way to
> > find the final event log depending on how things booted.
> 
> I believe Ross misunderstood what you were asking for here. There are two
> reasons this is not possible or desired. The first reason is that on Intel,
> the DRTM log is not initialized by TrenchBoot code in the preamble. It is
> only responsible for allocating a buffer and recording the location in the
> TXT structures. When the SINIT ACM is executed, it will initialize the log
> and record the measurement that CPU sent directly to the TPM and then the
> measurements the ACM makes of the environment. If you pointed at the SRTM
> log, then the ACM would write over existing log, which I don't think you
> want. Now if you pointed at the tail end of the SRTM log, you would still
> end up with a second, separate log that just happens to be memory adjacent.

Ok. I think it would be clearer if either the function names or some 
comments expressly indicated that this refers to the DRTM event log and 
that that's a separate entity from the SRTM one, "event log" on its own 
is likely to cause people to think of the existing log rather than 
associate it with something else.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-15 Thread Daniel P. Smith

On 5/12/23 12:17, Ross Philipson wrote:

On 5/12/23 07:26, Matthew Garrett wrote:

On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:


+static void sl_find_event_log(struct slr_table *slrt)


If this is called after the EFI stub then we're presumably
post-ExitBootServices and we're copied the TPM event log into a
configuration table so it's available to the runtime kernel. That also
means that we should be adding all further measurements to the Final
Events Table rather than the initial event log. How's that handled here,
both in terms of ensuring further events (generated by firmware or by
us) get added to the right place, and in terms of ensuring the event
logs the kernel has later on were covered appropriately? Or is the SL
event log an entirely different thing that can be merged in later
because it only covers the DRTM PCRs?


This is a good point. At this point it is really something we 
overlooked. We will have to revisit this and figure out the best way to 
find the final event log depending on how things booted.


I believe Ross misunderstood what you were asking for here. There are 
two reasons this is not possible or desired. The first reason is that on 
Intel, the DRTM log is not initialized by TrenchBoot code in the 
preamble. It is only responsible for allocating a buffer and recording 
the location in the TXT structures. When the SINIT ACM is executed, it 
will initialize the log and record the measurement that CPU sent 
directly to the TPM and then the measurements the ACM makes of the 
environment. If you pointed at the SRTM log, then the ACM would write 
over existing log, which I don't think you want. Now if you pointed at 
the tail end of the SRTM log, you would still end up with a second, 
separate log that just happens to be memory adjacent. The second reason 
is more from a trusted computing perspective, these are two different 
trust chains starting from two different Roots of Trust reflecting two 
different temporal states of the system, i.e. freshness. Typically this 
is were most will point out the need to have a measure of the resident 
firmware, i.e. SMM. To address that, should Intel to publish the spec 
for interacting with PPAM[1], TrenchBoot will be able to finally close 
the SMM gap, giving runtime validation of SMM.


[1] 
https://www.intel.com/content/dam/www/central-libraries/us/en/documents/drtm-based-computing-whitepaper.pdf


v/r,
dps

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-15 Thread Ross Philipson

On 5/12/23 14:04, Thomas Gleixner wrote:


On Thu, May 04 2023 at 14:50, Ross Philipson wrote:

+
+/* CPUID: leaf 1, ECX, SMX feature bit */
+#define X86_FEATURE_BIT_SMX(1 << 6)
+
+/* Can't include apiddef.h in asm */


Why not? All it needs is a #ifndef __ASSEMBLY__ guard around the C parts.


I guess I was reluctant to fiddle with another header file but I can do 
this.





+#define XAPIC_ENABLE   (1 << 11)
+#define X2APIC_ENABLE  (1 << 10)
+
+/* Can't include traps.h in asm */


NMI_VECTOR is defined in irq_vectors.h which just has a include
 for no real good reason.


Ack




+#define X86_TRAP_NMI   2





+/*
+ * See the comment in head_64.S for detailed informatoin on what this macro
+ * is used for.
+ */
+#define rva(X) ((X) - sl_stub_entry)


I'm having a hard time to find that comment in head_64.S. At least it's
not in this patch.


The is a macro very much like this one and large comment in head_64.S. I 
am just referencing that. If you would rather see that comment 
duplicated here, I can.





+.Lsl_ap_cs:
+   /* Load the relocated AP IDT */

[ 11 more citation lines. Click/Enter to show. ]

+   lidt(sl_ap_idt_desc - sl_txt_ap_wake_begin)(%ecx)
+
+   /* Fixup MTRRs and misc enable MSR on APs too */
+   callsl_txt_load_regs
+
+   /* Enable SMI with GETSEC[SMCTRL] */
+   GETSEC $(SMX_X86_GETSEC_SMCTRL)
+
+   /* IRET-to-self can be used to enable NMIs which SENTER disabled */
+   lealrva(.Lnmi_enabled_ap)(%ebx), %eax
+   pushfl
+   pushl   $(__SL32_CS)
+   pushl   %eax
+   iret


So from here on any NMI which hits the AP before it can reach the wait
loop will corrupt EDX...


+/* This is the beginning of the relocated AP wake code block */
+   .global sl_txt_ap_wake_begin

[ 10 more citation lines. Click/Enter to show. ]

+sl_txt_ap_wake_begin:
+
+   /*
+* Wait for NMI IPI in the relocated AP wake block which was provided
+* and protected in the memory map by the prelaunch code. Leave all
+* other interrupts masked since we do not expect anything but an NMI.
+*/
+   xorl%edx, %edx
+
+1:
+   hlt
+   testl   %edx, %edx
+   jz  1b


This really makes me nervous. A stray NMI and the AP starts going.

Can't this NMI just bring the AP out of HLT w/o changing any state and
the AP evaluates a memory location which indicates whether it should
start up or not.


Given you comments on patch 09, perhaps all this NMI business becomes 
obsolete.





+   /*
+* This is the long absolute jump to the 32b Secure Launch protected
+* mode stub code in the rmpiggy. The jump address will be fixed in


Providing an actual name for the stub might spare to rummage through
code to figure out where this is supposed to jump to.


That can be done.




+* the SMP boot code when the first AP is brought up. This whole area
+* is provided and protected in the memory map by the prelaunch code.

[ 2 more citation lines. Click/Enter to show. ]

+*/
+   .byte   0xea
+sl_ap_jmp_offset:
+   .long   0x
+   .word   __SL32_CS


Thanks,

tglx


Thanks
Ross

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-12 Thread Thomas Gleixner


On Thu, May 04 2023 at 14:50, Ross Philipson wrote:
> +
> +/* CPUID: leaf 1, ECX, SMX feature bit */
> +#define X86_FEATURE_BIT_SMX  (1 << 6)
> +
> +/* Can't include apiddef.h in asm */

Why not? All it needs is a #ifndef __ASSEMBLY__ guard around the C parts.

> +#define XAPIC_ENABLE (1 << 11)
> +#define X2APIC_ENABLE(1 << 10)
> +
> +/* Can't include traps.h in asm */

NMI_VECTOR is defined in irq_vectors.h which just has a include
 for no real good reason.

> +#define X86_TRAP_NMI 2



> +/*
> + * See the comment in head_64.S for detailed informatoin on what this macro
> + * is used for.
> + */
> +#define rva(X) ((X) - sl_stub_entry)

I'm having a hard time to find that comment in head_64.S. At least it's
not in this patch.

> +.Lsl_ap_cs:
> + /* Load the relocated AP IDT */
[ 11 more citation lines. Click/Enter to show. ]
> + lidt(sl_ap_idt_desc - sl_txt_ap_wake_begin)(%ecx)
> +
> + /* Fixup MTRRs and misc enable MSR on APs too */
> + callsl_txt_load_regs
> +
> + /* Enable SMI with GETSEC[SMCTRL] */
> + GETSEC $(SMX_X86_GETSEC_SMCTRL)
> +
> + /* IRET-to-self can be used to enable NMIs which SENTER disabled */
> + lealrva(.Lnmi_enabled_ap)(%ebx), %eax
> + pushfl
> + pushl   $(__SL32_CS)
> + pushl   %eax
> + iret

So from here on any NMI which hits the AP before it can reach the wait
loop will corrupt EDX...

> +/* This is the beginning of the relocated AP wake code block */
> + .global sl_txt_ap_wake_begin
[ 10 more citation lines. Click/Enter to show. ]
> +sl_txt_ap_wake_begin:
> +
> + /*
> +  * Wait for NMI IPI in the relocated AP wake block which was provided
> +  * and protected in the memory map by the prelaunch code. Leave all
> +  * other interrupts masked since we do not expect anything but an NMI.
> +  */
> + xorl%edx, %edx
> +
> +1:
> + hlt
> + testl   %edx, %edx
> + jz  1b

This really makes me nervous. A stray NMI and the AP starts going.

Can't this NMI just bring the AP out of HLT w/o changing any state and
the AP evaluates a memory location which indicates whether it should
start up or not.

> + /*
> +  * This is the long absolute jump to the 32b Secure Launch protected
> +  * mode stub code in the rmpiggy. The jump address will be fixed in

Providing an actual name for the stub might spare to rummage through
code to figure out where this is supposed to jump to.

> +  * the SMP boot code when the first AP is brought up. This whole area
> +  * is provided and protected in the memory map by the prelaunch code.
[ 2 more citation lines. Click/Enter to show. ]
> +  */
> + .byte   0xea
> +sl_ap_jmp_offset:
> + .long   0x
> + .word   __SL32_CS

Thanks,

tglx

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-12 Thread Matthew Garrett
On Fri, May 12, 2023 at 12:17:50PM -0400, Ross Philipson wrote:

> I am not 100% sure what you are asking but we also measure the EFI memory
> map. This comment is just to note that if the e820 exceeded the space in the
> fixed map in boot parameters, we would pick up any extra entries when
> measuring the setup_data list.

Ack, picked this up in a later patch but didn't come back to follow up. 
Thanks!

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-12 Thread Ross Philipson

On 5/12/23 07:26, Matthew Garrett wrote:

On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:


+static void sl_find_event_log(struct slr_table *slrt)


If this is called after the EFI stub then we're presumably
post-ExitBootServices and we're copied the TPM event log into a
configuration table so it's available to the runtime kernel. That also
means that we should be adding all further measurements to the Final
Events Table rather than the initial event log. How's that handled here,
both in terms of ensuring further events (generated by firmware or by
us) get added to the right place, and in terms of ensuring the event
logs the kernel has later on were covered appropriately? Or is the SL
event log an entirely different thing that can be merged in later
because it only covers the DRTM PCRs?


This is a good point. At this point it is really something we 
overlooked. We will have to revisit this and figure out the best way to 
find the final event log depending on how things booted.





+static void sl_extend_setup_data(struct slr_policy_entry *entry)
+{
+   struct setup_data *data;
+
+   /*
+* Measuring the boot params measured the fixed e820 memory map.
+* Measure any setup_data entries including e820 extended entries.
+*/
+   data = (struct setup_data *)(unsigned long)entry->entity;
+   while (data)
+   data = sl_handle_setup_data(data, entry);
+}


Is e820 sufficient here? There are cases where we use the EFI memory map
directly (sorry), but I don't know if any of them are relevant to DRTM
outcomes.


I am not 100% sure what you are asking but we also measure the EFI 
memory map. This comment is just to note that if the e820 exceeded the 
space in the fixed map in boot parameters, we would pick up any extra 
entries when measuring the setup_data list.


Thanks
Ross

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-12 Thread Matthew Garrett
On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:

> +static void sl_find_event_log(struct slr_table *slrt)

If this is called after the EFI stub then we're presumably 
post-ExitBootServices and we're copied the TPM event log into a 
configuration table so it's available to the runtime kernel. That also 
means that we should be adding all further measurements to the Final 
Events Table rather than the initial event log. How's that handled here, 
both in terms of ensuring further events (generated by firmware or by 
us) get added to the right place, and in terms of ensuring the event 
logs the kernel has later on were covered appropriately? Or is the SL 
event log an entirely different thing that can be merged in later 
because it only covers the DRTM PCRs?

> +static void sl_extend_setup_data(struct slr_policy_entry *entry)
> +{
> + struct setup_data *data;
> +
> + /*
> +  * Measuring the boot params measured the fixed e820 memory map.
> +  * Measure any setup_data entries including e820 extended entries.
> +  */
> + data = (struct setup_data *)(unsigned long)entry->entity;
> + while (data)
> + data = sl_handle_setup_data(data, entry);
> +}

Is e820 sufficient here? There are cases where we use the EFI memory map 
directly (sorry), but I don't know if any of them are relevant to DRTM 
outcomes.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


[PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-10 Thread Ross Philipson
The Secure Launch (SL) stub provides the entry point for Intel TXT (and
later AMD SKINIT) to vector to during the late launch. The symbol
sl_stub_entry is that entry point and its offset into the kernel is
conveyed to the launching code using the MLE (Measured Launch
Environment) header in the structure named mle_header. The offset of the
MLE header is set in the kernel_info. The routine sl_stub contains the
very early late launch setup code responsible for setting up the basic
environment to allow the normal kernel startup_32 code to proceed. It is
also responsible for properly waking and handling the APs on Intel
platforms. The routine sl_main which runs after entering 64b mode is
responsible for measuring configuration and module information before
it is used like the boot params, the kernel command line, the TXT heap,
an external initramfs, etc.

Signed-off-by: Ross Philipson 
---
 Documentation/arch/x86/boot.rst|  21 +
 arch/x86/boot/compressed/Makefile  |   3 +-
 arch/x86/boot/compressed/head_64.S |  37 ++
 arch/x86/boot/compressed/kernel_info.S |  34 ++
 arch/x86/boot/compressed/sl_main.c | 599 
 arch/x86/boot/compressed/sl_stub.S | 690 +
 arch/x86/include/uapi/asm/bootparam.h  |   1 +
 arch/x86/kernel/asm-offsets.c  |  20 +
 8 files changed, 1404 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/boot/compressed/sl_main.c
 create mode 100644 arch/x86/boot/compressed/sl_stub.S

diff --git a/Documentation/arch/x86/boot.rst b/Documentation/arch/x86/boot.rst
index 33520ec..90552f7 100644
--- a/Documentation/arch/x86/boot.rst
+++ b/Documentation/arch/x86/boot.rst
@@ -482,6 +482,14 @@ Protocol:  2.00+
- If 1, KASLR enabled.
- If 0, KASLR disabled.
 
+  Bit 2 (kernel internal): SLAUNCH_FLAG
+
+   - Used internally by the compressed kernel to communicate
+ Secure Launch status to kernel proper.
+
+   - If 1, Secure Launch enabled.
+   - If 0, Secure Launch disabled.
+
   Bit 5 (write): QUIET_FLAG
 
- If 0, print early messages.
@@ -1027,6 +1035,19 @@ Offset/size: 0x000c/4
 
   This field contains maximal allowed type for setup_data and setup_indirect 
structs.
 
+   =
+Field name:mle_header_offset
+Offset/size:   0x0010/4
+   =
+
+  This field contains the offset to the Secure Launch Measured Launch 
Environment
+  (MLE) header. This offset is used to locate information needed during a 
secure
+  late launch using Intel TXT. If the offset is zero, the kernel does not have
+  Secure Launch capabilities. The MLE entry point is called from TXT on the BSP
+  following a success measured launch. The specific state of the processors is
+  outlined in the TXT Software Development Guide, the latest can be found here:
+  
https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf
+
 
 The Image Checksum
 ==
diff --git a/arch/x86/boot/compressed/Makefile 
b/arch/x86/boot/compressed/Makefile
index 1d327d4..7f31473 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -112,7 +112,8 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
 vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
 vmlinux-objs-$(CONFIG_EFI_STUB) += 
$(objtree)/drivers/firmware/efi/libstub/lib.a
 
-vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/early_sha1.o 
$(obj)/early_sha256.o
+vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/early_sha1.o 
$(obj)/early_sha256.o \
+   $(obj)/sl_main.o $(obj)/sl_stub.o
 
 $(obj)/vmlinux: $(vmlinux-objs-y) FORCE
$(call if_changed,ld)
diff --git a/arch/x86/boot/compressed/head_64.S 
b/arch/x86/boot/compressed/head_64.S
index 03c4328..d079d8d 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -492,6 +492,17 @@ trampoline_return:
pushq   $0
popfq
 
+#ifdef CONFIG_SECURE_LAUNCH
+   pushq   %rsi
+
+   /* Ensure the relocation region coverd by a PMR */
+   movq%rbx, %rdi
+   movl$(_bss - startup_32), %esi
+   callq   sl_check_region
+
+   popq%rsi
+#endif
+
 /*
  * Copy the compressed kernel to the end of our buffer
  * where decompression in place becomes safe.
@@ -551,6 +562,32 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
shrq$3, %rcx
rep stosq
 
+#ifdef CONFIG_SECURE_LAUNCH
+   /*
+* Have to do the final early sl stub work in 64b area.
+*
+* *** NOTE ***
+*
+* Several boot params get used before we get a chance to measure
+* them in this call. This is a known issue and we currently don't
+* have a solution. The scratch field doesn't matter. There is no
+* obvious way to do anything about the use of kernel_alignment or
+* init_size though these seem low risk with all the PMR and overlap

Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-05 Thread Simon Horman
On Fri, May 05, 2023 at 02:58:28PM -0400, Ross Philipson wrote:
> On 5/5/23 13:47, Simon Horman wrote:
> > On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:

...

> > > +asmlinkage __visible void sl_check_region(void *base, u32 size)
> > > +{
> > > + sl_check_pmr_coverage(base, size, false);
> > > +}
> > 
> > I'm a nit unsure, what to do here, but clang-16 with W=1 says the following.
> > 
> > arch/x86/boot/compressed/sl_main.c:533:27: warning: no previous prototype 
> > for function 'sl_main' [-Wmissing-prototypes]
> > asmlinkage __visible void sl_main(void *bootparams)
> >^
> > arch/x86/boot/compressed/sl_main.c:533:22: note: declare 'static' if the 
> > function is not intended to be used outside of this translation unit
> > asmlinkage __visible void sl_main(void *bootparams)
> >   ^
> >   static
> 
> Yea we will have to look into why this is. This function is only ever called
> from asm code so that might have something to do with this.

Thanks.

...

> > > diff --git a/arch/x86/include/uapi/asm/bootparam.h 
> > > b/arch/x86/include/uapi/asm/bootparam.h
> > > index 01d19fc..74e3e7df 100644
> > > --- a/arch/x86/include/uapi/asm/bootparam.h
> > > +++ b/arch/x86/include/uapi/asm/bootparam.h
> > > @@ -26,6 +26,7 @@
> > >   /* loadflags */
> > >   #define LOADED_HIGH (1<<0)
> > >   #define KASLR_FLAG  (1<<1)
> > > +#define SLAUNCH_FLAG (1<<2)
> > >   #define QUIET_FLAG  (1<<5)
> > >   #define KEEP_SEGMENTS   (1<<6)
> > >   #define CAN_USE_HEAP(1<<7)
> > 
> > nit: please consider using BIT()
> 
> I am a little reluctant to change something like this in an existing header.
> It seems a bit out of scope for the patch set.

Yes, sorry for the noise on this one.
I agree that what you have is the best approach here.

___
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec


Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-05 Thread Ross Philipson

On 5/5/23 13:47, Simon Horman wrote:

On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:

The Secure Launch (SL) stub provides the entry point for Intel TXT (and
later AMD SKINIT) to vector to during the late launch. The symbol
sl_stub_entry is that entry point and its offset into the kernel is
conveyed to the launching code using the MLE (Measured Launch
Environment) header in the structure named mle_header. The offset of the
MLE header is set in the kernel_info. The routine sl_stub contains the
very early late launch setup code responsible for setting up the basic
environment to allow the normal kernel startup_32 code to proceed. It is
also responsible for properly waking and handling the APs on Intel
platforms. The routine sl_main which runs after entering 64b mode is
responsible for measuring configuration and module information before
it is used like the boot params, the kernel command line, the TXT heap,
an external initramfs, etc.

Signed-off-by: Ross Philipson 


...


diff --git a/arch/x86/boot/compressed/sl_main.c 
b/arch/x86/boot/compressed/sl_main.c


...


+static void *evtlog_base;
+static u32 evtlog_size;
+static struct txt_heap_event_log_pointer2_1_element *log20_elem;
+static u32 tpm_log_ver = SL_TPM12_LOG;
+struct tcg_efi_specid_event_algs tpm_algs[SL_TPM20_MAX_ALGS] = {0};


tpm_algs seems to only be used in this file.
Should it be static?


+
+extern u32 sl_cpu_type;
+extern u32 sl_mle_start;
+extern struct boot_params *boot_params;
+
+static u64 sl_txt_read(u32 reg)


Perhaps reg should have an __iomem annotation.


+{
+   return readq((void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
+}
+
+static void sl_txt_write(u32 reg, u64 val)


Likewise here.

...


+static void sl_check_pmr_coverage(void *base, u32 size, bool allow_hi)
+{
+   struct txt_os_sinit_data *os_sinit_data;
+   void *end = base + size;
+   void *txt_heap;
+
+   if (!(sl_cpu_type & SL_CPU_INTEL))
+   return;
+
+   txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+   os_sinit_data = txt_os_sinit_data_start(txt_heap);
+
+   if ((end >= (void *)0x1ULL) &&
+   (base < (void *)0x1ULL))
+   sl_txt_reset(SL_ERROR_REGION_STRADDLE_4GB);
+
+   /*
+* Note that the late stub code validates that the hi PMR covers
+* all memory above 4G. At this point the code can only check that
+* regions are within the hi PMR but that is sufficient.
+*/
+   if ((end > (void *)0x1ULL) &&
+   (base >= (void *)0x1ULL)) {
+   if (allow_hi) {
+   if (end >= (void *)(os_sinit_data->vtd_pmr_hi_base +
+  os_sinit_data->vtd_pmr_hi_size))
+   sl_txt_reset(SL_ERROR_BUFFER_BEYOND_PMR);
+   } else
+   sl_txt_reset(SL_ERROR_REGION_ABOVE_4GB);


nit: if any arm of a condition has '{}' then all arms should have them.
  So:

} else {
sl_txt_reset(SL_ERROR_REGION_ABOVE_4GB);
}

Also elsewhere in this patch.


+   }
+
+   if (end >= (void *)os_sinit_data->vtd_pmr_lo_size)
+   sl_txt_reset(SL_ERROR_BUFFER_BEYOND_PMR);
+}
+
+/*
+ * Some MSRs are modified by the pre-launch code including the MTRRs.
+ * The early MLE code has to restore these values. This code validates
+ * the values after they are measured.
+ */
+static void sl_txt_validate_msrs(struct txt_os_mle_data *os_mle_data)
+{
+   struct slr_txt_mtrr_state *saved_bsp_mtrrs;
+   u64 mtrr_caps, mtrr_def_type, mtrr_var;
+   struct slr_entry_intel_info *txt_info;
+   u64 misc_en_msr;
+   u32 vcnt, i;
+
+   txt_info = (struct slr_entry_intel_info *)os_mle_data->txt_info;
+   saved_bsp_mtrrs = &(txt_info->saved_bsp_mtrrs);


nit: unnecessary parentheses

...


+static void sl_validate_event_log_buffer(void)
+{
+   struct txt_os_sinit_data *os_sinit_data;
+   void *txt_heap, *txt_end;
+   void *mle_base, *mle_end;
+   void *evtlog_end;
+
+   if ((u64)evtlog_size > (LLONG_MAX - (u64)evtlog_base))
+   sl_txt_reset(SL_ERROR_INTEGER_OVERFLOW);
+   evtlog_end = evtlog_base + evtlog_size;
+
+   txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+   txt_end = txt_heap + sl_txt_read(TXT_CR_HEAP_SIZE);
+   os_sinit_data = txt_os_sinit_data_start(txt_heap);
+
+   mle_base = (void *)(u64)sl_mle_start;
+   mle_end = mle_base + os_sinit_data->mle_size;
+
+   /*
+* This check is to ensure the event log buffer does not overlap with
+* the MLE image.
+*/
+   if ((evtlog_base >= mle_end) &&
+   (evtlog_end > mle_end))
+   goto pmr_check; /* above */


Ditto.
Also, the if condition could be one line.
Also in several other places in this patch.


+
+   if ((evtlog_end <= mle_base) &&
+   (evtlog_base < mle_base))
+  

Re: [PATCH v6 07/14] x86: Secure Launch kernel early boot stub

2023-05-05 Thread Simon Horman
On Thu, May 04, 2023 at 02:50:16PM +, Ross Philipson wrote:
> The Secure Launch (SL) stub provides the entry point for Intel TXT (and
> later AMD SKINIT) to vector to during the late launch. The symbol
> sl_stub_entry is that entry point and its offset into the kernel is
> conveyed to the launching code using the MLE (Measured Launch
> Environment) header in the structure named mle_header. The offset of the
> MLE header is set in the kernel_info. The routine sl_stub contains the
> very early late launch setup code responsible for setting up the basic
> environment to allow the normal kernel startup_32 code to proceed. It is
> also responsible for properly waking and handling the APs on Intel
> platforms. The routine sl_main which runs after entering 64b mode is
> responsible for measuring configuration and module information before
> it is used like the boot params, the kernel command line, the TXT heap,
> an external initramfs, etc.
> 
> Signed-off-by: Ross Philipson 

...

> diff --git a/arch/x86/boot/compressed/sl_main.c 
> b/arch/x86/boot/compressed/sl_main.c

...

> +static void *evtlog_base;
> +static u32 evtlog_size;
> +static struct txt_heap_event_log_pointer2_1_element *log20_elem;
> +static u32 tpm_log_ver = SL_TPM12_LOG;
> +struct tcg_efi_specid_event_algs tpm_algs[SL_TPM20_MAX_ALGS] = {0};

tpm_algs seems to only be used in this file.
Should it be static?

> +
> +extern u32 sl_cpu_type;
> +extern u32 sl_mle_start;
> +extern struct boot_params *boot_params;
> +
> +static u64 sl_txt_read(u32 reg)

Perhaps reg should have an __iomem annotation.

> +{
> + return readq((void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
> +}
> +
> +static void sl_txt_write(u32 reg, u64 val)

Likewise here.

...

> +static void sl_check_pmr_coverage(void *base, u32 size, bool allow_hi)
> +{
> + struct txt_os_sinit_data *os_sinit_data;
> + void *end = base + size;
> + void *txt_heap;
> +
> + if (!(sl_cpu_type & SL_CPU_INTEL))
> + return;
> +
> + txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
> + os_sinit_data = txt_os_sinit_data_start(txt_heap);
> +
> + if ((end >= (void *)0x1ULL) &&
> + (base < (void *)0x1ULL))
> + sl_txt_reset(SL_ERROR_REGION_STRADDLE_4GB);
> +
> + /*
> +  * Note that the late stub code validates that the hi PMR covers
> +  * all memory above 4G. At this point the code can only check that
> +  * regions are within the hi PMR but that is sufficient.
> +  */
> + if ((end > (void *)0x1ULL) &&
> + (base >= (void *)0x1ULL)) {
> + if (allow_hi) {
> + if (end >= (void *)(os_sinit_data->vtd_pmr_hi_base +
> +os_sinit_data->vtd_pmr_hi_size))
> + sl_txt_reset(SL_ERROR_BUFFER_BEYOND_PMR);
> + } else
> + sl_txt_reset(SL_ERROR_REGION_ABOVE_4GB);

nit: if any arm of a condition has '{}' then all arms should have them.
 So:

} else {
sl_txt_reset(SL_ERROR_REGION_ABOVE_4GB);
}

Also elsewhere in this patch.

> + }
> +
> + if (end >= (void *)os_sinit_data->vtd_pmr_lo_size)
> + sl_txt_reset(SL_ERROR_BUFFER_BEYOND_PMR);
> +}
> +
> +/*
> + * Some MSRs are modified by the pre-launch code including the MTRRs.
> + * The early MLE code has to restore these values. This code validates
> + * the values after they are measured.
> + */
> +static void sl_txt_validate_msrs(struct txt_os_mle_data *os_mle_data)
> +{
> + struct slr_txt_mtrr_state *saved_bsp_mtrrs;
> + u64 mtrr_caps, mtrr_def_type, mtrr_var;
> + struct slr_entry_intel_info *txt_info;
> + u64 misc_en_msr;
> + u32 vcnt, i;
> +
> + txt_info = (struct slr_entry_intel_info *)os_mle_data->txt_info;
> + saved_bsp_mtrrs = &(txt_info->saved_bsp_mtrrs);

nit: unnecessary parentheses

...

> +static void sl_validate_event_log_buffer(void)
> +{
> + struct txt_os_sinit_data *os_sinit_data;
> + void *txt_heap, *txt_end;
> + void *mle_base, *mle_end;
> + void *evtlog_end;
> +
> + if ((u64)evtlog_size > (LLONG_MAX - (u64)evtlog_base))
> + sl_txt_reset(SL_ERROR_INTEGER_OVERFLOW);
> + evtlog_end = evtlog_base + evtlog_size;
> +
> + txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
> + txt_end = txt_heap + sl_txt_read(TXT_CR_HEAP_SIZE);
> + os_sinit_data = txt_os_sinit_data_start(txt_heap);
> +
> + mle_base = (void *)(u64)sl_mle_start;
> + mle_end = mle_base + os_sinit_data->mle_size;
> +
> + /*
> +  * This check is to ensure the event log buffer does not overlap with
> +  * the MLE image.
> +  */
> + if ((evtlog_base >= mle_end) &&
> + (evtlog_end > mle_end))
> + goto pmr_check; /* above */

Ditto.
Also, the if condition could be one line.
Also in several other places in this patch.

> +
> + if ((evtlog_end <= mle_base)