Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aem staging 14 10 24 rebase #19

Open
wants to merge 46 commits into
base: aem-staging-18-11-24
Choose a base branch
from

Conversation

krystian-hebel
Copy link
Member

@krystian-hebel krystian-hebel commented Oct 14, 2024

Changes beyond rebase (from aem-4.17.4, few changes aren't merged there yet) itself:

  • changed the early code to use fastcall instead of stdcall
  • updated comment on entry point, it was partially describing state on entry to ACM, not MLE (for some reason ACM entry is better described in Intel documentation than MLE)
  • based on above, modified few first instructions accordingly (%esi calculated based on %ebx instead of call/pop, GDT loaded with CS selector as DS is undefined)
  • changed #include "" to now supported #include <> in the early code, cleaned it up a bit
  • made sure that every commit builds (for git bisect), but haven't test booting yet
  • somehow I messed up tpm.c during rebase - its early entry point lost an argument, but as it's called from assembly, no error was produced never mind, my IDE didn't refresh the view automatically
  • FIXME: %ebp is overwritten before it is passed to slaunch_early_tests()

@krystian-hebel krystian-hebel force-pushed the aem-staging-14-10-24-rebase branch 2 times, most recently from 25a3a94 to e5764e1 Compare October 16, 2024 19:12
@krystian-hebel
Copy link
Member Author

Modified the entry point to fix %ebp being overwritten, and made it more compatible with TXT. SKL will need to be changed accordingly.

There is uint32_t slaunch_slrt; in early TPM code, which will have to go in order to work with https://lore.kernel.org/xen-devel/[email protected]/T/#m794a192186ed86a5a8adb51aaa45128a45885e5c. However, the same change will make it possible to link against external symbols, so the code will be able to access the final slaunch_slrt in slaunch.c, and local variable won't be needed at all. In fact, it could be set by slaunch_early_tests() and it won't have to be returned, which will further simplify arguments handling in head.S. Alternatively, slaunch_early_tests() may call tpm_extend_mbi() directly.

@krystian-hebel
Copy link
Member Author

Rebased to newer staging, renamed the target branch, but can't rename this one as it would close the PR.

Also included fix from d2aa2f5 (for others commits from #17 I'd like to check on hardware whether they actually fix any issue before including them) and reordered the commits to group them into categories. The code still builds on each commit. Some commit messages became outdated, but additional ones will be outdated after 32b code linking, so I left them for now.

@krystian-hebel
Copy link
Member Author

Updated SLRT definition to the latest one. No rebase done today as the patch I'm waiting for hasn't been merged.

There is an ongoing unification of all possible Xen entry points (MB2, EFI, PVH) being done, which doesn't impact us too much, but slight modifications will be needed. https://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=0fe607b2a1440191b59cc6da83a3e717bf3ff7c0 would cause problems on old (pre-SLRT) implementation, but now everything is measured before move_xen().

@krystian-hebel krystian-hebel force-pushed the aem-staging-14-10-24-rebase branch 6 times, most recently from 8a4535d to a9f4275 Compare November 5, 2024 12:21
@krystian-hebel krystian-hebel force-pushed the aem-staging-14-10-24-rebase branch 7 times, most recently from 13962c4 to 61d5a16 Compare November 8, 2024 17:00
xen/arch/x86/boot/slaunch_early.c Outdated Show resolved Hide resolved
xen/arch/x86/boot/head.S Show resolved Hide resolved
xen/arch/x86/boot/head.S Outdated Show resolved Hide resolved
@krystian-hebel krystian-hebel marked this pull request as ready for review November 18, 2024 16:29
A precarious approach was used to release the pages used to hold a boot module.
The precariousness stemmed from the fact that in the case of PV dom0, the
initrd module pages may be either mapped or copied into the dom0 address space.
In the former case, the PV dom0 construction code will set the size of the
module to zero, relying on discard_initial_images() to skip any modules with a
size of zero. In the latter case, the pages are freed by the PV dom0
construction code. This freeing of pages is done so that in either case, the
initrd variable can be reused for tracking the initrd location in dom0 memory
through the remaining dom0 construction code.

To encapsulate the logical action of releasing a boot module, the function
release_boot_module() is introduced along with the `released` flag added to
boot module. The boot module flag `released` allows the tracking of when a boot
module has been released by release_boot_module().

As part of adopting release_boot_module() the function discard_initial_images()
is renamed to free_boot_modules(), a name that better reflects the functions
actions.

Signed-off-by: Daniel P. Smith <[email protected]>
Reviewed-by: Andrew Cooper <[email protected]>
Copy link
Member

@SergiiDmytruk SergiiDmytruk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works on APU with a small change on top to use amd_info instead of dl_info for newer SKL and GRUB.

void * -> uint8_t * I think goes somewhat against Qubes OS review. Changes to not use things like u32 and __u32 in sha1/sha256 make files differ more from the original Linux sources. Otherwise this version seem to be in alignment with the previous ones, although I didn't go line by line.

Mind that there is also a FIXME commit regarding stack_base.

@krystian-hebel
Copy link
Member Author

krystian-hebel commented Nov 19, 2024

I've removed the FIXME commit, added smaller change in its place instead (a994bec). I've also moved change to x86/shutdown after commits directly related to SMP.

While not strictly needed to guarantee operator precedence is as expected, add
the parentheses to comply with Misra Rule 20.7.

No functional change intended.

Reported-by: Andrew Cooper <[email protected]>
Fixes: 5b52e1b ('x86/mm: skip super-page alignment checks for non-present entries')
Signed-off-by: Roger Pau Monné <[email protected]>
Acked-by: Jan Beulich <[email protected]>
Acked-by: Andrew Cooper <[email protected]>
No functional change.

Signed-off-by: Roger Pau Monné <[email protected]>
Acked-by: Andrew Cooper <[email protected]>
krystian-hebel and others added 28 commits November 20, 2024 13:09
…s and heap

The file contains TXT register spaces base address, registers offsets,
error codes and inline functions for accessing structures stored on
TXT heap.

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
The file provides constants, structures and several helper functions for
parsing SLRT.

slr_add_entry() and slr_init_table() were omitted to not have issues
with memcpy() usage (it comes from different places for different
translation units).

Signed-off-by: Sergii Dmytruk <[email protected]>
MLE header is used with Intel TXT, together with MB2 headers.
Entrypoint is different, but it is used just to differentiate
from other entries by moving a magic number to EAX. Execution
environment is similar to that of Multiboot 2 and code falls
through to MB2's entry point.

Signed-off-by: Kacper Stojek <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
These tests validate that important parts of memory are protected
against DMA attacks, including Xen and MBI. Modules can be tested later,
when it is possible to report issues to user before invoking TXT reset.

TPM event log validation is temporarily disabled due to issue with its
allocation by bootloader (GRUB) which will need to be modified to
address this. Ultimately event log will also have to be validated early
as it is used immediately after these tests to hold MBI measurements.
See larger comment in verify_pmr_ranges().

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
TXT heap is marked as reserved in e820 to protect against being allocated
and overwritten.

Signed-off-by: Kacper Stojek <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
In preparation for TXT SENTER call, GRUB had to modify MTRR settings
to be UC for everything except SINIT ACM. Old values are restored
from SLRT where they were saved by the bootloader.

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
The code comes from [1] and is licensed under GPL-2.0 license.
It's a combination of:
 - include/crypto/sha1.h
 - include/crypto/sha1_base.h
 - lib/crypto/sha1.c
 - crypto/sha1_generic.c

Changes:
 - includes
 - formatting
 - renames and splicing of trivial some functions that are called once
 - dropping of `int` return values (only zero was ever returned)
 - getting rid of references to `struct shash_desc`

[1]: https://github.com/torvalds/linux/tree/afdab700f65e14070d8ab92175544b1c62b8bf03

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
The code comes from [1] and is licensed under GPL-2.0 or later version of
license.  It's a combination of:
 - include/crypto/sha2.h
 - include/crypto/sha256_base.h
 - lib/crypto/sha256.c
 - crypto/sha256_generic.c

Changes:
 - includes
 - formatting
 - renames and splicing of trivial some functions that are called once
 - dropping of `int` return values (only zero was ever returned)
 - getting rid of references to `struct shash_desc`

[1]: https://github.com/torvalds/linux/tree/afdab700f65e14070d8ab92175544b1c62b8bf03

Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
This file is built twice: for early 32b mode without paging to measure
MBI and for 64b code to measure dom0 kernel and initramfs. Since MBI
is small, the first case uses TPM to do the hashing. Kernel and
initramfs on the other hand are too big, sending them to the TPM would
take multiple minutes.

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
SHA1 and SHA256 is hardcoded here, but their support by TPM is checked
for. Addition of event log for TPM2.0 will generalize the code further.

Signed-off-by: Sergii Dmytruk <[email protected]>
This is made as the first step of making parallel AP bring-up possible.
It should be enough for pre-C code.

Parallel AP bring-up is necessary because TXT by design releases all APs
at once. In addition to that it reduces number of IPIs (and more
importantly, delays between them) required to start all logical
processors. This results in significant reduction of boot time, even
when DRTM is not used, with performance gain growing with the number of
logical CPUs.

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
On Intel TXT, APs are started in one of two ways, depending on ACM
which reports it in its information table. In both cases, all APs are
started simultaneously after BSP requests them to do so. Two possible
ways are:
- GETSEC[WAKEUP] instruction,
- MONITOR address.

GETSEC[WAKEUP] requires versions >= 7 of SINIT to MLE Data, but there is
no clear mapping of that version with regard to processor family and
it's not known which CPUs actually use it. It could have been designed
for TXT support on CPUs that lack MONITOR/MWAIT, because GETSEC[WAKEUP]
seems to be more complicated, in software and hardware alike.

This patch implements only MONITOR approach, GETSEC[WAKEUP] support will
be added later once more details and means of testing are available and
if there is a practical need for it.

With this patch, every AP goes through assembly part, and only when in
start_secondary() in C they re-enter MONITOR/MWAIT iff they are not the
AP that was asked to boot. The same address is reused for simplicity,
and on next wakeup call APs don't have to go through assembly part
again (GDT, paging, stack setting).

Signed-off-by: Krystian Hebel <[email protected]>
Signed-off-by: Sergii Dmytruk <[email protected]>
…_id(cpu)

This is done in preparation to move data from x86_cpu_to_apicid[]
elsewhere.

Signed-off-by: Krystian Hebel <[email protected]>
Both fields held the same data.

Signed-off-by: Krystian Hebel <[email protected]>
Remove setting of this variable in do_boot_cpu(). It was not consumed
after that point, and the only consumer is BSP which isn't booted
through do_boot_cpu() in the first place.

Signed-off-by: Krystian Hebel <[email protected]>
It used to be called from smp_callin(), however BUG_ON() was invoked on
multiple occasions before that. It may end up calling machine_restart()
which tries to get APIC ID for CPU running this code. If BSP detected
that x2APIC is enabled, get_apic_id() will try to use it for all CPUs.
Enabling x2APIC on secondary CPUs earlier protects against an endless
loop of #GP exceptions caused by attempts to read IA32_X2APIC_APICID
MSR while x2APIC is disabled in IA32_APIC_BASE.

Signed-off-by: Krystian Hebel <[email protected]>
CPU id is obtained as a side effect of searching for appropriate
stack for AP. It can be used as a parameter to start_secondary().
Coincidentally this also makes further work on making AP bring-up
code parallel easier.

Signed-off-by: Krystian Hebel <[email protected]>
This will be used for parallel AP bring-up.

CPU_STATE_INIT changed direction. It was previously set by BSP and never
consumed by AP. Now it signals that AP got through assembly part of
initialization and waits for BSP to call notifiers that set up data
structures required for further initialization.

Signed-off-by: Krystian Hebel <[email protected]>
This is no longer necessary, since AP loops on cpu_state and CPU
index is passed as argument.

In addition, move TXT JOIN structure to static data. There is no
guarantee that it would be consumed before it is overwritten on BSP
stack.

Signed-off-by: Krystian Hebel <[email protected]>
This is another requirement for parallel AP bringup.

Signed-off-by: Krystian Hebel <[email protected]>
Multiple delays are required when sending IPIs and waiting for
responses. During boot, 4 such IPIs were sent per each AP. With this
change, only one set of broadcast IPIs is sent. This reduces boot time,
especially for platforms with large number of cores.

Single CPU initialization is still possible, it is used for hotplug.

During wakeup from S3 APs are started one by one. It should be possible
to enable parallel execution there as well, but I don't have a way of
testing it as of now.

Signed-off-by: Krystian Hebel <[email protected]>
If multiple CPUs called machine_restart() before actual restart took
place, but after boot CPU declared itself not online, ASSERT in
on_selected_cpus() will fail. Few calls later execution would end up
in machine_restart() again, with another frame on call stack for new
exception.

To protect against running out of stack, code checks if boot CPU is
still online before calling on_selected_cpus().

Signed-off-by: Krystian Hebel <[email protected]>
Go through entires in the DRTM policy of SLRT to hash and extend data
that they describe into corresponding PCRs.

Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
It holds physical address of SLRT. The value is produced by
slaunch_early (known as txt_early previously), gets set in assembly and
then used by the main C code which don't need to know how we got
it (which is different for different CPUs).

This change additionally renames txt_early.c into slaunch_early.c

Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
secure-kernel-loader on AMD with SKINIT passes MBI as a parameter for
Multiboot kernel.

Another thing of interest is the location of SLRT which is bootloader's
data after SKL.

Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
This mostly involves not running Intel-specific code when on AMD.

There are only a few new AMD-specific implementation details:
 - finding SLB start and size and then mapping and protecting it
 - managing offset for adding the next TPM log entry (TXT-compatible
   data prepared by SKL is stored inside of vendor data field of TCG
   header)

Signed-off-by: Sergii Dmytruk <[email protected]>
Signed-off-by: Krystian Hebel <[email protected]>
@krystian-hebel
Copy link
Member Author

https://lore.kernel.org/xen-devel/[email protected]/T/#m6c15a4ab1773d2563621532c3e324240d12a4134 got merged, I rebased this PR and updated the target branch to include it. This was the last of bootinfo patches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants