From adityag at linux.ibm.com  Thu Aug  1 00:22:27 2024
From: adityag at linux.ibm.com (Aditya Gupta)
Date: Thu,  1 Aug 2024 12:52:27 +0530
Subject: [PATCH] fix comment: Mention current logic for vmalloc_start
Message-ID: <20240801072227.40562-1-adityag@linux.ibm.com>

Previous comment is not valid anymore as for newer kernels we are
getting vmalloc_start from NUMBER(vmalloc_start)

The logic was changed in makedumpfile:
    commit 94241fd2feed ("[PATCH] ppc64: get vmalloc start address from vmcoreinfo")

Fix comment for better understanding.

Signed-off-by: Aditya Gupta <adityag at linux.ibm.com>

---
repository: makedumpfile

patch should apply on commit 900190de6b67b2de410cfc8023c1b198a416ceb3
---
---
 arch/ppc64.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/ppc64.c b/arch/ppc64.c
index a54f9a04db7f..8ad9d6e3265f 100644
--- a/arch/ppc64.c
+++ b/arch/ppc64.c
@@ -566,7 +566,9 @@ get_machdep_info_ppc64(void)
 	DEBUG_MSG("kernel_start : %lx\n", info->kernel_start);
 
 	/*
-	 * Get vmalloc_start value from either vmap_area_list or vmlist.
+	 * To get vmalloc_start, prefer NUMBER(vmalloc_start) if exported in
+	 * vmcoreinfo, as 'vmap_area_list' and 'vmlist' in Linux 6.9 and later
+	 * kernels might be empty
 	 */
 	if (NUMBER(vmalloc_start) != NOT_FOUND_NUMBER) {
 		vmalloc_start = NUMBER(vmalloc_start);
-- 
2.45.2



From bhe at redhat.com  Thu Aug  1 00:43:57 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 1 Aug 2024 15:43:57 +0800
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
Message-ID: <Zqs8veRya7v/pXEt@MiWiFi-R3L-srv>

On 07/31/24 at 08:57pm, Sourabh Jain wrote:
> The following errors are observed when kexec is done with SMT=off on
> powerpc.
> 
> [  358.458385] Removing IBM Power 842 compression device
> [  374.795734] kexec_core: Starting new kernel
> [  374.795748] kexec: Waking offline cpu 1.
> [  374.875695] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
> [  374.935833] kexec: Waking offline cpu 2.
> [  375.015664] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
> snip..
> [  375.515823] kexec: Waking offline cpu 6.
> [  375.635667] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
> [  375.695836] kexec: Waking offline cpu 7.
> 
> During kexec, the offline CPUs are brought online, which triggers the

Is this a generic action or specific on ppc about the offline CPUs being
brought line during kexec? 

> crash hotplug handler `crash_handle_hotplug_event()` to update the kdump
> image. Given that the system is on the kexec path and the kexec lock is
> taken, the `crash_handle_hotplug_event()` function fails to take the
> same lock to update the kdump image, resulting in the above error
> messages.
> 
> To fix this, let's return from `crash_handle_hotplug_event()` if kexec
> is in progress.
> 
> The same applies to the `crash_check_hotplug_support()` function.
> Return 0 if kexec is in progress.
> 
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: kexec at lists.infradead.org
> Cc: linuxppc-dev at ozlabs.org
> Cc: linux-kernel at vger.kernel.org
> Cc: x86 at kernel.org
> Reported-by: Sachin P Bappalige <sachinpb at linux.vnet.ibm.com>
> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> ---
>  kernel/crash_core.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..d37a16d5c3a1 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -502,6 +502,9 @@ int crash_check_hotplug_support(void)
>  {
>  	int rc = 0;
>  
> +	if (kexec_in_progress)
> +		return 0;
> +
>  	crash_hotplug_lock();
>  	/* Obtain lock while reading crash information */
>  	if (!kexec_trylock()) {
> @@ -537,6 +540,9 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>  {
>  	struct kimage *image;
>  
> +	if (kexec_in_progress)
> +		return;
> +
>  	crash_hotplug_lock();
>  	/* Obtain lock while changing crash information */
>  	if (!kexec_trylock()) {
> -- 
> 2.45.2
> 
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 



From katarzyna.jarosz at growthsyne.pl  Thu Aug  1 01:05:16 2024
From: katarzyna.jarosz at growthsyne.pl (Katarzyna Jarosz)
Date: Thu,  1 Aug 2024 08:05:16 GMT
Subject: Zmiana w dokumencie
Message-ID: <20240801084500-0.1.24.63se.0.ptmhrotc7n@growthsyne.pl>

Dzie? dobry,

chcia?bym zaproponowa? wst?pn? rozmow? na temat wsp??pracy z Pa?stwem.

Centralna baza dokument?w, kt?ra gromadzi dane i informacje w zakresie e-maili, dokument?w, klient?w, spraw/projekt?w - w pe?nej integracji z MS Outlook pozwoli Pa?stwu stworzy? korzystniejsze warunki prawno-biznesowe dla prowadzonych dzia?a?.

Nasi Klienci, niemal w ka?dym przypadku osi?gaj? wymierne korzy?ci po zastosowaniu proponowanego przez nas rozwi?zania w postaci znajdowarki dokument?w.

Czy mog? zadzwoni?, aby opowiedzie? o tym, w jakim zakresie mogliby?my wesprze? Pa?stwa firm??


Pozdrawiam
Katarzyna Jarosz


From sourabhjain at linux.ibm.com  Thu Aug  1 01:06:46 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Thu, 1 Aug 2024 13:36:46 +0530
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <Zqs8veRya7v/pXEt@MiWiFi-R3L-srv>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
 <Zqs8veRya7v/pXEt@MiWiFi-R3L-srv>
Message-ID: <b7a52f5b-df93-476b-a9b1-931fad1474e0@linux.ibm.com>

Hello Baoquan,

On 01/08/24 13:13, Baoquan He wrote:
> On 07/31/24 at 08:57pm, Sourabh Jain wrote:
>> The following errors are observed when kexec is done with SMT=off on
>> powerpc.
>>
>> [  358.458385] Removing IBM Power 842 compression device
>> [  374.795734] kexec_core: Starting new kernel
>> [  374.795748] kexec: Waking offline cpu 1.
>> [  374.875695] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
>> [  374.935833] kexec: Waking offline cpu 2.
>> [  375.015664] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
>> snip..
>> [  375.515823] kexec: Waking offline cpu 6.
>> [  375.635667] crash hp: kexec_trylock() failed, elfcorehdr may be inaccurate
>> [  375.695836] kexec: Waking offline cpu 7.
>>
>> During kexec, the offline CPUs are brought online, which triggers the
> Is this a generic action or specific on ppc about the offline CPUs being
> brought line during kexec?

I think it is powerpc specific.
Patch that introduced this on powerpc: e8e5c2155b003 ("powerpc/kexec: 
Fix orphaned offline CPUs across kexec")

- Sourabh Jain



From Ashish.Kalra at amd.com  Thu Aug  1 12:14:02 2024
From: Ashish.Kalra at amd.com (Ashish Kalra)
Date: Thu, 1 Aug 2024 19:14:02 +0000
Subject: [PATCH v13 0/3] x86/snp: Add kexec support
In-Reply-To: <20240614095904.1345461-1-kirill.shutemov@linux.intel.com>
References: <20240614095904.1345461-1-kirill.shutemov@linux.intel.com>
Message-ID: <cover.1722520012.git.ashish.kalra@amd.com>

From: Ashish Kalra <ashish.kalra at amd.com>

The patchset adds bits and pieces to get kexec (and crashkernel) work on
SNP guest.

This patchset requires the following fix for preventing EFI memory map
corruption while doing SNP guest kexec:
  https://lore.kernel.org/all/16131a10-b473-41cc-a96e-d71a4d930353 at amd.com/T/#m77f2f33f5521d1369b0e8d461802b99005b4ffd6

The series is based off and tested against tree:
  https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git

----

v13:
- fix potential kernel build issue without CONFIG_AMD_MEM_ENCRYPT set.

v12:
- cleanups as suggested as per upstream review.
- Moved unshare_all_bss_decrypted_memory() into unshare_all_memory().
- Zap make_pte_private() and merge into unshare_all_memory().

v11:
- Refactored __set_clr_pte_enc() and added two new helper functions to
  set/clear PTE C-bit from early SEV/SNP initialization code and
  later during normal system operations and shutdown/kexec.
- Removed kexec_last_addr_to_make_private and now skip per-cpu
  GHCB addresses when making all pages private and then after 
  converting all pages to private in snp_kexec_finish(), go over
  the per-cpu GHCB addresses and convert them to private explicitly.
- Fixed comments and commit logs as per upstream review.

v10:
- Removed pr_debug() calls as per upstream review feedback.
- Add review tags.

v9:
- Rebased onto current tip/master;
- Rebased on top of [PATCH] x86/sev: Move SEV compilation units 
  and uses the coco directory hierarchy for SEV guest kexec patches.
- Includes the above mentioned patch as part of this patch-set to
  fix any kernel test robot/build issues.
- Includes the massaged version of patch 2/3 as per upstream
  review/feedback.

v8:
- removed fix EFI memory map corruption with kexec patch as this
  is a use-after-free bug that is not specific to SNP/TDX or kexec
  and a generic fix for the same has been posted. 
- Add new early_sev_detect() and move detection of SEV-ES/SNP guest
  and skip accessing video RAM during decompressor stage into
  this function as per feedback from upstream review.

v7:
- Rebased onto current tip/master;
- Moved back to checking the md attribute instead of checking the
  efi_setup for detecting if running under kexec kernel as 
  suggested in upstream review feedback.

v6:
- Updated and restructured the commit message for patch 1/3 to
  explain the issue in detail.
- Updated inline comments in patch 1/3 to explain the issue in 
  detail.
- Moved back to checking efi_setup for detecting if running
  under kexec kernel.

v5:
- Removed sev_es_enabled() function and using sev_status directly to
  check for SEV-ES/SEV-SNP guest.
- used --base option to generate patches to specify Kirill's TDX guest
  kexec patches as prerequisite patches to fix kernel test robot
  build errors.

v4:
- Rebased to current tip/master.
- Reviewed-bys from Sathya.
- Remove snp_kexec_unprep_rom_memory() as it is not needed any more as 
  SEV-SNP code is not validating the ROM range in probe_roms() anymore.
- Fix kernel test robot build error/warnings.

v3:
- Rebased;
- moved Keep page tables that maps E820_TYPE_ACPI patch to Kirill's tdx
  guest kexec patch series.
- checking the md attribute instead of checking the efi_setup for
  detecting if running under kexec kernel.
- added new sev_es_enabled() function.
- skip video memory access in decompressor for SEV-ES/SNP systems to 
  prevent guest termination as boot stage2 #VC handler does not handle
  MMIO.

v2:
- address zeroing of unaccepted memory table mappings at all page table levels
  adding phys_pte_init(), phys_pud_init() and phys_p4d_init().
- include skip efi_arch_mem_reserve() in case of kexec as part of this 
  patch set.
- rename last_address_shd_kexec to a more appropriate 
  kexec_last_address_to_make_private.
- remove duplicate code shared with TDX and use common interfaces
  defined for SNP and TDX for kexec/kdump.
- remove set_pte_enc() dependency on pg_level_to_pfn() and make the 
  function simpler.
- rename unshare_pte() to make_pte_private().
- clarify and make the comment for using kexec_last_address_to_make_private  
  more understandable.
- general cleanup. 

Ashish Kalra (3):
  x86/boot: Skip video memory access in the decompressor for SEV-ES/SNP
  x86/mm: refactor __set_clr_pte_enc()
  x86/snp: Convert shared memory back to private on kexec

 arch/x86/boot/compressed/misc.c |  15 ++++
 arch/x86/coco/sev/core.c        | 132 ++++++++++++++++++++++++++++++++
 arch/x86/include/asm/sev.h      |  24 ++++++
 arch/x86/mm/mem_encrypt_amd.c   |  77 ++++++++++++-------
 4 files changed, 222 insertions(+), 26 deletions(-)

-- 
2.34.1



From Ashish.Kalra at amd.com  Thu Aug  1 12:14:17 2024
From: Ashish.Kalra at amd.com (Ashish Kalra)
Date: Thu, 1 Aug 2024 19:14:17 +0000
Subject: [PATCH v13 1/3] x86/boot: Skip video memory access in the decompressor for SEV-ES/SNP
In-Reply-To: <cover.1722520012.git.ashish.kalra@amd.com>
References: <20240614095904.1345461-1-kirill.shutemov@linux.intel.com> <cover.1722520012.git.ashish.kalra@amd.com>
Message-ID: <8a55ea86524c686e575d273311acbe57ce8cee23.1722520012.git.ashish.kalra@amd.com>

From: Ashish Kalra <ashish.kalra at amd.com>

Accessing guest video memory/RAM in the decompressor causes guest
termination as the boot stage2 #VC handler for SEV-ES/SNP systems does
not support MMIO handling.

This issue is observed during a SEV-ES/SNP guest kexec as kexec -c adds
screen_info to the boot parameters passed to the second kernel, which
causes console output to be dumped to both video and serial.

As the decompressor output gets cleared really fast, it is preferable to
get the console output only on serial, hence, skip accessing the video
RAM during decompressor stage to prevent guest termination.

Serial console output during decompressor stage works as boot stage2 #VC
handler already supports handling port I/O.

  [ bp: Massage. ]

Suggested-by: Borislav Petkov (AMD) <bp at alien8.de>
Suggested-by: Thomas Lendacky <thomas.lendacky at amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra at amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp at alien8.de>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy at linux.intel.com>
Reviewed-by: Tom Lendacky <thomas.lendacky at amd.com>
---
 arch/x86/boot/compressed/misc.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 944454306ef4..826b4d5cb1f0 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -385,6 +385,19 @@ static void parse_mem_encrypt(struct setup_header *hdr)
 		hdr->xloadflags |= XLF_MEM_ENCRYPTION;
 }
 
+static void early_sev_detect(void)
+{
+	/*
+	 * Accessing video memory causes guest termination because
+	 * the boot stage2 #VC handler of SEV-ES/SNP guests does not
+	 * support MMIO handling and kexec -c adds screen_info to the
+	 * boot parameters passed to the kexec kernel, which causes
+	 * console output to be dumped to both video and serial.
+	 */
+	if (sev_status & MSR_AMD64_SEV_ES_ENABLED)
+		lines = cols = 0;
+}
+
 /*
  * The compressed kernel image (ZO), has been moved so that its position
  * is against the end of the buffer used to hold the uncompressed kernel
@@ -440,6 +453,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
 	 */
 	early_tdx_detect();
 
+	early_sev_detect();
+
 	console_init();
 
 	/*
-- 
2.34.1



From Ashish.Kalra at amd.com  Thu Aug  1 12:14:34 2024
From: Ashish.Kalra at amd.com (Ashish Kalra)
Date: Thu, 1 Aug 2024 19:14:34 +0000
Subject: [PATCH v13 2/3] x86/mm: refactor __set_clr_pte_enc()
In-Reply-To: <cover.1722520012.git.ashish.kalra@amd.com>
References: <20240614095904.1345461-1-kirill.shutemov@linux.intel.com> <cover.1722520012.git.ashish.kalra@amd.com>
Message-ID: <5df4aa450447f28294d1c5a890e27b63ed4ded36.1722520012.git.ashish.kalra@amd.com>

From: Ashish Kalra <ashish.kalra at amd.com>

Refactor __set_clr_pte_enc() and add two new helper functions to
set/clear PTE C-bit from early SEV/SNP initialization code and
later during shutdown/kexec especially when all CPUs are stopped
and interrupts are disabled and set_memory_xx() interfaces can't
be used.

Co-developed-by: Borislav Petkov (AMD) <bp at alien8.de>
Signed-off-by: Borislav Petkov (AMD) <bp at alien8.de>
Signed-off-by: Ashish Kalra <ashish.kalra at amd.com>
---
 arch/x86/include/asm/sev.h    | 20 ++++++++++
 arch/x86/mm/mem_encrypt_amd.c | 75 +++++++++++++++++++++++------------
 2 files changed, 69 insertions(+), 26 deletions(-)

diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 79bbe2be900e..61684d0a64c0 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -285,6 +285,22 @@ struct svsm_attest_call {
 	u8 rsvd[4];
 };
 
+/* PTE descriptor used for the prepare_pte_enc() operations. */
+struct pte_enc_desc {
+	pte_t *kpte;
+	int pte_level;
+	bool encrypt;
+	/* pfn of the kpte above */
+	unsigned long pfn;
+	/* physical address of @pfn */
+	unsigned long pa;
+	/* virtual address of @pfn */
+	void *va;
+	/* memory covered by the pte */
+	unsigned long size;
+	pgprot_t new_pgprot;
+};
+
 /*
  * SVSM protocol structure
  */
@@ -399,6 +415,8 @@ u64 snp_get_unsupported_features(u64 status);
 u64 sev_get_status(void);
 void sev_show_status(void);
 void snp_update_svsm_ca(void);
+int prepare_pte_enc(struct pte_enc_desc *d);
+void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot);
 
 #else	/* !CONFIG_AMD_MEM_ENCRYPT */
 
@@ -435,6 +453,8 @@ static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
 static inline u64 sev_get_status(void) { return 0; }
 static inline void sev_show_status(void) { }
 static inline void snp_update_svsm_ca(void) { }
+static inline int prepare_pte_enc(struct pte_enc_desc *d) { return 0; }
+static inline void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot) { }
 
 #endif	/* CONFIG_AMD_MEM_ENCRYPT */
 
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 86a476a426c2..f4be81db72ee 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -311,59 +311,82 @@ static int amd_enc_status_change_finish(unsigned long vaddr, int npages, bool en
 	return 0;
 }
 
-static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
+int prepare_pte_enc(struct pte_enc_desc *d)
 {
-	pgprot_t old_prot, new_prot;
-	unsigned long pfn, pa, size;
-	pte_t new_pte;
+	pgprot_t old_prot;
 
-	pfn = pg_level_to_pfn(level, kpte, &old_prot);
-	if (!pfn)
-		return;
+	d->pfn = pg_level_to_pfn(d->pte_level, d->kpte, &old_prot);
+	if (!d->pfn)
+		return 1;
 
-	new_prot = old_prot;
-	if (enc)
-		pgprot_val(new_prot) |= _PAGE_ENC;
+	d->new_pgprot = old_prot;
+	if (d->encrypt)
+		pgprot_val(d->new_pgprot) |= _PAGE_ENC;
 	else
-		pgprot_val(new_prot) &= ~_PAGE_ENC;
+		pgprot_val(d->new_pgprot) &= ~_PAGE_ENC;
 
 	/* If prot is same then do nothing. */
-	if (pgprot_val(old_prot) == pgprot_val(new_prot))
-		return;
+	if (pgprot_val(old_prot) == pgprot_val(d->new_pgprot))
+		return 1;
 
-	pa = pfn << PAGE_SHIFT;
-	size = page_level_size(level);
+	d->pa = d->pfn << PAGE_SHIFT;
+	d->size = page_level_size(d->pte_level);
 
 	/*
-	 * We are going to perform in-place en-/decryption and change the
-	 * physical page attribute from C=1 to C=0 or vice versa. Flush the
-	 * caches to ensure that data gets accessed with the correct C-bit.
+	 * In-place en-/decryption and physical page attribute change
+	 * from C=1 to C=0 or vice versa will be performed. Flush the
+	 * caches to ensure that data gets accessed with the correct
+	 * C-bit.
 	 */
-	clflush_cache_range(__va(pa), size);
+	if (d->va)
+		clflush_cache_range(d->va, d->size);
+	else
+		clflush_cache_range(__va(d->pa), d->size);
+
+	return 0;
+}
+
+void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot)
+{
+	pte_t new_pte;
+
+	/* Change the page encryption mask. */
+	new_pte = pfn_pte(pfn, new_prot);
+	set_pte_atomic(kpte, new_pte);
+}
+
+static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
+{
+	struct pte_enc_desc d = {
+		.kpte	     = kpte,
+		.pte_level   = level,
+		.encrypt     = enc
+	};
+
+	if (prepare_pte_enc(&d))
+		return;
 
 	/* Encrypt/decrypt the contents in-place */
 	if (enc) {
-		sme_early_encrypt(pa, size);
+		sme_early_encrypt(d.pa, d.size);
 	} else {
-		sme_early_decrypt(pa, size);
+		sme_early_decrypt(d.pa, d.size);
 
 		/*
 		 * ON SNP, the page state in the RMP table must happen
 		 * before the page table updates.
 		 */
-		early_snp_set_memory_shared((unsigned long)__va(pa), pa, 1);
+		early_snp_set_memory_shared((unsigned long)__va(d.pa), d.pa, 1);
 	}
 
-	/* Change the page encryption mask. */
-	new_pte = pfn_pte(pfn, new_prot);
-	set_pte_atomic(kpte, new_pte);
+	set_pte_enc_mask(kpte, d.pfn, d.new_pgprot);
 
 	/*
 	 * If page is set encrypted in the page table, then update the RMP table to
 	 * add this page as private.
 	 */
 	if (enc)
-		early_snp_set_memory_private((unsigned long)__va(pa), pa, 1);
+		early_snp_set_memory_private((unsigned long)__va(d.pa), d.pa, 1);
 }
 
 static int __init early_set_memory_enc_dec(unsigned long vaddr,
-- 
2.34.1



From Ashish.Kalra at amd.com  Thu Aug  1 12:14:50 2024
From: Ashish.Kalra at amd.com (Ashish Kalra)
Date: Thu, 1 Aug 2024 19:14:50 +0000
Subject: [PATCH v13 3/3] x86/snp: Convert shared memory back to private on kexec
In-Reply-To: <cover.1722520012.git.ashish.kalra@amd.com>
References: <20240614095904.1345461-1-kirill.shutemov@linux.intel.com> <cover.1722520012.git.ashish.kalra@amd.com>
Message-ID: <05a8c15fb665dbb062b04a8cb3d592a63f235937.1722520012.git.ashish.kalra@amd.com>

From: Ashish Kalra <ashish.kalra at amd.com>

SNP guests allocate shared buffers to perform I/O. It is done by
allocating pages normally from the buddy allocator and converting them
to shared with set_memory_decrypted().

The second, kexec-ed, kernel has no idea what memory is converted this way.
It only sees E820_TYPE_RAM.

Accessing shared memory via private mapping will cause unrecoverable RMP
page-faults.

On kexec walk direct mapping and convert all shared memory back to
private. It makes all RAM private again and second kernel may use it
normally. Additionally for SNP guests convert all bss decrypted section
pages back to private.

The conversion occurs in two steps: stopping new conversions and
unsharing all memory. In the case of normal kexec, the stopping of
conversions takes place while scheduling is still functioning. This
allows for waiting until any ongoing conversions are finished. The
second step is carried out when all CPUs except one are inactive and
interrupts are disabled. This prevents any conflicts with code that may
access shared memory.

Co-developed-by: Borislav Petkov (AMD) <bp at alien8.de>
Signed-off-by: Borislav Petkov (AMD) <bp at alien8.de>
Reviewed-by: Tom Lendacky <thomas.lendacky at amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra at amd.com>
---
 arch/x86/coco/sev/core.c      | 132 ++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/sev.h    |   4 ++
 arch/x86/mm/mem_encrypt_amd.c |   2 +
 3 files changed, 138 insertions(+)

diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index de1df0cb45da..4278cdbee3a5 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1010,6 +1010,138 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end)
 	set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
 }
 
+static void set_pte_enc(pte_t *kpte, int level, void *va)
+{
+	struct pte_enc_desc d = {
+		.kpte	   = kpte,
+		.pte_level = level,
+		.va	   = va,
+		.encrypt   = true
+	};
+
+	prepare_pte_enc(&d);
+	set_pte_enc_mask(kpte, d.pfn, d.new_pgprot);
+}
+
+static void unshare_all_memory(void)
+{
+	unsigned long addr, end, size, ghcb;
+	struct sev_es_runtime_data *data;
+	unsigned int npages, level;
+	bool skipped_addr;
+	pte_t *pte;
+	int cpu;
+
+	/* Unshare the direct mapping. */
+	addr = PAGE_OFFSET;
+	end  = PAGE_OFFSET + get_max_mapped();
+
+	while (addr < end) {
+		pte = lookup_address(addr, &level);
+		size = page_level_size(level);
+		npages = size / PAGE_SIZE;
+		skipped_addr = false;
+
+		if (!pte || !pte_decrypted(*pte) || pte_none(*pte)) {
+			addr += size;
+			continue;
+		}
+
+		/*
+		 * Ensure that all the per-cpu GHCBs are made private at the
+		 * end of unsharing loop so that the switch to the slower MSR
+		 * protocol happens last.
+		 */
+		for_each_possible_cpu(cpu) {
+			data = per_cpu(runtime_data, cpu);
+			ghcb = (unsigned long)&data->ghcb_page;
+
+			if (addr <= ghcb && ghcb <= addr + size) {
+				skipped_addr = true;
+				break;
+			}
+		}
+
+		if (!skipped_addr) {
+			set_pte_enc(pte, level, (void *)addr);
+			snp_set_memory_private(addr, npages);
+		}
+		addr += size;
+	}
+
+	/* Unshare all bss decrypted memory. */
+	addr = (unsigned long)__start_bss_decrypted;
+	end  = (unsigned long)__start_bss_decrypted_unused;
+	npages = (end - addr) >> PAGE_SHIFT;
+
+	for (; addr < end; addr += PAGE_SIZE) {
+		pte = lookup_address(addr, &level);
+		if (!pte || !pte_decrypted(*pte) || pte_none(*pte))
+			continue;
+
+		set_pte_enc(pte, level, (void *)addr);
+	}
+	addr = (unsigned long)__start_bss_decrypted;
+	snp_set_memory_private(addr, npages);
+
+	__flush_tlb_all();
+}
+
+/* Stop new private<->shared conversions */
+void snp_kexec_begin(void)
+{
+	if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+		return;
+
+	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+		return;
+
+	/*
+	 * Crash kernel ends up here with interrupts disabled: can't wait for
+	 * conversions to finish.
+	 *
+	 * If race happened, just report and proceed.
+	 */
+	if (!set_memory_enc_stop_conversion())
+		pr_warn("Failed to stop shared<->private conversions\n");
+}
+
+void snp_kexec_finish(void)
+{
+	struct sev_es_runtime_data *data;
+	unsigned int level, cpu;
+	unsigned long size;
+	struct ghcb *ghcb;
+	pte_t *pte;
+
+	if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+		return;
+
+	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+		return;
+
+	unshare_all_memory();
+
+	/*
+	 * Switch to using the MSR protocol to change per-cpu
+	 * GHCBs to private.
+	 * All the per-cpu GHCBs have been switched back to private,
+	 * so can't do any more GHCB calls to the hypervisor beyond
+	 * this point till the kexec kernel starts running.
+	 */
+	boot_ghcb = NULL;
+	sev_cfg.ghcbs_initialized = false;
+
+	for_each_possible_cpu(cpu) {
+		data = per_cpu(runtime_data, cpu);
+		ghcb = &data->ghcb_page;
+		pte = lookup_address((unsigned long)ghcb, &level);
+		size = page_level_size(level);
+		set_pte_enc(pte, level, (void *)ghcb);
+		snp_set_memory_private((unsigned long)ghcb, (size / PAGE_SIZE));
+	}
+}
+
 static int snp_set_vmsa(void *va, void *caa, int apic_id, bool make_vmsa)
 {
 	int ret;
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 61684d0a64c0..733448e72a9b 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -417,6 +417,8 @@ void sev_show_status(void);
 void snp_update_svsm_ca(void);
 int prepare_pte_enc(struct pte_enc_desc *d);
 void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot);
+void snp_kexec_finish(void);
+void snp_kexec_begin(void);
 
 #else	/* !CONFIG_AMD_MEM_ENCRYPT */
 
@@ -455,6 +457,8 @@ static inline void sev_show_status(void) { }
 static inline void snp_update_svsm_ca(void) { }
 static inline int prepare_pte_enc(struct pte_enc_desc *d) { return 0; }
 static inline void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot) { }
+static inline void snp_kexec_finish(void) { }
+static inline void snp_kexec_begin(void) { }
 
 #endif	/* CONFIG_AMD_MEM_ENCRYPT */
 
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index f4be81db72ee..774f9677458f 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -490,6 +490,8 @@ void __init sme_early_init(void)
 	x86_platform.guest.enc_status_change_finish  = amd_enc_status_change_finish;
 	x86_platform.guest.enc_tlb_flush_required    = amd_enc_tlb_flush_required;
 	x86_platform.guest.enc_cache_flush_required  = amd_enc_cache_flush_required;
+	x86_platform.guest.enc_kexec_begin	     = snp_kexec_begin;
+	x86_platform.guest.enc_kexec_finish	     = snp_kexec_finish;
 
 	/*
 	 * AMD-SEV-ES intercepts the RDMSR to read the X2APIC ID in the
-- 
2.34.1



From bhe at redhat.com  Thu Aug  1 20:36:18 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 2 Aug 2024 11:36:18 +0800
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
Message-ID: <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>

On 07/31/24 at 06:34pm, A Kundu wrote:
> I am experiencing issues using kexec to load Xen 4.17(debian's apt version),
> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from source) on a
> debian host.

You should CC this to XEN dev list so that XEN dev knows this and may
provide help. Not everyone is interested in and knows XEN.

> 
> System information:
> $ uname -a
> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1 (2024-07-19)
> x86_64 GNU/Linux
> 
> $ kexec --version # compiled from source tarball with ./configure --with-xen
> kexec-tools 2.0.29
> 
> Steps to reproduce:
> 
> 1. Set variables:
> 
> XEN_HYPERVISOR="/boot/xen.gz"
> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
> 
> 2. Attempt to load Xen 4.19-rc4:
> 
> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
> Could not find a free area of memory of 0x3b6001 bytes...
> elf_exec_build_load_relocatable: ELF exec load failed
> 
> 3. Attempt to load Xen 4.20-dev:
> 
> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
> Could not find a free area of memory of 0x3f8001 bytes...
> elf_exec_build_load_relocatable: ELF exec load failed
> 
> 4. Attempt to load Xen 4.17 (from debian rrepositories):
> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
> Could not find a free area of memory of 0x3b4001 bytes...
> elf_exec_build_load_relocatable: ELF exec load failed
> 
> If you need any further information to investigate this problem,
> please let me know.
> 
> PS: If I used apt's pacakged version (which might be compiled
> --without-xen),
> it shows,
> 
> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
> Cannot determine the file type of /boot/xen-4.17-amd64.gz
> 
> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD" --type=bzImage
> Cannot determine the file type of /boot/xen-4.17-amd64.gz
> 
> 
> Thank you for your attention to this matter.
> 
> A Kundu
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 



From avikalpa at yahoo.com  Fri Aug  2 00:28:51 2024
From: avikalpa at yahoo.com (A Kundu)
Date: Fri, 2 Aug 2024 12:58:51 +0530
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
Message-ID: <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>

Done.


On 8/2/24 09:06, Baoquan He wrote:
> On 07/31/24 at 06:34pm, A Kundu wrote:
>> I am experiencing issues using kexec to load Xen 4.17(debian's apt version),
>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from source) on a
>> debian host.
> You should CC this to XEN dev list so that XEN dev knows this and may
> provide help. Not everyone is interested in and knows XEN.
>
>> System information:
>> $ uname -a
>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1 (2024-07-19)
>> x86_64 GNU/Linux
>>
>> $ kexec --version # compiled from source tarball with ./configure --with-xen
>> kexec-tools 2.0.29
>>
>> Steps to reproduce:
>>
>> 1. Set variables:
>>
>> XEN_HYPERVISOR="/boot/xen.gz"
>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
>>
>> 2. Attempt to load Xen 4.19-rc4:
>>
>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>> Could not find a free area of memory of 0x3b6001 bytes...
>> elf_exec_build_load_relocatable: ELF exec load failed
>>
>> 3. Attempt to load Xen 4.20-dev:
>>
>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>> Could not find a free area of memory of 0x3f8001 bytes...
>> elf_exec_build_load_relocatable: ELF exec load failed
>>
>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
>> Could not find a free area of memory of 0x3b4001 bytes...
>> elf_exec_build_load_relocatable: ELF exec load failed
>>
>> If you need any further information to investigate this problem,
>> please let me know.
>>
>> PS: If I used apt's pacakged version (which might be compiled
>> --without-xen),
>> it shows,
>>
>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>> Cannot determine the file type of /boot/xen-4.17-amd64.gz
>>
>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD" --type=bzImage
>> Cannot determine the file type of /boot/xen-4.17-amd64.gz
>>
>>
>> Thank you for your attention to this matter.
>>
>> A Kundu
>>
>> _______________________________________________
>> kexec mailing list
>> kexec at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/kexec
>>


From kamil.tralewski at originateinc.pl  Fri Aug  2 00:35:19 2024
From: kamil.tralewski at originateinc.pl (Kamil Tralewski)
Date: Fri,  2 Aug 2024 07:35:19 GMT
Subject: =?UTF-8?Q?S=C5=82owa_kluczowe_do_wypozycjonowania?=
Message-ID: <20240802074501-0.1.ec.1h215.0.s634l12ety@OriginateInc.pl>

Dzie? dobry,

zapozna?em si? z Pa?stwa ofert? i z przyjemno?ci? przyznaj?, ?e przyci?ga uwag? i zach?ca do dalszych rozm?w. 

Pomy?la?em, ?e mo?e m?g?bym mie? sw?j wk?ad w Pa?stwa rozw?j i pom?c dotrze? z t? ofert? do wi?kszego grona odbiorc?w. Pozycjonuj? strony www, dzi?ki czemu generuj? ?wietny ruch w sieci.

Mo?emy porozmawia? w najbli?szym czasie?


Pozdrawiam
Kamil Tralewski


From jbeulich at suse.com  Fri Aug  2 00:55:25 2024
From: jbeulich at suse.com (Jan Beulich)
Date: Fri, 2 Aug 2024 09:55:25 +0200
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
 <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
Message-ID: <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>

On 02.08.2024 09:28, A Kundu wrote:
> On 8/2/24 09:06, Baoquan He wrote:
>> On 07/31/24 at 06:34pm, A Kundu wrote:
>>> I am experiencing issues using kexec to load Xen 4.17(debian's apt version),
>>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from source) on a
>>> debian host.
>> You should CC this to XEN dev list so that XEN dev knows this and may
>> provide help. Not everyone is interested in and knows XEN.
>>
>>> System information:
>>> $ uname -a
>>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1 (2024-07-19)
>>> x86_64 GNU/Linux
>>>
>>> $ kexec --version # compiled from source tarball with ./configure --with-xen
>>> kexec-tools 2.0.29
>>>
>>> Steps to reproduce:
>>>
>>> 1. Set variables:
>>>
>>> XEN_HYPERVISOR="/boot/xen.gz"
>>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
>>>
>>> 2. Attempt to load Xen 4.19-rc4:
>>>
>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>> Could not find a free area of memory of 0x3b6001 bytes...
>>> elf_exec_build_load_relocatable: ELF exec load failed
>>>
>>> 3. Attempt to load Xen 4.20-dev:
>>>
>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>> Could not find a free area of memory of 0x3f8001 bytes...
>>> elf_exec_build_load_relocatable: ELF exec load failed
>>>
>>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
>>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
>>> Could not find a free area of memory of 0x3b4001 bytes...
>>> elf_exec_build_load_relocatable: ELF exec load failed

And with all of them saying effectively the same, did you verify you
actually have a sufficiently large area reserved? The obvious
place for you to look at is Xen's boot log (obtained via serial
console or "xl dmesg" immediately after booting the system). If you
find everything as expected there, ...

>>> If you need any further information to investigate this problem,
>>> please let me know.

... please provide that boot log.

Jan


From ruanjinjie at huawei.com  Fri Aug  2 02:01:05 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Fri, 2 Aug 2024 17:01:05 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
Message-ID: <20240802090105.3871929-1-ruanjinjie@huawei.com>

On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
will cause system stall as below:

	 Zone ranges:
	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
	   Normal   empty
	 Movable zone start for each node
	 Early memory node ranges
	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
	(stall here)

commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
bug") fix this on 32-bit architecture. However, the problem is not
completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
architecture, for example, when system memory is equal to
CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:

	-> reserve_crashkernel_generic() and high is true
	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).

Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
to simplify crashkernel reservation code"), x86 do not try to reserve crash
memory at low if it fails to alloc above high 4G. However before refator in
commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
crashkernel reservation"), arm64 try to reserve crash memory at low if it
fails above high 4G. For 64-bit systems, this attempt is less beneficial
than the opposite, remove it to fix this bug and align with native x86
implementation.

After this patch, it print:
	cannot allocate crashkernel (size:0x1f400000)

Fixes: 39365395046f ("riscv: kdump: use generic interface to simplify crashkernel reservation")
Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
---
 kernel/crash_reserve.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
index 5387269114f6..69e4b8b7b969 100644
--- a/kernel/crash_reserve.c
+++ b/kernel/crash_reserve.c
@@ -420,15 +420,6 @@ void __init reserve_crashkernel_generic(char *cmdline,
 				goto retry;
 		}
 
-		/*
-		 * For crashkernel=size[KMG],high, if the first attempt was
-		 * for high memory, fall back to low memory.
-		 */
-		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
-			search_end = CRASH_ADDR_LOW_MAX;
-			search_base = 0;
-			goto retry;
-		}
 		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
 			crash_size);
 		return;
-- 
2.34.1



From bhe at redhat.com  Fri Aug  2 03:11:01 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 2 Aug 2024 18:11:01 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <20240802090105.3871929-1-ruanjinjie@huawei.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
Message-ID: <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>

On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> will cause system stall as below:
> 
> 	 Zone ranges:
> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> 	   Normal   empty
> 	 Movable zone start for each node
> 	 Early memory node ranges
> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> 	(stall here)
> 
> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> bug") fix this on 32-bit architecture. However, the problem is not
> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> architecture, for example, when system memory is equal to
> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:

Interesting, I didn't expect risc-v defining them like these.

#define CRASH_ADDR_LOW_MAX              dma32_phys_limit
#define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()
> 
> 	-> reserve_crashkernel_generic() and high is true
> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> 
> Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> to simplify crashkernel reservation code"), x86 do not try to reserve crash
> memory at low if it fails to alloc above high 4G. However before refator in
> commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> crashkernel reservation"), arm64 try to reserve crash memory at low if it
> fails above high 4G. For 64-bit systems, this attempt is less beneficial
> than the opposite, remove it to fix this bug and align with native x86
> implementation.

And I don't like the idea crashkernel=,high failure will fallback to
attempt in low area, so this looks good to me.

> 
> After this patch, it print:
> 	cannot allocate crashkernel (size:0x1f400000)
> 
> Fixes: 39365395046f ("riscv: kdump: use generic interface to simplify crashkernel reservation")
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> ---
>  kernel/crash_reserve.c | 9 ---------
>  1 file changed, 9 deletions(-)

Acked-by: Baoquan He <bhe at redhat.com>

> 
> diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
> index 5387269114f6..69e4b8b7b969 100644
> --- a/kernel/crash_reserve.c
> +++ b/kernel/crash_reserve.c
> @@ -420,15 +420,6 @@ void __init reserve_crashkernel_generic(char *cmdline,
>  				goto retry;
>  		}
>  
> -		/*
> -		 * For crashkernel=size[KMG],high, if the first attempt was
> -		 * for high memory, fall back to low memory.
> -		 */
> -		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
> -			search_end = CRASH_ADDR_LOW_MAX;
> -			search_base = 0;
> -			goto retry;
> -		}
>  		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>  			crash_size);
>  		return;
> -- 
> 2.34.1
> 



From alex at ghiti.fr  Fri Aug  2 05:24:19 2024
From: alex at ghiti.fr (Alexandre Ghiti)
Date: Fri, 2 Aug 2024 14:24:19 +0200
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <20240802090105.3871929-1-ruanjinjie@huawei.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
Message-ID: <ce86ad6b-5f56-4856-9756-fa8867d0d1df@ghiti.fr>

Hi Jinjie,

On 02/08/2024 11:01, Jinjie Ruan wrote:
> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> will cause system stall as below:
>
> 	 Zone ranges:
> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> 	   Normal   empty
> 	 Movable zone start for each node
> 	 Early memory node ranges
> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> 	(stall here)
>
> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop


I can't find this revision, was this patch merged in 6.11?


> bug") fix this on 32-bit architecture. However, the problem is not
> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> architecture, for example, when system memory is equal to
> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
>
> 	-> reserve_crashkernel_generic() and high is true
> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
>
> Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> to simplify crashkernel reservation code"), x86 do not try to reserve crash
> memory at low if it fails to alloc above high 4G. However before refator in
> commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> crashkernel reservation"), arm64 try to reserve crash memory at low if it
> fails above high 4G. For 64-bit systems, this attempt is less beneficial
> than the opposite, remove it to fix this bug and align with native x86
> implementation.
>
> After this patch, it print:
> 	cannot allocate crashkernel (size:0x1f400000)
>
> Fixes: 39365395046f ("riscv: kdump: use generic interface to simplify crashkernel reservation")


Your patch subject indicates "-next" but I see this commit ^ landed in 
6.7, so I think we should merge it now, let me know if I missed something.

Thanks,

Alex


> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> ---
>   kernel/crash_reserve.c | 9 ---------
>   1 file changed, 9 deletions(-)
>
> diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
> index 5387269114f6..69e4b8b7b969 100644
> --- a/kernel/crash_reserve.c
> +++ b/kernel/crash_reserve.c
> @@ -420,15 +420,6 @@ void __init reserve_crashkernel_generic(char *cmdline,
>   				goto retry;
>   		}
>   
> -		/*
> -		 * For crashkernel=size[KMG],high, if the first attempt was
> -		 * for high memory, fall back to low memory.
> -		 */
> -		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
> -			search_end = CRASH_ADDR_LOW_MAX;
> -			search_base = 0;
> -			goto retry;
> -		}
>   		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>   			crash_size);
>   		return;


From avikalpa at yahoo.com  Sun Aug  4 06:17:23 2024
From: avikalpa at yahoo.com (A Kundu)
Date: Sun, 4 Aug 2024 18:47:23 +0530
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
 <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
 <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>
Message-ID: <dc5c9dff-6bee-493a-8315-b2eee48bd802@yahoo.com>

On 8/2/24 13:25, Jan Beulich wrote:
 > On 02.08.2024 09:28, A Kundu wrote:
 >> On 8/2/24 09:06, Baoquan He wrote:
 >>> On 07/31/24 at 06:34pm, A Kundu wrote:
 >>>> I am experiencing issues using kexec to load Xen 4.17(debian's apt 
version),
 >>>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from 
source) on a
 >>>> debian host.
 >>> You should CC this to XEN dev list so that XEN dev knows this and may
 >>> provide help. Not everyone is interested in and knows XEN.
 >>>
 >>>> System information:
 >>>> $ uname -a
 >>>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1 
(2024-07-19)
 >>>> x86_64 GNU/Linux
 >>>>
 >>>> $ kexec --version # compiled from source tarball with ./configure 
--with-xen
 >>>> kexec-tools 2.0.29
 >>>>
 >>>> Steps to reproduce:
 >>>>
 >>>> 1. Set variables:
 >>>>
 >>>> XEN_HYPERVISOR="/boot/xen.gz"
 >>>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
 >>>>
 >>>> 2. Attempt to load Xen 4.19-rc4:
 >>>>
 >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
 >>>> Could not find a free area of memory of 0x3b6001 bytes...
 >>>> elf_exec_build_load_relocatable: ELF exec load failed
 >>>>
 >>>> 3. Attempt to load Xen 4.20-dev:
 >>>>
 >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
 >>>> Could not find a free area of memory of 0x3f8001 bytes...
 >>>> elf_exec_build_load_relocatable: ELF exec load failed
 >>>>
 >>>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
 >>>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
 >>>> Could not find a free area of memory of 0x3b4001 bytes...
 >>>> elf_exec_build_load_relocatable: ELF exec load failed
 >
 > And with all of them saying effectively the same, did you verify you
 > actually have a sufficiently large area reserved? The obvious
 > place for you to look at is Xen's boot log (obtained via serial
 > console or "xl dmesg" immediately after booting the system). If you
 > find everything as expected there, ...
 >
 >>>> If you need any further information to investigate this problem,
 >>>> please let me know.
 >
 > ... please provide that boot log.

Dear Jan,

Thank you for your response and suggestions.

As mentioned in my original message, I have already attempted to load
Xen using kexec with various versions (4.17, 4.19-rc4, and 4.20-dev),
all of which resulted in the same error:

Could not find a free area of memory of 0x3b6001 bytes...
elf_exec_build_load_relocatable: ELF exec load failed

I have also followed up on your suggestion to check the Xen boot log
using "xl dmesg", but unfortunately, I received the following error:

xencall: error: Could not obtain handle on privileged command interface: 
No such file or directory
libxl: error: libxl.c:102:libxl_ctx_alloc: cannot open libxc handle: No 
such file or directory
cannot init xl context

This indicates that Xen did not boot successfully, so there are no logs
available.

 >
 > And with all of them saying effectively the same, did you verify you
 > actually have a sufficiently large area reserved? The obvious
 > place for you to look at is Xen's boot log (obtained via serial
 > console or "xl dmesg" immediately after booting the system). If you
 > find everything as expected there, ...
 >

In an attempt to resolve the memory allocation issue, I have tried the
following:

Added a crashkernel=<size>@<offset> parameter to the host kernel command
line to reserve a dedicated memory region for kexec, and attempted to
load Xen into that area.

Experimented with the mem=<size> parameter to limit the amount of memory
used by the host kernel, hoping to leave more contiguous space available
for loading Xen.

Unfortunately, neither of these approaches resolved the issue, and I
still encounter the same memory allocation error when attempting to load
Xen with kexec.

I have also reviewed the available documentation for kexec and Xen, but
much of it appears to be outdated, referencing archaic options like
--vmm which no longer exist in the current version of kexec-tools.

 > Jan

At this point, I'm unsure of how to proceed. I suspect the issue may be
related to changes in the kexec codebase and its interaction with Xen,
as kexec docs for Xen has not been actively maintained since 2017.

git log -1 --format="%ad" -- docs/misc/kexec_and_kdump.txt
Fri Jun 9 14:11:37 2017 +0200

If it's not too much to ask, could you please check if you can
successfully launch the Xen kernel using kexec with kexec-tools
version > 2.x.x and a Linux kernel version >= 6.6?

I have never been able to boot the Xen kernel with anything (syslinux,
zfsbootmenu)other than GRUB and mboot.c32, as used by Citrix or XCP-ng.

In fact, I have never come across a Xen distribution that doesn't rely
on GRUB for xen, which makes me question whether kexec'ing the Xen
kernel is even possible at this point.


For reference, I'm providing a log of my attempts to boot Xen using
ZFSBootMenu (a barebones linux kernel trying to boot via kexec; other 
details irrelevant):

tee: /zfsbootmenu/environments/zroot/ROOT/debian/mnt/var/zbm.log: 
Read-only file system
=== Attempting to Launch Xen ===
Selected Kernel???? : /boot/vmlinuz-6.9.12-amd64
Selected initramfs? : /boot/initrd.img-6.9.12-amd64
Selected BE???????? : zroot/ROOT/debian
Selected Mountpoint : /zfsbootmenu/environments/zroot/ROOT/debian/mnt
ZFSBootMenu kernel commandline: quiet loglevel=0

zfs get org.zfsbootmenu:commandline zroot/ROOT/debian
NAME?????????????? PROPERTY VALUE??????????????????????????????????????? 
SOURCE
zroot/ROOT/debian? org.zfsbootmenu:commandline? quiet crashkernel=0M 
memmap=64M$0x100000000? local
(^^^ This is the linux/dom0 commandline, executed by kexec)

=== Memory reported by head /proc/meminfo ===
MemTotal:??????? 8044084 kB
MemFree:???????? 7822332 kB
MemAvailable:??? 7687320 kB
Buffers:????????????? 0 kB
Cached:?????????? 49136 kB
SwapCached:?????????? 0 kB
Active:?????????? 45868 kB
Inactive:???????????? 0 kB
Active(anon):???? 45868 kB
Inactive(anon):?????? 0 kB
=== End of Memory Report ===

Xen kernel found. Attempting kexec...
Xen Kernel Path???? : 
/zfsbootmenu/environments/zroot/ROOT/debian/mnt/boot/xen.gz
Try gzip decompression.
Could not find a free area of memory of 0x3ba001 bytes...
elf_exec_build_load_relocatable: ELF exec load failed
Executing kexec...
Nothing has been loaded!

After booting into linux what happens, I have already shared.

If you have any further insights or suggestions on how to overcome this
memory allocation issue or successfully boot Xen using kexec on a modern
system, I would greatly appreciate your guidance.

Thank you for your time and assistance.

Best regards,
A Kundu


From ruanjinjie at huawei.com  Sun Aug  4 19:28:50 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Mon, 5 Aug 2024 10:28:50 +0800
Subject: [PATCH v18 0/6] powerpc/crash: Kernel handling of CPU and memory
 hotplug
In-Reply-To: <20240326055413.186534-1-sourabhjain@linux.ibm.com>
References: <20240326055413.186534-1-sourabhjain@linux.ibm.com>
Message-ID: <50498549-f6c1-ce2c-b190-e9eedd1eb9ee@huawei.com>



On 2024/3/26 13:54, Sourabh Jain wrote:
> Commit 247262756121 ("crash: add generic infrastructure for crash
> hotplug support") added a generic infrastructure that allows
> architectures to selectively update the kdump image component during CPU
> or memory add/remove events within the kernel itself.
> 
> This patch series adds crash hotplug handler for PowerPC and enable
> support to update the kdump image on CPU/Memory add/remove events.
> 
> Among the 6 patches in this series, the first two patches make changes
> to the generic crash hotplug handler to assist PowerPC in adding support
> for this feature. The last four patches add support for this feature.
> 
> The following section outlines the problem addressed by this patch
> series, along with the current solution, its shortcomings, and the
> proposed resolution.
> 
> Problem:
> ========
> Due to CPU/Memory hotplug or online/offline events the elfcorehdr
> (which describes the CPUs and memory of the crashed kernel) and FDT
> (Flattened Device Tree) of kdump image becomes outdated. Consequently,
> attempting dump collection with an outdated elfcorehdr or FDT can lead
> to failed or inaccurate dump collection.

Hi, Sourabh, are there any specific methods to reproduce the scenarios
for this feature? I would like to port this feature to ARM64, but I
don't know how to reproduce the issue.

> 
> Going forward CPU hotplug or online/offline events are referred as
> CPU/Memory add/remove events.
> 
> Existing solution and its shortcoming:
> ======================================
> The current solution to address the above issue involves monitoring the
> CPU/memory add/remove events in userspace using udev rules and whenever
> there are changes in CPU and memory resources, the entire kdump image
> is loaded again. The kdump image includes kernel, initrd, elfcorehdr,
> FDT, purgatory. Given that only elfcorehdr and FDT get outdated due to
> CPU/Memory add/remove events, reloading the entire kdump image is
> inefficient. More importantly, kdump remains inactive for a substantial
> amount of time until the kdump reload completes.
> 
> Proposed solution:
> ==================
> Instead of initiating a full kdump image reload from userspace on
> CPU/Memory hotplug and online/offline events, the proposed solution aims
> to update only the necessary kdump image component within the kernel
> itself.
> 
> Git tree for testing:
> =====================
> https://github.com/sourabhjains/linux/tree/kdump-in-kernel-crash-update-v18
> 
> Above tree is rebased on top of powerpc/next branch.
> 
> To realize this feature, the kdump udev rule must be updated. On RHEL,
> add the following two lines at the top of the
> "/usr/lib/udev/rules.d/98-kexec.rules" file.
> 
> SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
> SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
> 
> With the above change to the kdump udev rule, kdump reload is avoided
> during CPU/Memory add/remove events if this feature is enabled in the
> kernel.
> 
> Note: only kexec_file_load syscall will work. For kexec_load minor changes
> are required in kexec tool.
> 
> Changelog:
> ----------
> v18: [No functional changes]
>   - Update a comment in 2/6.
>   - Describe the clean-up done on x86 in patch description 2/6.
>   - Fix a minor typo in the patch description of 3/6.
> 
> v17: [https://lore.kernel.org/all/20240226084118.16310-1-sourabhjain at linux.ibm.com/]
>   - Rebase the patch series on top linux-next tree and below patch series
>     https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
>   - Split 0003 patch from v16 into two patches
>        1. Move get_crash_memory_ranges() along with other *_memory_ranges()
>           functions to ranges.c and make them public.
>        2. Make update_cpus_node function public and take this function
>           out of file_load_64.c
>   - Keep arch_crash_hotplug_support in crash.c instead of core_64.c [05/06]
>   - Use CONFIG_CRASH_MAX_MEMORY_RANGES to find extra elfcorehdr size [06/06]
> 
> v16: [https://lore.kernel.org/all/20240217081452.164571-1-sourabhjain at linux.ibm.com/]
>   - Remove the unused #define `crash_hotplug_cpu_support`
>     and `crash_hotplug_memory_support` in `arch/x86/include/asm/kexec.h`.
>   - Document why two kexec flag bits are used in
>     `arch_crash_hotplug_memory_support` (x86).
>   - Use a switch case to handle different hotplug operations
>     in `arch_crash_handle_hotplug_event` for PowerPC.
>   - Fix a typo in 4/5.
> 
> v15:
>   - Remove the patch that adds a new kexec flag for FDT update.
>   - Introduce a generic kexec flag bit to share hotplug support
>     intent between the kexec tool and the kernel for the kexec_load
>     syscall. (2/5)
>   - Introduce an architecture-specific handler to process the kexec
>     flag for crash hotplug support. (2/5)
>   - Rename the @update_elfcorehdr member of the struct kimage to
>     @hotplug_support. (2/5)
>   - Use a common function to advertise hotplug support for both CPU
>     and Memory. (2/5)
> 
> v14:
>   - Fix build warnings by including necessary header files
>   - Rebase to v6.7-rc5
> 
> v13:
>   - Fix a build warning, take ranges.c out of CONFIG_KEXEC_FILE
>   - Rebase to v6.7-rc4
> 
> v12:
>   - A patch to add new kexec flags to support this feature on kexec_load
>     system call
>   - Change in the way this feature is advertise to userspace for both
>     kexec_load syscall
>   - Rebase to v6.6-rc7
> 
> v11:
>   - Rebase to v6.4-rc6
>   - The patch that introduced CONFIG_CRASH_HOTPLUG for PowerPC has been
>     removed. The config is now part of common configuration:
>     https://lore.kernel.org/all/87ilbpflsk.fsf at mail.lhotse/
> 
> v10:
>   - Drop the patch that adds fdt_index attribute to struct kimage_arch
>     Find the fdt segment index when needed.
>   - Added more details into commits messages.
>   - Rebased onto 6.3.0-rc5
> 
> v9:
>   - Removed patch to prepare elfcorehdr crash notes for possible CPUs.
>     The patch is moved to generic patch series that introduces generic
>     infrastructure for in kernel crash update.
>   - Removed patch to pass the hotplug action type to the arch crash
>     hotplug handler function. The generic patch series has introduced
>     the hotplug action type in kimage struct.
>   - Add detail commit message for better understanding.
> 
> v8:
>   - Restrict fdt_index initialization to machine_kexec_post_load
>     it work for both kexec_load and kexec_file_load.[3/8] Laurent Dufour
> 
>   - Updated the logic to find the number of offline core. [6/8]
> 
>   - Changed the logic to find the elfcore program header to accommodate
>     future memory ranges due memory hotplug events. [8/8]
> 
> v7
>   - added a new config to configure this feature
>   - pass hotplug action type to arch specific handler
> 
> v6
>   - Added crash memory hotplug support
> 
> v5:
>   - Replace COFNIG_CRASH_HOTPLUG with CONFIG_HOTPLUG_CPU.
>   - Move fdt segment identification for kexec_load case to load path
>     instead of crash hotplug handler
>   - Keep new attribute defined under kimage_arch to track FDT segment
>     under CONFIG_HOTPLUG_CPU config.
> 
> v4:
>   - Update the logic to find the additional space needed for hotadd CPUs
>     post kexec load. Refer "[RFC v4 PATCH 4/5] powerpc/crash hp: add crash
>     hotplug support for kexec_file_load" patch to know more about the
>     change.
>   - Fix a couple of typo.
>   - Replace pr_err to pr_info_once to warn user about memory hotplug
>     support.
>   - In crash hotplug handle exit the for loop if FDT segment is found.
> 
> v3
>   - Move fdt_index and fdt_index_vaild variables to kimage_arch struct.
>   - Rebase patche on top of
>     https://lore.kernel.org/lkml/20220303162725.49640-1-eric.devolder at oracle.com/
>   - Fixed warning reported by checpatch script
> 
> v2:
>   - Use generic hotplug handler introduced by
>     https://lore.kernel.org/lkml/20220209195706.51522-1-eric.devolder at oracle.com/
>     a significant change from v1.
> 
> Cc: Akhil Raj <lf32.dev at gmail.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: Aneesh Kumar K.V <aneesh.kumar at kernel.org>
> Cc: Baoquan He <bhe at redhat.com>
> Cc: Borislav Petkov (AMD) <bp at alien8.de>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: Christophe Leroy <christophe.leroy at csgroup.eu>
> Cc: Dave Hansen <dave.hansen at linux.intel.com>
> Cc: Dave Young <dyoung at redhat.com>
> Cc: David Hildenbrand <david at redhat.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: Laurent Dufour <laurent.dufour at fr.ibm.com>
> Cc: Mahesh Salgaonkar <mahesh at linux.ibm.com>
> Cc: Michael Ellerman <mpe at ellerman.id.au>
> Cc: Mimi Zohar <zohar at linux.ibm.com>
> Cc: Naveen N Rao <naveen at kernel.org>
> Cc: Oscar Salvador <osalvador at suse.de>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Valentin Schneider <vschneid at redhat.com>
> Cc: Vivek Goyal <vgoyal at redhat.com>
> Cc: kexec at lists.infradead.org
> Cc: x86 at kernel.org
> 
> Sourabh Jain (6):
>   crash: forward memory_notify arg to arch crash hotplug handler
>   crash: add a new kexec flag for hotplug support
>   powerpc/kexec: move *_memory_ranges functions to ranges.c
>   PowerPC/kexec: make the update_cpus_node() function public
>   powerpc/crash: add crash CPU hotplug support
>   powerpc/crash: add crash memory hotplug support
> 
>  arch/powerpc/Kconfig                    |   4 +
>  arch/powerpc/include/asm/kexec.h        |  15 ++
>  arch/powerpc/include/asm/kexec_ranges.h |  20 +-
>  arch/powerpc/kexec/Makefile             |   4 +-
>  arch/powerpc/kexec/core_64.c            |  91 +++++++
>  arch/powerpc/kexec/crash.c              | 196 +++++++++++++++
>  arch/powerpc/kexec/elf_64.c             |   3 +-
>  arch/powerpc/kexec/file_load_64.c       | 314 +++---------------------
>  arch/powerpc/kexec/ranges.c             | 312 ++++++++++++++++++++++-
>  arch/x86/include/asm/kexec.h            |  13 +-
>  arch/x86/kernel/crash.c                 |  32 ++-
>  drivers/base/cpu.c                      |   2 +-
>  drivers/base/memory.c                   |   2 +-
>  include/linux/crash_core.h              |  15 +-
>  include/linux/kexec.h                   |  11 +-
>  include/uapi/linux/kexec.h              |   1 +
>  kernel/crash_core.c                     |  29 +--
>  kernel/kexec.c                          |   4 +-
>  kernel/kexec_file.c                     |   5 +
>  19 files changed, 714 insertions(+), 359 deletions(-)
> 


From sourabhjain at linux.ibm.com  Sun Aug  4 21:30:49 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon, 5 Aug 2024 10:00:49 +0530
Subject: [PATCH v18 0/6] powerpc/crash: Kernel handling of CPU and memory
 hotplug
In-Reply-To: <50498549-f6c1-ce2c-b190-e9eedd1eb9ee@huawei.com>
References: <20240326055413.186534-1-sourabhjain@linux.ibm.com>
 <50498549-f6c1-ce2c-b190-e9eedd1eb9ee@huawei.com>
Message-ID: <3a8a2610-f8ed-4a90-87c1-397b08f9c27b@linux.ibm.com>

Hello Jinjie,

On 05/08/24 07:58, Jinjie Ruan wrote:
>
> On 2024/3/26 13:54, Sourabh Jain wrote:
>> Commit 247262756121 ("crash: add generic infrastructure for crash
>> hotplug support") added a generic infrastructure that allows
>> architectures to selectively update the kdump image component during CPU
>> or memory add/remove events within the kernel itself.
>>
>> This patch series adds crash hotplug handler for PowerPC and enable
>> support to update the kdump image on CPU/Memory add/remove events.
>>
>> Among the 6 patches in this series, the first two patches make changes
>> to the generic crash hotplug handler to assist PowerPC in adding support
>> for this feature. The last four patches add support for this feature.
>>
>> The following section outlines the problem addressed by this patch
>> series, along with the current solution, its shortcomings, and the
>> proposed resolution.
>>
>> Problem:
>> ========
>> Due to CPU/Memory hotplug or online/offline events the elfcorehdr
>> (which describes the CPUs and memory of the crashed kernel) and FDT
>> (Flattened Device Tree) of kdump image becomes outdated. Consequently,
>> attempting dump collection with an outdated elfcorehdr or FDT can lead
>> to failed or inaccurate dump collection.
> Hi, Sourabh, are there any specific methods to reproduce the scenarios
> for this feature? I would like to port this feature to ARM64, but I
> don't know how to reproduce the issue.

On PowerPC, this issue is reproducible if the kernel crashes after bulk CPU
or memory hotplug operations. Try the same on ARM64; you might be
able to reproduce the issue.

Note: I used to hotplug hundreds of LMBs (Logical Memory Blocks),
each with a size of 256 MB, to easily reproduce this issue.

To hotplug CPU and memory, I used to use a PowerPC-specific tool. You
may need to find one that is available for ARM64.

Along with fixing the problem mentioned above, this feature also
significantly reduces the kdump service downtime. How?

1. Handle the kdump image update on CPU/Memory hotplug events in
 ??? the kernel itself, without userspace intervention.

2. Only recreate/update the relevant kexec segment instead of reloading
 ???? all segments.

Thanks,
Sourabh Jain

>> Going forward CPU hotplug or online/offline events are referred as
>> CPU/Memory add/remove events.
>>
>> Existing solution and its shortcoming:
>> ======================================
>> The current solution to address the above issue involves monitoring the
>> CPU/memory add/remove events in userspace using udev rules and whenever
>> there are changes in CPU and memory resources, the entire kdump image
>> is loaded again. The kdump image includes kernel, initrd, elfcorehdr,
>> FDT, purgatory. Given that only elfcorehdr and FDT get outdated due to
>> CPU/Memory add/remove events, reloading the entire kdump image is
>> inefficient. More importantly, kdump remains inactive for a substantial
>> amount of time until the kdump reload completes.
>>
>> Proposed solution:
>> ==================
>> Instead of initiating a full kdump image reload from userspace on
>> CPU/Memory hotplug and online/offline events, the proposed solution aims
>> to update only the necessary kdump image component within the kernel
>> itself.
>>
>> Git tree for testing:
>> =====================
>> https://github.com/sourabhjains/linux/tree/kdump-in-kernel-crash-update-v18
>>
>> Above tree is rebased on top of powerpc/next branch.
>>
>> To realize this feature, the kdump udev rule must be updated. On RHEL,
>> add the following two lines at the top of the
>> "/usr/lib/udev/rules.d/98-kexec.rules" file.
>>
>> SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>> SUBSYSTEM=="memory", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>>
>> With the above change to the kdump udev rule, kdump reload is avoided
>> during CPU/Memory add/remove events if this feature is enabled in the
>> kernel.
>>
>> Note: only kexec_file_load syscall will work. For kexec_load minor changes
>> are required in kexec tool.
>>
>> Changelog:
>> ----------
>> v18: [No functional changes]
>>    - Update a comment in 2/6.
>>    - Describe the clean-up done on x86 in patch description 2/6.
>>    - Fix a minor typo in the patch description of 3/6.
>>
>> v17: [https://lore.kernel.org/all/20240226084118.16310-1-sourabhjain at linux.ibm.com/]
>>    - Rebase the patch series on top linux-next tree and below patch series
>>      https://lore.kernel.org/all/20240213113150.1148276-1-hbathini at linux.ibm.com/
>>    - Split 0003 patch from v16 into two patches
>>         1. Move get_crash_memory_ranges() along with other *_memory_ranges()
>>            functions to ranges.c and make them public.
>>         2. Make update_cpus_node function public and take this function
>>            out of file_load_64.c
>>    - Keep arch_crash_hotplug_support in crash.c instead of core_64.c [05/06]
>>    - Use CONFIG_CRASH_MAX_MEMORY_RANGES to find extra elfcorehdr size [06/06]
>>
>> v16: [https://lore.kernel.org/all/20240217081452.164571-1-sourabhjain at linux.ibm.com/]
>>    - Remove the unused #define `crash_hotplug_cpu_support`
>>      and `crash_hotplug_memory_support` in `arch/x86/include/asm/kexec.h`.
>>    - Document why two kexec flag bits are used in
>>      `arch_crash_hotplug_memory_support` (x86).
>>    - Use a switch case to handle different hotplug operations
>>      in `arch_crash_handle_hotplug_event` for PowerPC.
>>    - Fix a typo in 4/5.
>>
>> v15:
>>    - Remove the patch that adds a new kexec flag for FDT update.
>>    - Introduce a generic kexec flag bit to share hotplug support
>>      intent between the kexec tool and the kernel for the kexec_load
>>      syscall. (2/5)
>>    - Introduce an architecture-specific handler to process the kexec
>>      flag for crash hotplug support. (2/5)
>>    - Rename the @update_elfcorehdr member of the struct kimage to
>>      @hotplug_support. (2/5)
>>    - Use a common function to advertise hotplug support for both CPU
>>      and Memory. (2/5)
>>
>> v14:
>>    - Fix build warnings by including necessary header files
>>    - Rebase to v6.7-rc5
>>
>> v13:
>>    - Fix a build warning, take ranges.c out of CONFIG_KEXEC_FILE
>>    - Rebase to v6.7-rc4
>>
>> v12:
>>    - A patch to add new kexec flags to support this feature on kexec_load
>>      system call
>>    - Change in the way this feature is advertise to userspace for both
>>      kexec_load syscall
>>    - Rebase to v6.6-rc7
>>
>> v11:
>>    - Rebase to v6.4-rc6
>>    - The patch that introduced CONFIG_CRASH_HOTPLUG for PowerPC has been
>>      removed. The config is now part of common configuration:
>>      https://lore.kernel.org/all/87ilbpflsk.fsf at mail.lhotse/
>>
>> v10:
>>    - Drop the patch that adds fdt_index attribute to struct kimage_arch
>>      Find the fdt segment index when needed.
>>    - Added more details into commits messages.
>>    - Rebased onto 6.3.0-rc5
>>
>> v9:
>>    - Removed patch to prepare elfcorehdr crash notes for possible CPUs.
>>      The patch is moved to generic patch series that introduces generic
>>      infrastructure for in kernel crash update.
>>    - Removed patch to pass the hotplug action type to the arch crash
>>      hotplug handler function. The generic patch series has introduced
>>      the hotplug action type in kimage struct.
>>    - Add detail commit message for better understanding.
>>
>> v8:
>>    - Restrict fdt_index initialization to machine_kexec_post_load
>>      it work for both kexec_load and kexec_file_load.[3/8] Laurent Dufour
>>
>>    - Updated the logic to find the number of offline core. [6/8]
>>
>>    - Changed the logic to find the elfcore program header to accommodate
>>      future memory ranges due memory hotplug events. [8/8]
>>
>> v7
>>    - added a new config to configure this feature
>>    - pass hotplug action type to arch specific handler
>>
>> v6
>>    - Added crash memory hotplug support
>>
>> v5:
>>    - Replace COFNIG_CRASH_HOTPLUG with CONFIG_HOTPLUG_CPU.
>>    - Move fdt segment identification for kexec_load case to load path
>>      instead of crash hotplug handler
>>    - Keep new attribute defined under kimage_arch to track FDT segment
>>      under CONFIG_HOTPLUG_CPU config.
>>
>> v4:
>>    - Update the logic to find the additional space needed for hotadd CPUs
>>      post kexec load. Refer "[RFC v4 PATCH 4/5] powerpc/crash hp: add crash
>>      hotplug support for kexec_file_load" patch to know more about the
>>      change.
>>    - Fix a couple of typo.
>>    - Replace pr_err to pr_info_once to warn user about memory hotplug
>>      support.
>>    - In crash hotplug handle exit the for loop if FDT segment is found.
>>
>> v3
>>    - Move fdt_index and fdt_index_vaild variables to kimage_arch struct.
>>    - Rebase patche on top of
>>      https://lore.kernel.org/lkml/20220303162725.49640-1-eric.devolder at oracle.com/
>>    - Fixed warning reported by checpatch script
>>
>> v2:
>>    - Use generic hotplug handler introduced by
>>      https://lore.kernel.org/lkml/20220209195706.51522-1-eric.devolder at oracle.com/
>>      a significant change from v1.
>>
>> Cc: Akhil Raj <lf32.dev at gmail.com>
>> Cc: Andrew Morton <akpm at linux-foundation.org>
>> Cc: Aneesh Kumar K.V <aneesh.kumar at kernel.org>
>> Cc: Baoquan He <bhe at redhat.com>
>> Cc: Borislav Petkov (AMD) <bp at alien8.de>
>> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
>> Cc: Christophe Leroy <christophe.leroy at csgroup.eu>
>> Cc: Dave Hansen <dave.hansen at linux.intel.com>
>> Cc: Dave Young <dyoung at redhat.com>
>> Cc: David Hildenbrand <david at redhat.com>
>> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
>> Cc: Hari Bathini <hbathini at linux.ibm.com>
>> Cc: Laurent Dufour <laurent.dufour at fr.ibm.com>
>> Cc: Mahesh Salgaonkar <mahesh at linux.ibm.com>
>> Cc: Michael Ellerman <mpe at ellerman.id.au>
>> Cc: Mimi Zohar <zohar at linux.ibm.com>
>> Cc: Naveen N Rao <naveen at kernel.org>
>> Cc: Oscar Salvador <osalvador at suse.de>
>> Cc: Thomas Gleixner <tglx at linutronix.de>
>> Cc: Valentin Schneider <vschneid at redhat.com>
>> Cc: Vivek Goyal <vgoyal at redhat.com>
>> Cc: kexec at lists.infradead.org
>> Cc: x86 at kernel.org
>>
>> Sourabh Jain (6):
>>    crash: forward memory_notify arg to arch crash hotplug handler
>>    crash: add a new kexec flag for hotplug support
>>    powerpc/kexec: move *_memory_ranges functions to ranges.c
>>    PowerPC/kexec: make the update_cpus_node() function public
>>    powerpc/crash: add crash CPU hotplug support
>>    powerpc/crash: add crash memory hotplug support
>>
>>   arch/powerpc/Kconfig                    |   4 +
>>   arch/powerpc/include/asm/kexec.h        |  15 ++
>>   arch/powerpc/include/asm/kexec_ranges.h |  20 +-
>>   arch/powerpc/kexec/Makefile             |   4 +-
>>   arch/powerpc/kexec/core_64.c            |  91 +++++++
>>   arch/powerpc/kexec/crash.c              | 196 +++++++++++++++
>>   arch/powerpc/kexec/elf_64.c             |   3 +-
>>   arch/powerpc/kexec/file_load_64.c       | 314 +++---------------------
>>   arch/powerpc/kexec/ranges.c             | 312 ++++++++++++++++++++++-
>>   arch/x86/include/asm/kexec.h            |  13 +-
>>   arch/x86/kernel/crash.c                 |  32 ++-
>>   drivers/base/cpu.c                      |   2 +-
>>   drivers/base/memory.c                   |   2 +-
>>   include/linux/crash_core.h              |  15 +-
>>   include/linux/kexec.h                   |  11 +-
>>   include/uapi/linux/kexec.h              |   1 +
>>   kernel/crash_core.c                     |  29 +--
>>   kernel/kexec.c                          |   4 +-
>>   kernel/kexec_file.c                     |   5 +
>>   19 files changed, 714 insertions(+), 359 deletions(-)
>>



From sourabhjain at linux.ibm.com  Sun Aug  4 22:08:29 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon,  5 Aug 2024 10:38:29 +0530
Subject: [PATCH] Document/kexec: Generalize crash hotplug description
Message-ID: <20240805050829.297171-1-sourabhjain@linux.ibm.com>

Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
generalizes the crash hotplug support to allow architectures to update
multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
Therefore, update the relevant kernel documentation to reflect the same.

No functional change.

Cc: Petr Tesarik <petr at tesarici.cz>
Cc: Hari Bathini <hbathini at linux.ibm.com>
Cc: kexec at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: x86 at kernel.org
Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
---

Discussion about the documentation update:
https://lore.kernel.org/all/68d0328d-531a-4a2b-ab26-c97fd8a12e8b at linux.ibm.com/

---
 .../ABI/testing/sysfs-devices-memory          |  6 ++--
 .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
 .../admin-guide/mm/memory-hotplug.rst         |  5 ++--
 Documentation/core-api/cpu_hotplug.rst        | 10 ++++---
 kernel/crash_core.c                           | 29 ++++++++++++-------
 5 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
index a95e0f17c35a..421acc8e2c6b 100644
--- a/Documentation/ABI/testing/sysfs-devices-memory
+++ b/Documentation/ABI/testing/sysfs-devices-memory
@@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
 Date:		Aug 2023
 Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
 Description:
-		(RO) indicates whether or not the kernel directly supports
-		modifying the crash elfcorehdr for memory hot un/plug and/or
-		on/offline changes.
+		(RO) indicates whether or not the kernel update of kexec
+		segments on memory hot un/plug and/or on/offline events,
+		avoiding the need to reload kdump kernel.
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 325873385b71..f4ada1cd2f96 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
 Date:		Aug 2023
 Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
 Description:
-		(RO) indicates whether or not the kernel directly supports
-		modifying the crash elfcorehdr for CPU hot un/plug and/or
-		on/offline changes.
+		(RO) indicates whether or not the kernel update of kexec
+		segments on CPU hot un/plug and/or on/offline events,
+		avoiding the need to reload kdump kernel.
 
 What:		/sys/devices/system/cpu/enabled
 Date:		Nov 2022
diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
index 098f14d83e99..cb2c080f400c 100644
--- a/Documentation/admin-guide/mm/memory-hotplug.rst
+++ b/Documentation/admin-guide/mm/memory-hotplug.rst
@@ -294,8 +294,9 @@ The following files are currently defined:
 ``crash_hotplug``      read-only: when changes to the system memory map
 		       occur due to hot un/plug of memory, this file contains
 		       '1' if the kernel updates the kdump capture kernel memory
-		       map itself (via elfcorehdr), or '0' if userspace must update
-		       the kdump capture kernel memory map.
+		       map itself (via elfcorehdr and other relevant kexec
+		       segments), or '0' if userspace must update the kdump
+		       capture kernel memory map.
 
 		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
 		       configuration option.
diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
index dcb0e379e5e8..a21dbf261be7 100644
--- a/Documentation/core-api/cpu_hotplug.rst
+++ b/Documentation/core-api/cpu_hotplug.rst
@@ -737,8 +737,9 @@ can process the event further.
 
 When changes to the CPUs in the system occur, the sysfs file
 /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
-updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
-or '0' if userspace must update the kdump capture kernel list of CPUs.
+updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
+other relevant kexec segment), or '0' if userspace must update the kdump
+capture kernel list of CPUs.
 
 The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
 option.
@@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
  SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
 
 For a CPU hot un/plug event, if the architecture supports kernel updates
-of the elfcorehdr (which contains the list of CPUs), then the rule skips
-the unload-then-reload of the kdump capture kernel.
+of the elfcorehdr (which contains the list of CPUs) and other relevant
+kexec segments, then the rule skips the unload-then-reload of the kdump
+capture kernel.
 
 Kernel Inline Documentations Reference
 ======================================
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 63cf89393c6e..64dad01e260b 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
 }
 
 /*
- * To accurately reflect hot un/plug changes of cpu and memory resources
- * (including onling and offlining of those resources), the elfcorehdr
- * (which is passed to the crash kernel via the elfcorehdr= parameter)
- * must be updated with the new list of CPUs and memories.
+ * To accurately reflect hot un/plug changes of CPU and Memory resources
+ * (including onling and offlining of those resources), the relevant
+ * kexec segments must be updated with latest CPU and Memory resources.
  *
- * In order to make changes to elfcorehdr, two conditions are needed:
- * First, the segment containing the elfcorehdr must be large enough
- * to permit a growing number of resources; the elfcorehdr memory size
- * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
- * Second, purgatory must explicitly exclude the elfcorehdr from the
- * list of segments it checks (since the elfcorehdr changes and thus
- * would require an update to purgatory itself to update the digest).
+ * Architectures must ensure two things for all segments that need
+ * updating during hotplug events:
+ *
+ * 1. Segments must be large enough to accommodate a growing number of
+ *    resources.
+ * 2. Exclude the segments from SHA verification.
+ *
+ * For example, on most architectures, the elfcorehdr (which is passed
+ * to the crash kernel via the elfcorehdr= parameter) must include the
+ * new list of CPUs and memory. To make changes to the elfcorehdr, it
+ * should be large enough to permit a growing number of CPU and Memory
+ * resources. One can estimate the elfcorehdr memory size based on
+ * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
+ * excluded from SHA verification by default if the architecture
+ * supports crash hotplug.
  */
 static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
 {
-- 
2.45.2



From jbeulich at suse.com  Sun Aug  4 23:01:33 2024
From: jbeulich at suse.com (Jan Beulich)
Date: Mon, 5 Aug 2024 08:01:33 +0200
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <dc5c9dff-6bee-493a-8315-b2eee48bd802@yahoo.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
 <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
 <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>
 <dc5c9dff-6bee-493a-8315-b2eee48bd802@yahoo.com>
Message-ID: <18032298-e535-4405-890e-6ab9d54cf7e3@suse.com>

On 04.08.2024 15:17, A Kundu wrote:
> On 8/2/24 13:25, Jan Beulich wrote:
>  > On 02.08.2024 09:28, A Kundu wrote:
>  >> On 8/2/24 09:06, Baoquan He wrote:
>  >>> On 07/31/24 at 06:34pm, A Kundu wrote:
>  >>>> I am experiencing issues using kexec to load Xen 4.17(debian's apt 
> version),
>  >>>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from 
> source) on a
>  >>>> debian host.
>  >>> You should CC this to XEN dev list so that XEN dev knows this and may
>  >>> provide help. Not everyone is interested in and knows XEN.
>  >>>
>  >>>> System information:
>  >>>> $ uname -a
>  >>>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1 
> (2024-07-19)
>  >>>> x86_64 GNU/Linux
>  >>>>
>  >>>> $ kexec --version # compiled from source tarball with ./configure 
> --with-xen
>  >>>> kexec-tools 2.0.29
>  >>>>
>  >>>> Steps to reproduce:
>  >>>>
>  >>>> 1. Set variables:
>  >>>>
>  >>>> XEN_HYPERVISOR="/boot/xen.gz"
>  >>>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
>  >>>>
>  >>>> 2. Attempt to load Xen 4.19-rc4:
>  >>>>
>  >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>  >>>> Could not find a free area of memory of 0x3b6001 bytes...
>  >>>> elf_exec_build_load_relocatable: ELF exec load failed
>  >>>>
>  >>>> 3. Attempt to load Xen 4.20-dev:
>  >>>>
>  >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>  >>>> Could not find a free area of memory of 0x3f8001 bytes...
>  >>>> elf_exec_build_load_relocatable: ELF exec load failed
>  >>>>
>  >>>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
>  >>>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
>  >>>> Could not find a free area of memory of 0x3b4001 bytes...
>  >>>> elf_exec_build_load_relocatable: ELF exec load failed
>  >
>  > And with all of them saying effectively the same, did you verify you
>  > actually have a sufficiently large area reserved? The obvious
>  > place for you to look at is Xen's boot log (obtained via serial
>  > console or "xl dmesg" immediately after booting the system). If you
>  > find everything as expected there, ...
>  >
>  >>>> If you need any further information to investigate this problem,
>  >>>> please let me know.
>  >
>  > ... please provide that boot log.
> 
> I have also followed up on your suggestion to check the Xen boot log
> using "xl dmesg", but unfortunately, I received the following error:
> 
> xencall: error: Could not obtain handle on privileged command interface: 
> No such file or directory
> libxl: error: libxl.c:102:libxl_ctx_alloc: cannot open libxc handle: No 
> such file or directory
> cannot init xl context
> 
> This indicates that Xen did not boot successfully, so there are no logs
> available.

The fact that you have Dom0 up makes clear that Xen booted okay(ish). The
fact that you get "No such file or directory" from xencall suggests you
either didn't load the xen-privcmd driver (normally arrangements are made
by distros for this to happen automatically), or you didn't even build it.

>  > And with all of them saying effectively the same, did you verify you
>  > actually have a sufficiently large area reserved? The obvious
>  > place for you to look at is Xen's boot log (obtained via serial
>  > console or "xl dmesg" immediately after booting the system). If you
>  > find everything as expected there, ...
>  >
> 
> In an attempt to resolve the memory allocation issue, I have tried the
> following:
> 
> Added a crashkernel=<size>@<offset> parameter to the host kernel command
> line to reserve a dedicated memory region for kexec, and attempted to
> load Xen into that area.

That was a remote guess of mine. This command line option is meaningless
when running under Xen. The reservation needs to be done in Xen.

Overall for the moment I'm inclined to say that xen-devel@ isn't the right
forum here. xen-users@ might be quite a bit more appropriate until you
actually run into issues with Xen itself, not with its (correct) use.

Jan


From linus.walleij at linaro.org  Mon Aug  5 00:14:40 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 5 Aug 2024 09:14:40 +0200
Subject: [PATCH 2/3] ARM: Fix crash kenrel data type bug
In-Reply-To: <20240708133348.3592667-3-ruanjinjie@huawei.com>
References: <20240708133348.3592667-1-ruanjinjie@huawei.com> <20240708133348.3592667-3-ruanjinjie@huawei.com>
Message-ID: <CACRpkda+ZqXXbvXBotNbpK39_ghtY77AVi_bGLYMn2r_r-X6-Q@mail.gmail.com>

On Mon, Jul 8, 2024 at 3:29?PM Jinjie Ruan <ruanjinjie at huawei.com> wrote:

> On QEMU vexpress-a9 with 1GB memory, the crash kernel "crashkernel=4G"
> is ok as below:
>         Reserving 4096MB of memory at 2432MB for crashkernel (System RAM: 1024MB)
>
> The above info is confusing, because the System memory is as below:
>         # cat /proc/iomem | grep Sys
>         60000000-9fffffff : System RAM
>
> The cause is that the crash_size is parsed and printed with "unsigned long
> long" data type which is 8 bytes but used with "phys_addr_t" which is
> 4 bytes in memblock_phys_alloc_range().

Is that the whole explanation?

>         /* invalid value specified or crashkernel=0 */
> +       crash_size = (phys_addr_t)crash_size;
>         if (ret || !crash_size)
>                 return;

How did crash_size get assigned before you added this oneliner?

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Aug  5 00:15:56 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 5 Aug 2024 09:15:56 +0200
Subject: [PATCH 1/3] crash: Fix memory reserve dead loop bug in reserve_crashkernel_generic()
In-Reply-To: <20240708133348.3592667-2-ruanjinjie@huawei.com>
References: <20240708133348.3592667-1-ruanjinjie@huawei.com> <20240708133348.3592667-2-ruanjinjie@huawei.com>
Message-ID: <CACRpkdbY-Lp7_AyqvLnQCFYkaazsmMGSHY5K85oJRNmPgM_yVA@mail.gmail.com>

On Mon, Jul 8, 2024 at 3:30?PM Jinjie Ruan <ruanjinjie at huawei.com> wrote:

> If the platform do not support memory above 4G, such as 32 bit arch,
> and CRASH_ADDR_LOW_MAX is equal to CRASH_ADDR_HIGH_MAX, the high
> crash kernel memory reservation is meaningless and it will cause
> dead loop and system stall:
>
> -> reserve_crashkernel_generic() and high is true
>  -> memblock_phys_alloc_range() fail and return 0
>     -> search_end = CRASH_ADDR_LOW_MAX(same as CRASH_ADDR_HIGH_MAX)
>        -> call memblock_phys_alloc_range() again and fail agin.
>           -> search_end == CRASH_ADDR_HIGH_MAX satisfy again
>         ......
>
> However, the current check only considers the case where
> CRASH_ADDR_HIGH_MAX is greater than CRASH_ADDR_LOW_MAX. Fix it.
>
> Fixes: 0ab97169aa05 ("crash_core: add generic function to do reservation")
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>

Looks good to me:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From julien.keller at vectorspeedbiz.com  Mon Aug  5 00:41:00 2024
From: julien.keller at vectorspeedbiz.com (Julien Keller)
Date: Mon,  5 Aug 2024 07:41:00 GMT
Subject: Mobile Phone Wholesale
Message-ID: <20240805084500-0.1.4p.3d2p.0.nxfgerf3ft@vectorspeedbiz.com>

Good morning, 

As a wholesaler of GSM mobile phones and accessories, we offer smartphones such as Motorola, Google, Honor, OnePlus, Oppo, POCO, Samsung and Xiaomi. 

By eliminating intermediaries, we provide truly competitive prices.

All phones are in stock and ready for immediate shipment. We guarantee delivery within 48 hours.

If you are interested in cooperation or have questions, please reply to this e-mail address.


Best regards
Julien Keller


From linus.walleij at linaro.org  Mon Aug  5 00:51:56 2024
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 5 Aug 2024 09:51:56 +0200
Subject: [PATCH v3 3/3] ARM: Use generic interface to simplify crashkernel reservation
In-Reply-To: <20240718035444.2977105-4-ruanjinjie@huawei.com>
References: <20240718035444.2977105-1-ruanjinjie@huawei.com> <20240718035444.2977105-4-ruanjinjie@huawei.com>
Message-ID: <CACRpkdaJLBt8-c_f4Q3_nLdB_7hZE9Pv5LiX0ObiycXZcj9j0g@mail.gmail.com>

On Thu, Jul 18, 2024 at 5:51?AM Jinjie Ruan <ruanjinjie at huawei.com> wrote:

> Currently, x86, arm64, riscv and loongarch has been switched to generic
> crashkernel reservation, which is also ready for 32bit system.
> So with the help of function parse_crashkernel() and generic
> reserve_crashkernel_generic(), arm32 crashkernel reservation can also
> be simplified by steps:
>
> 1) Add a new header file <asm/crash_reserve.h>, and define CRASH_ALIGN,
>    CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX in it;
>
> 2) Add arch_reserve_crashkernel() to call parse_crashkernel() and
>    reserve_crashkernel_generic();
>
> 3) Add ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION Kconfig in
>    arch/arm/Kconfig.
>
> The old reserve_crashkernel() can be removed.
>
> Following test cases have been performed as expected on QEMU vexpress-a9
> (1GB system memory):
>
> 1) crashkernel=4G,high                          // invalid
> 2) crashkernel=1G,high                          // invalid
> 3) crashkernel=1G,high crashkernel=0M,low       // invalid
> 4) crashkernel=256M,high                        // invalid
> 5) crashkernel=256M,low                         // invalid
> 6) crashkernel=256M crashkernel=256M,high       // high is ignored, ok
> 7) crashkernel=256M crashkernel=256M,low        // low is ignored, ok
> 8) crashkernel=256M,high crashkernel=256M,low   // invalid
> 9) crashkernel=256M,high crashkernel=4G,low     // invalid
> 10) crashkernel=256M                            // ok
> 11) crashkernel=512M                            // ok
> 12) crashkernel=256M at 0x88000000                 // ok
> 13) crashkernel=256M at 0x78000000                 // ok
> 14) crashkernel=512M at 0x78000000                 // ok
>
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> Tested-by: Jinjie Ruan <ruanjinjie at huawei.com>
> ---
> v3:
> - Update the commit message.

I haven't used crash much but it looks right to my untrained eye.
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From jgross at suse.com  Mon Aug  5 00:52:37 2024
From: jgross at suse.com (Juergen Gross)
Date: Mon, 5 Aug 2024 09:52:37 +0200
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <18032298-e535-4405-890e-6ab9d54cf7e3@suse.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
 <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
 <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>
 <dc5c9dff-6bee-493a-8315-b2eee48bd802@yahoo.com>
 <18032298-e535-4405-890e-6ab9d54cf7e3@suse.com>
Message-ID: <74bac0d8-de7a-41df-87ed-b7e2d4140ade@suse.com>

On 05.08.24 08:01, Jan Beulich wrote:
> On 04.08.2024 15:17, A Kundu wrote:
>> On 8/2/24 13:25, Jan Beulich wrote:
>>   > On 02.08.2024 09:28, A Kundu wrote:
>>   >> On 8/2/24 09:06, Baoquan He wrote:
>>   >>> On 07/31/24 at 06:34pm, A Kundu wrote:
>>   >>>> I am experiencing issues using kexec to load Xen 4.17(debian's apt
>> version),
>>   >>>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from
>> source) on a
>>   >>>> debian host.
>>   >>> You should CC this to XEN dev list so that XEN dev knows this and may
>>   >>> provide help. Not everyone is interested in and knows XEN.
>>   >>>
>>   >>>> System information:
>>   >>>> $ uname -a
>>   >>>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1
>> (2024-07-19)
>>   >>>> x86_64 GNU/Linux
>>   >>>>
>>   >>>> $ kexec --version # compiled from source tarball with ./configure
>> --with-xen
>>   >>>> kexec-tools 2.0.29
>>   >>>>
>>   >>>> Steps to reproduce:
>>   >>>>
>>   >>>> 1. Set variables:
>>   >>>>
>>   >>>> XEN_HYPERVISOR="/boot/xen.gz"
>>   >>>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
>>   >>>>
>>   >>>> 2. Attempt to load Xen 4.19-rc4:
>>   >>>>
>>   >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>   >>>> Could not find a free area of memory of 0x3b6001 bytes...
>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>   >>>>
>>   >>>> 3. Attempt to load Xen 4.20-dev:
>>   >>>>
>>   >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>   >>>> Could not find a free area of memory of 0x3f8001 bytes...
>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>   >>>>
>>   >>>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
>>   >>>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
>>   >>>> Could not find a free area of memory of 0x3b4001 bytes...
>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>   >
>>   > And with all of them saying effectively the same, did you verify you
>>   > actually have a sufficiently large area reserved? The obvious
>>   > place for you to look at is Xen's boot log (obtained via serial
>>   > console or "xl dmesg" immediately after booting the system). If you
>>   > find everything as expected there, ...
>>   >
>>   >>>> If you need any further information to investigate this problem,
>>   >>>> please let me know.
>>   >
>>   > ... please provide that boot log.
>>
>> I have also followed up on your suggestion to check the Xen boot log
>> using "xl dmesg", but unfortunately, I received the following error:
>>
>> xencall: error: Could not obtain handle on privileged command interface:
>> No such file or directory
>> libxl: error: libxl.c:102:libxl_ctx_alloc: cannot open libxc handle: No
>> such file or directory
>> cannot init xl context
>>
>> This indicates that Xen did not boot successfully, so there are no logs
>> available.
> 
> The fact that you have Dom0 up makes clear that Xen booted okay(ish). The
> fact that you get "No such file or directory" from xencall suggests you
> either didn't load the xen-privcmd driver (normally arrangements are made
> by distros for this to happen automatically), or you didn't even build it.

The messages seen don't indicate that Xen booted okay(ish). I get the same
messages when having booted the Linux kernel on bare metal without Xen.

> 
>>   > And with all of them saying effectively the same, did you verify you
>>   > actually have a sufficiently large area reserved? The obvious
>>   > place for you to look at is Xen's boot log (obtained via serial
>>   > console or "xl dmesg" immediately after booting the system). If you
>>   > find everything as expected there, ...
>>   >
>>
>> In an attempt to resolve the memory allocation issue, I have tried the
>> following:
>>
>> Added a crashkernel=<size>@<offset> parameter to the host kernel command
>> line to reserve a dedicated memory region for kexec, and attempted to
>> load Xen into that area.
> 
> That was a remote guess of mine. This command line option is meaningless
> when running under Xen. The reservation needs to be done in Xen.

Just one thing to add here: what do you want to accomplish by kexec-ing into
Xen? You need to specify a dom0 kernel and probably the dom0's initrd, too.

Or do you have configured your dom0 to work without an initrd? Even in this
case you'd need to pass on the dom0 to Xen via the kexec command.


Juergen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xB0DE9DD628BF132F.asc
Type: application/pgp-keys
Size: 3683 bytes
Desc: OpenPGP public key
URL: <http://lists.infradead.org/pipermail/kexec/attachments/20240805/ce3605e9/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/kexec/attachments/20240805/ce3605e9/attachment-0001.sig>

From jbeulich at suse.com  Mon Aug  5 01:13:22 2024
From: jbeulich at suse.com (Jan Beulich)
Date: Mon, 5 Aug 2024 10:13:22 +0200
Subject: kexec failure with Xen 4.19-rc4 and 4.20-dev on linux host
In-Reply-To: <74bac0d8-de7a-41df-87ed-b7e2d4140ade@suse.com>
References: <05395ed2-3bf3-4926-8e24-c2e7ff37ed26@yahoo.com>
 <cebc7800-df78-4f90-9f8e-82e3f9120b6e@yahoo.com>
 <ZqxUMgcEHakeFPaU@MiWiFi-R3L-srv>
 <abaceb99-4b80-49d7-ab7f-b190f73e858d@yahoo.com>
 <ac57dec1-68a3-471d-8f4c-c87fd9dca619@suse.com>
 <dc5c9dff-6bee-493a-8315-b2eee48bd802@yahoo.com>
 <18032298-e535-4405-890e-6ab9d54cf7e3@suse.com>
 <74bac0d8-de7a-41df-87ed-b7e2d4140ade@suse.com>
Message-ID: <ee4d05f4-f533-4f03-99ba-65ddefa54d82@suse.com>

On 05.08.2024 09:52, Juergen Gross wrote:
> On 05.08.24 08:01, Jan Beulich wrote:
>> On 04.08.2024 15:17, A Kundu wrote:
>>> On 8/2/24 13:25, Jan Beulich wrote:
>>>   > On 02.08.2024 09:28, A Kundu wrote:
>>>   >> On 8/2/24 09:06, Baoquan He wrote:
>>>   >>> On 07/31/24 at 06:34pm, A Kundu wrote:
>>>   >>>> I am experiencing issues using kexec to load Xen 4.17(debian's apt
>>> version),
>>>   >>>> Xen 4.19-rc4 (compiled from source) and 4.20-dev (compiled from
>>> source) on a
>>>   >>>> debian host.
>>>   >>> You should CC this to XEN dev list so that XEN dev knows this and may
>>>   >>> provide help. Not everyone is interested in and knows XEN.
>>>   >>>
>>>   >>>> System information:
>>>   >>>> $ uname -a
>>>   >>>> Linux host 6.9.10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.9.10-1
>>> (2024-07-19)
>>>   >>>> x86_64 GNU/Linux
>>>   >>>>
>>>   >>>> $ kexec --version # compiled from source tarball with ./configure
>>> --with-xen
>>>   >>>> kexec-tools 2.0.29
>>>   >>>>
>>>   >>>> Steps to reproduce:
>>>   >>>>
>>>   >>>> 1. Set variables:
>>>   >>>>
>>>   >>>> XEN_HYPERVISOR="/boot/xen.gz"
>>>   >>>> XEN_CMD="dom0_mem=6G dom0_max_vcpus=6 dom0_vcpus_pin cpufreq=xen"
>>>   >>>>
>>>   >>>> 2. Attempt to load Xen 4.19-rc4:
>>>   >>>>
>>>   >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>>   >>>> Could not find a free area of memory of 0x3b6001 bytes...
>>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>>   >>>>
>>>   >>>> 3. Attempt to load Xen 4.20-dev:
>>>   >>>>
>>>   >>>> # kexec -l "$XEN_HYPERVISOR" --command-line="$XEN_CMD"
>>>   >>>> Could not find a free area of memory of 0x3f8001 bytes...
>>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>>   >>>>
>>>   >>>> 4. Attempt to load Xen 4.17 (from debian rrepositories):
>>>   >>>> # kexec -l /boot/xen-4.17-amd64.gz --command-line="$XEN_CMD"
>>>   >>>> Could not find a free area of memory of 0x3b4001 bytes...
>>>   >>>> elf_exec_build_load_relocatable: ELF exec load failed
>>>   >
>>>   > And with all of them saying effectively the same, did you verify you
>>>   > actually have a sufficiently large area reserved? The obvious
>>>   > place for you to look at is Xen's boot log (obtained via serial
>>>   > console or "xl dmesg" immediately after booting the system). If you
>>>   > find everything as expected there, ...
>>>   >
>>>   >>>> If you need any further information to investigate this problem,
>>>   >>>> please let me know.
>>>   >
>>>   > ... please provide that boot log.
>>>
>>> I have also followed up on your suggestion to check the Xen boot log
>>> using "xl dmesg", but unfortunately, I received the following error:
>>>
>>> xencall: error: Could not obtain handle on privileged command interface:
>>> No such file or directory
>>> libxl: error: libxl.c:102:libxl_ctx_alloc: cannot open libxc handle: No
>>> such file or directory
>>> cannot init xl context
>>>
>>> This indicates that Xen did not boot successfully, so there are no logs
>>> available.
>>
>> The fact that you have Dom0 up makes clear that Xen booted okay(ish). The
>> fact that you get "No such file or directory" from xencall suggests you
>> either didn't load the xen-privcmd driver (normally arrangements are made
>> by distros for this to happen automatically), or you didn't even build it.
> 
> The messages seen don't indicate that Xen booted okay(ish). I get the same
> messages when having booted the Linux kernel on bare metal without Xen.

Hmm, I didn't even think of this as a possible case, considering the question
was forwarded to xen-devel (from a kexec list). I'm afraid Xen simply plays
no role when setting up kexec (to whatever target) from a bare metal env.

Jan


From petr.tesarik at suse.com  Mon Aug  5 08:07:50 2024
From: petr.tesarik at suse.com (Petr Tesarik)
Date: Mon,  5 Aug 2024 17:07:50 +0200
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y
Message-ID: <20240805150750.170739-1-petr.tesarik@suse.com>

From: Petr Tesarik <ptesarik at suse.com>

Fix the condition to exclude the elfcorehdr segment from the SHA digest
calculation.

The j iterator is an index into the output sha_regions[] array, not into
the input image->segment[] array. Once it reaches image->elfcorehdr_index,
all subsequent segments are excluded. Besides, if the purgatory segment
precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
the calculation.

Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
Cc: stable at kernel.org
Signed-off-by: Petr Tesarik <ptesarik at suse.com>
---
 kernel/kexec_file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 3d64290d24c9..3eedb8c226ad 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
 
 #ifdef CONFIG_CRASH_HOTPLUG
 		/* Exclude elfcorehdr segment to allow future changes via hotplug */
-		if (j == image->elfcorehdr_index)
+		if (i == image->elfcorehdr_index)
 			continue;
 #endif
 
-- 
2.45.2



From petr.tesarik at suse.com  Mon Aug  5 08:17:20 2024
From: petr.tesarik at suse.com (Petr Tesarik)
Date: Mon, 5 Aug 2024 17:17:20 +0200
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <20240805150750.170739-1-petr.tesarik@suse.com>
References: <20240805150750.170739-1-petr.tesarik@suse.com>
Message-ID: <20240805171720.3b661180@mordecai.tesarici.cz>

+Cc Eric DeVolder (current email address)

On Mon,  5 Aug 2024 17:07:50 +0200
Petr Tesarik <petr.tesarik at suse.com> wrote:

> From: Petr Tesarik <ptesarik at suse.com>
> 
> Fix the condition to exclude the elfcorehdr segment from the SHA digest
> calculation.
> 
> The j iterator is an index into the output sha_regions[] array, not into
> the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> all subsequent segments are excluded. Besides, if the purgatory segment
> precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> the calculation.
> 
> Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> Cc: stable at kernel.org
> Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> ---
>  kernel/kexec_file.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 3d64290d24c9..3eedb8c226ad 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
>  
>  #ifdef CONFIG_CRASH_HOTPLUG
>  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> -		if (j == image->elfcorehdr_index)
> +		if (i == image->elfcorehdr_index)
>  			continue;
>  #endif
>  



From bhe at redhat.com  Mon Aug  5 15:59:35 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 6 Aug 2024 06:59:35 +0800
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <20240805150750.170739-1-petr.tesarik@suse.com>
References: <20240805150750.170739-1-petr.tesarik@suse.com>
Message-ID: <ZrFZM4W7S89VpfaG@MiWiFi-R3L-srv>

On 08/05/24 at 05:07pm, Petr Tesarik wrote:
> From: Petr Tesarik <ptesarik at suse.com>
> 
> Fix the condition to exclude the elfcorehdr segment from the SHA digest
> calculation.
> 
> The j iterator is an index into the output sha_regions[] array, not into
> the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> all subsequent segments are excluded. Besides, if the purgatory segment
> precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> the calculation.

Indeed, good catch.

Acked-by: Baoquan He <bhe at redhat.com>

> 
> Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> Cc: stable at kernel.org
> Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> ---
>  kernel/kexec_file.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 3d64290d24c9..3eedb8c226ad 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
>  
>  #ifdef CONFIG_CRASH_HOTPLUG
>  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> -		if (j == image->elfcorehdr_index)
> +		if (i == image->elfcorehdr_index)
>  			continue;
>  #endif
>  
> -- 
> 2.45.2
> 



From yamazaki-msmt at nec.com  Tue Aug  6 02:02:22 2024
From: yamazaki-msmt at nec.com (=?utf-8?B?WUFNQVpBS0kgTUFTQU1JVFNVKOWxseW0juOAgOecn+WFiSk=?=)
Date: Tue, 6 Aug 2024 09:02:22 +0000
Subject: [PATCH makedumpfile] makedumpfile: make reserve_diskspace do
 nothing for flattened format
In-Reply-To: <5b665470-182f-4414-8a9b-b1ebf5337b2c@nec.com>
References: <ZnLJOTWFM5P1PTMf@dwarf.suse.cz>
 <5b665470-182f-4414-8a9b-b1ebf5337b2c@nec.com>
Message-ID: <99a146b3-bf8d-4de2-9d9c-0abcc705b3a6@nec.com>


On 2024/07/19 17:00, HAGIO KAZUHITO(?? ??) wrote:
> Hi Jiri,
>
> sorry for the long delay.
>
> On 2024/06/19 21:04, Jiri Bohac wrote:
>> makedumpfile: make reserve_diskspace do nothing for flattened format
>>
>> reserve_diskspace() is called by write_elf_header() to make sure there is
>> always space to write the program header, even if writing other data fails
>> because of ENOSPC.
>>
>> This is harmful when writing the flattened format to STDOUT for two reasons:
>>
>> First, it actually wastes disk space, because first the block of zeroes is sent
>> to STDOUT by reserve_diskspace() and then the actual program header is sent,
>> meant to overwrite the zeroes when the flattened format is rearranged.
>>
>> Second, the algorithm used to read flattened format directly by the crash
>> program does not cope with the flattened file containing two chunks meant for
>> the same offset. It uses a binary search on a sorted array of flat_data headers
>> to find the data in the flat file. It may return the zeroed chunk written by
>> reserve_diskspace() near the beginning of the file instead of the actual ELF
>> header located near the end of the flattened file.
> Thank you for the patch, I found a vmcore that reproduced the issue:
>
> $ makedumpfile -FEd 31 vmcore > dump.FEd31
> $ crash vmlinux dump.FEd31
> ...
> realloc: No such file or directory
> cannot realloc resized ELF header buffer
> $
>
> and the patch fixed this, so
>
> Acked-by: Kazuhito Hagio <k-hagio-ab at nec.com>
>
> (Masa will apply the patch, please wait for a while.)
>
> Thanks,
> Kazu
>
>
>> Fixes: e39216fce9f73759509ec158e39c289e6c211125 ("Make the incomplete dumpfile generated by ENOSPC error analyzable.")
>> Signed-off-by: Jiri Bohac <jbohac at suse.cz>
>>
>> ---
>>    makedumpfile.c | 3 +++
>>    1 file changed, 3 insertions(+)
>>
>> diff --git a/makedumpfile.c b/makedumpfile.c
>> index cadc596..9624c3f 100644
>> --- a/makedumpfile.c
>> +++ b/makedumpfile.c
>> @@ -5206,6 +5206,9 @@ reserve_diskspace(int fd, off_t start_offset, off_t end_offset, char *file_name)
>>    
>>    	int ret = FALSE;
>>    
>> +	if (info->flag_flatten)
>> +		return TRUE;
>> +
>>    	assert(start_offset < end_offset);
>>    	buf_size = end_offset - start_offset;
>>    
Thank you, Jiri, for the patch. Sorry for the late apply the patch.

https://github.com/makedumpfile/makedumpfile/commit/c76301277552b95b613ffe9d5a211d01df73bd79

Thanks,
Masa

From catalin.marinas at arm.com  Tue Aug  6 12:10:30 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 6 Aug 2024 20:10:30 +0100
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
Message-ID: <ZrJ1JkyDVpRRB_9e@arm.com>

To Jinjie, if you make generic changes that affect other architectures,
please either cc the individual lists/maintainers or at least cross-post
to linux-arch. I don't follow lkml, there's just too much traffic there.

On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
> On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
> > On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> > will cause system stall as below:
> > 
> > 	 Zone ranges:
> > 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> > 	   Normal   empty
> > 	 Movable zone start for each node
> > 	 Early memory node ranges
> > 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> > 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> > 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> > 	(stall here)
> > 
> > commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> > bug") fix this on 32-bit architecture. However, the problem is not
> > completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> > architecture, for example, when system memory is equal to
> > CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
> 
> Interesting, I didn't expect risc-v defining them like these.
> 
> #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
> #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()

arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
dynamic and x86 does something similar (SZ_64T). Not sure why the
generic code and riscv define it like this.

> > 	-> reserve_crashkernel_generic() and high is true
> > 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> > 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> > 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> > 
> > Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> > to simplify crashkernel reservation code"), x86 do not try to reserve crash
> > memory at low if it fails to alloc above high 4G. However before refator in
> > commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> > crashkernel reservation"), arm64 try to reserve crash memory at low if it
> > fails above high 4G. For 64-bit systems, this attempt is less beneficial
> > than the opposite, remove it to fix this bug and align with native x86
> > implementation.
> 
> And I don't like the idea crashkernel=,high failure will fallback to
> attempt in low area, so this looks good to me.

Well, I kind of liked this behaviour. One can specify ,high as a
preference rather than forcing a range. The arm64 land has different
platforms with some constrained memory layouts. Such fallback works well
as a default command line option shipped with distros without having to
guess the SoC memory layout.

Something like below should fix the issue as well (untested):

diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
index d3b4cd12bdd1..ae92d6745ef4 100644
--- a/kernel/crash_reserve.c
+++ b/kernel/crash_reserve.c
@@ -420,7 +420,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
 		 * For crashkernel=size[KMG],high, if the first attempt was
 		 * for high memory, fall back to low memory.
 		 */
-		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
+		if (high && search_end == CRASH_ADDR_HIGH_MAX &&
+		    CRASH_ADDR_LOW_MAX < CRASH_ADDR_HIGH_MAX) {
 			search_end = CRASH_ADDR_LOW_MAX;
 			search_base = 0;
 			goto retry;

-- 
Catalin


From catalin.marinas at arm.com  Tue Aug  6 12:34:42 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 6 Aug 2024 20:34:42 +0100
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrJ1JkyDVpRRB_9e@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
 <ZrJ1JkyDVpRRB_9e@arm.com>
Message-ID: <ZrJ60vopeGDXFZyK@arm.com>

On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
> > On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
> > > On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> > > will cause system stall as below:
> > > 
> > > 	 Zone ranges:
> > > 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> > > 	   Normal   empty
> > > 	 Movable zone start for each node
> > > 	 Early memory node ranges
> > > 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> > > 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> > > 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> > > 	(stall here)
> > > 
> > > commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> > > bug") fix this on 32-bit architecture. However, the problem is not
> > > completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> > > architecture, for example, when system memory is equal to
> > > CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
> > 
> > Interesting, I didn't expect risc-v defining them like these.
> > 
> > #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
> > #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()
> 
> arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
> dynamic and x86 does something similar (SZ_64T). Not sure why the
> generic code and riscv define it like this.
> 
> > > 	-> reserve_crashkernel_generic() and high is true
> > > 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> > > 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> > > 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> > > 
> > > Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> > > to simplify crashkernel reservation code"), x86 do not try to reserve crash
> > > memory at low if it fails to alloc above high 4G. However before refator in
> > > commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> > > crashkernel reservation"), arm64 try to reserve crash memory at low if it
> > > fails above high 4G. For 64-bit systems, this attempt is less beneficial
> > > than the opposite, remove it to fix this bug and align with native x86
> > > implementation.
> > 
> > And I don't like the idea crashkernel=,high failure will fallback to
> > attempt in low area, so this looks good to me.
> 
> Well, I kind of liked this behaviour. One can specify ,high as a
> preference rather than forcing a range. The arm64 land has different
> platforms with some constrained memory layouts. Such fallback works well
> as a default command line option shipped with distros without having to
> guess the SoC memory layout.

I haven't tried but it's possible that this patch also breaks those
arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
memblock_end_of_DRAM(). Here all memory would be low and in the absence
of no fallback, it fails to allocate.

So, my strong preference would be to re-instate the current behaviour
and work around the infinite loop in a different way.

Thanks.

-- 
Catalin


From ruanjinjie at huawei.com  Tue Aug  6 18:40:48 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Wed, 7 Aug 2024 09:40:48 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrJ1JkyDVpRRB_9e@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv> <ZrJ1JkyDVpRRB_9e@arm.com>
Message-ID: <795d228c-eec5-d3ff-698e-61d93338cb42@huawei.com>



On 2024/8/7 3:10, Catalin Marinas wrote:
> To Jinjie, if you make generic changes that affect other architectures,
> please either cc the individual lists/maintainers or at least cross-post
> to linux-arch. I don't follow lkml, there's just too much traffic there.

Sorry, I forgot to Cc to the other architectures.

> 
> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
>> On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
>>> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
>>> will cause system stall as below:
>>>
>>> 	 Zone ranges:
>>> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
>>> 	   Normal   empty
>>> 	 Movable zone start for each node
>>> 	 Early memory node ranges
>>> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
>>> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
>>> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
>>> 	(stall here)
>>>
>>> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
>>> bug") fix this on 32-bit architecture. However, the problem is not
>>> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
>>> architecture, for example, when system memory is equal to
>>> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
>>
>> Interesting, I didn't expect risc-v defining them like these.
>>
>> #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
>> #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()
> 
> arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
> dynamic and x86 does something similar (SZ_64T). Not sure why the
> generic code and riscv define it like this.
> 
>>> 	-> reserve_crashkernel_generic() and high is true
>>> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
>>> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
>>> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
>>>
>>> Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
>>> to simplify crashkernel reservation code"), x86 do not try to reserve crash
>>> memory at low if it fails to alloc above high 4G. However before refator in
>>> commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
>>> crashkernel reservation"), arm64 try to reserve crash memory at low if it
>>> fails above high 4G. For 64-bit systems, this attempt is less beneficial
>>> than the opposite, remove it to fix this bug and align with native x86
>>> implementation.
>>
>> And I don't like the idea crashkernel=,high failure will fallback to
>> attempt in low area, so this looks good to me.
> 
> Well, I kind of liked this behaviour. One can specify ,high as a
> preference rather than forcing a range. The arm64 land has different
> platforms with some constrained memory layouts. Such fallback works well
> as a default command line option shipped with distros without having to
> guess the SoC memory layout.
> 
> Something like below should fix the issue as well (untested):

I tested it on QEMU and it is good to fix this dead loop problem.

> 
> diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
> index d3b4cd12bdd1..ae92d6745ef4 100644
> --- a/kernel/crash_reserve.c
> +++ b/kernel/crash_reserve.c
> @@ -420,7 +420,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
>  		 * For crashkernel=size[KMG],high, if the first attempt was
>  		 * for high memory, fall back to low memory.
>  		 */
> -		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
> +		if (high && search_end == CRASH_ADDR_HIGH_MAX &&
> +		    CRASH_ADDR_LOW_MAX < CRASH_ADDR_HIGH_MAX) {
>  			search_end = CRASH_ADDR_LOW_MAX;
>  			search_base = 0;
>  			goto retry;
> 


From jacekt at dug.com  Tue Aug  6 19:57:24 2024
From: jacekt at dug.com (Jacek Tomaka)
Date: Tue, 6 Aug 2024 21:57:24 -0500
Subject: [PATCH] Add support for soft reserved memory range
Message-ID: <CAKVxXCVpgdybjKFbAQjOKbhepHuwtzqjZjtW_E6YUb3Yh758TQ@mail.gmail.com>

Essentially catch up with e820 related changes in the kernel.
Intel Sapphire Rapids MAX has high bandwidth memory which is
precious resource that is better not allocated by the kernel.

Userspace later can enable soft reserved range using daxctl.

Signed-off-by: Jacek Tomaka <jacek.tomaka at poczta.fm>
---
 include/x86/x86-linux.h               | 2 ++
 kexec/arch/i386/crashdump-x86.c       | 7 +++++++
 kexec/arch/i386/kexec-multiboot-x86.c | 1 +
 kexec/arch/i386/kexec-x86-common.c    | 5 +++++
 kexec/arch/i386/x86-linux-setup.c     | 3 +++
 kexec/firmware_memmap.c               | 2 ++
 kexec/kexec.h                         | 1 +
 7 files changed, 21 insertions(+)

diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
index 9646102835..fbde93df94 100644
--- a/include/x86/x86-linux.h
+++ b/include/x86/x86-linux.h
@@ -23,6 +23,8 @@ struct e820entry {
 #define E820_NVS 4
 #define E820_PMEM       7
 #define E820_PRAM       12
+#define E820_SOFT_RESERVED 0xefffffff
+
 } __attribute__((packed));
 #endif

diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index a01031e570..49108b2032 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -288,6 +288,10 @@ static int get_crash_memory_ranges(struct
memory_range **range, int *ranges,
  type = RANGE_RESERVED;
  } else if (memcmp(str, "Reserved\n", 9) == 0) {
  type = RANGE_RESERVED;
+ } else if (memcmp(str, "soft reserved\n", 14) == 0 ) {
+ type = RANGE_SOFT_RESERVED;
+ } else if (memcmp(str, "Soft Reserved\n", 14) == 0 ) {
+ type = RANGE_SOFT_RESERVED;
  } else if (memcmp(str, "GART\n", 5) == 0) {
  gart_start = start;
  gart_end = end;
@@ -615,6 +619,8 @@ static void cmdline_add_memmap_internal(char
*cmdline, unsigned long startk,
  strcat (str_mmap, "K@");
  else if (type == RANGE_RESERVED)
  strcat (str_mmap, "K$");
+ else if (type == RANGE_SOFT_RESERVED)
+ strcat (str_mmap, "K*");
  else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
  strcat (str_mmap, "K#");
  else if (type == RANGE_PRAM)
@@ -985,6 +991,7 @@ int load_crashdump_segments(struct kexec_info
*info, char* mod_cmdline,
  if ( !( mem_range[i].type == RANGE_ACPI
  || mem_range[i].type == RANGE_ACPI_NVS
  || mem_range[i].type == RANGE_RESERVED
+ || mem_range[i].type == RANGE_SOFT_RESERVED
  || mem_range[i].type == RANGE_PMEM
  || mem_range[i].type == RANGE_PRAM))
  continue;
diff --git a/kexec/arch/i386/kexec-multiboot-x86.c
b/kexec/arch/i386/kexec-multiboot-x86.c
index 33c885a2fa..49d57cb5ae 100644
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -379,6 +379,7 @@ int multiboot_x86_load(int argc, char **argv,
const char *buf, off_t len,
  mmap[i].Type = 4;
  break;
  case RANGE_RESERVED:
+ case RANGE_SOFT_RESERVED:
  default:
  mmap[i].Type = 2;  /* Not RAM (reserved) */
  }
diff --git a/kexec/arch/i386/kexec-x86-common.c
b/kexec/arch/i386/kexec-x86-common.c
index ffc95a9e43..116c4f4fd3 100644
--- a/kexec/arch/i386/kexec-x86-common.c
+++ b/kexec/arch/i386/kexec-x86-common.c
@@ -99,6 +99,9 @@ static int get_memory_ranges_proc_iomem(struct
memory_range **range, int *ranges
  else if (strncasecmp(str, "reserved\n", 9) == 0) {
  type = RANGE_RESERVED;
  }
+ else if (strncasecmp(str, "soft reserved\n", 9) == 0) {
+ type = RANGE_SOFT_RESERVED;
+ }
  else if (memcmp(str, "ACPI Tables\n", 12) == 0) {
  type = RANGE_ACPI;
  }
@@ -170,6 +173,8 @@ unsigned xen_e820_to_kexec_type(uint32_t type)
  return RANGE_PMEM;
  case E820_PRAM:
  return RANGE_PRAM;
+ case E820_SOFT_RESERVED;
+ return RANGE_SOFT_RESERVED;
  case E820_RESERVED:
  default:
  return RANGE_RESERVED;
diff --git a/kexec/arch/i386/x86-linux-setup.c
b/kexec/arch/i386/x86-linux-setup.c
index 73251b9339..afc83fe729 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -755,6 +755,9 @@ static void add_e820_map_from_mr(struct
x86_linux_param_header *real_mode,
  case RANGE_PRAM:
  e820[i].type = E820_PRAM;
  break;
+ case RANGE_SOFT_RESERVED:
+ e820[i].type = E820_SOFT_RESERVED;
+ break;
  default:
  case RANGE_RESERVED:
  e820[i].type = E820_RESERVED;
diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c
index 457c3dc9a6..fa0c22140a 100644
--- a/kexec/firmware_memmap.c
+++ b/kexec/firmware_memmap.c
@@ -182,6 +182,8 @@ static int parse_memmap_entry(const char *entry,
struct memory_range *range)
  range->type = RANGE_RESERVED;
  else if (strcmp(type, "Reserved") == 0)
  range->type = RANGE_RESERVED;
+        else if (strcmp(type, "Soft Reserved") == 0)
+                range->type = RANGE_SOFT_RESERVED;
  else if (strcmp(type, "Unknown E820 type") == 0)
  range->type = RANGE_RESERVED;
  else if (strcmp(type, "ACPI Non-volatile Storage") == 0)
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 31c323f674..dbb27a7607 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -139,6 +139,7 @@ struct memory_range {
 #define RANGE_UNCACHED 4
 #define RANGE_PMEM 6
 #define RANGE_PRAM 11
+#define RANGE_SOFT_RESERVED 0xefffffff
 };

 struct memory_ranges {
-- 
2.17.0


From ruanjinjie at huawei.com  Thu Aug  8 00:56:35 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Thu, 8 Aug 2024 15:56:35 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrJ60vopeGDXFZyK@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv> <ZrJ1JkyDVpRRB_9e@arm.com>
 <ZrJ60vopeGDXFZyK@arm.com>
Message-ID: <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>



On 2024/8/7 3:34, Catalin Marinas wrote:
> On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
>> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
>>> On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
>>>> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
>>>> will cause system stall as below:
>>>>
>>>> 	 Zone ranges:
>>>> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
>>>> 	   Normal   empty
>>>> 	 Movable zone start for each node
>>>> 	 Early memory node ranges
>>>> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
>>>> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
>>>> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
>>>> 	(stall here)
>>>>
>>>> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
>>>> bug") fix this on 32-bit architecture. However, the problem is not
>>>> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
>>>> architecture, for example, when system memory is equal to
>>>> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
>>>
>>> Interesting, I didn't expect risc-v defining them like these.
>>>
>>> #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
>>> #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()
>>
>> arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
>> dynamic and x86 does something similar (SZ_64T). Not sure why the
>> generic code and riscv define it like this.
>>
>>>> 	-> reserve_crashkernel_generic() and high is true
>>>> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
>>>> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
>>>> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
>>>>
>>>> Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
>>>> to simplify crashkernel reservation code"), x86 do not try to reserve crash
>>>> memory at low if it fails to alloc above high 4G. However before refator in
>>>> commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
>>>> crashkernel reservation"), arm64 try to reserve crash memory at low if it
>>>> fails above high 4G. For 64-bit systems, this attempt is less beneficial
>>>> than the opposite, remove it to fix this bug and align with native x86
>>>> implementation.
>>>
>>> And I don't like the idea crashkernel=,high failure will fallback to
>>> attempt in low area, so this looks good to me.
>>
>> Well, I kind of liked this behaviour. One can specify ,high as a
>> preference rather than forcing a range. The arm64 land has different
>> platforms with some constrained memory layouts. Such fallback works well
>> as a default command line option shipped with distros without having to
>> guess the SoC memory layout.
> 
> I haven't tried but it's possible that this patch also breaks those
> arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> memblock_end_of_DRAM(). Here all memory would be low and in the absence
> of no fallback, it fails to allocate.
> 
> So, my strong preference would be to re-instate the current behaviour
> and work around the infinite loop in a different way.

Hi, baoquan, What's your opinion?

Only this patch should be re-instate or all the 3 dead loop fix patch?

> 
> Thanks.
> 


From petr at tesarici.cz  Thu Aug  8 04:24:23 2024
From: petr at tesarici.cz (Petr =?UTF-8?B?VGVzYcWZw61r?=)
Date: Thu, 8 Aug 2024 13:24:23 +0200
Subject: [PATCH] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
References: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
Message-ID: <20240808132423.0f313ffe@meshulam.tesarici.cz>

Hi Sourabh,

sorry for late reply, was on vacation and then catching up...

On Mon,  5 Aug 2024 10:38:29 +0530
Sourabh Jain <sourabhjain at linux.ibm.com> wrote:

> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
> generalizes the crash hotplug support to allow architectures to update
> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
> Therefore, update the relevant kernel documentation to reflect the same.
> 
> No functional change.
> 
> Cc: Petr Tesarik <petr at tesarici.cz>
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: kexec at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: x86 at kernel.org
> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> ---
> 
> Discussion about the documentation update:
> https://lore.kernel.org/all/68d0328d-531a-4a2b-ab26-c97fd8a12e8b at linux.ibm.com/
> 
> ---
>  .../ABI/testing/sysfs-devices-memory          |  6 ++--
>  .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>  .../admin-guide/mm/memory-hotplug.rst         |  5 ++--
>  Documentation/core-api/cpu_hotplug.rst        | 10 ++++---
>  kernel/crash_core.c                           | 29 ++++++++++++-------
>  5 files changed, 33 insertions(+), 23 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
> index a95e0f17c35a..421acc8e2c6b 100644
> --- a/Documentation/ABI/testing/sysfs-devices-memory
> +++ b/Documentation/ABI/testing/sysfs-devices-memory
> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for memory hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel update of kexec
> +		segments on memory hot un/plug and/or on/offline events,
> +		avoiding the need to reload kdump kernel.

This sentence somehow lacks a verb. My suggestion:

  (RO) indicates whether or not the kernel updates relevant kexec
  segments on memory hot un/plug and/or on/offline events, avoiding the
  need to reload kdump kernel.

> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index 325873385b71..f4ada1cd2f96 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel update of kexec
> +		segments on CPU hot un/plug and/or on/offline events,
> +		avoiding the need to reload kdump kernel.

Same as above.

Otherwise LGTM.

Petr T


From bhe at redhat.com  Thu Aug  8 18:48:07 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 9 Aug 2024 09:48:07 +0800
Subject: [PATCH] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
References: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
Message-ID: <ZrV1V4QzDShYJSsI@MiWiFi-R3L-srv>

On 08/05/24 at 10:38am, Sourabh Jain wrote:
> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
> generalizes the crash hotplug support to allow architectures to update
> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
> Therefore, update the relevant kernel documentation to reflect the same.
> 
> No functional change.
> 
> Cc: Petr Tesarik <petr at tesarici.cz>
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: kexec at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: x86 at kernel.org
> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> ---
> 
> Discussion about the documentation update:
> https://lore.kernel.org/all/68d0328d-531a-4a2b-ab26-c97fd8a12e8b at linux.ibm.com/
> 
> ---
>  .../ABI/testing/sysfs-devices-memory          |  6 ++--
>  .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>  .../admin-guide/mm/memory-hotplug.rst         |  5 ++--
>  Documentation/core-api/cpu_hotplug.rst        | 10 ++++---
>  kernel/crash_core.c                           | 29 ++++++++++++-------
>  5 files changed, 33 insertions(+), 23 deletions(-)

The overall looks good to me, except of concern from Petr. Thanks.

> 
> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
> index a95e0f17c35a..421acc8e2c6b 100644
> --- a/Documentation/ABI/testing/sysfs-devices-memory
> +++ b/Documentation/ABI/testing/sysfs-devices-memory
> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for memory hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel update of kexec
> +		segments on memory hot un/plug and/or on/offline events,
> +		avoiding the need to reload kdump kernel.
> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index 325873385b71..f4ada1cd2f96 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel update of kexec
> +		segments on CPU hot un/plug and/or on/offline events,
> +		avoiding the need to reload kdump kernel.
>  
>  What:		/sys/devices/system/cpu/enabled
>  Date:		Nov 2022
> diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
> index 098f14d83e99..cb2c080f400c 100644
> --- a/Documentation/admin-guide/mm/memory-hotplug.rst
> +++ b/Documentation/admin-guide/mm/memory-hotplug.rst
> @@ -294,8 +294,9 @@ The following files are currently defined:
>  ``crash_hotplug``      read-only: when changes to the system memory map
>  		       occur due to hot un/plug of memory, this file contains
>  		       '1' if the kernel updates the kdump capture kernel memory
> -		       map itself (via elfcorehdr), or '0' if userspace must update
> -		       the kdump capture kernel memory map.
> +		       map itself (via elfcorehdr and other relevant kexec
> +		       segments), or '0' if userspace must update the kdump
> +		       capture kernel memory map.
>  
>  		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
>  		       configuration option.
> diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
> index dcb0e379e5e8..a21dbf261be7 100644
> --- a/Documentation/core-api/cpu_hotplug.rst
> +++ b/Documentation/core-api/cpu_hotplug.rst
> @@ -737,8 +737,9 @@ can process the event further.
>  
>  When changes to the CPUs in the system occur, the sysfs file
>  /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
> -updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
> -or '0' if userspace must update the kdump capture kernel list of CPUs.
> +updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
> +other relevant kexec segment), or '0' if userspace must update the kdump
> +capture kernel list of CPUs.
>  
>  The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
>  option.
> @@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
>   SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>  
>  For a CPU hot un/plug event, if the architecture supports kernel updates
> -of the elfcorehdr (which contains the list of CPUs), then the rule skips
> -the unload-then-reload of the kdump capture kernel.
> +of the elfcorehdr (which contains the list of CPUs) and other relevant
> +kexec segments, then the rule skips the unload-then-reload of the kdump
> +capture kernel.
>  
>  Kernel Inline Documentations Reference
>  ======================================
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..64dad01e260b 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>  }
>  
>  /*
> - * To accurately reflect hot un/plug changes of cpu and memory resources
> - * (including onling and offlining of those resources), the elfcorehdr
> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
> - * must be updated with the new list of CPUs and memories.
> + * To accurately reflect hot un/plug changes of CPU and Memory resources
> + * (including onling and offlining of those resources), the relevant
> + * kexec segments must be updated with latest CPU and Memory resources.
>   *
> - * In order to make changes to elfcorehdr, two conditions are needed:
> - * First, the segment containing the elfcorehdr must be large enough
> - * to permit a growing number of resources; the elfcorehdr memory size
> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
> - * Second, purgatory must explicitly exclude the elfcorehdr from the
> - * list of segments it checks (since the elfcorehdr changes and thus
> - * would require an update to purgatory itself to update the digest).
> + * Architectures must ensure two things for all segments that need
> + * updating during hotplug events:
> + *
> + * 1. Segments must be large enough to accommodate a growing number of
> + *    resources.
> + * 2. Exclude the segments from SHA verification.
> + *
> + * For example, on most architectures, the elfcorehdr (which is passed
> + * to the crash kernel via the elfcorehdr= parameter) must include the
> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
> + * should be large enough to permit a growing number of CPU and Memory
> + * resources. One can estimate the elfcorehdr memory size based on
> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
> + * excluded from SHA verification by default if the architecture
> + * supports crash hotplug.
>   */
>  static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>  {
> -- 
> 2.45.2
> 



From bhe at redhat.com  Thu Aug  8 18:56:25 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 9 Aug 2024 09:56:25 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
 <ZrJ1JkyDVpRRB_9e@arm.com>
 <ZrJ60vopeGDXFZyK@arm.com>
 <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>
Message-ID: <ZrV3SQZ43mgymxcr@MiWiFi-R3L-srv>

On 08/08/24 at 03:56pm, Jinjie Ruan wrote:
> 
> 
> On 2024/8/7 3:34, Catalin Marinas wrote:
> > On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
> >> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
> >>> On 08/02/24 at 05:01pm, Jinjie Ruan wrote:
> >>>> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> >>>> will cause system stall as below:
> >>>>
> >>>> 	 Zone ranges:
> >>>> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> >>>> 	   Normal   empty
> >>>> 	 Movable zone start for each node
> >>>> 	 Early memory node ranges
> >>>> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> >>>> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> >>>> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> >>>> 	(stall here)
> >>>>
> >>>> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> >>>> bug") fix this on 32-bit architecture. However, the problem is not
> >>>> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> >>>> architecture, for example, when system memory is equal to
> >>>> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
> >>>
> >>> Interesting, I didn't expect risc-v defining them like these.
> >>>
> >>> #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
> >>> #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()
> >>
> >> arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
> >> dynamic and x86 does something similar (SZ_64T). Not sure why the
> >> generic code and riscv define it like this.
> >>
> >>>> 	-> reserve_crashkernel_generic() and high is true
> >>>> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> >>>> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> >>>> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> >>>>
> >>>> Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> >>>> to simplify crashkernel reservation code"), x86 do not try to reserve crash
> >>>> memory at low if it fails to alloc above high 4G. However before refator in
> >>>> commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> >>>> crashkernel reservation"), arm64 try to reserve crash memory at low if it
> >>>> fails above high 4G. For 64-bit systems, this attempt is less beneficial
> >>>> than the opposite, remove it to fix this bug and align with native x86
> >>>> implementation.
> >>>
> >>> And I don't like the idea crashkernel=,high failure will fallback to
> >>> attempt in low area, so this looks good to me.
> >>
> >> Well, I kind of liked this behaviour. One can specify ,high as a
> >> preference rather than forcing a range. The arm64 land has different
> >> platforms with some constrained memory layouts. Such fallback works well
> >> as a default command line option shipped with distros without having to
> >> guess the SoC memory layout.
> > 
> > I haven't tried but it's possible that this patch also breaks those
> > arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> > memblock_end_of_DRAM(). Here all memory would be low and in the absence
> > of no fallback, it fails to allocate.
> > 
> > So, my strong preference would be to re-instate the current behaviour
> > and work around the infinite loop in a different way.
> 
> Hi, baoquan, What's your opinion?
> 
> Only this patch should be re-instate or all the 3 dead loop fix patch?

I am not sure which way Catalin suggested to take. 

Hi Catalin,

Could you say more words about your preference so that Jinjie can
proceed accordingly?

Thanks
Baoquan



From sourabhjain at linux.ibm.com  Thu Aug  8 22:35:28 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Fri, 9 Aug 2024 11:05:28 +0530
Subject: [PATCH] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240808132423.0f313ffe@meshulam.tesarici.cz>
References: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
 <20240808132423.0f313ffe@meshulam.tesarici.cz>
Message-ID: <ba0c218b-fb38-41a6-8339-265cc75466aa@linux.ibm.com>

Hello Petr,

On 08/08/24 16:54, Petr Tesa??k wrote:
> Hi Sourabh,
>
> sorry for late reply, was on vacation and then catching up...
>
> On Mon,  5 Aug 2024 10:38:29 +0530
> Sourabh Jain <sourabhjain at linux.ibm.com> wrote:
>
>> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
>> generalizes the crash hotplug support to allow architectures to update
>> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
>> Therefore, update the relevant kernel documentation to reflect the same.
>>
>> No functional change.
>>
>> Cc: Petr Tesarik <petr at tesarici.cz>
>> Cc: Hari Bathini <hbathini at linux.ibm.com>
>> Cc: kexec at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linuxppc-dev at lists.ozlabs.org
>> Cc: x86 at kernel.org
>> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
>> ---
>>
>> Discussion about the documentation update:
>> https://lore.kernel.org/all/68d0328d-531a-4a2b-ab26-c97fd8a12e8b at linux.ibm.com/
>>
>> ---
>>   .../ABI/testing/sysfs-devices-memory          |  6 ++--
>>   .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>>   .../admin-guide/mm/memory-hotplug.rst         |  5 ++--
>>   Documentation/core-api/cpu_hotplug.rst        | 10 ++++---
>>   kernel/crash_core.c                           | 29 ++++++++++++-------
>>   5 files changed, 33 insertions(+), 23 deletions(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
>> index a95e0f17c35a..421acc8e2c6b 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-memory
>> +++ b/Documentation/ABI/testing/sysfs-devices-memory
>> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for memory hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel update of kexec
>> +		segments on memory hot un/plug and/or on/offline events,
>> +		avoiding the need to reload kdump kernel.
> This sentence somehow lacks a verb. My suggestion:
>
>    (RO) indicates whether or not the kernel updates relevant kexec
>    segments on memory hot un/plug and/or on/offline events, avoiding the
>    need to reload kdump kernel.


Thanks for the review. I will update the document as suggested.


- Sourabh Jain

>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> index 325873385b71..f4ada1cd2f96 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
>> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel update of kexec
>> +		segments on CPU hot un/plug and/or on/offline events,
>> +		avoiding the need to reload kdump kernel.
> Same as above.
>
> Otherwise LGTM.
>
> Petr T



From catalin.marinas at arm.com  Fri Aug  9 02:51:39 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 9 Aug 2024 10:51:39 +0100
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
 <ZrJ1JkyDVpRRB_9e@arm.com>
 <ZrJ60vopeGDXFZyK@arm.com>
 <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>
Message-ID: <ZrXmqyhalkcY-wpx@arm.com>

On Thu, Aug 08, 2024 at 03:56:35PM +0800, Jinjie Ruan wrote:
> On 2024/8/7 3:34, Catalin Marinas wrote:
> > On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
> >> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
> >>> And I don't like the idea crashkernel=,high failure will fallback to
> >>> attempt in low area, so this looks good to me.
> >>
> >> Well, I kind of liked this behaviour. One can specify ,high as a
> >> preference rather than forcing a range. The arm64 land has different
> >> platforms with some constrained memory layouts. Such fallback works well
> >> as a default command line option shipped with distros without having to
> >> guess the SoC memory layout.
> > 
> > I haven't tried but it's possible that this patch also breaks those
> > arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> > memblock_end_of_DRAM(). Here all memory would be low and in the absence
> > of no fallback, it fails to allocate.
> > 
> > So, my strong preference would be to re-instate the current behaviour
> > and work around the infinite loop in a different way.
> 
> Hi, baoquan, What's your opinion?
> 
> Only this patch should be re-instate or all the 3 dead loop fix patch?

Only the riscv64 patch that that removes the ,high reservation fallback
to ,low. From this series:

https://lore.kernel.org/r/20240719095735.1912878-1-ruanjinjie at huawei.com/

the first two fixes look fine (x86_32). The third one (arm32), not sure
why it's in the series called "crash: Fix x86_32 memory reserve dead
loop bug". Does it fix a problem on arm32? Anyway, I'm not against it
getting merged but I'm not maintaining arm32. If the first two patches
could be merged for 6.11, I think the arm32 one is more of a 6.12
material (unless it does fix something).

On the riscv64 patch removing the high->low fallback to avoid the
infinite loop, I'd rather replace it with something similar to the
x86_32 fix in the series above. I suggested something in the main if
block but, looking at the x86_32 fix, for consistency, I think it would
look better as something like:

diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
index d3b4cd12bdd1..64d44a52c011 100644
--- a/kernel/crash_reserve.c
+++ b/kernel/crash_reserve.c
@@ -423,7 +423,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
 		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
 			search_end = CRASH_ADDR_LOW_MAX;
 			search_base = 0;
-			goto retry;
+			if (search_end != CRASH_ADDR_HIGH_MAX)
+				goto retry;
 		}
 		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
 			crash_size);

In summary, just replace the riscv64 fix with something along the lines
of the diff above (or pick whatever you prefer that still keeps the
fallback).

Thanks.

-- 
Catalin


From ruanjinjie at huawei.com  Fri Aug  9 03:15:23 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Fri, 9 Aug 2024 18:15:23 +0800
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrXmqyhalkcY-wpx@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv> <ZrJ1JkyDVpRRB_9e@arm.com>
 <ZrJ60vopeGDXFZyK@arm.com> <e01df216-0225-ef49-8eb3-2ccdcb424785@huawei.com>
 <ZrXmqyhalkcY-wpx@arm.com>
Message-ID: <abf192cf-e1ba-dd28-93f3-46fd7a07fef1@huawei.com>



On 2024/8/9 17:51, Catalin Marinas wrote:
> On Thu, Aug 08, 2024 at 03:56:35PM +0800, Jinjie Ruan wrote:
>> On 2024/8/7 3:34, Catalin Marinas wrote:
>>> On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
>>>> On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:
>>>>> And I don't like the idea crashkernel=,high failure will fallback to
>>>>> attempt in low area, so this looks good to me.
>>>>
>>>> Well, I kind of liked this behaviour. One can specify ,high as a
>>>> preference rather than forcing a range. The arm64 land has different
>>>> platforms with some constrained memory layouts. Such fallback works well
>>>> as a default command line option shipped with distros without having to
>>>> guess the SoC memory layout.
>>>
>>> I haven't tried but it's possible that this patch also breaks those
>>> arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
>>> memblock_end_of_DRAM(). Here all memory would be low and in the absence
>>> of no fallback, it fails to allocate.
>>>
>>> So, my strong preference would be to re-instate the current behaviour
>>> and work around the infinite loop in a different way.
>>
>> Hi, baoquan, What's your opinion?
>>
>> Only this patch should be re-instate or all the 3 dead loop fix patch?
> 
> Only the riscv64 patch that that removes the ,high reservation fallback
> to ,low. From this series:
> 
> https://lore.kernel.org/r/20240719095735.1912878-1-ruanjinjie at huawei.com/
> 
> the first two fixes look fine (x86_32). The third one (arm32), not sure
> why it's in the series called "crash: Fix x86_32 memory reserve dead
> loop bug". Does it fix a problem on arm32? Anyway, I'm not against it
> getting merged but I'm not maintaining arm32. If the first two patches
> could be merged for 6.11, I think the arm32 one is more of a 6.12
> material (unless it does fix something).
> 
> On the riscv64 patch removing the high->low fallback to avoid the
> infinite loop, I'd rather replace it with something similar to the
> x86_32 fix in the series above. I suggested something in the main if
> block but, looking at the x86_32 fix, for consistency, I think it would
> look better as something like:
> 
> diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
> index d3b4cd12bdd1..64d44a52c011 100644
> --- a/kernel/crash_reserve.c
> +++ b/kernel/crash_reserve.c
> @@ -423,7 +423,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
>  		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
>  			search_end = CRASH_ADDR_LOW_MAX;
>  			search_base = 0;
> -			goto retry;
> +			if (search_end != CRASH_ADDR_HIGH_MAX)
> +				goto retry;
>  		}
>  		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>  			crash_size);
> 
> In summary, just replace the riscv64 fix with something along the lines
> of the diff above (or pick whatever you prefer that still keeps the
> fallback).

Hi, Andrew

Could you please help to remove the riscv64 fix from your mm tree as
Catalin suggested? we will give the new patch sooner.

> 
> Thanks.
> 


From sourabhjain at linux.ibm.com  Fri Aug  9 04:03:10 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Fri, 9 Aug 2024 16:33:10 +0530
Subject: [PATCH] Document/kexec: Generalize crash hotplug description
In-Reply-To: <ZrV1V4QzDShYJSsI@MiWiFi-R3L-srv>
References: <20240805050829.297171-1-sourabhjain@linux.ibm.com>
 <ZrV1V4QzDShYJSsI@MiWiFi-R3L-srv>
Message-ID: <10624524-a078-404e-a5ba-c250de81c36f@linux.ibm.com>

Hello Baoquan,

On 09/08/24 07:18, Baoquan He wrote:
> On 08/05/24 at 10:38am, Sourabh Jain wrote:
>> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
>> generalizes the crash hotplug support to allow architectures to update
>> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
>> Therefore, update the relevant kernel documentation to reflect the same.
>>
>> No functional change.
>>
>> Cc: Petr Tesarik <petr at tesarici.cz>
>> Cc: Hari Bathini <hbathini at linux.ibm.com>
>> Cc: kexec at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linuxppc-dev at lists.ozlabs.org
>> Cc: x86 at kernel.org
>> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
>> ---
>>
>> Discussion about the documentation update:
>> https://lore.kernel.org/all/68d0328d-531a-4a2b-ab26-c97fd8a12e8b at linux.ibm.com/
>>
>> ---
>>   .../ABI/testing/sysfs-devices-memory          |  6 ++--
>>   .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>>   .../admin-guide/mm/memory-hotplug.rst         |  5 ++--
>>   Documentation/core-api/cpu_hotplug.rst        | 10 ++++---
>>   kernel/crash_core.c                           | 29 ++++++++++++-------
>>   5 files changed, 33 insertions(+), 23 deletions(-)
> The overall looks good to me, except of concern from Petr. Thanks.

Thanks for the review. I will make the suggested changes in v2.

Additionally I will also generalize the error message
"kexec_trylock() failed, elfcorehdr may be inaccurate " from
functions crash_handle_hotplug_event() and crash_check_hotplug_support()
to "kexec_trylock() failed, kdump image may be inaccurate"

- Sourabh Jain

>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
>> index a95e0f17c35a..421acc8e2c6b 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-memory
>> +++ b/Documentation/ABI/testing/sysfs-devices-memory
>> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for memory hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel update of kexec
>> +		segments on memory hot un/plug and/or on/offline events,
>> +		avoiding the need to reload kdump kernel.
>> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> index 325873385b71..f4ada1cd2f96 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
>> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel update of kexec
>> +		segments on CPU hot un/plug and/or on/offline events,
>> +		avoiding the need to reload kdump kernel.
>>   
>>   What:		/sys/devices/system/cpu/enabled
>>   Date:		Nov 2022
>> diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
>> index 098f14d83e99..cb2c080f400c 100644
>> --- a/Documentation/admin-guide/mm/memory-hotplug.rst
>> +++ b/Documentation/admin-guide/mm/memory-hotplug.rst
>> @@ -294,8 +294,9 @@ The following files are currently defined:
>>   ``crash_hotplug``      read-only: when changes to the system memory map
>>   		       occur due to hot un/plug of memory, this file contains
>>   		       '1' if the kernel updates the kdump capture kernel memory
>> -		       map itself (via elfcorehdr), or '0' if userspace must update
>> -		       the kdump capture kernel memory map.
>> +		       map itself (via elfcorehdr and other relevant kexec
>> +		       segments), or '0' if userspace must update the kdump
>> +		       capture kernel memory map.
>>   
>>   		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
>>   		       configuration option.
>> diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
>> index dcb0e379e5e8..a21dbf261be7 100644
>> --- a/Documentation/core-api/cpu_hotplug.rst
>> +++ b/Documentation/core-api/cpu_hotplug.rst
>> @@ -737,8 +737,9 @@ can process the event further.
>>   
>>   When changes to the CPUs in the system occur, the sysfs file
>>   /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
>> -updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
>> -or '0' if userspace must update the kdump capture kernel list of CPUs.
>> +updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
>> +other relevant kexec segment), or '0' if userspace must update the kdump
>> +capture kernel list of CPUs.
>>   
>>   The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
>>   option.
>> @@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
>>    SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>>   
>>   For a CPU hot un/plug event, if the architecture supports kernel updates
>> -of the elfcorehdr (which contains the list of CPUs), then the rule skips
>> -the unload-then-reload of the kdump capture kernel.
>> +of the elfcorehdr (which contains the list of CPUs) and other relevant
>> +kexec segments, then the rule skips the unload-then-reload of the kdump
>> +capture kernel.
>>   
>>   Kernel Inline Documentations Reference
>>   ======================================
>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>> index 63cf89393c6e..64dad01e260b 100644
>> --- a/kernel/crash_core.c
>> +++ b/kernel/crash_core.c
>> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>>   }
>>   
>>   /*
>> - * To accurately reflect hot un/plug changes of cpu and memory resources
>> - * (including onling and offlining of those resources), the elfcorehdr
>> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
>> - * must be updated with the new list of CPUs and memories.
>> + * To accurately reflect hot un/plug changes of CPU and Memory resources
>> + * (including onling and offlining of those resources), the relevant
>> + * kexec segments must be updated with latest CPU and Memory resources.
>>    *
>> - * In order to make changes to elfcorehdr, two conditions are needed:
>> - * First, the segment containing the elfcorehdr must be large enough
>> - * to permit a growing number of resources; the elfcorehdr memory size
>> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
>> - * Second, purgatory must explicitly exclude the elfcorehdr from the
>> - * list of segments it checks (since the elfcorehdr changes and thus
>> - * would require an update to purgatory itself to update the digest).
>> + * Architectures must ensure two things for all segments that need
>> + * updating during hotplug events:
>> + *
>> + * 1. Segments must be large enough to accommodate a growing number of
>> + *    resources.
>> + * 2. Exclude the segments from SHA verification.
>> + *
>> + * For example, on most architectures, the elfcorehdr (which is passed
>> + * to the crash kernel via the elfcorehdr= parameter) must include the
>> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
>> + * should be large enough to permit a growing number of CPU and Memory
>> + * resources. One can estimate the elfcorehdr memory size based on
>> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
>> + * excluded from SHA verification by default if the architecture
>> + * supports crash hotplug.
>>    */
>>   static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>>   {
>> -- 
>> 2.45.2
>>



From sourabhjain at linux.ibm.com  Sun Aug 11 21:16:51 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon, 12 Aug 2024 09:46:51 +0530
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
Message-ID: <20240812041651.703156-1-sourabhjain@linux.ibm.com>

Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
generalizes the crash hotplug support to allow architectures to update
multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
Therefore, update the relevant kernel documentation to reflect the same.

No functional change.

Cc: Petr Tesarik <petr at tesarici.cz>
Cc: Hari Bathini <hbathini at linux.ibm.com>
Cc: kexec at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: x86 at kernel.org
Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
---

Changelog:

Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
  - Update crash_hotplug sysfs document as suggested by Petr T
  - Update an error message in crash_handle_hotplug_event and
    crash_check_hotplug_support function.

---
 .../ABI/testing/sysfs-devices-memory          |  6 ++--
 .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
 .../admin-guide/mm/memory-hotplug.rst         |  5 +--
 Documentation/core-api/cpu_hotplug.rst        | 10 +++---
 kernel/crash_core.c                           | 33 +++++++++++--------
 5 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
index a95e0f17c35a..cec65827e602 100644
--- a/Documentation/ABI/testing/sysfs-devices-memory
+++ b/Documentation/ABI/testing/sysfs-devices-memory
@@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
 Date:		Aug 2023
 Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
 Description:
-		(RO) indicates whether or not the kernel directly supports
-		modifying the crash elfcorehdr for memory hot un/plug and/or
-		on/offline changes.
+		(RO) indicates whether or not the kernel updates relevant kexec
+		segments on memory hot un/plug and/or on/offline events, avoiding the
+		need to reload kdump kernel.
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 325873385b71..1a31b7c71676 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
 Date:		Aug 2023
 Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
 Description:
-		(RO) indicates whether or not the kernel directly supports
-		modifying the crash elfcorehdr for CPU hot un/plug and/or
-		on/offline changes.
+		(RO) indicates whether or not the kernel updates relevant kexec
+		segments on memory hot un/plug and/or on/offline events, avoiding the
+		need to reload kdump kernel.
 
 What:		/sys/devices/system/cpu/enabled
 Date:		Nov 2022
diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
index 098f14d83e99..cb2c080f400c 100644
--- a/Documentation/admin-guide/mm/memory-hotplug.rst
+++ b/Documentation/admin-guide/mm/memory-hotplug.rst
@@ -294,8 +294,9 @@ The following files are currently defined:
 ``crash_hotplug``      read-only: when changes to the system memory map
 		       occur due to hot un/plug of memory, this file contains
 		       '1' if the kernel updates the kdump capture kernel memory
-		       map itself (via elfcorehdr), or '0' if userspace must update
-		       the kdump capture kernel memory map.
+		       map itself (via elfcorehdr and other relevant kexec
+		       segments), or '0' if userspace must update the kdump
+		       capture kernel memory map.
 
 		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
 		       configuration option.
diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
index dcb0e379e5e8..a21dbf261be7 100644
--- a/Documentation/core-api/cpu_hotplug.rst
+++ b/Documentation/core-api/cpu_hotplug.rst
@@ -737,8 +737,9 @@ can process the event further.
 
 When changes to the CPUs in the system occur, the sysfs file
 /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
-updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
-or '0' if userspace must update the kdump capture kernel list of CPUs.
+updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
+other relevant kexec segment), or '0' if userspace must update the kdump
+capture kernel list of CPUs.
 
 The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
 option.
@@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
  SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
 
 For a CPU hot un/plug event, if the architecture supports kernel updates
-of the elfcorehdr (which contains the list of CPUs), then the rule skips
-the unload-then-reload of the kdump capture kernel.
+of the elfcorehdr (which contains the list of CPUs) and other relevant
+kexec segments, then the rule skips the unload-then-reload of the kdump
+capture kernel.
 
 Kernel Inline Documentations Reference
 ======================================
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 63cf89393c6e..c1048893f4b6 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
 	crash_hotplug_lock();
 	/* Obtain lock while reading crash information */
 	if (!kexec_trylock()) {
-		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
+		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
 		crash_hotplug_unlock();
 		return 0;
 	}
@@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
 }
 
 /*
- * To accurately reflect hot un/plug changes of cpu and memory resources
- * (including onling and offlining of those resources), the elfcorehdr
- * (which is passed to the crash kernel via the elfcorehdr= parameter)
- * must be updated with the new list of CPUs and memories.
+ * To accurately reflect hot un/plug changes of CPU and Memory resources
+ * (including onling and offlining of those resources), the relevant
+ * kexec segments must be updated with latest CPU and Memory resources.
  *
- * In order to make changes to elfcorehdr, two conditions are needed:
- * First, the segment containing the elfcorehdr must be large enough
- * to permit a growing number of resources; the elfcorehdr memory size
- * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
- * Second, purgatory must explicitly exclude the elfcorehdr from the
- * list of segments it checks (since the elfcorehdr changes and thus
- * would require an update to purgatory itself to update the digest).
+ * Architectures must ensure two things for all segments that need
+ * updating during hotplug events:
+ *
+ * 1. Segments must be large enough to accommodate a growing number of
+ *    resources.
+ * 2. Exclude the segments from SHA verification.
+ *
+ * For example, on most architectures, the elfcorehdr (which is passed
+ * to the crash kernel via the elfcorehdr= parameter) must include the
+ * new list of CPUs and memory. To make changes to the elfcorehdr, it
+ * should be large enough to permit a growing number of CPU and Memory
+ * resources. One can estimate the elfcorehdr memory size based on
+ * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
+ * excluded from SHA verification by default if the architecture
+ * supports crash hotplug.
  */
 static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
 {
@@ -540,7 +547,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
 	crash_hotplug_lock();
 	/* Obtain lock while changing crash information */
 	if (!kexec_trylock()) {
-		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
+		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
 		crash_hotplug_unlock();
 		return;
 	}
-- 
2.45.2



From ptesarik at suse.com  Sun Aug 11 22:41:52 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Mon, 12 Aug 2024 07:41:52 +0200
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
Message-ID: <20240812074152.321febe5@mordecai.tesarici.cz>

On Mon, 12 Aug 2024 09:46:51 +0530
Sourabh Jain <sourabhjain at linux.ibm.com> wrote:

> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
> generalizes the crash hotplug support to allow architectures to update
> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
> Therefore, update the relevant kernel documentation to reflect the same.
> 
> No functional change.
> 
> Cc: Petr Tesarik <petr at tesarici.cz>
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: kexec at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: x86 at kernel.org
> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>

It's perfect now.

Reviewed-by: Petr Tesarik <ptesarik at suse.com>

Petr T

> ---
> 
> Changelog:
> 
> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>   - Update crash_hotplug sysfs document as suggested by Petr T
>   - Update an error message in crash_handle_hotplug_event and
>     crash_check_hotplug_support function.
> 
> ---
>  .../ABI/testing/sysfs-devices-memory          |  6 ++--
>  .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>  .../admin-guide/mm/memory-hotplug.rst         |  5 +--
>  Documentation/core-api/cpu_hotplug.rst        | 10 +++---
>  kernel/crash_core.c                           | 33 +++++++++++--------
>  5 files changed, 35 insertions(+), 25 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
> index a95e0f17c35a..cec65827e602 100644
> --- a/Documentation/ABI/testing/sysfs-devices-memory
> +++ b/Documentation/ABI/testing/sysfs-devices-memory
> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for memory hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel updates relevant kexec
> +		segments on memory hot un/plug and/or on/offline events, avoiding the
> +		need to reload kdump kernel.
> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index 325873385b71..1a31b7c71676 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel updates relevant kexec
> +		segments on memory hot un/plug and/or on/offline events, avoiding the
> +		need to reload kdump kernel.
>  
>  What:		/sys/devices/system/cpu/enabled
>  Date:		Nov 2022
> diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
> index 098f14d83e99..cb2c080f400c 100644
> --- a/Documentation/admin-guide/mm/memory-hotplug.rst
> +++ b/Documentation/admin-guide/mm/memory-hotplug.rst
> @@ -294,8 +294,9 @@ The following files are currently defined:
>  ``crash_hotplug``      read-only: when changes to the system memory map
>  		       occur due to hot un/plug of memory, this file contains
>  		       '1' if the kernel updates the kdump capture kernel memory
> -		       map itself (via elfcorehdr), or '0' if userspace must update
> -		       the kdump capture kernel memory map.
> +		       map itself (via elfcorehdr and other relevant kexec
> +		       segments), or '0' if userspace must update the kdump
> +		       capture kernel memory map.
>  
>  		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
>  		       configuration option.
> diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
> index dcb0e379e5e8..a21dbf261be7 100644
> --- a/Documentation/core-api/cpu_hotplug.rst
> +++ b/Documentation/core-api/cpu_hotplug.rst
> @@ -737,8 +737,9 @@ can process the event further.
>  
>  When changes to the CPUs in the system occur, the sysfs file
>  /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
> -updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
> -or '0' if userspace must update the kdump capture kernel list of CPUs.
> +updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
> +other relevant kexec segment), or '0' if userspace must update the kdump
> +capture kernel list of CPUs.
>  
>  The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
>  option.
> @@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
>   SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>  
>  For a CPU hot un/plug event, if the architecture supports kernel updates
> -of the elfcorehdr (which contains the list of CPUs), then the rule skips
> -the unload-then-reload of the kdump capture kernel.
> +of the elfcorehdr (which contains the list of CPUs) and other relevant
> +kexec segments, then the rule skips the unload-then-reload of the kdump
> +capture kernel.
>  
>  Kernel Inline Documentations Reference
>  ======================================
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..c1048893f4b6 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>  	crash_hotplug_lock();
>  	/* Obtain lock while reading crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>  		crash_hotplug_unlock();
>  		return 0;
>  	}
> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>  }
>  
>  /*
> - * To accurately reflect hot un/plug changes of cpu and memory resources
> - * (including onling and offlining of those resources), the elfcorehdr
> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
> - * must be updated with the new list of CPUs and memories.
> + * To accurately reflect hot un/plug changes of CPU and Memory resources
> + * (including onling and offlining of those resources), the relevant
> + * kexec segments must be updated with latest CPU and Memory resources.
>   *
> - * In order to make changes to elfcorehdr, two conditions are needed:
> - * First, the segment containing the elfcorehdr must be large enough
> - * to permit a growing number of resources; the elfcorehdr memory size
> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
> - * Second, purgatory must explicitly exclude the elfcorehdr from the
> - * list of segments it checks (since the elfcorehdr changes and thus
> - * would require an update to purgatory itself to update the digest).
> + * Architectures must ensure two things for all segments that need
> + * updating during hotplug events:
> + *
> + * 1. Segments must be large enough to accommodate a growing number of
> + *    resources.
> + * 2. Exclude the segments from SHA verification.
> + *
> + * For example, on most architectures, the elfcorehdr (which is passed
> + * to the crash kernel via the elfcorehdr= parameter) must include the
> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
> + * should be large enough to permit a growing number of CPU and Memory
> + * resources. One can estimate the elfcorehdr memory size based on
> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
> + * excluded from SHA verification by default if the architecture
> + * supports crash hotplug.
>   */
>  static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>  {
> @@ -540,7 +547,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>  	crash_hotplug_lock();
>  	/* Obtain lock while changing crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>  		crash_hotplug_unlock();
>  		return;
>  	}



From sourabhjain at linux.ibm.com  Sun Aug 11 22:45:25 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon, 12 Aug 2024 11:15:25 +0530
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240812074152.321febe5@mordecai.tesarici.cz>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
 <20240812074152.321febe5@mordecai.tesarici.cz>
Message-ID: <01d935c2-bdb9-4117-841c-3e90f3c3dade@linux.ibm.com>



On 12/08/24 11:11, Petr Tesarik wrote:
> On Mon, 12 Aug 2024 09:46:51 +0530
> Sourabh Jain <sourabhjain at linux.ibm.com> wrote:
>
>> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
>> generalizes the crash hotplug support to allow architectures to update
>> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
>> Therefore, update the relevant kernel documentation to reflect the same.
>>
>> No functional change.
>>
>> Cc: Petr Tesarik <petr at tesarici.cz>
>> Cc: Hari Bathini <hbathini at linux.ibm.com>
>> Cc: kexec at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linuxppc-dev at lists.ozlabs.org
>> Cc: x86 at kernel.org
>> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> It's perfect now.
>
> Reviewed-by: Petr Tesarik <ptesarik at suse.com>


Thank you the review, Petr.

- Sourabh Jain


> Petr T
>
>> ---
>>
>> Changelog:
>>
>> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>>    - Update crash_hotplug sysfs document as suggested by Petr T
>>    - Update an error message in crash_handle_hotplug_event and
>>      crash_check_hotplug_support function.
>>
>> ---
>>   .../ABI/testing/sysfs-devices-memory          |  6 ++--
>>   .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>>   .../admin-guide/mm/memory-hotplug.rst         |  5 +--
>>   Documentation/core-api/cpu_hotplug.rst        | 10 +++---
>>   kernel/crash_core.c                           | 33 +++++++++++--------
>>   5 files changed, 35 insertions(+), 25 deletions(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
>> index a95e0f17c35a..cec65827e602 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-memory
>> +++ b/Documentation/ABI/testing/sysfs-devices-memory
>> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for memory hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel updates relevant kexec
>> +		segments on memory hot un/plug and/or on/offline events, avoiding the
>> +		need to reload kdump kernel.
>> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> index 325873385b71..1a31b7c71676 100644
>> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
>> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
>> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>>   Date:		Aug 2023
>>   Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>>   Description:
>> -		(RO) indicates whether or not the kernel directly supports
>> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
>> -		on/offline changes.
>> +		(RO) indicates whether or not the kernel updates relevant kexec
>> +		segments on memory hot un/plug and/or on/offline events, avoiding the
>> +		need to reload kdump kernel.
>>   
>>   What:		/sys/devices/system/cpu/enabled
>>   Date:		Nov 2022
>> diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
>> index 098f14d83e99..cb2c080f400c 100644
>> --- a/Documentation/admin-guide/mm/memory-hotplug.rst
>> +++ b/Documentation/admin-guide/mm/memory-hotplug.rst
>> @@ -294,8 +294,9 @@ The following files are currently defined:
>>   ``crash_hotplug``      read-only: when changes to the system memory map
>>   		       occur due to hot un/plug of memory, this file contains
>>   		       '1' if the kernel updates the kdump capture kernel memory
>> -		       map itself (via elfcorehdr), or '0' if userspace must update
>> -		       the kdump capture kernel memory map.
>> +		       map itself (via elfcorehdr and other relevant kexec
>> +		       segments), or '0' if userspace must update the kdump
>> +		       capture kernel memory map.
>>   
>>   		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
>>   		       configuration option.
>> diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
>> index dcb0e379e5e8..a21dbf261be7 100644
>> --- a/Documentation/core-api/cpu_hotplug.rst
>> +++ b/Documentation/core-api/cpu_hotplug.rst
>> @@ -737,8 +737,9 @@ can process the event further.
>>   
>>   When changes to the CPUs in the system occur, the sysfs file
>>   /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
>> -updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
>> -or '0' if userspace must update the kdump capture kernel list of CPUs.
>> +updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
>> +other relevant kexec segment), or '0' if userspace must update the kdump
>> +capture kernel list of CPUs.
>>   
>>   The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
>>   option.
>> @@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
>>    SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>>   
>>   For a CPU hot un/plug event, if the architecture supports kernel updates
>> -of the elfcorehdr (which contains the list of CPUs), then the rule skips
>> -the unload-then-reload of the kdump capture kernel.
>> +of the elfcorehdr (which contains the list of CPUs) and other relevant
>> +kexec segments, then the rule skips the unload-then-reload of the kdump
>> +capture kernel.
>>   
>>   Kernel Inline Documentations Reference
>>   ======================================
>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>> index 63cf89393c6e..c1048893f4b6 100644
>> --- a/kernel/crash_core.c
>> +++ b/kernel/crash_core.c
>> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>>   	crash_hotplug_lock();
>>   	/* Obtain lock while reading crash information */
>>   	if (!kexec_trylock()) {
>> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>>   		crash_hotplug_unlock();
>>   		return 0;
>>   	}
>> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>>   }
>>   
>>   /*
>> - * To accurately reflect hot un/plug changes of cpu and memory resources
>> - * (including onling and offlining of those resources), the elfcorehdr
>> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
>> - * must be updated with the new list of CPUs and memories.
>> + * To accurately reflect hot un/plug changes of CPU and Memory resources
>> + * (including onling and offlining of those resources), the relevant
>> + * kexec segments must be updated with latest CPU and Memory resources.
>>    *
>> - * In order to make changes to elfcorehdr, two conditions are needed:
>> - * First, the segment containing the elfcorehdr must be large enough
>> - * to permit a growing number of resources; the elfcorehdr memory size
>> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
>> - * Second, purgatory must explicitly exclude the elfcorehdr from the
>> - * list of segments it checks (since the elfcorehdr changes and thus
>> - * would require an update to purgatory itself to update the digest).
>> + * Architectures must ensure two things for all segments that need
>> + * updating during hotplug events:
>> + *
>> + * 1. Segments must be large enough to accommodate a growing number of
>> + *    resources.
>> + * 2. Exclude the segments from SHA verification.
>> + *
>> + * For example, on most architectures, the elfcorehdr (which is passed
>> + * to the crash kernel via the elfcorehdr= parameter) must include the
>> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
>> + * should be large enough to permit a growing number of CPU and Memory
>> + * resources. One can estimate the elfcorehdr memory size based on
>> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
>> + * excluded from SHA verification by default if the architecture
>> + * supports crash hotplug.
>>    */
>>   static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>>   {
>> @@ -540,7 +547,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>>   	crash_hotplug_lock();
>>   	/* Obtain lock while changing crash information */
>>   	if (!kexec_trylock()) {
>> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>>   		crash_hotplug_unlock();
>>   		return;
>>   	}



From ruanjinjie at huawei.com  Sun Aug 11 23:20:17 2024
From: ruanjinjie at huawei.com (Jinjie Ruan)
Date: Mon, 12 Aug 2024 14:20:17 +0800
Subject: [PATCH -next v2] crash: Fix riscv64 crash memory reserve dead loop
Message-ID: <20240812062017.2674441-1-ruanjinjie@huawei.com>

On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
will cause system stall as below:

	 Zone ranges:
	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
	   Normal   empty
	 Movable zone start for each node
	 Early memory node ranges
	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
	(stall here)

commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
bug") fix this on 32-bit architecture. However, the problem is not
completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
architecture, for example, when system memory is equal to
CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:

	-> reserve_crashkernel_generic() and high is true
	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).

As Catalin suggested, do not remove the ",high" reservation fallback to
",low" logic which will change arm64's kdump behavior, but fix it by
skipping the above situation similar to commit d2f32f23190b ("crash: fix
x86_32 crash memory reserve dead loop").

After this patch, it print:
	cannot allocate crashkernel (size:0x1f400000)

Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
---
v2:
- Fix it in another way suggested by Catalin.
- Add Suggested-by.
---
 kernel/crash_reserve.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
index 5387269114f6..aae4a9e998d1 100644
--- a/kernel/crash_reserve.c
+++ b/kernel/crash_reserve.c
@@ -427,7 +427,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
 		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
 			search_end = CRASH_ADDR_LOW_MAX;
 			search_base = 0;
-			goto retry;
+			if (search_end != CRASH_ADDR_HIGH_MAX)
+				goto retry;
 		}
 		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
 			crash_size);
-- 
2.34.1



From catalin.marinas at arm.com  Mon Aug 12 03:39:52 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 12 Aug 2024 11:39:52 +0100
Subject: [PATCH -next v2] crash: Fix riscv64 crash memory reserve dead
 loop
In-Reply-To: <20240812062017.2674441-1-ruanjinjie@huawei.com>
References: <20240812062017.2674441-1-ruanjinjie@huawei.com>
Message-ID: <ZrnmeKCgHc1XgUdU@arm.com>

On Mon, Aug 12, 2024 at 02:20:17PM +0800, Jinjie Ruan wrote:
> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> will cause system stall as below:
> 
> 	 Zone ranges:
> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> 	   Normal   empty
> 	 Movable zone start for each node
> 	 Early memory node ranges
> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> 	(stall here)
> 
> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> bug") fix this on 32-bit architecture. However, the problem is not
> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> architecture, for example, when system memory is equal to
> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
> 
> 	-> reserve_crashkernel_generic() and high is true
> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> 
> As Catalin suggested, do not remove the ",high" reservation fallback to
> ",low" logic which will change arm64's kdump behavior, but fix it by
> skipping the above situation similar to commit d2f32f23190b ("crash: fix
> x86_32 crash memory reserve dead loop").
> 
> After this patch, it print:
> 	cannot allocate crashkernel (size:0x1f400000)
> 
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Thanks.


From ptesarik at suse.com  Mon Aug 12 07:36:33 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Mon, 12 Aug 2024 16:36:33 +0200
Subject: [PATCH 0/7] Kexec-tools: Improve RISC-V port
In-Reply-To: <20240518083304.GD475595@kernel.org>
References: <20230915035013.1582679-1-songshuaishuai@tinylab.org>
	<20230920115634.GG224399@kernel.org>
	<DA84A55096BADE15+594e239a-ff6a-368f-ae92-b6cfebbf8dc0@tinylab.org>
	<CALu+AoSr+an7Ps-jhcSbvrq4E4FnqkiNZVH-2BhV_3=B+oDcFQ@mail.gmail.com>
	<20240518083304.GD475595@kernel.org>
Message-ID: <20240812163633.098f8f07@mordecai.tesarici.cz>

Hi,

On Sat, 18 May 2024 09:33:04 +0100
Simon Horman <horms at kernel.org> wrote:

> On Sat, May 18, 2024 at 11:39:18AM +0800, Dave Young wrote:
> > On Wed, 11 Oct 2023 at 13:24, Song Shuai <songshuaishuai at tinylab.org> wrote:  
> > >
> > >
> > >
> > > ? 2023/9/20 19:56, Simon Horman ??:  
> > > > On Fri, Sep 15, 2023 at 11:50:06AM +0800, Song Shuai wrote:  
> > > >> Hi,
> > > >>
> > > >> This series is created to improve RISC-V port of kexec-tools,
> > > >> and is based on the horms/kexec-tools:build-test-riscv-v2 branch.  
> > > >
> > > > In my mind the big question is how to move RISC-V support
> > > > from that branch, to being merged into main.
> > > >
> > > > IIRC there were some issues that needed to be addressed.
> > > > Perhaps they are all addressed by this series, and with
> > > > some appropriate squashing we can move forwards with a series
> > > > based on main?  
> > >
> > > Hi, Simon and Nick:
> > >
> > > I squashed the first four patches as a "RISC-V: Some fixes for riscv
> > > port" patch and then took the horms/main as the base to collect the 2
> > > patches from horms/build-test-riscv-v2 branch and this series togother.
> > > These are the Github link and all commits for RISC-V.
> > >
> > > https://github.com/sugarfillet/kexec-tools/commits/main_rv
> > >
> > > 5dc133e RISC-V: Support loading Image binary file
> > > b042f6d RISC-V: Separate elf_riscv_find_pbase out
> > > 8f344c7 RISC-V: Enable kexec_file_load syscall
> > > 7d4b982 RISC-V: Some fixes for riscv port
> > > 3205c1c local: RISC-V: distribute purgatory/riscv/Makefile
> > > 54f9daf RISC-V: Add support for riscv kexec/kdump on kexec-tools
> > >
> > > Since I didn't found the issues/fixes as Nick mentioned with these
> > > commits, I prefer to merge them into horms/main and let more kexec/kdump
> > > users to help improve/fixup RISC-V port.  
> > 
> > Hi,  I noticed another pr for Fedora kexec-tools:
> > https://src.fedoraproject.org/rpms/kexec-tools/pull-request/24
> > 
> > It is bad to take it as Fedora only,   I would suggest posting all the
> > refreshed patches together here again for review.
> > 
> > If no enough reviewers can review them my another suggestion is to
> > drop the kexec_load support code for the time being, and only enable
> > the kexec_file_load support code in kexec-tools, and I assume below
> > kernel commit make the kexec_file_load kernel piece of work done.
> > Then it will be easier to review and make something working at least.
> > commit 6261586e0c91db14c34f894f4bc48f2300cff1d4
> > Author: Liao Chang <liaochang1 at huawei.com>
> > Date:   Fri Apr 8 18:09:11 2022 +0800
> > 
> >     RISC-V: Add kexec_file support  
> 
> Hi,
> 
> I would gladly take a patchset for kexec-tools that adds RISC-V support in
> a coherent manner.

Have I missed some progress on this topic? FWIW I can take care of
RISC-V support in kexec-tools, I even received a VisionFive 2 board
from RVI last year specifically to help with kexec.

I merely don't want to duplicate efforts or "steal" someone else's
project. Is RISC-V support in kexec-tools an orphaned project now?

Petr T


From ross.philipson at oracle.com  Mon Aug 12 12:02:18 2024
From: ross.philipson at oracle.com (ross.philipson at oracle.com)
Date: Mon, 12 Aug 2024 12:02:18 -0700
Subject: [PATCH v9 09/19] x86: Secure Launch kernel late boot stub
In-Reply-To: <D1RHZDG3HJNK.ZWTFLXDBEXD1@kernel.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-10-ross.philipson@oracle.com>
 <D1RHZDG3HJNK.ZWTFLXDBEXD1@kernel.org>
Message-ID: <ad84cdaf-bea6-483e-82f3-c83a6b7006c3@oracle.com>

On 6/4/24 3:59 PM, Jarkko Sakkinen wrote:
> On Fri May 31, 2024 at 4:03 AM EEST, Ross Philipson wrote:
>> The routine slaunch_setup is called out of the x86 specific setup_arch()
>> routine during early kernel boot. After determining what platform is
>> present, various operations specific to that platform occur. This
>> includes finalizing setting for the platform late launch and verifying
>> that memory protections are in place.
>>
>> For TXT, this code also reserves the original compressed kernel setup
>> area where the APs were left looping so that this memory cannot be used.
>>
>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
>> ---
>>   arch/x86/kernel/Makefile   |   1 +
>>   arch/x86/kernel/setup.c    |   3 +
>>   arch/x86/kernel/slaunch.c  | 525 +++++++++++++++++++++++++++++++++++++
>>   drivers/iommu/intel/dmar.c |   4 +
>>   4 files changed, 533 insertions(+)
>>   create mode 100644 arch/x86/kernel/slaunch.c
>>
>> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
>> index 5d128167e2e2..b35ca99ab0a0 100644
>> --- a/arch/x86/kernel/Makefile
>> +++ b/arch/x86/kernel/Makefile
>> @@ -76,6 +76,7 @@ obj-$(CONFIG_X86_32)		+= tls.o
>>   obj-$(CONFIG_IA32_EMULATION)	+= tls.o
>>   obj-y				+= step.o
>>   obj-$(CONFIG_INTEL_TXT)		+= tboot.o
>> +obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
> 
> Hmm... should that be CONFIG_X86_SECURE_LAUNCH?

Further thoughts on this after discussions...

The Secure Launch feature will cover other architectures beyond x86 in 
the future. We may have to rework/move the config settings at that point 
but for now I don't think we want to change it.

Thanks
Ross

> 
> Just asking...
> 
> BR, Jarkko
> 



From bhe at redhat.com  Mon Aug 12 20:31:50 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 13 Aug 2024 11:31:50 +0800
Subject: [PATCH -next v2] crash: Fix riscv64 crash memory reserve dead
 loop
In-Reply-To: <20240812062017.2674441-1-ruanjinjie@huawei.com>
References: <20240812062017.2674441-1-ruanjinjie@huawei.com>
Message-ID: <ZrrTpgvC/buAY/OV@MiWiFi-R3L-srv>

On 08/12/24 at 02:20pm, Jinjie Ruan wrote:
> On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> will cause system stall as below:
> 
> 	 Zone ranges:
> 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> 	   Normal   empty
> 	 Movable zone start for each node
> 	 Early memory node ranges
> 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> 	(stall here)
> 
> commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> bug") fix this on 32-bit architecture. However, the problem is not
> completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> architecture, for example, when system memory is equal to
> CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:
> 
> 	-> reserve_crashkernel_generic() and high is true
> 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly
> 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> 
> As Catalin suggested, do not remove the ",high" reservation fallback to
> ",low" logic which will change arm64's kdump behavior, but fix it by
> skipping the above situation similar to commit d2f32f23190b ("crash: fix
> x86_32 crash memory reserve dead loop").
> 
> After this patch, it print:
> 	cannot allocate crashkernel (size:0x1f400000)
> 
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> ---
> v2:
> - Fix it in another way suggested by Catalin.
> - Add Suggested-by.
> ---
>  kernel/crash_reserve.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Acked-by: Baoquan He <bhe at redhat.com>

> 
> diff --git a/kernel/crash_reserve.c b/kernel/crash_reserve.c
> index 5387269114f6..aae4a9e998d1 100644
> --- a/kernel/crash_reserve.c
> +++ b/kernel/crash_reserve.c
> @@ -427,7 +427,8 @@ void __init reserve_crashkernel_generic(char *cmdline,
>  		if (high && search_end == CRASH_ADDR_HIGH_MAX) {
>  			search_end = CRASH_ADDR_LOW_MAX;
>  			search_base = 0;
> -			goto retry;
> +			if (search_end != CRASH_ADDR_HIGH_MAX)
> +				goto retry;
>  		}
>  		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>  			crash_size);
> -- 
> 2.34.1
> 



From bhe at redhat.com  Mon Aug 12 22:04:50 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 13 Aug 2024 13:04:50 +0800
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
Message-ID: <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>

On 08/12/24 at 09:46am, Sourabh Jain wrote:
......
> ---
> 
> Changelog:
> 
> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>   - Update crash_hotplug sysfs document as suggested by Petr T
>   - Update an error message in crash_handle_hotplug_event and
>     crash_check_hotplug_support function.
> 
> ---
......
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..c1048893f4b6 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>  	crash_hotplug_lock();
>  	/* Obtain lock while reading crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");

Wondering why this need be updated.

>  		crash_hotplug_unlock();
>  		return 0;
>  	}
> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>  }
>  
>  /*
> - * To accurately reflect hot un/plug changes of cpu and memory resources
> - * (including onling and offlining of those resources), the elfcorehdr
> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
> - * must be updated with the new list of CPUs and memories.
> + * To accurately reflect hot un/plug changes of CPU and Memory resources
> + * (including onling and offlining of those resources), the relevant
> + * kexec segments must be updated with latest CPU and Memory resources.
>   *
> - * In order to make changes to elfcorehdr, two conditions are needed:
> - * First, the segment containing the elfcorehdr must be large enough
> - * to permit a growing number of resources; the elfcorehdr memory size
> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
> - * Second, purgatory must explicitly exclude the elfcorehdr from the
> - * list of segments it checks (since the elfcorehdr changes and thus
> - * would require an update to purgatory itself to update the digest).
> + * Architectures must ensure two things for all segments that need
> + * updating during hotplug events:
> + *
> + * 1. Segments must be large enough to accommodate a growing number of
> + *    resources.
> + * 2. Exclude the segments from SHA verification.
> + *
> + * For example, on most architectures, the elfcorehdr (which is passed
> + * to the crash kernel via the elfcorehdr= parameter) must include the
> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
> + * should be large enough to permit a growing number of CPU and Memory
> + * resources. One can estimate the elfcorehdr memory size based on
> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
> + * excluded from SHA verification by default if the architecture
> + * supports crash hotplug.
>   */
>  static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>  {
> @@ -540,7 +547,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>  	crash_hotplug_lock();
>  	/* Obtain lock while changing crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>  		crash_hotplug_unlock();
>  		return;
>  	}
> -- 
> 2.45.2
> 



From sourabhjain at linux.ibm.com  Mon Aug 12 22:28:12 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Tue, 13 Aug 2024 10:58:12 +0530
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
 <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>
Message-ID: <4cbbf314-5134-4a1a-8a4d-f6f8c09104d3@linux.ibm.com>

Hello Baoquan,

On 13/08/24 10:34, Baoquan He wrote:
> On 08/12/24 at 09:46am, Sourabh Jain wrote:
> ......
>> ---
>>
>> Changelog:
>>
>> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>>    - Update crash_hotplug sysfs document as suggested by Petr T
>>    - Update an error message in crash_handle_hotplug_event and
>>      crash_check_hotplug_support function.
>>
>> ---
> ......
>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>> index 63cf89393c6e..c1048893f4b6 100644
>> --- a/kernel/crash_core.c
>> +++ b/kernel/crash_core.c
>> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>>   	crash_hotplug_lock();
>>   	/* Obtain lock while reading crash information */
>>   	if (!kexec_trylock()) {
>> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
> Wondering why this need be updated.

In some architectures, additional kexec segments become obsolete during 
a hotplug event,
so simply calling out the `elfcorehdr may be inaccurate` may not be 
sufficient.
Therefore, it has been generalized with the kdump image.


Thanks,
Sourabh Jain


From petr at tesarici.cz  Tue Aug 13 01:40:06 2024
From: petr at tesarici.cz (Petr =?UTF-8?B?VGVzYcWZw61r?=)
Date: Tue, 13 Aug 2024 10:40:06 +0200
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrJ60vopeGDXFZyK@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
	<ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
	<ZrJ1JkyDVpRRB_9e@arm.com>
	<ZrJ60vopeGDXFZyK@arm.com>
Message-ID: <20240813104006.520bf42d@mordecai.tesarici.cz>

Hi Catalin,

On Tue, 6 Aug 2024 20:34:42 +0100
Catalin Marinas <catalin.marinas at arm.com> wrote:

> On Tue, Aug 06, 2024 at 08:10:30PM +0100, Catalin Marinas wrote:
> > On Fri, Aug 02, 2024 at 06:11:01PM +0800, Baoquan He wrote:  
> > > On 08/02/24 at 05:01pm, Jinjie Ruan wrote:  
> > > > On RISCV64 Qemu machine with 512MB memory, cmdline "crashkernel=500M,high"
> > > > will cause system stall as below:
> > > > 
> > > > 	 Zone ranges:
> > > > 	   DMA32    [mem 0x0000000080000000-0x000000009fffffff]
> > > > 	   Normal   empty
> > > > 	 Movable zone start for each node
> > > > 	 Early memory node ranges
> > > > 	   node   0: [mem 0x0000000080000000-0x000000008005ffff]
> > > > 	   node   0: [mem 0x0000000080060000-0x000000009fffffff]
> > > > 	 Initmem setup node 0 [mem 0x0000000080000000-0x000000009fffffff]
> > > > 	(stall here)
> > > > 
> > > > commit 5d99cadf1568 ("crash: fix x86_32 crash memory reserve dead loop
> > > > bug") fix this on 32-bit architecture. However, the problem is not
> > > > completely solved. If `CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX` on 64-bit
> > > > architecture, for example, when system memory is equal to
> > > > CRASH_ADDR_LOW_MAX on RISCV64, the following infinite loop will also occur:  
> > > 
> > > Interesting, I didn't expect risc-v defining them like these.
> > > 
> > > #define CRASH_ADDR_LOW_MAX              dma32_phys_limit
> > > #define CRASH_ADDR_HIGH_MAX             memblock_end_of_DRAM()  
> > 
> > arm64 defines the high limit as PHYS_MASK+1, it doesn't need to be
> > dynamic and x86 does something similar (SZ_64T). Not sure why the
> > generic code and riscv define it like this.
> >   
> > > > 	-> reserve_crashkernel_generic() and high is true
> > > > 	   -> alloc at [CRASH_ADDR_LOW_MAX, CRASH_ADDR_HIGH_MAX] fail
> > > > 	      -> alloc at [0, CRASH_ADDR_LOW_MAX] fail and repeatedly  
> > > > 	         (because CRASH_ADDR_LOW_MAX = CRASH_ADDR_HIGH_MAX).
> > > > 
> > > > Before refactor in commit 9c08a2a139fe ("x86: kdump: use generic interface
> > > > to simplify crashkernel reservation code"), x86 do not try to reserve crash
> > > > memory at low if it fails to alloc above high 4G. However before refator in
> > > > commit fdc268232dbba ("arm64: kdump: use generic interface to simplify
> > > > crashkernel reservation"), arm64 try to reserve crash memory at low if it
> > > > fails above high 4G. For 64-bit systems, this attempt is less beneficial
> > > > than the opposite, remove it to fix this bug and align with native x86
> > > > implementation.  
> > > 
> > > And I don't like the idea crashkernel=,high failure will fallback to
> > > attempt in low area, so this looks good to me.  
> > 
> > Well, I kind of liked this behaviour. One can specify ,high as a
> > preference rather than forcing a range. The arm64 land has different
> > platforms with some constrained memory layouts. Such fallback works well
> > as a default command line option shipped with distros without having to
> > guess the SoC memory layout.  
> 
> I haven't tried but it's possible that this patch also breaks those
> arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> memblock_end_of_DRAM(). Here all memory would be low and in the absence
> of no fallback, it fails to allocate.

I'm afraid you've just opened a Pandora box... ;-)

Another (unrelated) patch series made us aware of a platforms where RAM
starts at 32G, but IIUC the host bridge maps 32G-33G to bus addresses
0-1G, and there is a device on that bus which can produce only 30-bit
addresses.

Now, what was the idea behind allocating some crash memory "low"?
Right, it should allow the crash kernel to access devices with
addressing constraints. So, on the above-mentioned platform, allocating
"low" would in fact mean allocating between 32G and 33G (in host address
domain).

Should we rethink the whole concept of high/low?

Petr T


From bhe at redhat.com  Tue Aug 13 02:17:04 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 13 Aug 2024 17:17:04 +0800
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <4cbbf314-5134-4a1a-8a4d-f6f8c09104d3@linux.ibm.com>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
 <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>
 <4cbbf314-5134-4a1a-8a4d-f6f8c09104d3@linux.ibm.com>
Message-ID: <ZrskkDuMlQu+uBN4@MiWiFi-R3L-srv>

On 08/13/24 at 10:58am, Sourabh Jain wrote:
> Hello Baoquan,
> 
> On 13/08/24 10:34, Baoquan He wrote:
> > On 08/12/24 at 09:46am, Sourabh Jain wrote:
> > ......
> > > ---
> > > 
> > > Changelog:
> > > 
> > > Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
> > >    - Update crash_hotplug sysfs document as suggested by Petr T
> > >    - Update an error message in crash_handle_hotplug_event and
> > >      crash_check_hotplug_support function.
> > > 
> > > ---
> > ......
> > > diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> > > index 63cf89393c6e..c1048893f4b6 100644
> > > --- a/kernel/crash_core.c
> > > +++ b/kernel/crash_core.c
> > > @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
> > >   	crash_hotplug_lock();
> > >   	/* Obtain lock while reading crash information */
> > >   	if (!kexec_trylock()) {
> > > -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> > > +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
> > Wondering why this need be updated.
> 
> In some architectures, additional kexec segments become obsolete during a
> hotplug event,
> so simply calling out the `elfcorehdr may be inaccurate` may not be
> sufficient.
> Therefore, it has been generalized with the kdump image.

OK, I forgot the case in ppc, makes sense to me, thx.

Acked-by: Baoquan He <bhe at redhat.com>



From sourabhjain at linux.ibm.com  Tue Aug 13 02:25:28 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Tue, 13 Aug 2024 14:55:28 +0530
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <ZrskkDuMlQu+uBN4@MiWiFi-R3L-srv>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
 <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>
 <4cbbf314-5134-4a1a-8a4d-f6f8c09104d3@linux.ibm.com>
 <ZrskkDuMlQu+uBN4@MiWiFi-R3L-srv>
Message-ID: <4ccfd375-f588-4b9a-b505-49e021b90817@linux.ibm.com>

Hello Boaquan,

On 13/08/24 14:47, Baoquan He wrote:
> On 08/13/24 at 10:58am, Sourabh Jain wrote:
>> Hello Baoquan,
>>
>> On 13/08/24 10:34, Baoquan He wrote:
>>> On 08/12/24 at 09:46am, Sourabh Jain wrote:
>>> ......
>>>> ---
>>>>
>>>> Changelog:
>>>>
>>>> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>>>>     - Update crash_hotplug sysfs document as suggested by Petr T
>>>>     - Update an error message in crash_handle_hotplug_event and
>>>>       crash_check_hotplug_support function.
>>>>
>>>> ---
>>> ......
>>>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>>>> index 63cf89393c6e..c1048893f4b6 100644
>>>> --- a/kernel/crash_core.c
>>>> +++ b/kernel/crash_core.c
>>>> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>>>>    	crash_hotplug_lock();
>>>>    	/* Obtain lock while reading crash information */
>>>>    	if (!kexec_trylock()) {
>>>> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>>>> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>>> Wondering why this need be updated.
>> In some architectures, additional kexec segments become obsolete during a
>> hotplug event,
>> so simply calling out the `elfcorehdr may be inaccurate` may not be
>> sufficient.
>> Therefore, it has been generalized with the kdump image.
> OK, I forgot the case in ppc, makes sense to me, thx.
>
> Acked-by: Baoquan He <bhe at redhat.com>

Thanks for the Ack!

- Sourabh Jain


From catalin.marinas at arm.com  Tue Aug 13 05:04:31 2024
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 13 Aug 2024 13:04:31 +0100
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <20240813104006.520bf42d@mordecai.tesarici.cz>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
 <ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
 <ZrJ1JkyDVpRRB_9e@arm.com>
 <ZrJ60vopeGDXFZyK@arm.com>
 <20240813104006.520bf42d@mordecai.tesarici.cz>
Message-ID: <ZrtLz8VHzZIULbOT@arm.com>

Hi Petr,

On Tue, Aug 13, 2024 at 10:40:06AM +0200, Petr Tesa??k wrote:
> On Tue, 6 Aug 2024 20:34:42 +0100
> Catalin Marinas <catalin.marinas at arm.com> wrote:
> > I haven't tried but it's possible that this patch also breaks those
> > arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> > memblock_end_of_DRAM(). Here all memory would be low and in the absence
> > of no fallback, it fails to allocate.
> 
> I'm afraid you've just opened a Pandora box... ;-)

Not that bad ;) but, yeah, this patch was dropped in favour of this:

https://lore.kernel.org/r/20240812062017.2674441-1-ruanjinjie at huawei.com/

> Another (unrelated) patch series made us aware of a platforms where RAM
> starts at 32G, but IIUC the host bridge maps 32G-33G to bus addresses
> 0-1G, and there is a device on that bus which can produce only 30-bit
> addresses.
> 
> Now, what was the idea behind allocating some crash memory "low"?
> Right, it should allow the crash kernel to access devices with
> addressing constraints. So, on the above-mentioned platform, allocating
> "low" would in fact mean allocating between 32G and 33G (in host address
> domain).

Indeed. If that's not available, the crash kernel won't be able to boot
(unless the corresponding device is removed from DT or ACPI tables).

> Should we rethink the whole concept of high/low?

Yeah, it would be good to revisit those at some point. For the time
being, 'low' in this context on arm64 means ZONE_DMA memory, basically
the common denominator address range that supports all devices on an
SoC. For others like x86_32, this means the memory that the kernel can
actually map (not necessarily device/DMA related).

So, it's not always about the DMA capabilities but also what the crash
kernel can map (so somewhat different from the zone allocator case we've
been discussing in other threads).

-- 
Catalin


From petr at tesarici.cz  Tue Aug 13 06:33:52 2024
From: petr at tesarici.cz (Petr =?UTF-8?B?VGVzYcWZw61r?=)
Date: Tue, 13 Aug 2024 15:33:52 +0200
Subject: [PATCH -next] crash: Fix riscv64 crash memory reserve dead loop
In-Reply-To: <ZrtLz8VHzZIULbOT@arm.com>
References: <20240802090105.3871929-1-ruanjinjie@huawei.com>
	<ZqywtegyIS/YXOVv@MiWiFi-R3L-srv>
	<ZrJ1JkyDVpRRB_9e@arm.com>
	<ZrJ60vopeGDXFZyK@arm.com>
	<20240813104006.520bf42d@mordecai.tesarici.cz>
	<ZrtLz8VHzZIULbOT@arm.com>
Message-ID: <20240813153338.1972c10c@mordecai.tesarici.cz>

On Tue, 13 Aug 2024 13:04:31 +0100
Catalin Marinas <catalin.marinas at arm.com> wrote:

> Hi Petr,
> 
> On Tue, Aug 13, 2024 at 10:40:06AM +0200, Petr Tesa??k wrote:
> > On Tue, 6 Aug 2024 20:34:42 +0100
> > Catalin Marinas <catalin.marinas at arm.com> wrote:  
> > > I haven't tried but it's possible that this patch also breaks those
> > > arm64 platforms with all RAM above 4GB when CRASH_ADDR_LOW_MAX is
> > > memblock_end_of_DRAM(). Here all memory would be low and in the absence
> > > of no fallback, it fails to allocate.  
> > 
> > I'm afraid you've just opened a Pandora box... ;-)  
> 
> Not that bad ;) but, yeah, this patch was dropped in favour of this:
> 
> https://lore.kernel.org/r/20240812062017.2674441-1-ruanjinjie at huawei.com/

Yes, I have noticed. That one simply preserves the status quo and a
fuzzy definition of "low".

> > Another (unrelated) patch series made us aware of a platforms where RAM
> > starts at 32G, but IIUC the host bridge maps 32G-33G to bus addresses
> > 0-1G, and there is a device on that bus which can produce only 30-bit
> > addresses.
> > 
> > Now, what was the idea behind allocating some crash memory "low"?
> > Right, it should allow the crash kernel to access devices with
> > addressing constraints. So, on the above-mentioned platform, allocating
> > "low" would in fact mean allocating between 32G and 33G (in host address
> > domain).  
> 
> Indeed. If that's not available, the crash kernel won't be able to boot
> (unless the corresponding device is removed from DT or ACPI tables).

Then it may be able to boot, but it won't be able to save a crash dump
on disk or send it over the network, rendering the panic kernel
environment a bit less useful. 

> > Should we rethink the whole concept of high/low?  
> 
> Yeah, it would be good to revisit those at some point. For the time
> being, 'low' in this context on arm64 means ZONE_DMA memory, basically
> the common denominator address range that supports all devices on an
> SoC. For others like x86_32, this means the memory that the kernel can
> actually map (not necessarily device/DMA related).

Ah, right. I forgot that there are also constraints on the placement of
the kernel identity mapping in CPU physical address space.

> So, it's not always about the DMA capabilities but also what the crash
> kernel can map (so somewhat different from the zone allocator case we've
> been discussing in other threads).

It seems to me that a good panic kernel environment requires:

  1. memory where kernel text/data can be mapped (even at early init)
  2. memory that is accessible to I/O devices
  3. memory that can be allocated to user space (e.g. makedumpfile)

The first two blocks may require special placement in bus/CPU physical
address space, the third does not, but it needs to be big enough for
the workload.

I'll try to transform this knowledge into something actionable or even
reviewable.

For now, I agree there's nothing more to discuss.

Thanks
Petr T


From horms at kernel.org  Tue Aug 13 07:26:32 2024
From: horms at kernel.org (Simon Horman)
Date: Tue, 13 Aug 2024 15:26:32 +0100
Subject: [PATCH 0/7] Kexec-tools: Improve RISC-V port
In-Reply-To: <20240812163633.098f8f07@mordecai.tesarici.cz>
References: <20230915035013.1582679-1-songshuaishuai@tinylab.org>
 <20230920115634.GG224399@kernel.org>
 <DA84A55096BADE15+594e239a-ff6a-368f-ae92-b6cfebbf8dc0@tinylab.org>
 <CALu+AoSr+an7Ps-jhcSbvrq4E4FnqkiNZVH-2BhV_3=B+oDcFQ@mail.gmail.com>
 <20240518083304.GD475595@kernel.org>
 <20240812163633.098f8f07@mordecai.tesarici.cz>
Message-ID: <20240813142632.GA69536@kernel.org>

On Mon, Aug 12, 2024 at 04:36:33PM +0200, Petr Tesarik wrote:
> Hi,
> 
> On Sat, 18 May 2024 09:33:04 +0100
> Simon Horman <horms at kernel.org> wrote:
> 
> > On Sat, May 18, 2024 at 11:39:18AM +0800, Dave Young wrote:
> > > On Wed, 11 Oct 2023 at 13:24, Song Shuai <songshuaishuai at tinylab.org> wrote:  
> > > >
> > > >
> > > >
> > > > ? 2023/9/20 19:56, Simon Horman ??:  
> > > > > On Fri, Sep 15, 2023 at 11:50:06AM +0800, Song Shuai wrote:  
> > > > >> Hi,
> > > > >>
> > > > >> This series is created to improve RISC-V port of kexec-tools,
> > > > >> and is based on the horms/kexec-tools:build-test-riscv-v2 branch.  
> > > > >
> > > > > In my mind the big question is how to move RISC-V support
> > > > > from that branch, to being merged into main.
> > > > >
> > > > > IIRC there were some issues that needed to be addressed.
> > > > > Perhaps they are all addressed by this series, and with
> > > > > some appropriate squashing we can move forwards with a series
> > > > > based on main?  
> > > >
> > > > Hi, Simon and Nick:
> > > >
> > > > I squashed the first four patches as a "RISC-V: Some fixes for riscv
> > > > port" patch and then took the horms/main as the base to collect the 2
> > > > patches from horms/build-test-riscv-v2 branch and this series togother.
> > > > These are the Github link and all commits for RISC-V.
> > > >
> > > > https://github.com/sugarfillet/kexec-tools/commits/main_rv
> > > >
> > > > 5dc133e RISC-V: Support loading Image binary file
> > > > b042f6d RISC-V: Separate elf_riscv_find_pbase out
> > > > 8f344c7 RISC-V: Enable kexec_file_load syscall
> > > > 7d4b982 RISC-V: Some fixes for riscv port
> > > > 3205c1c local: RISC-V: distribute purgatory/riscv/Makefile
> > > > 54f9daf RISC-V: Add support for riscv kexec/kdump on kexec-tools
> > > >
> > > > Since I didn't found the issues/fixes as Nick mentioned with these
> > > > commits, I prefer to merge them into horms/main and let more kexec/kdump
> > > > users to help improve/fixup RISC-V port.  
> > > 
> > > Hi,  I noticed another pr for Fedora kexec-tools:
> > > https://src.fedoraproject.org/rpms/kexec-tools/pull-request/24
> > > 
> > > It is bad to take it as Fedora only,   I would suggest posting all the
> > > refreshed patches together here again for review.
> > > 
> > > If no enough reviewers can review them my another suggestion is to
> > > drop the kexec_load support code for the time being, and only enable
> > > the kexec_file_load support code in kexec-tools, and I assume below
> > > kernel commit make the kexec_file_load kernel piece of work done.
> > > Then it will be easier to review and make something working at least.
> > > commit 6261586e0c91db14c34f894f4bc48f2300cff1d4
> > > Author: Liao Chang <liaochang1 at huawei.com>
> > > Date:   Fri Apr 8 18:09:11 2022 +0800
> > > 
> > >     RISC-V: Add kexec_file support  
> > 
> > Hi,
> > 
> > I would gladly take a patchset for kexec-tools that adds RISC-V support in
> > a coherent manner.
> 
> Have I missed some progress on this topic? FWIW I can take care of
> RISC-V support in kexec-tools, I even received a VisionFive 2 board
> from RVI last year specifically to help with kexec.
> 
> I merely don't want to duplicate efforts or "steal" someone else's
> project. Is RISC-V support in kexec-tools an orphaned project now?

Hi Petr,

If there has been progress then I am not aware of it.
And if you would like to step up and provide a single, well structured,
patchset that adds RISC-V support then I for one would be most grateful.



From horms at kernel.org  Tue Aug 13 07:29:01 2024
From: horms at kernel.org (Simon Horman)
Date: Tue, 13 Aug 2024 15:29:01 +0100
Subject: [PATCH] Add support for soft reserved memory range
In-Reply-To: <CAKVxXCVpgdybjKFbAQjOKbhepHuwtzqjZjtW_E6YUb3Yh758TQ@mail.gmail.com>
References: <CAKVxXCVpgdybjKFbAQjOKbhepHuwtzqjZjtW_E6YUb3Yh758TQ@mail.gmail.com>
Message-ID: <20240813142901.GB69536@kernel.org>

On Tue, Aug 06, 2024 at 09:57:24PM -0500, Jacek Tomaka wrote:
> Essentially catch up with e820 related changes in the kernel.
> Intel Sapphire Rapids MAX has high bandwidth memory which is
> precious resource that is better not allocated by the kernel.
> 
> Userspace later can enable soft reserved range using daxctl.
> 
> Signed-off-by: Jacek Tomaka <jacek.tomaka at poczta.fm>

Hi Jacek,

Unfortunately this patch does not apply - it looks like
somehow indentation white space has been collapsed.

Would it be possible for you to repost.
Perhaps using b4 or get format-patch + git send-email ?

Thanks!


From wangming01 at loongson.cn  Tue Aug 13 19:43:15 2024
From: wangming01 at loongson.cn (Ming Wang)
Date: Wed, 14 Aug 2024 10:43:15 +0800
Subject: [PATCH makedumpfile] Fix incorrect PFN exclusion when LOAD segments overlap
Message-ID: <20240814024315.3166766-1-wangming01@loongson.cn>

When iterating through LOAD segments to exclude pages in
`exclude_nodata_pages`, simply using `phys_end` to track allocated
PFNs can lead to the erroneous exclusion of valid pages from a
subsequent LOAD segment if its `phys_start` overlaps with the
previous segment's address range.

This patch addresses the issue by checking for such overlaps with the
next LOAD segment's physical address range. If an overlap is
detected, we continue including PFNs from the current segment until
reaching the end of the overlapping region.

This fix ensures that all valid pages within overlapping LOAD segments
are correctly included during PFN exclusion.

Signed-off-by: Ming Wang <wangming01 at loongson.cn>
---
 makedumpfile.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index ce0d40e..f07f831 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -5207,7 +5207,7 @@ static void
 exclude_nodata_pages(struct cycle *cycle)
 {
 	int i;
-	unsigned long long phys_start, phys_end;
+	unsigned long long phys_start, phys_end, next_phys_start, next_phys_end, overlap;
 	off_t file_size;
 
 	i = 0;
@@ -5222,7 +5222,25 @@ exclude_nodata_pages(struct cycle *cycle)
 			pfn = cycle->start_pfn;
 		if (pfn_end >= cycle->end_pfn)
 			pfn_end = cycle->end_pfn;
-		while (pfn < pfn_end) {
+
+		/**
+		 * phys_start                        phys_end
+		 * LOAD[ 0]           200000          2186200
+		 * LOAD[ 1]           200000          ee00000
+		 * LOAD[ 2]         90400000         b8a00000
+		 *
+		 * In the above example, When iterating through LOAD segments, simply excluding
+		 * already allocated Physical Frames (PFNs) based on 'phys_end' can lead to an
+		 * incorrect exclusion of valid pages within load[1], particularly in overlapping
+		 * regions between load[0] and load[1].
+		 */
+		get_pt_load_extents(i + 1, &next_phys_start, &next_phys_end, NULL, &file_size);
+		if (next_phys_start == phys_start && next_phys_end > phys_end)
+			overlap = TRUE;
+		else
+			overlap = FALSE;
+
+		while (pfn < pfn_end && !overlap) {
 			clear_bit_on_2nd_bitmap(pfn, cycle);
 			++pfn;
 		}
-- 
2.39.2



From jacekt at dugeo.com  Tue Aug 13 22:33:13 2024
From: jacekt at dugeo.com (Jacek Tomaka)
Date: Wed, 14 Aug 2024 13:33:13 +0800
Subject: [PATCH] Add support for soft reserved memory range
In-Reply-To: <20240814052024.25731-1-jacekt@dugeo.com>
References: <20240814052024.25731-1-jacekt@dugeo.com>
Message-ID: <20240814053313.35251-1-jacekt@dugeo.com>

Essentially catch up with e820 related changes in the kernel.
Intel Sapphire Rappids MAX has high bandwidth memory which is
precious resource that is better not allocated by the kernel.

Userspace later can enable soft reserved range using daxctl.

Signed-off-by: Jacek Tomaka <jacek.tomaka at poczta.fm>
---
 include/x86/x86-linux.h               | 2 ++
 kexec/arch/i386/crashdump-x86.c       | 7 +++++++
 kexec/arch/i386/kexec-multiboot-x86.c | 1 +
 kexec/arch/i386/kexec-x86-common.c    | 5 +++++
 kexec/arch/i386/x86-linux-setup.c     | 3 +++
 kexec/firmware_memmap.c               | 2 ++
 kexec/kexec.h                         | 1 +
 7 files changed, 21 insertions(+)

diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
index 9646102835..fbde93df94 100644
--- a/include/x86/x86-linux.h
+++ b/include/x86/x86-linux.h
@@ -23,6 +23,8 @@ struct e820entry {
 #define E820_NVS	4
 #define E820_PMEM       7
 #define E820_PRAM       12
+#define E820_SOFT_RESERVED 0xefffffff
+
 } __attribute__((packed));
 #endif
 
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index a01031e570..49108b2032 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -288,6 +288,10 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
 			type = RANGE_RESERVED;
 		} else if (memcmp(str, "Reserved\n", 9) == 0) {
 			type = RANGE_RESERVED;
+		} else if (memcmp(str, "soft reserved\n", 14) == 0 ) {
+			type = RANGE_SOFT_RESERVED;
+		} else if (memcmp(str, "Soft Reserved\n", 14) == 0 ) {
+			type = RANGE_SOFT_RESERVED;
 		} else if (memcmp(str, "GART\n", 5) == 0) {
 			gart_start = start;
 			gart_end = end;
@@ -615,6 +619,8 @@ static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk,
 		strcat (str_mmap, "K@");
 	else if (type == RANGE_RESERVED)
 		strcat (str_mmap, "K$");
+	else if (type == RANGE_SOFT_RESERVED)
+		strcat (str_mmap, "K*");
 	else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
 		strcat (str_mmap, "K#");
 	else if (type == RANGE_PRAM)
@@ -985,6 +991,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 		if ( !( mem_range[i].type == RANGE_ACPI
 			|| mem_range[i].type == RANGE_ACPI_NVS
 			|| mem_range[i].type == RANGE_RESERVED
+			|| mem_range[i].type == RANGE_SOFT_RESERVED
 			|| mem_range[i].type == RANGE_PMEM
 			|| mem_range[i].type == RANGE_PRAM))
 			continue;
diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c
index 33c885a2fa..49d57cb5ae 100644
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -379,6 +379,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 			mmap[i].Type = 4;
 			break;
 		case RANGE_RESERVED:
+		case RANGE_SOFT_RESERVED:
 		default:
 			mmap[i].Type = 2;  /* Not RAM (reserved) */
 		}
diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
index ffc95a9e43..116c4f4fd3 100644
--- a/kexec/arch/i386/kexec-x86-common.c
+++ b/kexec/arch/i386/kexec-x86-common.c
@@ -99,6 +99,9 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges
 		else if (strncasecmp(str, "reserved\n", 9) == 0) {
 			type = RANGE_RESERVED;
 		}
+		else if (strncasecmp(str, "soft reserved\n", 9) == 0) {
+			type = RANGE_SOFT_RESERVED;
+		}
 		else if (memcmp(str, "ACPI Tables\n", 12) == 0) {
 			type = RANGE_ACPI;
 		}
@@ -170,6 +173,8 @@ unsigned xen_e820_to_kexec_type(uint32_t type)
 			return RANGE_PMEM;
 		case E820_PRAM:
 			return RANGE_PRAM;
+		case E820_SOFT_RESERVED;
+			return RANGE_SOFT_RESERVED;
 		case E820_RESERVED:
 		default:
 			return RANGE_RESERVED;
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 73251b9339..afc83fe729 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -755,6 +755,9 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode,
 			case RANGE_PRAM:
 				e820[i].type = E820_PRAM;
 				break;
+			case RANGE_SOFT_RESERVED:
+				e820[i].type = E820_SOFT_RESERVED;
+				break;
 			default:
 			case RANGE_RESERVED:
 				e820[i].type = E820_RESERVED;
diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c
index 457c3dc9a6..fa0c22140a 100644
--- a/kexec/firmware_memmap.c
+++ b/kexec/firmware_memmap.c
@@ -182,6 +182,8 @@ static int parse_memmap_entry(const char *entry, struct memory_range *range)
 		range->type = RANGE_RESERVED;
 	else if (strcmp(type, "Reserved") == 0)
 		range->type = RANGE_RESERVED;
+        else if (strcmp(type, "Soft Reserved") == 0)
+                range->type = RANGE_SOFT_RESERVED;
 	else if (strcmp(type, "Unknown E820 type") == 0)
 		range->type = RANGE_RESERVED;
 	else if (strcmp(type, "ACPI Non-volatile Storage") == 0)
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 31c323f674..dbb27a7607 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -139,6 +139,7 @@ struct memory_range {
 #define RANGE_UNCACHED	4
 #define RANGE_PMEM		6
 #define RANGE_PRAM		11
+#define RANGE_SOFT_RESERVED 0xefffffff
 };
 
 struct memory_ranges {
-- 
2.17.0



From dyoung at redhat.com  Wed Aug 14 01:23:04 2024
From: dyoung at redhat.com (Dave Young)
Date: Wed, 14 Aug 2024 16:23:04 +0800
Subject: [PATCH 0/7] Kexec-tools: Improve RISC-V port
In-Reply-To: <20240812163633.098f8f07@mordecai.tesarici.cz>
References: <20230915035013.1582679-1-songshuaishuai@tinylab.org>
 <20230920115634.GG224399@kernel.org> <DA84A55096BADE15+594e239a-ff6a-368f-ae92-b6cfebbf8dc0@tinylab.org>
 <CALu+AoSr+an7Ps-jhcSbvrq4E4FnqkiNZVH-2BhV_3=B+oDcFQ@mail.gmail.com>
 <20240518083304.GD475595@kernel.org> <20240812163633.098f8f07@mordecai.tesarici.cz>
Message-ID: <CALu+AoSmG9eehL+udT2KHzn4H5Gq9eJ_t-C_H8mkJMhvB3VpPQ@mail.gmail.com>

On Mon, 12 Aug 2024 at 22:36, Petr Tesarik <ptesarik at suse.com> wrote:
>
> Hi,
>
> On Sat, 18 May 2024 09:33:04 +0100
> Simon Horman <horms at kernel.org> wrote:
>
> > On Sat, May 18, 2024 at 11:39:18AM +0800, Dave Young wrote:
> > > On Wed, 11 Oct 2023 at 13:24, Song Shuai <songshuaishuai at tinylab.org> wrote:
> > > >
> > > >
> > > >
> > > > ? 2023/9/20 19:56, Simon Horman ??:
> > > > > On Fri, Sep 15, 2023 at 11:50:06AM +0800, Song Shuai wrote:
> > > > >> Hi,
> > > > >>
> > > > >> This series is created to improve RISC-V port of kexec-tools,
> > > > >> and is based on the horms/kexec-tools:build-test-riscv-v2 branch.
> > > > >
> > > > > In my mind the big question is how to move RISC-V support
> > > > > from that branch, to being merged into main.
> > > > >
> > > > > IIRC there were some issues that needed to be addressed.
> > > > > Perhaps they are all addressed by this series, and with
> > > > > some appropriate squashing we can move forwards with a series
> > > > > based on main?
> > > >
> > > > Hi, Simon and Nick:
> > > >
> > > > I squashed the first four patches as a "RISC-V: Some fixes for riscv
> > > > port" patch and then took the horms/main as the base to collect the 2
> > > > patches from horms/build-test-riscv-v2 branch and this series togother.
> > > > These are the Github link and all commits for RISC-V.
> > > >
> > > > https://github.com/sugarfillet/kexec-tools/commits/main_rv
> > > >
> > > > 5dc133e RISC-V: Support loading Image binary file
> > > > b042f6d RISC-V: Separate elf_riscv_find_pbase out
> > > > 8f344c7 RISC-V: Enable kexec_file_load syscall
> > > > 7d4b982 RISC-V: Some fixes for riscv port
> > > > 3205c1c local: RISC-V: distribute purgatory/riscv/Makefile
> > > > 54f9daf RISC-V: Add support for riscv kexec/kdump on kexec-tools
> > > >
> > > > Since I didn't found the issues/fixes as Nick mentioned with these
> > > > commits, I prefer to merge them into horms/main and let more kexec/kdump
> > > > users to help improve/fixup RISC-V port.
> > >
> > > Hi,  I noticed another pr for Fedora kexec-tools:
> > > https://src.fedoraproject.org/rpms/kexec-tools/pull-request/24
> > >
> > > It is bad to take it as Fedora only,   I would suggest posting all the
> > > refreshed patches together here again for review.
> > >
> > > If no enough reviewers can review them my another suggestion is to
> > > drop the kexec_load support code for the time being, and only enable
> > > the kexec_file_load support code in kexec-tools, and I assume below
> > > kernel commit make the kexec_file_load kernel piece of work done.
> > > Then it will be easier to review and make something working at least.
> > > commit 6261586e0c91db14c34f894f4bc48f2300cff1d4
> > > Author: Liao Chang <liaochang1 at huawei.com>
> > > Date:   Fri Apr 8 18:09:11 2022 +0800
> > >
> > >     RISC-V: Add kexec_file support
> >
> > Hi,
> >
> > I would gladly take a patchset for kexec-tools that adds RISC-V support in
> > a coherent manner.
>
> Have I missed some progress on this topic? FWIW I can take care of
> RISC-V support in kexec-tools, I even received a VisionFive 2 board
> from RVI last year specifically to help with kexec.
>
> I merely don't want to duplicate efforts or "steal" someone else's
> project. Is RISC-V support in kexec-tools an orphaned project now?
>

I thought about a simple kexec_file_load only approach previously but
I have no time to work on it actually.  In theory I think a simple
kexec_file_load implementation should only share some common functions
eg. arguments parsing, file reading etc. and load the kernel and
initrd into memory, pass the fds and cmdline buffer into kernel,
that's all,  Even no need to have the arch specific file format
checking as they should have been done in the related kernel code.
But looking at the code it is not easy.  Currently the kexec_load and
kexec_file_load implementations are not logically separate in the code
and the cleanup is hard.

Thanks
Dave



From patchwork-bot+linux-riscv at kernel.org  Wed Aug 14 07:10:33 2024
From: patchwork-bot+linux-riscv at kernel.org (patchwork-bot+linux-riscv at kernel.org)
Date: Wed, 14 Aug 2024 14:10:33 +0000
Subject: [PATCH v1] riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and
 R_RISCV_SUB16 unknown
In-Reply-To: <20240711083236.2859632-1-sunying@isrc.iscas.ac.cn>
References: <20240711083236.2859632-1-sunying@isrc.iscas.ac.cn>
Message-ID: <172364463350.2278280.14691701821976528565.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer at rivosinc.com>:

On Thu, 11 Jul 2024 08:32:36 +0000 you wrote:
> From: Ying Sun <sunying at isrc.iscas.ac.cn>
> 
> Runs on the kernel with CONFIG_RISCV_ALTERNATIVE enabled:
>   kexec -sl vmlinux
> 
> Error:
>   kexec_image: Unknown rela relocation: 34
>   kexec_image: Error loading purgatory ret=-8
> and
>   kexec_image: Unknown rela relocation: 38
>   kexec_image: Error loading purgatory ret=-8
> 
> [...]

Here is the summary with links:
  - [v1] riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and R_RISCV_SUB16 unknown
    https://git.kernel.org/riscv/c/2d1f51d8a4b0

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From bhe at redhat.com  Wed Aug 14 23:15:40 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 15 Aug 2024 14:15:40 +0800
Subject: [PATCHv2 3/4] x86/64/kexec: Map original relocate_kernel() in
 init_transition_pgtable()
In-Reply-To: <20240814124613.2632226-4-kirill.shutemov@linux.intel.com>
References: <20240814124613.2632226-1-kirill.shutemov@linux.intel.com>
 <20240814124613.2632226-4-kirill.shutemov@linux.intel.com>
Message-ID: <Zr2dDKP4JuRUSOL3@MiWiFi-R3L-srv>

Cc Eric and kexec mailing list.

On 08/14/24 at 03:46pm, Kirill A. Shutemov wrote:
> The init_transition_pgtable() function sets up transitional page tables.
> It ensures that the relocate_kernel() function is present in the
> identity mapping at the same location as in the kernel page tables.
> relocate_kernel() switches to the identity mapping, and the function
> must be present at the same location in the virtual address space before
> and after switching page tables.
> 
> init_transition_pgtable() maps a copy of relocate_kernel() in
> image->control_code_page at the relocate_kernel() virtual address, but
> the original physical address of relocate_kernel() would also work.
> 
> It is safe to use original relocate_kernel() physical address cannot be
> overwritten until swap_pages() is called, and the relocate_kernel()
> virtual address will not be used by then.

I haven't read these codes for long time, wondering if we still need
copy relocate_kernel() to image->control_code_page + PAGE_SIZE as you
said.

> 
> Map the original relocate_kernel() at the relocate_kernel() virtual
> address in the identity mapping. It is preparation to replace the
> init_transition_pgtable() implementation with a call to
> kernel_ident_mapping_init().
> 
> Note that while relocate_kernel() switches to the identity mapping, it
> does not flush global TLB entries (CR4.PGE is not cleared). This means
> that in most cases, the kernel still runs relocate_kernel() from the
> original physical address before the change.
> 
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
> ---
>  arch/x86/kernel/machine_kexec_64.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
> index 9c9ac606893e..645690e81c2d 100644
> --- a/arch/x86/kernel/machine_kexec_64.c
> +++ b/arch/x86/kernel/machine_kexec_64.c
> @@ -157,7 +157,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
>  	pte_t *pte;
>  
>  	vaddr = (unsigned long)relocate_kernel;
> -	paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE);
> +	paddr = __pa(relocate_kernel);
>  	pgd += pgd_index(vaddr);
>  	if (!pgd_present(*pgd)) {
>  		p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL);
> -- 
> 2.43.0
> 



From kirill.shutemov at linux.intel.com  Thu Aug 15 02:18:32 2024
From: kirill.shutemov at linux.intel.com (Kirill A. Shutemov)
Date: Thu, 15 Aug 2024 12:18:32 +0300
Subject: [PATCHv2 3/4] x86/64/kexec: Map original relocate_kernel() in
 init_transition_pgtable()
In-Reply-To: <Zr2dDKP4JuRUSOL3@MiWiFi-R3L-srv>
References: <20240814124613.2632226-1-kirill.shutemov@linux.intel.com>
 <20240814124613.2632226-4-kirill.shutemov@linux.intel.com>
 <Zr2dDKP4JuRUSOL3@MiWiFi-R3L-srv>
Message-ID: <6a5jgjdwnjseqxsxfzfcyflqyrpmzr7n5ki5haxc3e6llu5cbe@3lmi4qbfol7q>

On Thu, Aug 15, 2024 at 02:15:40PM +0800, Baoquan He wrote:
> Cc Eric and kexec mailing list.
> 
> On 08/14/24 at 03:46pm, Kirill A. Shutemov wrote:
> > The init_transition_pgtable() function sets up transitional page tables.
> > It ensures that the relocate_kernel() function is present in the
> > identity mapping at the same location as in the kernel page tables.
> > relocate_kernel() switches to the identity mapping, and the function
> > must be present at the same location in the virtual address space before
> > and after switching page tables.
> > 
> > init_transition_pgtable() maps a copy of relocate_kernel() in
> > image->control_code_page at the relocate_kernel() virtual address, but
> > the original physical address of relocate_kernel() would also work.
> > 
> > It is safe to use original relocate_kernel() physical address cannot be
> > overwritten until swap_pages() is called, and the relocate_kernel()
> > virtual address will not be used by then.
> 
> I haven't read these codes for long time, wondering if we still need
> copy relocate_kernel() to image->control_code_page + PAGE_SIZE as you
> said.

I think we can get away with only coping starting with identity_mapped().
But given that KEXEC_CONTROL_CODE_MAX_SIZE is 2K I don't see a reason to
change anything here.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov


From stefan.wiehler at nokia.com  Thu Aug 15 07:17:33 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Thu, 15 Aug 2024 16:17:33 +0200
Subject: [PATCH 1/2] makedumpfile: Add ftruncate error handling
Message-ID: <20240815141733.4050230-2-stefan.wiehler@nokia.com>

Found via -Werror:

  makedumpfile.c: In function ?dump_dmesg?:
  makedumpfile.c:5884:33: error: ignoring return value of ?ftruncate? declared with attribute ?warn_unused_result? [-Werror=unused-result]
   5884 |                                 ftruncate(info->fd_dumpfile, 0);
        |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
---
 makedumpfile.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index ce0d40e..c6f70ff 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -5881,7 +5881,11 @@ dump_dmesg()
 				char *first;
 
 				/* Clear everything we have already written... */
-				ftruncate(info->fd_dumpfile, 0);
+				if (ftruncate(info->fd_dumpfile, 0) != 0) {
+					ERRMSG("Can't truncate file(%s). %s\n",
+					       info->name_dumpfile, strerror(errno));
+					goto out;
+				}
 				lseek(info->fd_dumpfile, 0, SEEK_SET);
 
 				/* ...and only write up to the corruption. */
-- 
2.42.0



From stefan.wiehler at nokia.com  Thu Aug 15 07:17:34 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Thu, 15 Aug 2024 16:17:34 +0200
Subject: [PATCH 2/2] sadump_info: Return empty string instead of NULL
In-Reply-To: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
References: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
Message-ID: <20240815141733.4050230-3-stefan.wiehler@nokia.com>

Found via -Werror:

  In file included from makedumpfile.h:47,
                   from makedumpfile.c:16:
  makedumpfile.c: In function ?initial?:
  makedumpfile.c:4546:29: error: ?%s? directive argument is null [-Werror=format-overflow=]
   4546 |                         MSG("because %s is sadump %s format.\n",
        |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  print_info.h:61:41: note: in definition of macro ?MSG?
     61 |                         fprintf(stdout, x); \
        |                                         ^
  makedumpfile.c:4546:51: note: format string is defined here
   4546 |                         MSG("because %s is sadump %s format.\n",
        |                                                   ^~
  makedumpfile.c:4546:29: error: ?%s? directive argument is null [-Werror=format-overflow=]
   4546 |                         MSG("because %s is sadump %s format.\n",
        |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  print_info.h:59:41: note: in definition of macro ?MSG?
     59 |                         fprintf(stderr, x); \
        |                                         ^
  makedumpfile.c:4546:51: note: format string is defined here
   4546 |                         MSG("because %s is sadump %s format.\n",
        |

Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
---
 sadump_info.c | 2 +-
 sadump_info.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sadump_info.c b/sadump_info.c
index 2c44068..0dbde90 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -2351,7 +2351,7 @@ sadump_format_type_name(void)
 	case SADUMP_UNKNOWN:
 		return "unknown";
 	}
-	return NULL;
+	return "";
 }
 
 void
diff --git a/sadump_info.h b/sadump_info.h
index 131687a..f7872b4 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -142,7 +142,7 @@ sadump_head_disk_name_memory(void)
 
 static inline char *sadump_format_type_name(void)
 {
-	return NULL;
+	return "";
 }
 
 static inline void free_sadump_info(void)
-- 
2.42.0



From dpsmith at apertussolutions.com  Thu Aug 15 10:38:52 2024
From: dpsmith at apertussolutions.com (Daniel P. Smith)
Date: Thu, 15 Aug 2024 13:38:52 -0400
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <874jaegk8i.fsf@email.froward.int.ebiederm.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
Message-ID: <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>

On 5/31/24 09:54, Eric W. Biederman wrote:
> Eric Biggers <ebiggers at kernel.org> writes:
> 
>> On Thu, May 30, 2024 at 06:03:18PM -0700, Ross Philipson wrote:
>>> From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
>>>
>>> For better or worse, Secure Launch needs SHA-1 and SHA-256. The
>>> choice of hashes used lie with the platform firmware, not with
>>> software, and is often outside of the users control.
>>>
>>> Even if we'd prefer to use SHA-256-only, if firmware elected to start us
>>> with the SHA-1 and SHA-256 backs active, we still need SHA-1 to parse
>>> the TPM event log thus far, and deliberately cap the SHA-1 PCRs in order
>>> to safely use SHA-256 for everything else.
>>>
>>> The SHA-1 code here has its origins in the code from the main kernel:
>>>
>>> commit c4d5b9ffa31f ("crypto: sha1 - implement base layer for SHA-1")
>>>
>>> A modified version of this code was introduced to the lib/crypto/sha1.c
>>> to bring it in line with the SHA-256 code and allow it to be pulled into the
>>> setup kernel in the same manner as SHA-256 is.
>>>
>>> Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
>>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
>>
>> Thanks.  This explanation doesn't seem to have made it into the actual code or
>> documentation.  Can you please get it into a more permanent location?
>>
>> Also, can you point to where the "deliberately cap the SHA-1 PCRs" thing happens
>> in the code?
>>
>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
>> but why would you not at least *prefer* SHA-256?
> 
> Yes.  Please prefer to use SHA-256.
> 
> Have you considered implementing I think it is SHA1-DC (as git has) that
> is compatible with SHA1 but blocks the known class of attacks where
> sha1 is actively broken at this point?

We are using the kernel's implementation, addressing what the kernel 
provides is beyond our efforts. Perhaps someone who is interested in 
improving the kernel's SHA1 could submit a patch implementing/replacing 
it with SHA1-DC, as I am sure the maintainers would welcome the help.

v/r,
dps


From jarkko at kernel.org  Thu Aug 15 11:35:13 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Thu, 15 Aug 2024 21:35:13 +0300
Subject: [PATCH v9 09/19] x86: Secure Launch kernel late boot stub
In-Reply-To: <ad84cdaf-bea6-483e-82f3-c83a6b7006c3@oracle.com>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-10-ross.philipson@oracle.com>
 <D1RHZDG3HJNK.ZWTFLXDBEXD1@kernel.org>
 <ad84cdaf-bea6-483e-82f3-c83a6b7006c3@oracle.com>
Message-ID: <D3GPA85MRNMM.3GMP3BTBEEYFP@kernel.org>

On Mon Aug 12, 2024 at 10:02 PM EEST,  wrote:
> On 6/4/24 3:59 PM, Jarkko Sakkinen wrote:
> > On Fri May 31, 2024 at 4:03 AM EEST, Ross Philipson wrote:
> >> The routine slaunch_setup is called out of the x86 specific setup_arch()
> >> routine during early kernel boot. After determining what platform is
> >> present, various operations specific to that platform occur. This
> >> includes finalizing setting for the platform late launch and verifying
> >> that memory protections are in place.
> >>
> >> For TXT, this code also reserves the original compressed kernel setup
> >> area where the APs were left looping so that this memory cannot be used.
> >>
> >> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
> >> ---
> >>   arch/x86/kernel/Makefile   |   1 +
> >>   arch/x86/kernel/setup.c    |   3 +
> >>   arch/x86/kernel/slaunch.c  | 525 +++++++++++++++++++++++++++++++++++++
> >>   drivers/iommu/intel/dmar.c |   4 +
> >>   4 files changed, 533 insertions(+)
> >>   create mode 100644 arch/x86/kernel/slaunch.c
> >>
> >> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> >> index 5d128167e2e2..b35ca99ab0a0 100644
> >> --- a/arch/x86/kernel/Makefile
> >> +++ b/arch/x86/kernel/Makefile
> >> @@ -76,6 +76,7 @@ obj-$(CONFIG_X86_32)		+= tls.o
> >>   obj-$(CONFIG_IA32_EMULATION)	+= tls.o
> >>   obj-y				+= step.o
> >>   obj-$(CONFIG_INTEL_TXT)		+= tboot.o
> >> +obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
> > 
> > Hmm... should that be CONFIG_X86_SECURE_LAUNCH?
>
> Further thoughts on this after discussions...
>
> The Secure Launch feature will cover other architectures beyond x86 in 
> the future. We may have to rework/move the config settings at that point 
> but for now I don't think we want to change it.

OK got it.

BR, Jarkko


From dpsmith at apertussolutions.com  Thu Aug 15 11:52:33 2024
From: dpsmith at apertussolutions.com (Daniel P. Smith)
Date: Thu, 15 Aug 2024 14:52:33 -0400
Subject: [PATCH v9 13/19] tpm: Protect against locality counter underflow
In-Reply-To: <D1RI95NQL24F.2E53ZWDFAA8QM@kernel.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-14-ross.philipson@oracle.com>
 <D1RI95NQL24F.2E53ZWDFAA8QM@kernel.org>
Message-ID: <1c3d7b31-89c0-400f-8f37-45089f7078e8@apertussolutions.com>

On 6/4/24 16:12, Jarkko Sakkinen wrote:
> On Fri May 31, 2024 at 4:03 AM EEST, Ross Philipson wrote:
>> From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
>>
>> Commit 933bfc5ad213 introduced the use of a locality counter to control when a
>> locality request is allowed to be sent to the TPM. In the commit, the counter
>> is indiscriminately decremented. Thus creating a situation for an integer
>> underflow of the counter.
>>
>> Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
>> Reported-by: Kanth Ghatraju <kanth.ghatraju at oracle.com>
>> Fixes: 933bfc5ad213 ("tpm, tpm: Implement usage counter for locality")
> 
> Not sure if we have practical use for fixes tag here but open for
> argument ofc. I.e. I'm not sure what is the practical scenario to
> worry about if Trenchboot did not exist.

We can drop the fixes line.

>> ---
>>   drivers/char/tpm/tpm_tis_core.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>> index 176cd8dbf1db..7c1761bd6000 100644
>> --- a/drivers/char/tpm/tpm_tis_core.c
>> +++ b/drivers/char/tpm/tpm_tis_core.c
>> @@ -180,7 +180,8 @@ static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
>>   	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
>>   
>>   	mutex_lock(&priv->locality_count_mutex);
>> -	priv->locality_count--;
>> +	if (priv->locality_count > 0)
>> +		priv->locality_count--;
> 
> I'd signal the situation with pr_info() in else branch.

Ack.

>>   	if (priv->locality_count == 0)
>>   		__tpm_tis_relinquish_locality(priv, l);
>>   	mutex_unlock(&priv->locality_count_mutex);
> 
> BR, Jarkko


From tglx at linutronix.de  Thu Aug 15 12:10:14 2024
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 15 Aug 2024 21:10:14 +0200
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
Message-ID: <87ttflli09.ffs@tglx>

On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
> On 5/31/24 09:54, Eric W. Biederman wrote:
>> Eric Biggers <ebiggers at kernel.org> writes:
>>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
>>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
>>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
>>> but why would you not at least *prefer* SHA-256?
>> 
>> Yes.  Please prefer to use SHA-256.
>> 
>> Have you considered implementing I think it is SHA1-DC (as git has) that
>> is compatible with SHA1 but blocks the known class of attacks where
>> sha1 is actively broken at this point?
>
> We are using the kernel's implementation, addressing what the kernel 
> provides is beyond our efforts. Perhaps someone who is interested in 
> improving the kernel's SHA1 could submit a patch implementing/replacing 
> it with SHA1-DC, as I am sure the maintainers would welcome the help.

Well, someone who is interested to get his "secure" code merged should
have a vested interested to have a non-broken SHA1 implementation if
there is a sensible requirement to use SHA1 in that new "secure" code,
no?

Just for the record. The related maintainers can rightfully decide to
reject known broken "secure" code on a purely technical argument.

Thanks,

        tglx



From dpsmith at apertussolutions.com  Thu Aug 15 12:24:00 2024
From: dpsmith at apertussolutions.com (Daniel P. Smith)
Date: Thu, 15 Aug 2024 15:24:00 -0400
Subject: [PATCH v9 14/19] tpm: Ensure tpm is in known state at startup
In-Reply-To: <D1RIB8BHWRC5.3RRW0ZKV3KDVM@kernel.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-15-ross.philipson@oracle.com>
 <D1RIB8BHWRC5.3RRW0ZKV3KDVM@kernel.org>
Message-ID: <32f0bc58-c0a1-4c11-bd02-c6e61b0e2eb6@apertussolutions.com>

On 6/4/24 16:14, Jarkko Sakkinen wrote:
> On Fri May 31, 2024 at 4:03 AM EEST, Ross Philipson wrote:
>> From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
>>
>> When tis core initializes, it assumes all localities are closed. There
> 
> s/tis_core/tpm_tis_core/

Ack.

>> are cases when this may not be the case. This commit addresses this by
>> ensuring all localities are closed before initializing begins.
>>
>> Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
>> ---
>>   drivers/char/tpm/tpm_tis_core.c | 11 ++++++++++-
>>   include/linux/tpm.h             |  6 ++++++
>>   2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
>> index 7c1761bd6000..9fb53bb3e73f 100644
>> --- a/drivers/char/tpm/tpm_tis_core.c
>> +++ b/drivers/char/tpm/tpm_tis_core.c
>> @@ -1104,7 +1104,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>>   	u32 intmask;
>>   	u32 clkrun_val;
>>   	u8 rid;
>> -	int rc, probe;
>> +	int rc, probe, i;
>>   	struct tpm_chip *chip;
>>   
>>   	chip = tpmm_chip_alloc(dev, &tpm_tis);
>> @@ -1166,6 +1166,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
>>   		goto out_err;
>>   	}
>>   
>> +	/*
>> +	 * There are environments, like Intel TXT, that may leave a TPM
> 
> What else at this point than Intel TXT reflecting the state of the
> mainline?

Leaving the TPM in Locality 2 is a requirement of the TCG D-RTM 
specification. This will be the situation for AMD and Arm as well. The 
comment can be updated to ref the TCG spec instead of a specific 
implementation.

>> +	 * locality open. Close all localities to start from a known state.
>> +	 */
>> +	for (i = 0; i <= TPM_MAX_LOCALITY; i++) {
>> +		if (check_locality(chip, i))
>> +			tpm_tis_relinquish_locality(chip, i);
>> +	}
> 
> To be strict this should be enabled only for x86 platforms.
> 
> I.e. should be flagged.

As mentioned above, this will also affect Arm.

>> +
>>   	/* Take control of the TPM's interrupt hardware and shut it off */
>>   	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
>>   	if (rc < 0)
>> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
>> index c17e4efbb2e5..363f7078c3a9 100644
>> --- a/include/linux/tpm.h
>> +++ b/include/linux/tpm.h
>> @@ -147,6 +147,12 @@ struct tpm_chip_seqops {
>>    */
>>   #define TPM2_MAX_CONTEXT_SIZE 4096
>>   
>> +/*
>> + * The maximum locality (0 - 4) for a TPM, as defined in section 3.2 of the
>> + * Client Platform Profile Specification.
>> + */
>> +#define TPM_MAX_LOCALITY		4
>> +
>>   struct tpm_chip {
>>   	struct device dev;
>>   	struct device devs;
> 
> 
> BR, Jarkko

v/r,
dps


From k-hagio-ab at nec.com  Thu Aug 15 22:50:33 2024
From: k-hagio-ab at nec.com (=?utf-8?B?SEFHSU8gS0FaVUhJVE8o6JCp5bC+44CA5LiA5LuBKQ==?=)
Date: Fri, 16 Aug 2024 05:50:33 +0000
Subject: [PATCH 1/2] makedumpfile: Add ftruncate error handling
In-Reply-To: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
References: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
Message-ID: <db15a94c-3fa5-47e6-8c8d-59665bb119a8@nec.com>

On 2024/08/15 23:17, Stefan Wiehler wrote:
> Found via -Werror:
> 
>    makedumpfile.c: In function ?dump_dmesg?:
>    makedumpfile.c:5884:33: error: ignoring return value of ?ftruncate? declared with attribute ?warn_unused_result? [-Werror=unused-result]
>     5884 |                                 ftruncate(info->fd_dumpfile, 0);
>          |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Hi Stefan, thanks for the patch.

I tried to reproduce those warnings, but could not get either one
with a plain make command and gcc 14.1 (or clang 18.1).

out of curiosity, what compiler version and build command do you use?

Thanks,
Kazu

> 
> Signed-off-by: Stefan Wiehler <stefan.wiehler at nokia.com>
> ---
>   makedumpfile.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/makedumpfile.c b/makedumpfile.c
> index ce0d40e..c6f70ff 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -5881,7 +5881,11 @@ dump_dmesg()
>   				char *first;
>   
>   				/* Clear everything we have already written... */
> -				ftruncate(info->fd_dumpfile, 0);
> +				if (ftruncate(info->fd_dumpfile, 0) != 0) {
> +					ERRMSG("Can't truncate file(%s). %s\n",
> +					       info->name_dumpfile, strerror(errno));
> +					goto out;
> +				}
>   				lseek(info->fd_dumpfile, 0, SEEK_SET);
>   
>   				/* ...and only write up to the corruption. */

From ptesarik at suse.com  Thu Aug 15 23:33:49 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Fri, 16 Aug 2024 08:33:49 +0200
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <ZrFZM4W7S89VpfaG@MiWiFi-R3L-srv>
References: <20240805150750.170739-1-petr.tesarik@suse.com>
	<ZrFZM4W7S89VpfaG@MiWiFi-R3L-srv>
Message-ID: <20240816083349.3fd6f1c1@mordecai.tesarici.cz>

On Tue, 6 Aug 2024 06:59:35 +0800
Baoquan He <bhe at redhat.com> wrote:

> On 08/05/24 at 05:07pm, Petr Tesarik wrote:
> > From: Petr Tesarik <ptesarik at suse.com>
> > 
> > Fix the condition to exclude the elfcorehdr segment from the SHA digest
> > calculation.
> > 
> > The j iterator is an index into the output sha_regions[] array, not into
> > the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> > all subsequent segments are excluded. Besides, if the purgatory segment
> > precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> > the calculation.  
> 
> Indeed, good catch.
> 
> Acked-by: Baoquan He <bhe at redhat.com>

Thank you, Baoquan.

Who should apply the fix now? How can it be merged into Linus tree?

Petr T

> > 
> > Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> > Cc: stable at kernel.org
> > Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> > ---
> >  kernel/kexec_file.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> > index 3d64290d24c9..3eedb8c226ad 100644
> > --- a/kernel/kexec_file.c
> > +++ b/kernel/kexec_file.c
> > @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
> >  
> >  #ifdef CONFIG_CRASH_HOTPLUG
> >  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> > -		if (j == image->elfcorehdr_index)
> > +		if (i == image->elfcorehdr_index)
> >  			continue;
> >  #endif
> >  
> > -- 
> > 2.45.2
> >   
> 



From bhe at redhat.com  Fri Aug 16 00:12:38 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 16 Aug 2024 15:12:38 +0800
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <20240805150750.170739-1-petr.tesarik@suse.com>
References: <20240805150750.170739-1-petr.tesarik@suse.com>
Message-ID: <Zr775rzbuVP6AwMu@MiWiFi-R3L-srv>

Hi Andrew,

On 08/05/24 at 05:07pm, Petr Tesarik wrote:
> From: Petr Tesarik <ptesarik at suse.com>
> 
> Fix the condition to exclude the elfcorehdr segment from the SHA digest
> calculation.
> 
> The j iterator is an index into the output sha_regions[] array, not into
> the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> all subsequent segments are excluded. Besides, if the purgatory segment
> precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> the calculation.

Ping.

This is a good fix, could you pick this one into your tree?

Thanks
Baoquan

> 
> Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> Cc: stable at kernel.org
> Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> ---
>  kernel/kexec_file.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 3d64290d24c9..3eedb8c226ad 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
>  
>  #ifdef CONFIG_CRASH_HOTPLUG
>  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> -		if (j == image->elfcorehdr_index)
> +		if (i == image->elfcorehdr_index)
>  			continue;
>  #endif
>  
> -- 
> 2.45.2
> 



From jarkko at kernel.org  Fri Aug 16 03:42:13 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Fri, 16 Aug 2024 13:42:13 +0300
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <87ttflli09.ffs@tglx>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
Message-ID: <D3H9ULV1NH4M.1A8EKXWZFTEF2@kernel.org>

On Thu Aug 15, 2024 at 10:10 PM EEST, Thomas Gleixner wrote:
> On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
> > On 5/31/24 09:54, Eric W. Biederman wrote:
> >> Eric Biggers <ebiggers at kernel.org> writes:
> >>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
> >>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
> >>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
> >>> but why would you not at least *prefer* SHA-256?
> >> 
> >> Yes.  Please prefer to use SHA-256.
> >> 
> >> Have you considered implementing I think it is SHA1-DC (as git has) that
> >> is compatible with SHA1 but blocks the known class of attacks where
> >> sha1 is actively broken at this point?
> >
> > We are using the kernel's implementation, addressing what the kernel 
> > provides is beyond our efforts. Perhaps someone who is interested in 
> > improving the kernel's SHA1 could submit a patch implementing/replacing 
> > it with SHA1-DC, as I am sure the maintainers would welcome the help.

Git also has a bit more wide than secure launch, and the timeline is
also completely different. Git maintains legacy, while has also
introduced SHA-256 support in 2018. This as a new feature in the kernel
stack.

The purpose of SHA1-DC has obviously been to extend the lifespan, not
fix SHA-1.

Linux will be better of not adding anything new related to SHA-1 or
TPM 1.2. They still have a maintenance cost and I think that time
would be better spent of for almost anything else (starting from
taking your trashes out or boiling coffee) ;-)

>
> Well, someone who is interested to get his "secure" code merged should
> have a vested interested to have a non-broken SHA1 implementation if
> there is a sensible requirement to use SHA1 in that new "secure" code,
> no?
>
> Just for the record. The related maintainers can rightfully decide to
> reject known broken "secure" code on a purely technical argument.
>
> Thanks,
>
>         tglx

BR, Jarkko


From andrew.cooper3 at citrix.com  Fri Aug 16 04:01:15 2024
From: andrew.cooper3 at citrix.com (Andrew Cooper)
Date: Fri, 16 Aug 2024 12:01:15 +0100
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <87ttflli09.ffs@tglx>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
Message-ID: <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>

On 15/08/2024 8:10 pm, Thomas Gleixner wrote:
> On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
>> On 5/31/24 09:54, Eric W. Biederman wrote:
>>> Eric Biggers <ebiggers at kernel.org> writes:
>>>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
>>>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
>>>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
>>>> but why would you not at least *prefer* SHA-256?
>>> Yes.  Please prefer to use SHA-256.
>>>
>>> Have you considered implementing I think it is SHA1-DC (as git has) that
>>> is compatible with SHA1 but blocks the known class of attacks where
>>> sha1 is actively broken at this point?
>> We are using the kernel's implementation, addressing what the kernel 
>> provides is beyond our efforts. Perhaps someone who is interested in 
>> improving the kernel's SHA1 could submit a patch implementing/replacing 
>> it with SHA1-DC, as I am sure the maintainers would welcome the help.
> Well, someone who is interested to get his "secure" code merged should
> have a vested interested to have a non-broken SHA1 implementation if
> there is a sensible requirement to use SHA1 in that new "secure" code,
> no?

No.

The use of SHA-1 is necessary even on modern systems to avoid a
vulnerability.

It is the platform, not Linux, which decides which TPM PCR banks are active.

Linux *must* have an algorithm for every active bank (which is the
platform's choice), even if the single thing it intends to do is cap the
bank and use better ones.

Capping a bank requires updating the TPM Log without corrupting it,
which requires a hash calculation of the correct type for the bank.

~Andrew


From jarkko at kernel.org  Fri Aug 16 04:22:04 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Fri, 16 Aug 2024 14:22:04 +0300
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx> <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
Message-ID: <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org>

On Fri Aug 16, 2024 at 2:01 PM EEST, Andrew Cooper wrote:
> On 15/08/2024 8:10 pm, Thomas Gleixner wrote:
> > On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
> >> On 5/31/24 09:54, Eric W. Biederman wrote:
> >>> Eric Biggers <ebiggers at kernel.org> writes:
> >>>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
> >>>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
> >>>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
> >>>> but why would you not at least *prefer* SHA-256?
> >>> Yes.  Please prefer to use SHA-256.
> >>>
> >>> Have you considered implementing I think it is SHA1-DC (as git has) that
> >>> is compatible with SHA1 but blocks the known class of attacks where
> >>> sha1 is actively broken at this point?
> >> We are using the kernel's implementation, addressing what the kernel 
> >> provides is beyond our efforts. Perhaps someone who is interested in 
> >> improving the kernel's SHA1 could submit a patch implementing/replacing 
> >> it with SHA1-DC, as I am sure the maintainers would welcome the help.
> > Well, someone who is interested to get his "secure" code merged should
> > have a vested interested to have a non-broken SHA1 implementation if
> > there is a sensible requirement to use SHA1 in that new "secure" code,
> > no?
>
> No.
>
> The use of SHA-1 is necessary even on modern systems to avoid a
> vulnerability.
>
> It is the platform, not Linux, which decides which TPM PCR banks are active.
>
> Linux *must* have an algorithm for every active bank (which is the
> platform's choice), even if the single thing it intends to do is cap the
> bank and use better ones.

For (any) non-legacy features we can choose, which choices we choose to
support, and which we do not. This is not an oppositive view just saying
how it is, and platforms set of choices is not a selling argument.

>
> Capping a bank requires updating the TPM Log without corrupting it,
> which requires a hash calculation of the correct type for the bank.
>
> ~Andrew

BR, Jarkko


From ebiederm at xmission.com  Fri Aug 16 05:54:52 2024
From: ebiederm at xmission.com (Eric W. Biederman)
Date: Fri, 16 Aug 2024 07:54:52 -0500
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <20240805150750.170739-1-petr.tesarik@suse.com> (Petr Tesarik's
	message of "Mon, 5 Aug 2024 17:07:50 +0200")
References: <20240805150750.170739-1-petr.tesarik@suse.com>
Message-ID: <871q2oy6eb.fsf@email.froward.int.ebiederm.org>

Petr Tesarik <petr.tesarik at suse.com> writes:

> From: Petr Tesarik <ptesarik at suse.com>
>
> Fix the condition to exclude the elfcorehdr segment from the SHA digest
> calculation.
>
> The j iterator is an index into the output sha_regions[] array, not into
> the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> all subsequent segments are excluded. Besides, if the purgatory segment
> precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> the calculation.

I would rather make CONFIG_CRASH_HOTPLUG depend on broken.

The hash is supposed to include everything we depend upon so when
a borken machine corrupts something we can detect that corruption
and not attempt to take a crash dump.

The elfcorehdr is definitely something that needs to be part of the
hash.

So please go back to the drawing board and find a way to include the
program header in the hash even with CONFIG_CRASH_HOTPLUG.


Eric


> Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> Cc: stable at kernel.org
> Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> ---
>  kernel/kexec_file.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 3d64290d24c9..3eedb8c226ad 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
>  
>  #ifdef CONFIG_CRASH_HOTPLUG
>  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> -		if (j == image->elfcorehdr_index)
> +		if (i == image->elfcorehdr_index)
>  			continue;
>  #endif


From ptesarik at suse.com  Fri Aug 16 06:42:44 2024
From: ptesarik at suse.com (Petr Tesarik)
Date: Fri, 16 Aug 2024 15:42:44 +0200
Subject: [PATCH 1/1] kexec_file: fix elfcorehdr digest exclusion when
 CONFIG_CRASH_HOTPLUG=y
In-Reply-To: <871q2oy6eb.fsf@email.froward.int.ebiederm.org>
References: <20240805150750.170739-1-petr.tesarik@suse.com>
	<871q2oy6eb.fsf@email.froward.int.ebiederm.org>
Message-ID: <20240816154244.0c6271a6@mordecai.tesarici.cz>

On Fri, 16 Aug 2024 07:54:52 -0500
"Eric W. Biederman" <ebiederm at xmission.com> wrote:

> Petr Tesarik <petr.tesarik at suse.com> writes:
> 
> > From: Petr Tesarik <ptesarik at suse.com>
> >
> > Fix the condition to exclude the elfcorehdr segment from the SHA digest
> > calculation.
> >
> > The j iterator is an index into the output sha_regions[] array, not into
> > the input image->segment[] array. Once it reaches image->elfcorehdr_index,
> > all subsequent segments are excluded. Besides, if the purgatory segment
> > precedes the elfcorehdr segment, the elfcorehdr may be wrongly included in
> > the calculation.  
> 
> I would rather make CONFIG_CRASH_HOTPLUG depend on broken.
> 
> The hash is supposed to include everything we depend upon so when
> a borken machine corrupts something we can detect that corruption
> and not attempt to take a crash dump.
> 
> The elfcorehdr is definitely something that needs to be part of the
> hash.
> 
> So please go back to the drawing board and find a way to include the
> program header in the hash even with CONFIG_CRASH_HOTPLUG.

I'm not trying to argue with your opinion, but it seems you're
complaining to the wrong person. My present patch merely fixes an
obvious trivial mistake in commit f7cc804a9fd4 ("kexec: exclude
elfcorehdr from the segment digest") to exclude _only_ the elfcorehdr
segment from the hash (which was intended) and not any _other_ segments
(which was not intended but is what currently happens).

If you want to change the direction of kexec hotplug support, feel free
to revert commit f7cc804a9fd4 instead. That would also fix the bug and
make me happy.

Petr T

> Eric
> 
> 
> > Fixes: f7cc804a9fd4 ("kexec: exclude elfcorehdr from the segment digest")
> > Cc: stable at kernel.org
> > Signed-off-by: Petr Tesarik <ptesarik at suse.com>
> > ---
> >  kernel/kexec_file.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> > index 3d64290d24c9..3eedb8c226ad 100644
> > --- a/kernel/kexec_file.c
> > +++ b/kernel/kexec_file.c
> > @@ -752,7 +752,7 @@ static int kexec_calculate_store_digests(struct kimage *image)
> >  
> >  #ifdef CONFIG_CRASH_HOTPLUG
> >  		/* Exclude elfcorehdr segment to allow future changes via hotplug */
> > -		if (j == image->elfcorehdr_index)
> > +		if (i == image->elfcorehdr_index)
> >  			continue;
> >  #endif  



From mjg59 at srcf.ucam.org  Fri Aug 16 11:41:16 2024
From: mjg59 at srcf.ucam.org (Matthew Garrett)
Date: Fri, 16 Aug 2024 19:41:16 +0100
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
 <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
 <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org>
Message-ID: <Zr+dTMYZNY1b9cRV@srcf.ucam.org>

On Fri, Aug 16, 2024 at 02:22:04PM +0300, Jarkko Sakkinen wrote:

> For (any) non-legacy features we can choose, which choices we choose to
> support, and which we do not. This is not an oppositive view just saying
> how it is, and platforms set of choices is not a selling argument.

NIST still permits the use of SHA-1 until 2030, and the most significant 
demonstrated weaknesses in it don't seem applicable to the use case 
here. We certainly shouldn't encourage any new uses of it, and anyone 
who's able to use SHA-2 should be doing that instead, but it feels like 
people are arguing about not supporting hardware that exists in the real 
world for vibes reasons rather than it being a realistically attackable 
weakness (and if we really *are* that concerned about SHA-1, why are we 
still supporting TPM 1.2 at all?)


From sourabhjain at linux.ibm.com  Sun Aug 18 21:11:14 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon, 19 Aug 2024 09:41:14 +0530
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <ZrskkDuMlQu+uBN4@MiWiFi-R3L-srv>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
 <Zrrpcn7cnCigNfWd@MiWiFi-R3L-srv>
 <4cbbf314-5134-4a1a-8a4d-f6f8c09104d3@linux.ibm.com>
 <ZrskkDuMlQu+uBN4@MiWiFi-R3L-srv>
Message-ID: <c40d12df-fdb6-4597-8936-69c4af602609@linux.ibm.com>

Hello Baoquan,

On 13/08/24 14:47, Baoquan He wrote:
> On 08/13/24 at 10:58am, Sourabh Jain wrote:
>> Hello Baoquan,
>>
>> On 13/08/24 10:34, Baoquan He wrote:
>>> On 08/12/24 at 09:46am, Sourabh Jain wrote:
>>> ......
>>>> ---
>>>>
>>>> Changelog:
>>>>
>>>> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>>>>     - Update crash_hotplug sysfs document as suggested by Petr T
>>>>     - Update an error message in crash_handle_hotplug_event and
>>>>       crash_check_hotplug_support function.
>>>>
>>>> ---
>>> ......
>>>> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
>>>> index 63cf89393c6e..c1048893f4b6 100644
>>>> --- a/kernel/crash_core.c
>>>> +++ b/kernel/crash_core.c
>>>> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>>>>    	crash_hotplug_lock();
>>>>    	/* Obtain lock while reading crash information */
>>>>    	if (!kexec_trylock()) {
>>>> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>>>> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>>> Wondering why this need be updated.
>> In some architectures, additional kexec segments become obsolete during a
>> hotplug event,
>> so simply calling out the `elfcorehdr may be inaccurate` may not be
>> sufficient.
>> Therefore, it has been generalized with the kdump image.
> OK, I forgot the case in ppc, makes sense to me, thx.
>
> Acked-by: Baoquan He <bhe at redhat.com>

Do we know who will be applying this patch and how it will be merged 
into Linus?s tree?

Thanks,
Sourabh Jain


From sourabhjain at linux.ibm.com  Sun Aug 18 21:15:55 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Mon, 19 Aug 2024 09:45:55 +0530
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <10c666ae-d528-4f49-82e9-8e0fee7099e0@linux.ibm.com>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
 <87v80lnf8d.fsf@mail.lhotse>
 <10c666ae-d528-4f49-82e9-8e0fee7099e0@linux.ibm.com>
Message-ID: <355b58b1-6c51-4c42-b6ea-dcd6b1617a18@linux.ibm.com>

Hello Michael and Boaquan

On 01/08/24 12:21, Sourabh Jain wrote:
> Hello Michael,
>
> On 01/08/24 08:04, Michael Ellerman wrote:
>> Sourabh Jain <sourabhjain at linux.ibm.com> writes:
>>> The following errors are observed when kexec is done with SMT=off on
>>> powerpc.
>>>
>>> [? 358.458385] Removing IBM Power 842 compression device
>>> [? 374.795734] kexec_core: Starting new kernel
>>> [? 374.795748] kexec: Waking offline cpu 1.
>>> [? 374.875695] crash hp: kexec_trylock() failed, elfcorehdr may be 
>>> inaccurate
>>> [? 374.935833] kexec: Waking offline cpu 2.
>>> [? 375.015664] crash hp: kexec_trylock() failed, elfcorehdr may be 
>>> inaccurate
>>> snip..
>>> [? 375.515823] kexec: Waking offline cpu 6.
>>> [? 375.635667] crash hp: kexec_trylock() failed, elfcorehdr may be 
>>> inaccurate
>>> [? 375.695836] kexec: Waking offline cpu 7.
>> Are they actually errors though? Do they block the actual kexec from
>> happening? Or are they just warnings in dmesg?
>
> The kexec kernel boots fine.
>
> This warning appears regardless of whether the kdump kernel is loaded.
>
> However, when the kdump kernel is loaded, we will not be able to 
> update the kdump image (FDT).
> I think this should be fine given that kexec is in progress.
>
> Please let me know your opinion.
>
>> Because the fix looks like it could be racy.
>
> It seems like it is racy, but given that kexec takes the lock first 
> and then
> brings the CPU up, which triggers the kdump image, which always fails to
> update the kdump image because it could not take the same lock.
>
> Note: the kexec lock is not released unless kexec boot fails.

Any comments or suggestions on this fix?

Thanks,
Sourabh Jain



From bhe at redhat.com  Sun Aug 18 23:15:52 2024
From: bhe at redhat.com (Baoquan He)
Date: Mon, 19 Aug 2024 14:15:52 +0800
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <355b58b1-6c51-4c42-b6ea-dcd6b1617a18@linux.ibm.com>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
 <87v80lnf8d.fsf@mail.lhotse>
 <10c666ae-d528-4f49-82e9-8e0fee7099e0@linux.ibm.com>
 <355b58b1-6c51-4c42-b6ea-dcd6b1617a18@linux.ibm.com>
Message-ID: <ZsLjGJvAUIaxrG6x@MiWiFi-R3L-srv>

On 08/19/24 at 09:45am, Sourabh Jain wrote:
> Hello Michael and Boaquan
> 
> On 01/08/24 12:21, Sourabh Jain wrote:
> > Hello Michael,
> > 
> > On 01/08/24 08:04, Michael Ellerman wrote:
> > > Sourabh Jain <sourabhjain at linux.ibm.com> writes:
> > > > The following errors are observed when kexec is done with SMT=off on
> > > > powerpc.
> > > > 
> > > > [? 358.458385] Removing IBM Power 842 compression device
> > > > [? 374.795734] kexec_core: Starting new kernel
> > > > [? 374.795748] kexec: Waking offline cpu 1.
> > > > [? 374.875695] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > be inaccurate
> > > > [? 374.935833] kexec: Waking offline cpu 2.
> > > > [? 375.015664] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > be inaccurate
> > > > snip..
> > > > [? 375.515823] kexec: Waking offline cpu 6.
> > > > [? 375.635667] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > be inaccurate
> > > > [? 375.695836] kexec: Waking offline cpu 7.
> > > Are they actually errors though? Do they block the actual kexec from
> > > happening? Or are they just warnings in dmesg?
> > 
> > The kexec kernel boots fine.
> > 
> > This warning appears regardless of whether the kdump kernel is loaded.
> > 
> > However, when the kdump kernel is loaded, we will not be able to update
> > the kdump image (FDT).
> > I think this should be fine given that kexec is in progress.
> > 
> > Please let me know your opinion.
> > 
> > > Because the fix looks like it could be racy.
> > 
> > It seems like it is racy, but given that kexec takes the lock first and
> > then
> > brings the CPU up, which triggers the kdump image, which always fails to
> > update the kdump image because it could not take the same lock.
> > 
> > Note: the kexec lock is not released unless kexec boot fails.
> 
> Any comments or suggestions on this fix?

Is this a little better?

diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 63cf89393c6e..0355ffb712f4 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -504,7 +504,7 @@ int crash_check_hotplug_support(void)
 
 	crash_hotplug_lock();
 	/* Obtain lock while reading crash information */
-	if (!kexec_trylock()) {
+	if (!kexec_trylock() && kexec_in_progress) {
 		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
 		crash_hotplug_unlock();
 		return 0;
@@ -539,7 +539,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
 
 	crash_hotplug_lock();
 	/* Obtain lock while changing crash information */
-	if (!kexec_trylock()) {
+	if (!kexec_trylock() && kexec_in_progress) {
 		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
 		crash_hotplug_unlock();
 		return;



From bhe at redhat.com  Mon Aug 19 02:36:51 2024
From: bhe at redhat.com (Baoquan He)
Date: Mon, 19 Aug 2024 17:36:51 +0800
Subject: [PATCH v2] Document/kexec: Generalize crash hotplug description
In-Reply-To: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
References: <20240812041651.703156-1-sourabhjain@linux.ibm.com>
Message-ID: <ZsMSM4Hgfm7yxFdj@MiWiFi-R3L-srv>

Add Jonathan and Andew.

On 08/12/24 at 09:46am, Sourabh Jain wrote:
> Commit 79365026f869 ("crash: add a new kexec flag for hotplug support")
> generalizes the crash hotplug support to allow architectures to update
> multiple kexec segments on CPU/Memory hotplug and not just elfcorehdr.
> Therefore, update the relevant kernel documentation to reflect the same.

Hi Jonathan and Andew,

Could any of you pick this into your tree?

Thanks
Baoquan

> 
> Cc: Petr Tesarik <petr at tesarici.cz>
> Cc: Hari Bathini <hbathini at linux.ibm.com>
> Cc: kexec at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: x86 at kernel.org
> Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
> ---
> 
> Changelog:
> 
> Since v1: https://lore.kernel.org/all/20240805050829.297171-1-sourabhjain at linux.ibm.com/
>   - Update crash_hotplug sysfs document as suggested by Petr T
>   - Update an error message in crash_handle_hotplug_event and
>     crash_check_hotplug_support function.
> 
> ---
>  .../ABI/testing/sysfs-devices-memory          |  6 ++--
>  .../ABI/testing/sysfs-devices-system-cpu      |  6 ++--
>  .../admin-guide/mm/memory-hotplug.rst         |  5 +--
>  Documentation/core-api/cpu_hotplug.rst        | 10 +++---
>  kernel/crash_core.c                           | 33 +++++++++++--------
>  5 files changed, 35 insertions(+), 25 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-devices-memory b/Documentation/ABI/testing/sysfs-devices-memory
> index a95e0f17c35a..cec65827e602 100644
> --- a/Documentation/ABI/testing/sysfs-devices-memory
> +++ b/Documentation/ABI/testing/sysfs-devices-memory
> @@ -115,6 +115,6 @@ What:		/sys/devices/system/memory/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for memory hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel updates relevant kexec
> +		segments on memory hot un/plug and/or on/offline events, avoiding the
> +		need to reload kdump kernel.
> diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
> index 325873385b71..1a31b7c71676 100644
> --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
> +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
> @@ -703,9 +703,9 @@ What:		/sys/devices/system/cpu/crash_hotplug
>  Date:		Aug 2023
>  Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
>  Description:
> -		(RO) indicates whether or not the kernel directly supports
> -		modifying the crash elfcorehdr for CPU hot un/plug and/or
> -		on/offline changes.
> +		(RO) indicates whether or not the kernel updates relevant kexec
> +		segments on memory hot un/plug and/or on/offline events, avoiding the
> +		need to reload kdump kernel.
>  
>  What:		/sys/devices/system/cpu/enabled
>  Date:		Nov 2022
> diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst b/Documentation/admin-guide/mm/memory-hotplug.rst
> index 098f14d83e99..cb2c080f400c 100644
> --- a/Documentation/admin-guide/mm/memory-hotplug.rst
> +++ b/Documentation/admin-guide/mm/memory-hotplug.rst
> @@ -294,8 +294,9 @@ The following files are currently defined:
>  ``crash_hotplug``      read-only: when changes to the system memory map
>  		       occur due to hot un/plug of memory, this file contains
>  		       '1' if the kernel updates the kdump capture kernel memory
> -		       map itself (via elfcorehdr), or '0' if userspace must update
> -		       the kdump capture kernel memory map.
> +		       map itself (via elfcorehdr and other relevant kexec
> +		       segments), or '0' if userspace must update the kdump
> +		       capture kernel memory map.
>  
>  		       Availability depends on the CONFIG_MEMORY_HOTPLUG kernel
>  		       configuration option.
> diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst
> index dcb0e379e5e8..a21dbf261be7 100644
> --- a/Documentation/core-api/cpu_hotplug.rst
> +++ b/Documentation/core-api/cpu_hotplug.rst
> @@ -737,8 +737,9 @@ can process the event further.
>  
>  When changes to the CPUs in the system occur, the sysfs file
>  /sys/devices/system/cpu/crash_hotplug contains '1' if the kernel
> -updates the kdump capture kernel list of CPUs itself (via elfcorehdr),
> -or '0' if userspace must update the kdump capture kernel list of CPUs.
> +updates the kdump capture kernel list of CPUs itself (via elfcorehdr and
> +other relevant kexec segment), or '0' if userspace must update the kdump
> +capture kernel list of CPUs.
>  
>  The availability depends on the CONFIG_HOTPLUG_CPU kernel configuration
>  option.
> @@ -750,8 +751,9 @@ file can be used in a udev rule as follows:
>   SUBSYSTEM=="cpu", ATTRS{crash_hotplug}=="1", GOTO="kdump_reload_end"
>  
>  For a CPU hot un/plug event, if the architecture supports kernel updates
> -of the elfcorehdr (which contains the list of CPUs), then the rule skips
> -the unload-then-reload of the kdump capture kernel.
> +of the elfcorehdr (which contains the list of CPUs) and other relevant
> +kexec segments, then the rule skips the unload-then-reload of the kdump
> +capture kernel.
>  
>  Kernel Inline Documentations Reference
>  ======================================
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..c1048893f4b6 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -505,7 +505,7 @@ int crash_check_hotplug_support(void)
>  	crash_hotplug_lock();
>  	/* Obtain lock while reading crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>  		crash_hotplug_unlock();
>  		return 0;
>  	}
> @@ -520,18 +520,25 @@ int crash_check_hotplug_support(void)
>  }
>  
>  /*
> - * To accurately reflect hot un/plug changes of cpu and memory resources
> - * (including onling and offlining of those resources), the elfcorehdr
> - * (which is passed to the crash kernel via the elfcorehdr= parameter)
> - * must be updated with the new list of CPUs and memories.
> + * To accurately reflect hot un/plug changes of CPU and Memory resources
> + * (including onling and offlining of those resources), the relevant
> + * kexec segments must be updated with latest CPU and Memory resources.
>   *
> - * In order to make changes to elfcorehdr, two conditions are needed:
> - * First, the segment containing the elfcorehdr must be large enough
> - * to permit a growing number of resources; the elfcorehdr memory size
> - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES.
> - * Second, purgatory must explicitly exclude the elfcorehdr from the
> - * list of segments it checks (since the elfcorehdr changes and thus
> - * would require an update to purgatory itself to update the digest).
> + * Architectures must ensure two things for all segments that need
> + * updating during hotplug events:
> + *
> + * 1. Segments must be large enough to accommodate a growing number of
> + *    resources.
> + * 2. Exclude the segments from SHA verification.
> + *
> + * For example, on most architectures, the elfcorehdr (which is passed
> + * to the crash kernel via the elfcorehdr= parameter) must include the
> + * new list of CPUs and memory. To make changes to the elfcorehdr, it
> + * should be large enough to permit a growing number of CPU and Memory
> + * resources. One can estimate the elfcorehdr memory size based on
> + * NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. The elfcorehdr is
> + * excluded from SHA verification by default if the architecture
> + * supports crash hotplug.
>   */
>  static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu, void *arg)
>  {
> @@ -540,7 +547,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>  	crash_hotplug_lock();
>  	/* Obtain lock while changing crash information */
>  	if (!kexec_trylock()) {
> -		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> +		pr_info("kexec_trylock() failed, kdump image may be inaccurate\n");
>  		crash_hotplug_unlock();
>  		return;
>  	}
> -- 
> 2.45.2
> 



From piliu at redhat.com  Mon Aug 19 07:53:33 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:33 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
Message-ID: <20240819145417.23367-1-piliu@redhat.com>

*** Background ***

As more PE format kernel images are introduced, it post challenge to kexec to
cope with the new format.

In my attempt to add support for arm64 zboot image in the kernel [1],
Ard suggested using an emulator to tackle this issue.  Last year, when
Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
emulator approach again [3]

After discussion, Ard's approach seems to be a more promising solution
to handle PE format kernels once and for all.  This series follows that
approach and implements an emulator to emulate EFI boot time services,
allowing the efistub kernel to self-extract and boot.

Another year has passed, and UKI kernel is more and more frequently used
in product. I think it is time to pay effort to resolve this issue.


*** Overview of implement ***
The whole model consits of three parts:

-1. The emulator
It is a self-relocatable PIC code, which is finally linked into kernel, but not
export any internal symbol to kernel.  It mainly contains: a PE file parser,
which loads PE format kernel, a group of functions to emulate efi boot service.

-2. inside kernel, PE-format loader
Its main task is to set up two extra kexec_segment, one for emulator, the other
for passing information from the first kernel to emulator.

-3. set up identity mapping only for the memory used by the emulator.
Here it relies on kimage_alloc_control_pages() to get pages, which will not
stamped during the process of kexec relocate (cp from src to dst). And since the
mapping only covers a small range of memory, it cost small amount memory.


*** To do ***

Currently, it only works on arm64 virt machine. For x86, it needs some slightly
changes. (I plan to do it in the next version)

Also, this series does not implement a memory allocator, which I plan to
implement with the help of bitmap.

About console, currently it hard code for arm64 virt machine, later it should
extract the information through ACPI table.

For kdump code, it is not implmented yet. But it should share the majority of
this series.


*** Test of this series ***
I have tested this series on arm64 virt machine. There I booted the vmlinuz.efi
and kexec_file_load a UKI image, then switch to the second kernel.

I used a modified kexec-tools [4], which just skips the check of the file format and passes the file directly to kernel.

[1]: https://lore.kernel.org/linux-arm-kernel/ZBvKSis+dfnqa+Vz at piliu.users.ipa.redhat.com/T/#m42abb0ad3c10126b8b3bfae8a596deb707d6f76e
[2]: https://lore.kernel.org/lkml/20230918173607.421d2616 at rotkaeppchen/T/
[3]: https://lore.kernel.org/lkml/20230918173607.421d2616 at rotkaeppchen/T/#mc60aa591cb7616ceb39e1c98f352383f9ba6e985
[4]: https://github.com/pfliu/kexec-tools.git branch: kexec_uefi_emulator


RFCv1 -> RFCv2:
-1.Support to run UKI kernel by: add LoadImage() and StartImage(), add
   PE file relocation support, add InstallMultiProtocol()
-2.Also set up idmap for EFI runtime memory descriptor since UKI's
   systemd-stub calls runtime service
-3.Move kexec_pe_image.c from arch/arm64/kernel to kernel/, since it
   aims to provide a more general architecture support.

RFCv1: https://lore.kernel.org/linux-efi/20240718085759.13247-1-piliu at redhat.com/
RFCv2: https://github.com/pfliu/linux.git  branch kexec_uefi_emulator_RFCv2

Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Jan Hendrik Farr <kernel at jfarr.cc>
Cc: Philipp Rudo <prudo at redhat.com>
Cc: Lennart Poettering <mzxreary at 0pointer.de>
Cc: Jarkko Sakkinen <jarkko at kernel.org>
Cc: Eric Biederman <ebiederm at xmission.com>
Cc: Baoquan He <bhe at redhat.com>
Cc: Dave Young <dyoung at redhat.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: kexec at lists.infradead.org
Cc: linux-efi at vger.kernel.org
Cc: linux-kernel at vger.kernel.org



Pingfan Liu (9):
  efi/libstub: Ask efi_random_alloc() to skip unusable memory
  efi/libstub: Complete efi_simple_text_output_protocol
  efi/emulator: Initial rountines to emulate EFI boot time service
  efi/emulator: Turn on mmu for arm64
  kexec: Introduce kexec_pe_image to parse and load PE file
  arm64: kexec: Introduce a new member param_mem to kimage_arch
  arm64: mm: Change to prototype of
  arm64: kexec: Prepare page table for emulator
  arm64: kexec: Enable kexec_pe_image

 arch/arm64/Kconfig                            |   4 +
 arch/arm64/include/asm/kexec.h                |   1 +
 arch/arm64/include/asm/mmu.h                  |   6 +
 arch/arm64/kernel/asm-offsets.c               |   2 +-
 arch/arm64/kernel/machine_kexec.c             | 103 +++-
 arch/arm64/kernel/machine_kexec_file.c        |   4 +
 arch/arm64/kernel/relocate_kernel.S           |   2 +-
 arch/arm64/mm/mmu.c                           |  67 ++-
 drivers/firmware/efi/Makefile                 |   1 +
 drivers/firmware/efi/efi_emulator/Makefile    |  99 ++++
 .../firmware/efi/efi_emulator/amba-pl011.c    |  81 +++
 .../efi_emulator/arm64_emulator_service.lds   |  45 ++
 .../firmware/efi/efi_emulator/arm64_proc.S    | 175 ++++++
 .../firmware/efi/efi_emulator/config_table.c  |  25 +
 drivers/firmware/efi/efi_emulator/core.c      | 376 +++++++++++++
 .../firmware/efi/efi_emulator/device_handle.c | 138 +++++
 drivers/firmware/efi/efi_emulator/earlycon.h  |  19 +
 .../firmware/efi/efi_emulator/efi_emulator.S  |  12 +
 drivers/firmware/efi/efi_emulator/emulator.h  | 106 ++++
 drivers/firmware/efi/efi_emulator/entry.c     |  68 +++
 drivers/firmware/efi/efi_emulator/head.S      |  10 +
 drivers/firmware/efi/efi_emulator/lib.c       |  73 +++
 drivers/firmware/efi/efi_emulator/memory.c    |  27 +
 .../firmware/efi/efi_emulator/memory_api.c    |  74 +++
 drivers/firmware/efi/efi_emulator/misc.c      |  43 ++
 drivers/firmware/efi/efi_emulator/pe_loader.c | 173 ++++++
 drivers/firmware/efi/efi_emulator/printf.c    | 373 +++++++++++++
 .../efi/efi_emulator/protocol_device_path.c   |  75 +++
 .../protocol_simple_text_output.c             |  50 ++
 drivers/firmware/efi/libstub/efistub.h        |   7 +
 drivers/firmware/efi/libstub/randomalloc.c    |   5 +
 include/linux/efi_emulator.h                  |  46 ++
 include/linux/kexec.h                         |   6 +
 kernel/Makefile                               |   1 +
 kernel/kexec_pe_image.c                       | 503 ++++++++++++++++++
 35 files changed, 2764 insertions(+), 36 deletions(-)
 create mode 100644 drivers/firmware/efi/efi_emulator/Makefile
 create mode 100644 drivers/firmware/efi/efi_emulator/amba-pl011.c
 create mode 100644 drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds
 create mode 100644 drivers/firmware/efi/efi_emulator/arm64_proc.S
 create mode 100644 drivers/firmware/efi/efi_emulator/config_table.c
 create mode 100644 drivers/firmware/efi/efi_emulator/core.c
 create mode 100644 drivers/firmware/efi/efi_emulator/device_handle.c
 create mode 100644 drivers/firmware/efi/efi_emulator/earlycon.h
 create mode 100644 drivers/firmware/efi/efi_emulator/efi_emulator.S
 create mode 100644 drivers/firmware/efi/efi_emulator/emulator.h
 create mode 100644 drivers/firmware/efi/efi_emulator/entry.c
 create mode 100644 drivers/firmware/efi/efi_emulator/head.S
 create mode 100644 drivers/firmware/efi/efi_emulator/lib.c
 create mode 100644 drivers/firmware/efi/efi_emulator/memory.c
 create mode 100644 drivers/firmware/efi/efi_emulator/memory_api.c
 create mode 100644 drivers/firmware/efi/efi_emulator/misc.c
 create mode 100644 drivers/firmware/efi/efi_emulator/pe_loader.c
 create mode 100644 drivers/firmware/efi/efi_emulator/printf.c
 create mode 100644 drivers/firmware/efi/efi_emulator/protocol_device_path.c
 create mode 100644 drivers/firmware/efi/efi_emulator/protocol_simple_text_output.c
 create mode 100644 include/linux/efi_emulator.h
 create mode 100644 kernel/kexec_pe_image.c

-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:34 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:34 +0800
Subject: [RFCv2 1/9] efi/libstub: Ask efi_random_alloc() to skip unusable memory
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-2-piliu@redhat.com>

efi_random_alloc() demands EFI_ALLOCATE_ADDRESS when allocate_pages(),
but the current implement can not ensure the selected target locates
inside free area, that is to exclude EFI_BOOT_SERVICES_*,
EFI_RUNTIME_SERVICES_* etc.

Fix the issue by checking md->type.

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
To: linux-efi at vger.kernel.org
---
 drivers/firmware/efi/libstub/randomalloc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c
index c41e7b2091cdd..7304e767688f2 100644
--- a/drivers/firmware/efi/libstub/randomalloc.c
+++ b/drivers/firmware/efi/libstub/randomalloc.c
@@ -79,6 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size,
 		efi_memory_desc_t *md = (void *)map->map + map_offset;
 		unsigned long slots;
 
+		if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
+			continue;
 		slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
 					    alloc_max);
 		MD_NUM_SLOTS(md) = slots;
@@ -111,6 +113,9 @@ efi_status_t efi_random_alloc(unsigned long size,
 		efi_physical_addr_t target;
 		unsigned long pages;
 
+		if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
+			continue;
+
 		if (total_mirrored_slots > 0 &&
 		    !(md->attribute & EFI_MEMORY_MORE_RELIABLE))
 			continue;
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:35 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:35 +0800
Subject: [RFCv2 2/9] efi/libstub: Complete efi_simple_text_output_protocol
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-3-piliu@redhat.com>

Some uefi applications e.g systemd-stub uses more members in
efi_simple_text_output_protocol, hence extending its members as UEFI
specification.

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
To: linux-efi at vger.kernel.org
---
 drivers/firmware/efi/libstub/efistub.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 27abb4ce02917..a075d327a11ba 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -506,6 +506,13 @@ union efi_simple_text_output_protocol {
 		efi_status_t (__efiapi *output_string)(efi_simple_text_output_protocol_t *,
 						       efi_char16_t *);
 		void *test_string;
+		void *query_mode;
+		void *set_mode;
+		void *set_attribute;
+		void *clean_screen;
+		void *set_cursor_pos;
+		void *enable_cursor;
+		void *mode;
 	};
 	struct {
 		u32 reset;
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:37 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:37 +0800
Subject: [RFCv2 4/9] efi/emulator: Turn on mmu for arm64
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-5-piliu@redhat.com>

On arm64, when kexec switches to the new kernel, the mmu is off. So the
efi emulator should turn on the mmu to enable the identity mapping at
the first stage.

In fact, the kexec switching can run with mmu-on if it enters emulator,
but that requires the re-arrangement of the relocate_kernel.S [1].
After that, this patch can be drop.

But let us focus on emulator itself and keep things simple for the time
being.

[1]: https://lore.kernel.org/linux-arm-kernel/20240328115656.24090-1-piliu at redhat.com/

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
To: linux-efi at vger.kernel.org
---
 drivers/firmware/efi/efi_emulator/Makefile    |   2 +-
 .../firmware/efi/efi_emulator/arm64_proc.S    | 175 ++++++++++++++++++
 drivers/firmware/efi/efi_emulator/entry.c     |   7 +
 3 files changed, 183 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/efi/efi_emulator/arm64_proc.S

diff --git a/drivers/firmware/efi/efi_emulator/Makefile b/drivers/firmware/efi/efi_emulator/Makefile
index d696381d168ba..9d295b77a2be3 100644
--- a/drivers/firmware/efi/efi_emulator/Makefile
+++ b/drivers/firmware/efi/efi_emulator/Makefile
@@ -65,7 +65,7 @@ emulator-y			:= head.o entry.o \
 				   core.o pe_loader.o memory.o memory_api.o config_table.o misc.o \
 				   device_handle.o protocol_simple_text_output.o protocol_device_path.o \
 				   lib.o printf.o \
-				   amba-pl011.o
+				   amba-pl011.o arm64_proc.o
 obj-y				:= efi_emulator.o
 
 
diff --git a/drivers/firmware/efi/efi_emulator/arm64_proc.S b/drivers/firmware/efi/efi_emulator/arm64_proc.S
new file mode 100644
index 0000000000000..8364c459b8348
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/arm64_proc.S
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Based on arch/arm/mm/proc.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Catalin Marinas <catalin.marinas at arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/pgtable.h>
+#include <linux/cfi_types.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/asm_pointer_auth.h>
+#include <asm/hwcap.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative.h>
+#include <asm/smp.h>
+#include <asm/sysreg.h>
+
+#ifdef CONFIG_ARM64_64K_PAGES
+#define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
+#define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
+#endif
+
+#ifdef CONFIG_RANDOMIZE_BASE
+#define TCR_KASLR_FLAGS	TCR_NFD1
+#else
+#define TCR_KASLR_FLAGS	0
+#endif
+
+#define TCR_SMP_FLAGS	TCR_SHARED
+
+/* PTWs cacheable, inner/outer WBWA */
+#define TCR_CACHE_FLAGS	TCR_IRGN_WBWA | TCR_ORGN_WBWA
+
+#ifdef CONFIG_KASAN_SW_TAGS
+#define TCR_KASAN_SW_FLAGS TCR_TBI1 | TCR_TBID1
+#else
+#define TCR_KASAN_SW_FLAGS 0
+#endif
+
+#ifdef CONFIG_KASAN_HW_TAGS
+#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
+#elif defined(CONFIG_ARM64_MTE)
+/*
+ * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
+ * TBI being enabled at EL1.
+ */
+#define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1
+#else
+#define TCR_MTE_FLAGS 0
+#endif
+
+/*
+ * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
+ * changed during mte_cpu_setup to Normal Tagged if the system supports MTE.
+ */
+#define MAIR_EL1_SET							\
+	(MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |	\
+	 MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) |	\
+	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) |		\
+	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) |			\
+	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED))
+
+
+SYM_FUNC_START(__cpu_setup)
+	tlbi	vmalle1				// Invalidate local TLB
+	dsb	nsh
+
+	msr	cpacr_el1, xzr			// Reset cpacr_el1
+	mov_q	x1, CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN | CPACR_EL1_ZEN_EL1EN
+	msr	cpacr_el1, x1			// avoid the trap of FPSIMD in uefi code
+	isb
+	mov	x1, #1 << 12			// Reset mdscr_el1 and disable
+	msr	mdscr_el1, x1			// access to the DCC from EL0
+	reset_pmuserenr_el0 x1			// Disable PMU access from EL0
+	reset_amuserenr_el0 x1			// Disable AMU access from EL0
+
+	/*
+	 * Default values for VMSA control registers. These will be adjusted
+	 * below depending on detected CPU features.
+	 */
+	mair	.req	x17
+	tcr	.req	x16
+	mov_q	mair, MAIR_EL1_SET
+	mov_q	tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS_MIN) | TCR_CACHE_FLAGS | \
+		     TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+		     TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+
+	tcr_clear_errata_bits tcr, x9, x5
+
+#ifdef CONFIG_ARM64_VA_BITS_52
+	mov		x9, #64 - VA_BITS
+alternative_if ARM64_HAS_VA52
+	tcr_set_t1sz	tcr, x9
+#ifdef CONFIG_ARM64_LPA2
+	orr		tcr, tcr, #TCR_DS
+#endif
+alternative_else_nop_endif
+#endif
+
+	/*
+	 * Set the IPS bits in TCR_EL1.
+	 */
+	tcr_compute_pa_size tcr, #TCR_IPS_SHIFT, x5, x6
+#ifdef CONFIG_ARM64_HW_AFDBM
+	/*
+	 * Enable hardware update of the Access Flags bit.
+	 * Hardware dirty bit management is enabled later,
+	 * via capabilities.
+	 */
+	mrs	x9, ID_AA64MMFR1_EL1
+	and	x9, x9, ID_AA64MMFR1_EL1_HAFDBS_MASK
+	cbz	x9, 1f
+	orr	tcr, tcr, #TCR_HA		// hardware Access flag update
+1:
+#endif	/* CONFIG_ARM64_HW_AFDBM */
+	msr	mair_el1, mair
+	msr	tcr_el1, tcr
+
+	mrs_s	x1, SYS_ID_AA64MMFR3_EL1
+	ubfx	x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
+	cbz	x1, .Lskip_indirection
+
+	/*
+	 * The PROT_* macros describing the various memory types may resolve to
+	 * C expressions if they include the PTE_MAYBE_* macros, and so they
+	 * can only be used from C code. The PIE_E* constants below are also
+	 * defined in terms of those macros, but will mask out those
+	 * PTE_MAYBE_* constants, whether they are set or not. So #define them
+	 * as 0x0 here so we can evaluate the PIE_E* constants in asm context.
+	 */
+
+#define PTE_MAYBE_NG		0
+#define PTE_MAYBE_SHARED	0
+
+	mov_q	x0, PIE_E0
+	msr	REG_PIRE0_EL1, x0
+	mov_q	x0, PIE_E1
+	msr	REG_PIR_EL1, x0
+
+#undef PTE_MAYBE_NG
+#undef PTE_MAYBE_SHARED
+
+	mov	x0, TCR2_EL1x_PIE
+	msr	REG_TCR2_EL1, x0
+
+.Lskip_indirection:
+
+	/*
+	 * Prepare SCTLR
+	 */
+	mov_q	x0, INIT_SCTLR_EL1_MMU_ON
+	ret					// return to head.S
+
+	.unreq	mair
+	.unreq	tcr
+SYM_FUNC_END(__cpu_setup)
+
+SYM_FUNC_START(enable_sctlr_el1)
+	stp     x29, x30, [sp, #-16]!
+	bl      __cpu_setup
+	set_sctlr_el1 x0
+	ldp     x29, x30, [sp], #16
+	ret
+SYM_FUNC_END(enable_sctlr_el1)
+
diff --git a/drivers/firmware/efi/efi_emulator/entry.c b/drivers/firmware/efi/efi_emulator/entry.c
index e5a31bd303858..835021ab0f629 100644
--- a/drivers/firmware/efi/efi_emulator/entry.c
+++ b/drivers/firmware/efi/efi_emulator/entry.c
@@ -13,6 +13,13 @@ extern void enable_sctlr_el1(unsigned long scratch_reg);
 static void arch_handle_mmu(struct efi_emulator_param *param)
 {
 	if (!param->mmu_on && param->pgd_root) {
+		unsigned long scratch_reg = 0;
+		// in fact, we need SYM_FUNC_START(__cpu_setup), later, set SCTLR_EL1
+		//  At present, the mmu is not ON
+		write_sysreg(param->pgd_root, ttbr0_el1);
+		isb();
+		/* scratch_reg asks the C compiler to save x0 */
+		enable_sctlr_el1(scratch_reg);
 	}
 }
 
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:38 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:38 +0800
Subject: [RFCv2 5/9] kexec: Introduce kexec_pe_image to parse and load PE file
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-6-piliu@redhat.com>

As UEFI becomes popular, a few architectures support to boot a PE format
kernel image directly. And the internal of PE format may be different.
This introduces a new kexec_file_ops implementation, named pe_image_ops,
which prepares UEFI environment for the trampoline code 'efi emulator'.

The pe_image_ops considers efi emulator and its input parameters,
'efi_emulator_param' as two additional kexec_segment. And it constructs
efi_memory_desc_t[], encodes efi runtime service info inside the parameter buffer.
Finally, it asks architecture implement's page table routine to set up
identity map for all memory used in 'efi emulator'

To do: This is a POC version, at present, it aims for arm64, later, it
needs abstraction to cope with x86

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Baoquan He <bhe at redhat.com>
Cc: Dave Young <dyoung at redhat.com>
Cc: Eric Biederman <ebiederm at xmission.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: linux-kernel at vger.kernel.org
To: kexec at lists.infradead.org
---
 include/linux/kexec.h   |   1 +
 kernel/Makefile         |   1 +
 kernel/kexec_pe_image.c | 503 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 505 insertions(+)
 create mode 100644 kernel/kexec_pe_image.c

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index cff6b6869498b..57b98bcaa5228 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -385,6 +385,7 @@ static inline int machine_kexec_post_load(struct kimage *image) { return 0; }
 
 extern struct kimage *kexec_image;
 extern struct kimage *kexec_crash_image;
+extern const struct kexec_file_ops pe_image_ops;
 
 bool kexec_load_permitted(int kexec_image_type);
 
diff --git a/kernel/Makefile b/kernel/Makefile
index 3c13240dfc9f0..f14d78b03fd0f 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
 obj-$(CONFIG_CRASH_DUMP) += crash_core.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
+obj-$(CONFIG_ARCH_SELECTS_KEXEC_PEIMAGE) += kexec_pe_image.o
 obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
 obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
 obj-$(CONFIG_COMPAT) += compat.o
diff --git a/kernel/kexec_pe_image.c b/kernel/kexec_pe_image.c
new file mode 100644
index 0000000000000..d14b8a5f69a99
--- /dev/null
+++ b/kernel/kexec_pe_image.c
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kexec image loader
+
+ * Copyright (C) 2024 Red Hat, Inc
+ * Author: Pingfan Liu <piliu at redhat.com>
+ */
+
+#define pr_fmt(fmt)	"kexec_file(Image): " fmt
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <linux/pe.h>
+#include <linux/efi.h>
+#include <linux/efi_emulator.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+#include <asm/cpufeature.h>
+#include <asm/image.h>
+#include <asm/memory.h>
+
+/*
+ * The UEFI Terse Executable (TE) image has MZ header.
+*/
+static int pe_image_probe(const char *kernel_buf, unsigned long kernel_len)
+{
+	struct mz_hdr *mz = (struct mz_hdr *)kernel_buf;
+	struct pe_hdr *pe;
+
+	if (mz->magic != MZ_MAGIC)
+		return -1;
+	pe = (struct pe_hdr *)(kernel_buf + mz->peaddr);
+	if (pe->magic != PE_MAGIC)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Efi runtime code or data are marked as EFI_RUNTIME_SERVICES_CODE
+ * or EFI_RUNTIME_SERVICES_DATA memory descriptor. When building mapping for the
+ * emulator, they should be mapped. Here just recording the entries to those regions.
+ */
+static void build_rt_info(struct efi_rt_info *rt)
+{
+	unsigned int desc_size = efi.memmap.desc_size;
+	int i, cnt;
+
+	i = cnt = 0;
+	if (desc_size) {
+		cnt = (efi.memmap.map_end - efi.memmap.map) / desc_size;
+		/* The emulator heap memory split the continous memory into three chunk */
+		cnt += 2;
+	}
+
+	/*
+	 * This virtual address is in UEFI address space, and the mapping is recorded
+	 * in efi_memory_desc_t[] and passed to reboot kernel.
+	 *
+	 * EFI stub may use runtime service, so its mapping should be set up
+	 */
+	rt->runtime = efi.runtime;
+	rt->runtime_version = efi.runtime_version;
+	rt->runtime_supported_mask = efi.runtime_supported_mask;
+	/*
+	 * Reconstruct the persistent systab's tables, which are recorded in efi.
+	 */
+	if (efi.acpi != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.acpi;
+		rt->systab_tables[i].guid = ACPI_TABLE_GUID;
+		i++;
+	}
+	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.acpi20;
+		rt->systab_tables[i].guid = ACPI_20_TABLE_GUID;
+		i++;
+	}
+	if (efi.smbios != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.smbios;
+		rt->systab_tables[i].guid = SMBIOS_TABLE_GUID;
+		i++;
+	}
+	if (efi.smbios3 != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.smbios3;
+		rt->systab_tables[i].guid = SMBIOS3_TABLE_GUID;
+		i++;
+	}
+	if (efi.esrt != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.esrt;
+		rt->systab_tables[i].guid = EFI_SYSTEM_RESOURCE_TABLE_GUID;
+		i++;
+	}
+	if (efi.tpm_log != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.tpm_log;
+		rt->systab_tables[i].guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
+		i++;
+	}
+	if (efi.tpm_final_log != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.tpm_final_log;
+		rt->systab_tables[i].guid = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;
+		i++;
+	}
+#ifdef CONFIG_LOAD_UEFI_KEYS
+	if (efi.mokvar_table != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.mokvar_table;
+		rt->systab_tables[i].guid = LINUX_EFI_MOK_VARIABLE_TABLE_GUID;
+		i++;
+	}
+#endif
+#ifdef CONFIG_EFI_COCO_SECRET
+	if (efi.coco_secret != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.coco_secret;
+		rt->systab_tables[i].guid = LINUX_EFI_COCO_SECRET_AREA_GUID;
+		i++;
+	}
+#endif
+#ifdef CONFIG_UNACCEPTED_MEMORY
+	if (efi.unaccepted != EFI_INVALID_TABLE_ADDR) {
+		rt->systab_tables[i].table = (void *)efi.unaccepted;
+		rt->systab_tables[i].guid = LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID;
+		i++;
+	}
+#endif
+	if (!desc_size) {
+		//todo, if noefi boot, LINUX_EFI_MEMRESERVE_TABLE_GUID should be used to pass IMA
+	}
+
+	rt->systab_nr_tables = i;
+
+	rt->memmap.map_size = desc_size * cnt;
+	/* In case of non-EFI booting, these two fields will be faked later */
+	rt->memmap.desc_size = efi.memmap.desc_size;
+	rt->memmap.desc_ver = efi.memmap.desc_version;
+}
+
+static int create_md_from_res(struct resource *res, void *data)
+{
+	struct efi_emulator_param *param = (struct efi_emulator_param *)data;
+	struct efi_boot_memmap *memmap = &param->rt_info.memmap;
+	efi_memory_desc_t *dst_md;
+
+	dst_md = (void *)memmap->map + memmap->map_size;
+
+	/* Split res into three chunk */
+	if ((res->start <= param->mempool_start) &&
+	      res->end > (param->mempool_start + param->mempool_sz)) {
+
+		dst_md->phys_addr = res->start;
+		dst_md->num_pages = (param->mempool_start - res->start) >> EFI_PAGE_SHIFT;
+		/* Pretend that it is occupied */
+		dst_md->type = EFI_BOOT_SERVICES_DATA;
+		dst_md->attribute = EFI_MEMORY_WB;
+		dst_md = (void *)dst_md + memmap->desc_size;
+
+		dst_md->phys_addr = param->mempool_start;
+		dst_md->num_pages = param->mempool_sz >> EFI_PAGE_SHIFT;
+		/* Confine memory footprint inside this region before exit boot service */
+		dst_md->type = EFI_CONVENTIONAL_MEMORY;
+		dst_md->attribute = EFI_MEMORY_WB;
+		dst_md = (void *)dst_md + memmap->desc_size;
+
+		dst_md->phys_addr = param->mempool_start  + param->mempool_sz;
+		dst_md->num_pages = (res->end - dst_md->phys_addr) >> EFI_PAGE_SHIFT;
+		/* Pretend that it is occupied */
+		dst_md->type = EFI_BOOT_SERVICES_DATA;
+		dst_md->attribute = EFI_MEMORY_WB;
+
+		memmap->map_size += 3 * (memmap->desc_size);
+	} else {
+		dst_md->phys_addr = res->start;
+		dst_md->num_pages = (res->end - res->start) >> EFI_PAGE_SHIFT;
+		/* Pretend that it is occupied */
+		dst_md->type = EFI_BOOT_SERVICES_DATA;
+		dst_md->attribute = EFI_MEMORY_WB;
+
+		memmap->map_size += memmap->desc_size;
+	}
+
+	return 0;
+}
+
+static efi_memory_desc_t *conclude_md(efi_memory_desc_t *dst_md,
+		unsigned int desc_size, unsigned long pool_start, unsigned long num_pages)
+{
+	if (dst_md->num_pages == 0)
+		return dst_md;
+
+	/* Split into three sections */
+	if (dst_md->phys_addr <= pool_start && dst_md->num_pages >= num_pages ) {
+		u64 virt_base, phys_base, left_pages, attribute;
+		u32 type;
+
+		type = dst_md->type;
+		attribute = dst_md->attribute;
+		phys_base = dst_md->phys_addr;
+		/*
+		* After SetVirtualAddressMap, the mapping is installed into
+		* firmware and can not be changed. The second kernel should
+		* be aware of this info
+		*/
+		virt_base = dst_md->virt_addr;
+		left_pages = dst_md->num_pages;
+
+		dst_md->num_pages = (pool_start - phys_base) >> EFI_PAGE_SHIFT;
+		/* Pretend that it is occupied until exit boot service */
+		dst_md->type = EFI_BOOT_SERVICES_DATA;
+		left_pages -= dst_md->num_pages;
+
+		dst_md = (void *)dst_md + desc_size;
+		dst_md->phys_addr = pool_start;
+		dst_md->virt_addr = virt_base + (dst_md->phys_addr - phys_base);
+		dst_md->num_pages = num_pages;
+		dst_md->attribute = attribute;
+		/* Confine the memory footprint on it, which has page table mapping */
+		dst_md->type = EFI_CONVENTIONAL_MEMORY;
+		left_pages -= dst_md->num_pages;
+
+		dst_md = (void *)dst_md + desc_size;
+		dst_md->phys_addr = pool_start + (num_pages << EFI_PAGE_SHIFT);
+		dst_md->virt_addr = virt_base + (dst_md->phys_addr - phys_base);
+		dst_md->num_pages = left_pages;
+		dst_md->attribute = attribute;
+		/* Pretend that it is occupied until exit boot service */
+		dst_md->type = EFI_BOOT_SERVICES_DATA;
+	}
+
+	dst_md = (void *)dst_md + desc_size;
+
+	return dst_md;
+}
+
+static void create_md_from_efi(efi_memory_desc_t *dst, unsigned int desc_sz,
+		struct efi_emulator_param *param)
+{
+	efi_memory_desc_t *md, *dst_md, *prev_md = NULL;
+	unsigned long pool_start, num_pages;
+
+	dst_md = dst;
+	pool_start = param->mempool_start;
+	num_pages = param->mempool_sz >> EFI_PAGE_SHIFT;
+	for_each_efi_memory_desc(md) {
+		switch (md->type) {
+			// todo, how to ensure kexec dst avoid the EFI_RUNTIME_SERVICES_CODE etc
+			case EFI_RUNTIME_SERVICES_CODE:
+			case EFI_RUNTIME_SERVICES_DATA:
+			case EFI_RESERVED_TYPE:
+			case EFI_UNUSABLE_MEMORY:
+			case EFI_ACPI_RECLAIM_MEMORY:
+				//test whether the current dst_md covers the heap, if yes, split it into three
+				dst_md = conclude_md(dst_md, desc_sz, pool_start, num_pages);
+				dst_md->phys_addr = md->phys_addr;
+				dst_md->virt_addr = md->virt_addr;
+				dst_md->num_pages = md->num_pages;
+				dst_md->type = md->type;
+				dst_md->attribute = md->attribute;
+				dst_md = conclude_md(dst_md, desc_sz, pool_start, num_pages);
+				break;
+
+			default:
+				if (dst_md->num_pages == 0) {
+					dst_md->phys_addr = md->phys_addr;
+					dst_md->virt_addr = md->virt_addr;
+					dst_md->num_pages = md->num_pages;
+					/*
+					 * Pretend as boot service data to prevent allocation
+					 * from it before  efi_exit_boot_services.
+					 */
+					dst_md->type = EFI_BOOT_SERVICES_DATA;
+					dst_md->attribute = md->attribute;
+				} else {
+					/* merge */
+					if (prev_md && prev_md->attribute == md->attribute &&
+					(md->phys_addr - prev_md->phys_addr) >> EFI_PAGE_SHIFT == prev_md->num_pages) {
+						dst_md->num_pages += md->num_pages;
+					} else {
+						dst_md = conclude_md(dst_md, desc_sz, pool_start, num_pages);
+						dst_md->phys_addr = md->phys_addr;
+						dst_md->virt_addr = md->virt_addr;
+						dst_md->num_pages = md->num_pages;
+						/* Pretend as boot service data */
+						dst_md->type = EFI_BOOT_SERVICES_DATA;
+						dst_md->attribute = md->attribute;
+					}
+				}
+				break;
+		}
+
+		prev_md = md;
+	}
+	dst_md = conclude_md(dst_md, desc_sz, pool_start, num_pages);
+	param->rt_info.memmap.map_size = (void *)dst_md - (void *)dst;
+}
+
+/*
+ * All efi runtime information should be passed to kexec reboot kernel. Record
+ * them in scratch. These information should be in EFI_RUNTIME_SERVICES md, so
+ * copying index is enough. Later the mapping for that md will be set up in
+ * arch_emulator_prepare_pgtable().
+ *
+ * If the system is not booted by efi, fake one.
+ */
+static void encode_efi_runtime_info(struct efi_emulator_param *param, struct kimage *image)
+{
+	struct efi_rt_info *rt = &param->rt_info;
+	efi_memory_desc_t *dst_md;
+	unsigned int sz;
+
+	build_rt_info(rt);
+	sz = efi.memmap.map_end - efi.memmap.map;
+	/* booted by efi firmware */
+	if (sz) {
+		unsigned long desc_size = efi.memmap.desc_size;
+
+		dst_md = rt->memmap.map;
+		/*
+		 * It has no point to pass efi.memmap directly to the reboot kernel since
+		 * EFI_BOOT_SERVICES_DATA etc has changed. But EFI_RUNTIME_SERVICES_DATA
+		 * etc should be paid attention to.
+		 */
+		create_md_from_efi(dst_md, desc_size, param);
+	} else {
+		param->noefi_boot = true;
+		/*
+		* Kernel is booted by non-EFI loader, which parses the PE format. In
+		* kexec case, faking memory descriptor so that efi-stub can self-parse.
+		* But there is no efi runtime service, and the kernel cmdline should
+		* have 'noefi' 
+		*/
+		rt->memmap.desc_size = sizeof(efi_memory_desc_t);
+		rt->memmap.desc_ver = EFI_MEMORY_DESCRIPTOR_VERSION;
+		walk_system_ram_res(0, ULONG_MAX, param, create_md_from_res);
+
+		/*
+		 * Besides, efi stub removes two dt node '/memreserve', one for initrd
+		 * and the other for IMA. EFI_RESERVED_TYPE can not serve that purpose.
+		 * That should be handled by LINUX_EFI_MEMRESERVE_TABLE_GUID
+		 */
+	}
+}
+
+extern phys_addr_t arch_emulator_prepare_pgtable(struct kimage *kimage,
+		struct efi_emulator_param *param);
+
+static void detect_earlycon(struct efi_emulator_param *param)
+{
+	//todo, autodetect the console register base and size
+	// aarch64 MACHINE_VIRT_UART_BASE
+	size_t sz = 15 < strlen("amba-pl011") ? 15 : strlen("amba-pl011");
+
+	memcpy(param->earlycon_name, "amba-pl011", sz);
+	param->earlycon_reg_base = 0x9000000;
+	param->earlycon_reg_sz = PAGE_SIZE;
+	param->print_enabled = true;
+}
+
+static phys_addr_t emulator_prepare_pgtable(struct kimage *kimage,
+		struct efi_emulator_param *param)
+{
+
+	detect_earlycon(param);
+
+	return arch_emulator_prepare_pgtable(kimage, param);
+}
+
+/* param, stack, and basic heap */
+#define EMULATOR_STACK_SIZE	(1 << 17)
+#define EMULATOR_PARAM_SIZE  (1 << 20)
+
+static void *pe_image_load(struct kimage *image,
+				char *kernel, unsigned long kernel_len,
+				char *initrd, unsigned long initrd_len,
+				char *cmdline, unsigned long cmdline_len)
+{
+	struct kexec_segment *emulator_seg, *param_seg, *kernel_segment;
+	struct efi_emulator_param *param;
+	struct page *param_pages;
+	struct kexec_buf kbuf;
+	unsigned long kseg_num;
+	int ret;
+
+	image->is_pe = true;
+	/* Do not parse image format, just load it. */
+	kbuf.image = image;
+	kbuf.buf_min = 0;
+	kbuf.buf_max = ULONG_MAX;
+	kbuf.top_down = false;
+	kbuf.buffer = kernel;
+	kbuf.bufsz = kernel_len;
+	kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+	kbuf.memsz = kernel_len;
+	kbuf.buf_align = MIN_KIMG_ALIGN;
+
+	kseg_num = image->nr_segments;
+	/*
+	 * The location of the kernel segment may make it impossible to satisfy
+	 * the other segment requirements, so we try repeatedly to find a
+	 * location that will work.
+	 */
+	while ((ret = kexec_add_buffer(&kbuf)) == 0) {
+		/* Try to load additional data */
+		kernel_segment = &image->segment[kseg_num];
+		ret = load_other_segments(image, kernel_segment->mem,
+					  kernel_segment->memsz, initrd,
+					  initrd_len, cmdline);
+		if (!ret)
+			break;
+
+		/*
+		 * We couldn't find space for the other segments; erase the
+		 * kernel segment and try the next available hole.
+		 */
+		image->nr_segments -= 1;
+		kbuf.buf_min = kernel_segment->mem + kernel_segment->memsz;
+		kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+	}
+
+	if (ret) {
+		pr_err("Could not find any suitable kernel location!");
+		return ERR_PTR(ret);
+	}
+	kernel_segment = &image->segment[kseg_num];
+
+	/* Load EFI emulator */
+	emulator_seg = &image->segment[image->nr_segments];
+	kbuf.buffer = _efi_emulator_start;
+	kbuf.bufsz = _efi_emulator_end - _efi_emulator_start;
+	kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+	kbuf.memsz = kbuf.bufsz;
+	kbuf.buf_align = PAGE_SIZE;
+	ret = kexec_add_buffer(&kbuf);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/* 
+	 * Prepare param and memory for emulator. One page for param,
+	 * rear page for stack and the rest for runtime heap.
+	 */
+	param_seg = &image->segment[image->nr_segments];
+	//to do, zero page is not required in kimage_entry_t
+	//  and free them
+	param_pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, 2);
+	param = page_to_virt(param_pages);
+
+	/* These chunk of information will be copied to the KEXEC SOURCE PAGE */
+	/* emulator loaded address */
+	param->load_address = emulator_seg->mem;
+	/* PE file payload at the beginning of this RAM range */
+	param->kernel_img_start = kernel_segment->mem;
+	param->kernel_img_sz = kernel_segment->memsz;
+	/* uefi protocol need it */
+	param->dtb = image->arch.dtb_mem;
+	param->sz_in_byte = utf8s_to_utf16s(cmdline, cmdline_len,
+						 UTF16_LITTLE_ENDIAN, param->cmdline, 512);
+	param->sz_in_byte *= sizeof(wchar_t);
+	kbuf.buffer = param;
+	/*
+	 * One page for param, one page for stack, the rest for heap, which should
+	 *  also has enough room for kernel and its decompression (256MB)
+	 */
+	kbuf.bufsz = EMULATOR_PARAM_SIZE + kernel_segment->memsz + (1 << 28);
+	kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+	kbuf.memsz = kbuf.bufsz;
+	kbuf.buf_align = PAGE_SIZE;
+	ret = kexec_add_buffer(&kbuf);
+	if (ret)
+		return ERR_PTR(ret);
+
+	/* These info is formed after param segment is built */
+	/* stack size equals 64K -sizeof(*param) */
+	param->sp = param_seg->mem  + EMULATOR_STACK_SIZE;
+	/* heap information */
+	param->mempool_start = param->sp;
+	param->mempool_sz = kbuf.bufsz - EMULATOR_STACK_SIZE;
+
+	param->pgd_root = emulator_prepare_pgtable(image, param);
+	/* For the time being, reset routine will turn off mmu */
+	param->mmu_on = false;
+	encode_efi_runtime_info(param, image);
+
+	/* relocate.s jumps to it */
+	image->start = emulator_seg->mem;
+	/* the 3rd input param for restart() */
+	image->arch.param_mem = param_seg->mem;
+	image->arch.dtb_mem = image->arch.param_mem;
+
+	kexec_dprintk("Loaded emulator at 0x%lx bufsz=0x%lx\n",
+		      emulator_seg->mem, emulator_seg->memsz);
+	kexec_dprintk("Loaded param blob at 0x%lx bufsz=0x%lx, sp=0x%lx\n",
+		      param_seg->mem, param_seg->memsz, param->sp);
+	kexec_dprintk("pgd_root:0x%llx\n", param->pgd_root);
+
+	return NULL;
+}
+
+const struct kexec_file_ops pe_image_ops = {
+	.probe = pe_image_probe,
+	.load = pe_image_load,
+#ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG
+	.verify_sig = kexec_kernel_verify_pe_sig,
+#endif
+};
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:39 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:39 +0800
Subject: [RFCv2 6/9] arm64: kexec: Introduce a new member param_mem to kimage_arch
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-7-piliu@redhat.com>

relocate_kernel will be used either to boot vmlinux directly or PE
image. In the latter case, the efi emulator needs efi_emulator_param
instead of dtb as input parameter.  On the other hand, dtb is still
required to pass down through efi_emulator_param to the second kernel,
so keep kimage_arch->dtb_mem as scratch and introduce another member
'param_mem'

When booting vmlinux, param_mem equals dtb_mem.

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/kexec.h         | 1 +
 arch/arm64/kernel/asm-offsets.c        | 2 +-
 arch/arm64/kernel/machine_kexec.c      | 2 +-
 arch/arm64/kernel/machine_kexec_file.c | 1 +
 arch/arm64/kernel/relocate_kernel.S    | 2 +-
 5 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 4d9cc7a76d9ca..f4c63a1a9531f 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -109,6 +109,7 @@ int machine_kexec_post_load(struct kimage *image);
 struct kimage_arch {
 	void *dtb;
 	phys_addr_t dtb_mem;
+	phys_addr_t param_mem;
 	phys_addr_t kern_reloc;
 	phys_addr_t el2_vectors;
 	phys_addr_t ttbr0;
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 81496083c0413..8633a94fcb9f1 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -187,7 +187,7 @@ int main(void)
   BLANK();
 #endif
 #ifdef CONFIG_KEXEC_CORE
-  DEFINE(KIMAGE_ARCH_DTB_MEM,		offsetof(struct kimage, arch.dtb_mem));
+  DEFINE(KIMAGE_ARCH_PARAM_MEM,		offsetof(struct kimage, arch.param_mem));
   DEFINE(KIMAGE_ARCH_EL2_VECTORS,	offsetof(struct kimage, arch.el2_vectors));
   DEFINE(KIMAGE_ARCH_ZERO_PAGE,		offsetof(struct kimage, arch.zero_page));
   DEFINE(KIMAGE_ARCH_PHYS_OFFSET,	offsetof(struct kimage, arch.phys_offset));
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 82e2203d86a31..6958c1fc84a5a 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -192,7 +192,7 @@ void machine_kexec(struct kimage *kimage)
 
 		cpu_install_idmap();
 		restart = (void *)__pa_symbol(cpu_soft_restart);
-		restart(is_hyp_nvhe(), kimage->start, kimage->arch.dtb_mem,
+		restart(is_hyp_nvhe(), kimage->start, kimage->arch.param_mem,
 			0, 0);
 	} else {
 		void (*kernel_reloc)(struct kimage *kimage);
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index af1ca875c52ce..9fca3a35f04d5 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -184,6 +184,7 @@ int load_other_segments(struct kimage *image,
 		goto out_err;
 	image->arch.dtb = dtb;
 	image->arch.dtb_mem = kbuf.mem;
+	image->arch.param_mem = image->arch.dtb_mem;
 
 	kexec_dprintk("Loaded dtb at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
 		      kbuf.mem, kbuf.bufsz, kbuf.memsz);
diff --git a/arch/arm64/kernel/relocate_kernel.S b/arch/arm64/kernel/relocate_kernel.S
index 413f899e4ac63..84e1bbb7def21 100644
--- a/arch/arm64/kernel/relocate_kernel.S
+++ b/arch/arm64/kernel/relocate_kernel.S
@@ -44,7 +44,7 @@ SYM_CODE_START(arm64_relocate_new_kernel)
 	 */
 	ldr	x28, [x0, #KIMAGE_START]
 	ldr	x27, [x0, #KIMAGE_ARCH_EL2_VECTORS]
-	ldr	x26, [x0, #KIMAGE_ARCH_DTB_MEM]
+	ldr	x26, [x0, #KIMAGE_ARCH_PARAM_MEM]
 
 	/* Setup the list loop variables. */
 	ldr	x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:40 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:40 +0800
Subject: [RFCv2 7/9] arm64: mm: Change to prototype of
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-8-piliu@redhat.com>

The current allocator of __create_pgd_mapping_locked() takes only one
parameter, which reflects the current level of page table.

But kexec_page_alloc() should extra control information from the
parameter kimage. In order to make kexec_page_alloc() as an allocator,
re-shape the prototype of the allocator and hence of the
__create_pgd_mapping_locked().

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/mmu.h |  6 ++++
 arch/arm64/mm/mmu.c          | 67 ++++++++++++++++++++----------------
 2 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 65977c7783c58..4b908e0650105 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -64,6 +64,12 @@ extern void arm64_memblock_init(void);
 extern void paging_init(void);
 extern void bootmem_init(void);
 extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
+extern void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
+					unsigned long virt, phys_addr_t size,
+					pgprot_t prot,
+					phys_addr_t (*pgtable_alloc)(int, void *),
+					void *arg,
+					int flags);
 extern void create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
 				   phys_addr_t size, pgprot_t prot);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index c927e9312f102..875e2bc0cfb39 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -106,7 +106,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 }
 EXPORT_SYMBOL(phys_mem_access_prot);
 
-static phys_addr_t __init early_pgtable_alloc(int shift)
+static phys_addr_t __init early_pgtable_alloc(int shift, void *unused)
 {
 	phys_addr_t phys;
 
@@ -190,7 +190,8 @@ static void init_pte(pte_t *ptep, unsigned long addr, unsigned long end,
 static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
 				unsigned long end, phys_addr_t phys,
 				pgprot_t prot,
-				phys_addr_t (*pgtable_alloc)(int),
+				phys_addr_t (*pgtable_alloc)(int, void *arg),
+				void *arg,
 				int flags)
 {
 	unsigned long next;
@@ -205,7 +206,7 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
 		if (flags & NO_EXEC_MAPPINGS)
 			pmdval |= PMD_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
-		pte_phys = pgtable_alloc(PAGE_SHIFT);
+		pte_phys = pgtable_alloc(PAGE_SHIFT, arg);
 		ptep = pte_set_fixmap(pte_phys);
 		init_clear_pgtable(ptep);
 		ptep += pte_index(addr);
@@ -241,7 +242,9 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
 
 static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
 		     phys_addr_t phys, pgprot_t prot,
-		     phys_addr_t (*pgtable_alloc)(int), int flags)
+		     phys_addr_t (*pgtable_alloc)(int, void *),
+		     void *arg,
+		     int flags)
 {
 	unsigned long next;
 
@@ -263,7 +266,7 @@ static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
 						      READ_ONCE(pmd_val(*pmdp))));
 		} else {
 			alloc_init_cont_pte(pmdp, addr, next, phys, prot,
-					    pgtable_alloc, flags);
+					    pgtable_alloc, arg, flags);
 
 			BUG_ON(pmd_val(old_pmd) != 0 &&
 			       pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp)));
@@ -275,7 +278,9 @@ static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
 static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 				unsigned long end, phys_addr_t phys,
 				pgprot_t prot,
-				phys_addr_t (*pgtable_alloc)(int), int flags)
+				phys_addr_t (*pgtable_alloc)(int, void *),
+				void * arg,
+				int flags)
 {
 	unsigned long next;
 	pud_t pud = READ_ONCE(*pudp);
@@ -292,7 +297,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 		if (flags & NO_EXEC_MAPPINGS)
 			pudval |= PUD_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
-		pmd_phys = pgtable_alloc(PMD_SHIFT);
+		pmd_phys = pgtable_alloc(PMD_SHIFT, arg);
 		pmdp = pmd_set_fixmap(pmd_phys);
 		init_clear_pgtable(pmdp);
 		pmdp += pmd_index(addr);
@@ -312,7 +317,7 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 		    (flags & NO_CONT_MAPPINGS) == 0)
 			__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
 
-		init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags);
+		init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, arg, flags);
 
 		pmdp += pmd_index(next) - pmd_index(addr);
 		phys += next - addr;
@@ -323,7 +328,8 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
 
 static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
 			   phys_addr_t phys, pgprot_t prot,
-			   phys_addr_t (*pgtable_alloc)(int),
+			   phys_addr_t (*pgtable_alloc)(int, void *),
+			   void *arg,
 			   int flags)
 {
 	unsigned long next;
@@ -337,7 +343,7 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
 		if (flags & NO_EXEC_MAPPINGS)
 			p4dval |= P4D_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
-		pud_phys = pgtable_alloc(PUD_SHIFT);
+		pud_phys = pgtable_alloc(PUD_SHIFT, arg);
 		pudp = pud_set_fixmap(pud_phys);
 		init_clear_pgtable(pudp);
 		pudp += pud_index(addr);
@@ -368,7 +374,7 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
 						      READ_ONCE(pud_val(*pudp))));
 		} else {
 			alloc_init_cont_pmd(pudp, addr, next, phys, prot,
-					    pgtable_alloc, flags);
+					    pgtable_alloc, arg, flags);
 
 			BUG_ON(pud_val(old_pud) != 0 &&
 			       pud_val(old_pud) != READ_ONCE(pud_val(*pudp)));
@@ -381,7 +387,8 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
 
 static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
 			   phys_addr_t phys, pgprot_t prot,
-			   phys_addr_t (*pgtable_alloc)(int),
+			   phys_addr_t (*pgtable_alloc)(int, void *),
+			   void *arg,
 			   int flags)
 {
 	unsigned long next;
@@ -395,7 +402,7 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
 		if (flags & NO_EXEC_MAPPINGS)
 			pgdval |= PGD_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
-		p4d_phys = pgtable_alloc(P4D_SHIFT);
+		p4d_phys = pgtable_alloc(P4D_SHIFT, arg);
 		p4dp = p4d_set_fixmap(p4d_phys);
 		init_clear_pgtable(p4dp);
 		p4dp += p4d_index(addr);
@@ -411,7 +418,7 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
 		next = p4d_addr_end(addr, end);
 
 		alloc_init_pud(p4dp, addr, next, phys, prot,
-			       pgtable_alloc, flags);
+			       pgtable_alloc, arg, flags);
 
 		BUG_ON(p4d_val(old_p4d) != 0 &&
 		       p4d_val(old_p4d) != READ_ONCE(p4d_val(*p4dp)));
@@ -422,10 +429,11 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
 	p4d_clear_fixmap();
 }
 
-static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
+void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
 					unsigned long virt, phys_addr_t size,
 					pgprot_t prot,
-					phys_addr_t (*pgtable_alloc)(int),
+					phys_addr_t (*pgtable_alloc)(int, void *),
+					void *arg,
 					int flags)
 {
 	unsigned long addr, end, next;
@@ -445,7 +453,7 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
 	do {
 		next = pgd_addr_end(addr, end);
 		alloc_init_p4d(pgdp, addr, next, phys, prot, pgtable_alloc,
-			       flags);
+			       arg, flags);
 		phys += next - addr;
 	} while (pgdp++, addr = next, addr != end);
 }
@@ -453,12 +461,13 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
 static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
 				 unsigned long virt, phys_addr_t size,
 				 pgprot_t prot,
-				 phys_addr_t (*pgtable_alloc)(int),
+				 phys_addr_t (*pgtable_alloc)(int, void *),
+				 void *arg,
 				 int flags)
 {
 	mutex_lock(&fixmap_lock);
 	__create_pgd_mapping_locked(pgdir, phys, virt, size, prot,
-				    pgtable_alloc, flags);
+				    pgtable_alloc, arg, flags);
 	mutex_unlock(&fixmap_lock);
 }
 
@@ -466,10 +475,10 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
 extern __alias(__create_pgd_mapping_locked)
 void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
 			     phys_addr_t size, pgprot_t prot,
-			     phys_addr_t (*pgtable_alloc)(int), int flags);
+			     phys_addr_t (*pgtable_alloc)(int, void *), void *arg, int flags);
 #endif
 
-static phys_addr_t __pgd_pgtable_alloc(int shift)
+static phys_addr_t __pgd_pgtable_alloc(int shift, void *unused)
 {
 	/* Page is zeroed by init_clear_pgtable() so don't duplicate effort. */
 	void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL & ~__GFP_ZERO);
@@ -478,9 +487,9 @@ static phys_addr_t __pgd_pgtable_alloc(int shift)
 	return __pa(ptr);
 }
 
-static phys_addr_t pgd_pgtable_alloc(int shift)
+static phys_addr_t pgd_pgtable_alloc(int shift, void *unused)
 {
-	phys_addr_t pa = __pgd_pgtable_alloc(shift);
+	phys_addr_t pa = __pgd_pgtable_alloc(shift, unused);
 	struct ptdesc *ptdesc = page_ptdesc(phys_to_page(pa));
 
 	/*
@@ -512,7 +521,7 @@ void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
 			&phys, virt);
 		return;
 	}
-	__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL,
+	__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, NULL,
 			     NO_CONT_MAPPINGS);
 }
 
@@ -528,7 +537,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 		flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 
 	__create_pgd_mapping(mm->pgd, phys, virt, size, prot,
-			     pgd_pgtable_alloc, flags);
+			     pgd_pgtable_alloc, NULL, flags);
 }
 
 static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
@@ -540,7 +549,7 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
 		return;
 	}
 
-	__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL,
+	__create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, NULL,
 			     NO_CONT_MAPPINGS);
 
 	/* flush the TLBs after updating live kernel mappings */
@@ -551,7 +560,7 @@ static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start,
 				  phys_addr_t end, pgprot_t prot, int flags)
 {
 	__create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start,
-			     prot, early_pgtable_alloc, flags);
+			     prot, early_pgtable_alloc, NULL, flags);
 }
 
 void __init mark_linear_text_alias_ro(void)
@@ -742,7 +751,7 @@ static int __init map_entry_trampoline(void)
 	memset(tramp_pg_dir, 0, PGD_SIZE);
 	__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
 			     entry_tramp_text_size(), prot,
-			     __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS);
+			     __pgd_pgtable_alloc, NULL, NO_BLOCK_MAPPINGS);
 
 	/* Map both the text and data into the kernel page table */
 	for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
@@ -1344,7 +1353,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
 		flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
 
 	__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
-			     size, params->pgprot, __pgd_pgtable_alloc,
+			     size, params->pgprot, __pgd_pgtable_alloc, NULL,
 			     flags);
 
 	memblock_clear_nomap(start, size);
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:41 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:41 +0800
Subject: [RFCv2 8/9] arm64: kexec: Prepare page table for emulator
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-9-piliu@redhat.com>

The emulator will run in identity mapping, and the first kernel prepares
for it. The special allocator resorts to kimage_alloc_control_pages(),
which can avoid the allocation on the spot of the destination and
overwritten during copying the kernel.

The identity mapping covers only all of the kexec segments and efi
runtime service.  This reduces the memory consumption of page table.

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/kernel/machine_kexec.c | 101 ++++++++++++++++++++++++++++--
 include/linux/kexec.h             |   5 +-
 2 files changed, 101 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 6958c1fc84a5a..871ee1163ebca 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -14,6 +14,7 @@
 #include <linux/reboot.h>
 #include <linux/set_memory.h>
 #include <linux/smp.h>
+#include <linux/efi_emulator.h>
 
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
@@ -86,8 +87,22 @@ static void kexec_segment_flush(const struct kimage *kimage)
 	}
 }
 
+/* todo: alloc page for the pgtable used by efi emulator in crashkernel range */
+static phys_addr_t crash_page_alloc(int unused, void *arg)
+{
+	struct kimage *kimage = (struct kimage *)arg;
+	int i;
+
+	//skip kimage->segment[].mem
+	for (i = 0; i < kimage->nr_segments; i ++) {
+		//seg = &kimage->segment[i];
+	}
+	//skip any range allocated
+	return -1;
+}
+
 /* Allocates pages for kexec page table */
-static void *kexec_page_alloc(void *arg)
+static void *__kexec_page_alloc(void *arg)
 {
 	struct kimage *kimage = arg;
 	struct page *page = kimage_alloc_control_pages(kimage, 0);
@@ -102,6 +117,82 @@ static void *kexec_page_alloc(void *arg)
 	return vaddr;
 }
 
+static phys_addr_t kexec_page_alloc(int unused, void *arg)
+{
+	void *vaddr;
+
+	vaddr = __kexec_page_alloc(arg);
+	if (!vaddr)
+		return (phys_addr_t)-1;
+	return virt_to_phys(vaddr);
+}
+
+/*
+ * This function should be called after all kimage segments have been profiled 
+ * Return physical address of page table's root
+ */
+phys_addr_t arch_emulator_prepare_pgtable(struct kimage *kimage,
+		struct efi_emulator_param *param)
+{
+	efi_memory_desc_t *md;
+	struct kexec_segment *seg;
+	unsigned long paddr, vaddr, sz;
+	pgd_t *pgd;
+	typedef phys_addr_t (* alloc_fn)(int, void *);
+	alloc_fn alloc;
+	phys_addr_t pgd_paddr;
+	int i;
+
+	/*
+	 * Set up pgtable of emulator, either for crash or for reboot.
+	 * All of the segments have been profiled, and kimage_alloc_normal_control_pages()
+	 * will allocate page in safe zone.
+	 * On the other hand, these pages are not in any segment, which means they are
+	 * left, not copied. Hence the radix tree laying out on them is not broken.
+	 */
+	if (kimage->head & IND_DONE)
+		alloc = crash_page_alloc;
+	else
+		alloc = kexec_page_alloc;
+	pgd_paddr = alloc(0, kimage);
+	pgd = (pgd_t *)phys_to_virt(pgd_paddr);
+	for (i = 0; i < kimage->nr_segments; i ++) {
+		seg = &kimage->segment[i];
+		paddr = ALIGN_DOWN(seg->mem, PAGE_SIZE);
+		sz = ALIGN(seg->mem - paddr + seg->memsz, PAGE_SIZE);
+		kexec_dprintk("Set up mapping for phyaddr: 0x%lx, size:0x%lx", paddr, sz);
+		//todo: distinguish executable segment
+		__create_pgd_mapping_locked(pgd, paddr, paddr, sz,
+				PAGE_KERNEL_EXEC, alloc, kimage, 0);
+	}
+
+	/*
+	 * UEFI stub can call EFI runtime service either before or after one-shot
+	 * SetVirtualAddressMap(). That means the mapping for
+	 * EFI_RUNTIME_SERVICES_CODE/_DATA should be set up here.
+	 * And the virtual address range occupied by md must be reserved,
+	 * accordingly, its physical address should not be allocated by kexec
+	 * allocator
+	 */
+	for_each_efi_memory_desc(md) {
+		if (md->attribute & EFI_MEMORY_RUNTIME) {
+			vaddr = md->virt_addr;
+			paddr = md->phys_addr;
+			sz = md->num_pages * EFI_PAGE_SIZE;
+			kexec_dprintk("Set up mapping for md phyaddr: 0x%lx, virt: 0x%lx, size:0x%lx", paddr, vaddr, sz);
+			__create_pgd_mapping_locked(pgd, paddr, vaddr, sz,
+					PAGE_KERNEL_EXEC, alloc, kimage, 0);
+		}
+	}
+
+	if (param->print_enabled)
+		__create_pgd_mapping_locked(pgd, param->earlycon_reg_base,
+				param->earlycon_reg_base, param->earlycon_reg_sz,
+				pgprot_device(PAGE_KERNEL), alloc, kimage, 0);
+
+	return pgd_paddr;
+}
+
 int machine_kexec_post_load(struct kimage *kimage)
 {
 	int rc;
@@ -109,7 +200,7 @@ int machine_kexec_post_load(struct kimage *kimage)
 	void *reloc_code = page_to_virt(kimage->control_code_page);
 	long reloc_size;
 	struct trans_pgd_info info = {
-		.trans_alloc_page	= kexec_page_alloc,
+		.trans_alloc_page	= __kexec_page_alloc,
 		.trans_alloc_arg	= kimage,
 	};
 
@@ -129,7 +220,7 @@ int machine_kexec_post_load(struct kimage *kimage)
 	}
 
 	/* Create a copy of the linear map */
-	trans_pgd = kexec_page_alloc(kimage);
+	trans_pgd = __kexec_page_alloc(kimage);
 	if (!trans_pgd)
 		return -ENOMEM;
 	rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
@@ -145,6 +236,7 @@ int machine_kexec_post_load(struct kimage *kimage)
 				  &kimage->arch.t0sz, reloc_code);
 	if (rc)
 		return rc;
+
 	kimage->arch.phys_offset = virt_to_phys(kimage) - (long)kimage;
 
 	/* Flush the reloc_code in preparation for its execution. */
@@ -175,7 +267,6 @@ void machine_kexec(struct kimage *kimage)
 		"Some CPUs may be stale, kdump will be unreliable.\n");
 
 	pr_info("Bye!\n");
-
 	local_daif_mask();
 
 	/*
@@ -192,6 +283,7 @@ void machine_kexec(struct kimage *kimage)
 
 		cpu_install_idmap();
 		restart = (void *)__pa_symbol(cpu_soft_restart);
+		/* kimage->start can be either the entry of kernel or efi emulator */
 		restart(is_hyp_nvhe(), kimage->start, kimage->arch.param_mem,
 			0, 0);
 	} else {
@@ -201,6 +293,7 @@ void machine_kexec(struct kimage *kimage)
 			__hyp_set_vectors(kimage->arch.el2_vectors);
 		cpu_install_ttbr0(kimage->arch.ttbr0, kimage->arch.t0sz);
 		kernel_reloc = (void *)kimage->arch.kern_reloc;
+		//tell between the emulator and normal kernel inside the relocate code 
 		kernel_reloc(kimage);
 	}
 
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 57b98bcaa5228..1599c21e7c5d5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -22,6 +22,7 @@
 
 #include <uapi/linux/kexec.h>
 #include <linux/verification.h>
+#include <linux/efi_emulator.h>
 
 extern note_buf_t __percpu *crash_notes;
 
@@ -464,7 +465,9 @@ static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, g
 static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { }
 #endif
 
-extern phys_addr_t arch_emulator_prepare_pgtable(struct kimage *kimage);
+extern phys_addr_t arch_emulator_prepare_pgtable(struct kimage *kimage,
+		struct efi_emulator_param *param);
+
 extern bool kexec_file_dbg_print;
 
 #define kexec_dprintk(fmt, arg...) \
-- 
2.41.0



From piliu at redhat.com  Mon Aug 19 07:53:42 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:42 +0800
Subject: [RFCv2 9/9] arm64: kexec: Enable kexec_pe_image
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-10-piliu@redhat.com>

Now, anything is ready, enable PE image loading on arm64

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/Kconfig                     | 4 ++++
 arch/arm64/kernel/machine_kexec_file.c | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5d91259ee7b53..fb6de7b4cd008 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1550,6 +1550,10 @@ config ARCH_SELECTS_KEXEC_FILE
 	depends on KEXEC_FILE
 	select HAVE_IMA_KEXEC if IMA
 
+config ARCH_SELECTS_KEXEC_PEIMAGE
+	def_bool y
+	depends on KEXEC_FILE
+
 config ARCH_SUPPORTS_KEXEC_SIG
 	def_bool y
 
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 9fca3a35f04d5..c259d871b8e33 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -24,6 +24,9 @@
 
 const struct kexec_file_ops * const kexec_file_loaders[] = {
 	&kexec_image_ops,
+#ifdef CONFIG_ARCH_SELECTS_KEXEC_PEIMAGE
+	&pe_image_ops,
+#endif
 	NULL
 };
 
-- 
2.41.0



From jarkko at kernel.org  Mon Aug 19 11:00:08 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Mon, 19 Aug 2024 21:00:08 +0300
Subject: [RFCv2 1/9] efi/libstub: Ask efi_random_alloc() to skip
 unusable memory
In-Reply-To: <20240819145417.23367-2-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
 <20240819145417.23367-2-piliu@redhat.com>
Message-ID: <D3K31JJ5PZQG.2XW6Y6OR1CTLG@kernel.org>

On Mon Aug 19, 2024 at 5:53 PM EEST, Pingfan Liu wrote:
> efi_random_alloc() demands EFI_ALLOCATE_ADDRESS when allocate_pages(),
> but the current implement can not ensure the selected target locates
> inside free area, that is to exclude EFI_BOOT_SERVICES_*,
> EFI_RUNTIME_SERVICES_* etc.
>
> Fix the issue by checking md->type.

If it is a fix shouldn't this have a fixes tag?

>
> Signed-off-by: Pingfan Liu <piliu at redhat.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> To: linux-efi at vger.kernel.org
> ---
>  drivers/firmware/efi/libstub/randomalloc.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c
> index c41e7b2091cdd..7304e767688f2 100644
> --- a/drivers/firmware/efi/libstub/randomalloc.c
> +++ b/drivers/firmware/efi/libstub/randomalloc.c
> @@ -79,6 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size,
>  		efi_memory_desc_t *md = (void *)map->map + map_offset;
>  		unsigned long slots;
>  

I'd add this inline comment:

/* Skip "unconventional" memory: */

> +		if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> +			continue;
>  		slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
>  					    alloc_max);
>  		MD_NUM_SLOTS(md) = slots;
> @@ -111,6 +113,9 @@ efi_status_t efi_random_alloc(unsigned long size,
>  		efi_physical_addr_t target;
>  		unsigned long pages;
>  
> +		if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> +			continue;
> +
>  		if (total_mirrored_slots > 0 &&
>  		    !(md->attribute & EFI_MEMORY_MORE_RELIABLE))
>  			continue;

BR, Jarkko


From jarkko at kernel.org  Mon Aug 19 11:05:47 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Mon, 19 Aug 2024 21:05:47 +0300
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <Zr+dTMYZNY1b9cRV@srcf.ucam.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx> <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
 <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org> <Zr+dTMYZNY1b9cRV@srcf.ucam.org>
Message-ID: <D3K35VBCWZSW.2WCXJMW1HGGD5@kernel.org>

On Fri Aug 16, 2024 at 9:41 PM EEST, Matthew Garrett wrote:
> On Fri, Aug 16, 2024 at 02:22:04PM +0300, Jarkko Sakkinen wrote:
>
> > For (any) non-legacy features we can choose, which choices we choose to
> > support, and which we do not. This is not an oppositive view just saying
> > how it is, and platforms set of choices is not a selling argument.
>
> NIST still permits the use of SHA-1 until 2030, and the most significant 
> demonstrated weaknesses in it don't seem applicable to the use case 
> here. We certainly shouldn't encourage any new uses of it, and anyone 
> who's able to use SHA-2 should be doing that instead, but it feels like 
> people are arguing about not supporting hardware that exists in the real 
> world for vibes reasons rather than it being a realistically attackable 
> weakness (and if we really *are* that concerned about SHA-1, why are we 
> still supporting TPM 1.2 at all?)

We are life-supporting TPM 1.2 as long as necessary but neither the
support is extended nor new features will gain TPM 1.2 support. So
that is at least my policy for that feature.

BR, Jarkko


From mjg59 at srcf.ucam.org  Mon Aug 19 11:24:02 2024
From: mjg59 at srcf.ucam.org (Matthew Garrett)
Date: Mon, 19 Aug 2024 19:24:02 +0100
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <D3K35VBCWZSW.2WCXJMW1HGGD5@kernel.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
 <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
 <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org>
 <Zr+dTMYZNY1b9cRV@srcf.ucam.org>
 <D3K35VBCWZSW.2WCXJMW1HGGD5@kernel.org>
Message-ID: <ZsONwsWs3zCln70O@srcf.ucam.org>

On Mon, Aug 19, 2024 at 09:05:47PM +0300, Jarkko Sakkinen wrote:
> On Fri Aug 16, 2024 at 9:41 PM EEST, Matthew Garrett wrote:
> > On Fri, Aug 16, 2024 at 02:22:04PM +0300, Jarkko Sakkinen wrote:
> >
> > > For (any) non-legacy features we can choose, which choices we choose to
> > > support, and which we do not. This is not an oppositive view just saying
> > > how it is, and platforms set of choices is not a selling argument.
> >
> > NIST still permits the use of SHA-1 until 2030, and the most significant 
> > demonstrated weaknesses in it don't seem applicable to the use case 
> > here. We certainly shouldn't encourage any new uses of it, and anyone 
> > who's able to use SHA-2 should be doing that instead, but it feels like 
> > people are arguing about not supporting hardware that exists in the real 
> > world for vibes reasons rather than it being a realistically attackable 
> > weakness (and if we really *are* that concerned about SHA-1, why are we 
> > still supporting TPM 1.2 at all?)
> 
> We are life-supporting TPM 1.2 as long as necessary but neither the
> support is extended nor new features will gain TPM 1.2 support. So
> that is at least my policy for that feature.

But the fact that we support it and provide no warning labels is a 
pretty clear indication that we're not actively trying to prevent people 
from using SHA-1 in the general case. Why is this a different case? 
Failing to support it actually opens an entire separate set of footgun 
opportunities in terms of the SHA-1 banks now being out of sync with the 
SHA-2 ones, so either way we're leaving people open to making poor 
choices.


From piliu at redhat.com  Mon Aug 19 17:58:01 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Tue, 20 Aug 2024 08:58:01 +0800
Subject: [RFCv2 1/9] efi/libstub: Ask efi_random_alloc() to skip unusable memory
In-Reply-To: <D3K31JJ5PZQG.2XW6Y6OR1CTLG@kernel.org>
References: <20240819145417.23367-1-piliu@redhat.com> <20240819145417.23367-2-piliu@redhat.com>
 <D3K31JJ5PZQG.2XW6Y6OR1CTLG@kernel.org>
Message-ID: <CAF+s44TK1RZ6m=b3RX_KTsptRQ06XZO_knn3=39eWXLv64AxoA@mail.gmail.com>

On Tue, Aug 20, 2024 at 2:00?AM Jarkko Sakkinen <jarkko at kernel.org> wrote:
>
> On Mon Aug 19, 2024 at 5:53 PM EEST, Pingfan Liu wrote:
> > efi_random_alloc() demands EFI_ALLOCATE_ADDRESS when allocate_pages(),
> > but the current implement can not ensure the selected target locates
> > inside free area, that is to exclude EFI_BOOT_SERVICES_*,
> > EFI_RUNTIME_SERVICES_* etc.
> >
> > Fix the issue by checking md->type.
>
> If it is a fix shouldn't this have a fixes tag?
>
Yes, I will supplement the following in the next version
Fixes: 2ddbfc81eac8 ("efi: stub: add implementation of efi_random_alloc()")

> >
> > Signed-off-by: Pingfan Liu <piliu at redhat.com>
> > Cc: Ard Biesheuvel <ardb at kernel.org>
> > To: linux-efi at vger.kernel.org
> > ---
> >  drivers/firmware/efi/libstub/randomalloc.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c
> > index c41e7b2091cdd..7304e767688f2 100644
> > --- a/drivers/firmware/efi/libstub/randomalloc.c
> > +++ b/drivers/firmware/efi/libstub/randomalloc.c
> > @@ -79,6 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size,
> >               efi_memory_desc_t *md = (void *)map->map + map_offset;
> >               unsigned long slots;
> >
>
> I'd add this inline comment:
>
> /* Skip "unconventional" memory: */
>

Adopt.

Thanks for your kind review.

Best Regards,

Pingfan

> > +             if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> > +                     continue;
> >               slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
> >                                           alloc_max);
> >               MD_NUM_SLOTS(md) = slots;
> > @@ -111,6 +113,9 @@ efi_status_t efi_random_alloc(unsigned long size,
> >               efi_physical_addr_t target;
> >               unsigned long pages;
> >
> > +             if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> > +                     continue;
> > +
> >               if (total_mirrored_slots > 0 &&
> >                   !(md->attribute & EFI_MEMORY_MORE_RELIABLE))
> >                       continue;
>
> BR, Jarkko
>



From sourabhjain at linux.ibm.com  Mon Aug 19 23:40:27 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Tue, 20 Aug 2024 12:10:27 +0530
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <ZsLjGJvAUIaxrG6x@MiWiFi-R3L-srv>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
 <87v80lnf8d.fsf@mail.lhotse>
 <10c666ae-d528-4f49-82e9-8e0fee7099e0@linux.ibm.com>
 <355b58b1-6c51-4c42-b6ea-dcd6b1617a18@linux.ibm.com>
 <ZsLjGJvAUIaxrG6x@MiWiFi-R3L-srv>
Message-ID: <1e4a8e18-cda9-45f5-a842-8ffcd725efc9@linux.ibm.com>

Hello Baoquan,

On 19/08/24 11:45, Baoquan He wrote:
> On 08/19/24 at 09:45am, Sourabh Jain wrote:
>> Hello Michael and Boaquan
>>
>> On 01/08/24 12:21, Sourabh Jain wrote:
>>> Hello Michael,
>>>
>>> On 01/08/24 08:04, Michael Ellerman wrote:
>>>> Sourabh Jain <sourabhjain at linux.ibm.com> writes:
>>>>> The following errors are observed when kexec is done with SMT=off on
>>>>> powerpc.
>>>>>
>>>>> [? 358.458385] Removing IBM Power 842 compression device
>>>>> [? 374.795734] kexec_core: Starting new kernel
>>>>> [? 374.795748] kexec: Waking offline cpu 1.
>>>>> [? 374.875695] crash hp: kexec_trylock() failed, elfcorehdr may
>>>>> be inaccurate
>>>>> [? 374.935833] kexec: Waking offline cpu 2.
>>>>> [? 375.015664] crash hp: kexec_trylock() failed, elfcorehdr may
>>>>> be inaccurate
>>>>> snip..
>>>>> [? 375.515823] kexec: Waking offline cpu 6.
>>>>> [? 375.635667] crash hp: kexec_trylock() failed, elfcorehdr may
>>>>> be inaccurate
>>>>> [? 375.695836] kexec: Waking offline cpu 7.
>>>> Are they actually errors though? Do they block the actual kexec from
>>>> happening? Or are they just warnings in dmesg?
>>> The kexec kernel boots fine.
>>>
>>> This warning appears regardless of whether the kdump kernel is loaded.
>>>
>>> However, when the kdump kernel is loaded, we will not be able to update
>>> the kdump image (FDT).
>>> I think this should be fine given that kexec is in progress.
>>>
>>> Please let me know your opinion.
>>>
>>>> Because the fix looks like it could be racy.
>>> It seems like it is racy, but given that kexec takes the lock first and
>>> then
>>> brings the CPU up, which triggers the kdump image, which always fails to
>>> update the kdump image because it could not take the same lock.
>>>
>>> Note: the kexec lock is not released unless kexec boot fails.
>> Any comments or suggestions on this fix?
> Is this a little better?
>
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6e..0355ffb712f4 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -504,7 +504,7 @@ int crash_check_hotplug_support(void)
>   
>   	crash_hotplug_lock();
>   	/* Obtain lock while reading crash information */
> -	if (!kexec_trylock()) {
> +	if (!kexec_trylock() && kexec_in_progress) {
>   		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>   		crash_hotplug_unlock();
>   		return 0;
> @@ -539,7 +539,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
>   
>   	crash_hotplug_lock();
>   	/* Obtain lock while changing crash information */
> -	if (!kexec_trylock()) {
> +	if (!kexec_trylock() && kexec_in_progress) {
>   		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
>   		crash_hotplug_unlock();
>   		return;

Ideally, when `kexec_in_progress` is True, there should be no way to 
acquire the kexec lock.
Therefore, calling `kexec_trylock()` before checking `kexec_in_progress` 
is not helpful.
The kernel will print the error message "kexec_trylock() failed, 
elfcorehdr may be inaccurate."
So, with the above changes, the original problem remains unsolved.

However, after closely inspecting the 
`kernel/kexec_core.c:kernel_kexec()` function, I discovered
an exceptional case where my patch needs an update. The issue arises 
when the system returns
from the `machine_kexec()` function, which indicates that kexec has failed.

In this scenario, the kexec lock is released, but `kexec_in_progress` 
remains True.

I am unsure why `kexec_in_progress` is NOT set to False when kexec 
fails. Was this by design,
or was it an oversight because returning from the `machine_kexec()` 
function is highly unlikely?

Here is my proposal to address the original problem along with the 
exceptional case I described
above.

Let's implement two patches:

1. A patch that sets `kexec_in_progress` to False if the system returns 
from `machine_kexec()` before
 ?? unlocking the kexec lock in the `kernel_kexec()` function.

 ?? ```
 ?? diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
 ?? index c0caa14880c3..b41277183455 100644
 ?? --- a/kernel/kexec_core.c
 ?? +++ b/kernel/kexec_core.c
 ?? @@ -1069,6 +1069,7 @@ int kernel_kexec(void)
 ?? #endif

 ??? Unlock:
 ?? +????? kexec_in_progress = false;
 ?????????? kexec_unlock();
 ?????????? return error;
 ??? ```

2. A patch to return early from the `crash_handle_hotplug_event()` 
function if `kexec_in_progress` is
 ?? set to True. This is essentially my original patch.

Please share your comments on the new approach.

Thank you for review.

- Sourabh Jain


From jarkko at kernel.org  Tue Aug 20 08:26:31 2024
From: jarkko at kernel.org (Jarkko Sakkinen)
Date: Tue, 20 Aug 2024 18:26:31 +0300
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <ZsONwsWs3zCln70O@srcf.ucam.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx> <550d15cd-5c48-4c20-92c2-f09a7e30adc9@citrix.com>
 <D3HAP4O4OVS3.2LOSH5HMQ34OZ@kernel.org> <Zr+dTMYZNY1b9cRV@srcf.ucam.org>
 <D3K35VBCWZSW.2WCXJMW1HGGD5@kernel.org> <ZsONwsWs3zCln70O@srcf.ucam.org>
Message-ID: <D3KUEGW4Q63K.NEFOY5C6ZG2O@kernel.org>

On Mon Aug 19, 2024 at 9:24 PM EEST, Matthew Garrett wrote:
> On Mon, Aug 19, 2024 at 09:05:47PM +0300, Jarkko Sakkinen wrote:
> > On Fri Aug 16, 2024 at 9:41 PM EEST, Matthew Garrett wrote:
> > > On Fri, Aug 16, 2024 at 02:22:04PM +0300, Jarkko Sakkinen wrote:
> > >
> > > > For (any) non-legacy features we can choose, which choices we choose to
> > > > support, and which we do not. This is not an oppositive view just saying
> > > > how it is, and platforms set of choices is not a selling argument.
> > >
> > > NIST still permits the use of SHA-1 until 2030, and the most significant 
> > > demonstrated weaknesses in it don't seem applicable to the use case 
> > > here. We certainly shouldn't encourage any new uses of it, and anyone 
> > > who's able to use SHA-2 should be doing that instead, but it feels like 
> > > people are arguing about not supporting hardware that exists in the real 
> > > world for vibes reasons rather than it being a realistically attackable 
> > > weakness (and if we really *are* that concerned about SHA-1, why are we 
> > > still supporting TPM 1.2 at all?)
> > 
> > We are life-supporting TPM 1.2 as long as necessary but neither the
> > support is extended nor new features will gain TPM 1.2 support. So
> > that is at least my policy for that feature.
>
> But the fact that we support it and provide no warning labels is a 
> pretty clear indication that we're not actively trying to prevent people 
> from using SHA-1 in the general case. Why is this a different case? 
> Failing to support it actually opens an entire separate set of footgun 
> opportunities in terms of the SHA-1 banks now being out of sync with the 
> SHA-2 ones, so either way we're leaving people open to making poor 
> choices.

This is a fair and enclosing argument. I get where you are coming from
now. Please as material for the commit message.

BR, Jarkko



From stefan.wiehler at nokia.com  Wed Aug 21 00:30:00 2024
From: stefan.wiehler at nokia.com (Stefan Wiehler)
Date: Wed, 21 Aug 2024 09:30:00 +0200
Subject: [PATCH 1/2] makedumpfile: Add ftruncate error handling
In-Reply-To: <db15a94c-3fa5-47e6-8c8d-59665bb119a8@nec.com>
References: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
 <db15a94c-3fa5-47e6-8c8d-59665bb119a8@nec.com>
Message-ID: <2874031e-bb32-43dc-8220-7756dc2b36a2@nokia.com>

> I tried to reproduce those warnings, but could not get either one
> with a plain make command and gcc 14.1 (or clang 18.1).
> 
> out of curiosity, what compiler version and build command do you use?

We use GCC 12.2.0 and build via the BitBake recipe:

https://layers.openembedded.org/layerindex/recipe/52214/

The recipe removes hardcoded CFLAGS in the Makefile, so it is not
obvious to me right now if we get these error warnings due to additional
CFLAGS we inject by default to each recipe or due to below patch alone:

https://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-kernel/makedumpfile/makedumpfile/0001-makedumpfile-replace-hardcode-CFLAGS.patch?h=master

Kind regards,

Stefan


From jan.polasek at envisioncraftsman.com  Wed Aug 21 00:35:59 2024
From: jan.polasek at envisioncraftsman.com (=?UTF-8?Q? Jan_Pol=C3=A1=C5=A1ek ?=)
Date: Wed, 21 Aug 2024 07:35:59 GMT
Subject: Quick Question About Collaboration
Message-ID: <20240821084500-0.1.4j.va9m.0.5b7aifmnz0@envisioncraftsman.com>

Hello!

I am very impressed with the products and services you offer.

I thought we could help you reach a larger audience with your offerings. Would you be interested in collaborating with us in an affiliate marketing campaign?

For example, our program for a company in the e-commerce sector resulted in an increase in revenue from 8% to an impressive 19% (on average per quarter).

We achieve up to 13% turnover in GA4, while standard affiliate networks generate only 3-6%.

Would you have time for a short conversation in the next few days?


Best regards
Jan Pol??ek


From piliu at redhat.com  Mon Aug 19 07:53:36 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Mon, 19 Aug 2024 22:53:36 +0800
Subject: [RFCv2 3/9] efi/emulator: Initial rountines to emulate EFI boot time service
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <20240819145417.23367-4-piliu@redhat.com>

From: Pingfan Liu <kernelfans at gmail.com>

efi emulator aims to serve the kexec if the kernel wrapped by efistub.
It is paired with efistub, so only implements the minimus set of EFI boot
service which merely enough boots up efistub.

To simplify the code, the task such as the building of page table etc is
shift to the first kernel as more as possible. (This part is implement
in the later patch in this series)

To do:
-1. a simple memory allocator
-2. a few extra efi boot service.

Signed-off-by: Pingfan Liu <piliu at redhat.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: kexec at lists.infradead.org
To: linux-efi at vger.kernel.org
---
 drivers/firmware/efi/Makefile                 |   1 +
 drivers/firmware/efi/efi_emulator/Makefile    |  99 +++++
 .../firmware/efi/efi_emulator/amba-pl011.c    |  81 ++++
 .../efi_emulator/arm64_emulator_service.lds   |  45 +++
 .../firmware/efi/efi_emulator/config_table.c  |  25 ++
 drivers/firmware/efi/efi_emulator/core.c      | 376 ++++++++++++++++++
 .../firmware/efi/efi_emulator/device_handle.c | 138 +++++++
 drivers/firmware/efi/efi_emulator/earlycon.h  |  19 +
 .../firmware/efi/efi_emulator/efi_emulator.S  |  12 +
 drivers/firmware/efi/efi_emulator/emulator.h  | 106 +++++
 drivers/firmware/efi/efi_emulator/entry.c     |  61 +++
 drivers/firmware/efi/efi_emulator/head.S      |  10 +
 drivers/firmware/efi/efi_emulator/lib.c       |  73 ++++
 drivers/firmware/efi/efi_emulator/memory.c    |  27 ++
 .../firmware/efi/efi_emulator/memory_api.c    |  74 ++++
 drivers/firmware/efi/efi_emulator/misc.c      |  43 ++
 drivers/firmware/efi/efi_emulator/pe_loader.c | 173 ++++++++
 drivers/firmware/efi/efi_emulator/printf.c    | 373 +++++++++++++++++
 .../efi/efi_emulator/protocol_device_path.c   |  75 ++++
 .../protocol_simple_text_output.c             |  50 +++
 include/linux/efi_emulator.h                  |  46 +++
 include/linux/kexec.h                         |   2 +
 22 files changed, 1909 insertions(+)
 create mode 100644 drivers/firmware/efi/efi_emulator/Makefile
 create mode 100644 drivers/firmware/efi/efi_emulator/amba-pl011.c
 create mode 100644 drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds
 create mode 100644 drivers/firmware/efi/efi_emulator/config_table.c
 create mode 100644 drivers/firmware/efi/efi_emulator/core.c
 create mode 100644 drivers/firmware/efi/efi_emulator/device_handle.c
 create mode 100644 drivers/firmware/efi/efi_emulator/earlycon.h
 create mode 100644 drivers/firmware/efi/efi_emulator/efi_emulator.S
 create mode 100644 drivers/firmware/efi/efi_emulator/emulator.h
 create mode 100644 drivers/firmware/efi/efi_emulator/entry.c
 create mode 100644 drivers/firmware/efi/efi_emulator/head.S
 create mode 100644 drivers/firmware/efi/efi_emulator/lib.c
 create mode 100644 drivers/firmware/efi/efi_emulator/memory.c
 create mode 100644 drivers/firmware/efi/efi_emulator/memory_api.c
 create mode 100644 drivers/firmware/efi/efi_emulator/misc.c
 create mode 100644 drivers/firmware/efi/efi_emulator/pe_loader.c
 create mode 100644 drivers/firmware/efi/efi_emulator/printf.c
 create mode 100644 drivers/firmware/efi/efi_emulator/protocol_device_path.c
 create mode 100644 drivers/firmware/efi/efi_emulator/protocol_simple_text_output.c
 create mode 100644 include/linux/efi_emulator.h

diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index a2d0009560d0f..41471416945eb 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_EFI_VARS_PSTORE)		+= efi-pstore.o
 obj-$(CONFIG_UEFI_CPER)			+= cper.o cper_cxl.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
 subdir-$(CONFIG_EFI_STUB)		+= libstub
+obj-$(CONFIG_ARCH_SELECTS_KEXEC_PEIMAGE)	+= efi_emulator/
 obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)	+= efibc.o
 obj-$(CONFIG_EFI_TEST)			+= test/
 obj-$(CONFIG_EFI_DEV_PATH_PARSER)	+= dev-path-parser.o
diff --git a/drivers/firmware/efi/efi_emulator/Makefile b/drivers/firmware/efi/efi_emulator/Makefile
new file mode 100644
index 0000000000000..d696381d168ba
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/Makefile
@@ -0,0 +1,99 @@
+# non-x86 reuses KBUILD_CFLAGS, x86 does not
+cflags-y			:= $(KBUILD_CFLAGS)
+
+cflags-$(CONFIG_X86_32)		:= -march=i386
+cflags-$(CONFIG_X86_64)		:= -mcmodel=small
+cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
+				   -fno-strict-aliasing -mno-red-zone \
+				   -mno-mmx -mno-sse -fshort-wchar \
+				   -Wno-pointer-sign \
+				   $(call cc-disable-warning, address-of-packed-member) \
+				   $(call cc-disable-warning, gnu) \
+				   -fno-asynchronous-unwind-tables \
+				   $(CLANG_FLAGS)
+
+# arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
+# disable the stackleak plugin
+cflags-$(CONFIG_ARM64)		+= $(DISABLE_STACKLEAK_PLUGIN) \
+				   -fno-unwind-tables -fno-asynchronous-unwind-tables
+cflags-$(CONFIG_ARM)		+= -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \
+				   -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \
+				   -DEFI_HAVE_STRCMP -fno-builtin  \
+				   $(call cc-option,-mno-single-pic-base)
+cflags-$(CONFIG_RISCV)		+= -DNO_ALTERNATIVE -mno-relax
+cflags-$(CONFIG_LOONGARCH)	+=
+
+cflags-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= -I$(srctree)/scripts/dtc/libfdt
+
+cflags-y	+= -I drivers/firmware/efi/libstub
+
+KBUILD_CFLAGS			:= $(subst $(CC_FLAGS_FTRACE),,$(cflags-y)) \
+				   -Os -DDISABLE_BRANCH_PROFILING \
+				   -D__NO_FORTIFY \
+				   -ffreestanding \
+				   -fno-stack-protector \
+				   $(call cc-option,-fno-addrsig) \
+				   -D__DISABLE_EXPORTS
+
+#
+# struct randomization only makes sense for Linux internal types, which the EFI
+# stub code never touches, so let's turn off struct randomization for the stub
+# altogether
+#
+KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS), $(KBUILD_CFLAGS))
+
+# remove SCS flags from all objects in this directory
+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
+# disable CFI
+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_CFI), $(KBUILD_CFLAGS))
+# disable LTO
+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
+
+GCOV_PROFILE			:= n
+# Sanitizer runtimes are unavailable and cannot be linked here.
+KASAN_SANITIZE			:= n
+KCSAN_SANITIZE			:= n
+KMSAN_SANITIZE			:= n
+UBSAN_SANITIZE			:= n
+OBJECT_FILES_NON_STANDARD	:= y
+
+# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
+KCOV_INSTRUMENT			:= n
+
+OBJECT_FILES_NON_STANDARD	:= y
+emulator-y			:= head.o entry.o \
+				   core.o pe_loader.o memory.o memory_api.o config_table.o misc.o \
+				   device_handle.o protocol_simple_text_output.o protocol_device_path.o \
+				   lib.o printf.o \
+				   amba-pl011.o
+obj-y				:= efi_emulator.o
+
+
+EMULATOR_OBJS = $(addprefix $(obj)/,$(emulator-y))
+
+quiet_cmd_ar_emulator = PAD     $@
+      cmd_ar_emulator = $(AR) rcSTP $@ $^
+
+$(obj)/emulator.a: $(EMULATOR_OBJS)
+	$(call if_changed,ar_emulator)
+
+
+quiet_cmd_link_emulator = PAD     $@
+      cmd_link_emulator = ld -z norelro -z noexecstack -shared --no-undefined -X -Bsymbolic -z notext --emit-relocs --no-apply-dynamic-relocs  \
+				-T $(srctree)/drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds \
+                                --whole-archive $< --no-whole-archive -o $@
+
+
+$(obj)/emulator.ro: $(obj)/emulator.a FORCE
+	$(call if_changed,link_emulator)
+
+
+$(obj)/emulator.raw: $(obj)/emulator.ro FORCE
+	@$(OBJCOPY)  -O binary -R .note -R .note.gnu.build-id -R .comment -g $< $@
+
+$(obj)/efi_emulator.o: $(obj)/emulator.raw
+
+
+targets				+= $(emulator-y)
+
+
diff --git a/drivers/firmware/efi/efi_emulator/amba-pl011.c b/drivers/firmware/efi/efi_emulator/amba-pl011.c
new file mode 100644
index 0000000000000..e81b12b2a7d21
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/amba-pl011.c
@@ -0,0 +1,81 @@
+//SPDX-License-Identifier: GPL-2.0
+
+#include <linux/stdarg.h>
+#include <linux/amba/serial.h>
+#include "earlycon.h"
+
+#define SERIAL_IO_MEM32 3
+#define UPIO_MEM32 SERIAL_IO_MEM32
+
+struct uart_port {
+	unsigned long		iobase;			/* in/out[bwl] */
+	unsigned char __iomem	*membase;		/* read/write[bwl] */
+	unsigned char		iotype;			/* io access style */
+};
+
+static struct uart_port pl011_port;
+
+static void pl011_putc(struct uart_port *port, unsigned char c)
+{
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+		cpu_relax();
+	if (port->iotype == UPIO_MEM32)
+		writel(c, port->membase + UART01x_DR);
+	else
+		writeb(c, port->membase + UART01x_DR);
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
+		cpu_relax();
+}
+
+static int pl011_put_str(const char *str, void *data)
+{
+	char *p = (char *)str;
+	struct uart_port *port = (struct uart_port *)data;
+
+	for (; *p != '\0'; p++)
+		pl011_putc(port, *p);
+
+	return (p - str);
+}
+
+static void pl011_write(struct uart_port *port, unsigned int reg, unsigned int val)
+{
+	void __iomem *addr = port->membase + reg;
+
+	if (port->iotype == UPIO_MEM32)
+		writel_relaxed(val, addr);
+	else
+		writew_relaxed(val, addr);
+}
+
+static bool pl011_match(struct efi_emulator_param *param, const char *name)
+{
+	struct uart_port *port = &pl011_port;
+
+	if (strcmp(param->earlycon_name, name))
+		return false;
+
+	port->iotype = UPIO_MEM32;
+	port->membase = (unsigned char *)param->earlycon_reg_base;
+	return true;
+}
+
+static void pl011_reset(void *data)
+{
+	struct uart_port *port = data;
+
+	/* disable DMA */
+	pl011_write(port, UART011_DMACR, 0);
+	/* disable interrupt */
+	pl011_write(port, UART011_IMSC, 0);
+	/* Skip: set clk rate */
+	/* Now, pl011 can be used in poll mode */
+}
+
+struct earlycon pl011 = {
+	.match = pl011_match,
+	.reset = pl011_reset,
+	.put_str = pl011_put_str,
+	.data = &pl011_port,
+	.name = "amba-pl011",
+};
diff --git a/drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds b/drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds
new file mode 100644
index 0000000000000..82d7659346af5
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/arm64_emulator_service.lds
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+ENTRY(emulator_entry)
+EMULATOR_BASE_ADDR = 0x0;
+
+SECTIONS
+{
+	. = EMULATOR_BASE_ADDR;
+	.head : ALIGN(4096) {
+		*(.head.text)
+	}
+
+	.text : {
+		*(.text* .init.text*)
+	}
+
+	.rodata : ALIGN(8) {
+		*(.rodata* .init.rodata* .srodata*)
+
+		_etext = ALIGN(4096);
+		. = _etext;
+	}
+
+	.rela.dyn : ALIGN(4096) {
+		_rela_start = .;
+		*(.rela .rela*)
+		_rela_end = .;
+	}
+
+	.data : ALIGN(4096) {
+		*(.data* .init.data*)
+		_edata = ALIGN(512);
+		. = _edata;
+	}
+
+	.bss : {
+		*(.bss* .init.bss*)
+		_end = ALIGN(512);
+		. = _end;
+	}
+
+	/DISCARD/ : {
+		*(.modinfo .init.modinfo)
+	}
+}
diff --git a/drivers/firmware/efi/efi_emulator/config_table.c b/drivers/firmware/efi/efi_emulator/config_table.c
new file mode 100644
index 0000000000000..32b702a156ba4
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/config_table.c
@@ -0,0 +1,25 @@
+//SPDX-License-Identifier: GPL-2.0
+
+#include "emulator.h"
+
+static efi_status_t conjoin_memreserve_table(void *table, efi_config_table_t *head)
+{
+	struct linux_efi_memreserve *new, *next;
+
+	new = (struct linux_efi_memreserve *)table;
+	new->next = 0;
+	next = (struct linux_efi_memreserve *)head->table;
+	while (next->next != 0)
+		next = (struct linux_efi_memreserve *)next->next;
+	next->next = (phys_addr_t)new;
+
+	return EFI_SUCCESS;
+}
+
+efi_status_t conjoin_table(efi_guid_t *uuid, void *table, efi_config_table_t *t)
+{
+	if (!efi_guidcmp(t->guid, LINUX_EFI_MEMRESERVE_TABLE_GUID))
+		return conjoin_memreserve_table(table, t);
+
+	return EFI_OUT_OF_RESOURCES;
+}
diff --git a/drivers/firmware/efi/efi_emulator/core.c b/drivers/firmware/efi/efi_emulator/core.c
new file mode 100644
index 0000000000000..9045f6953250c
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/core.c
@@ -0,0 +1,376 @@
+//SPDX-License-Identifier: GPL-2.0
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "emulator.h"
+
+int emulator_initialize(void);
+
+struct efi_emulator_param *emulator_param;
+bool print_enabled;
+
+static efi_loaded_image_t loaded_image;
+
+static LIST_HEAD(image_instance_list);
+
+struct efi_pe_instance *get_instance_by_handle(efi_handle_t h)
+{
+	struct efi_pe_instance *pos;
+
+	list_for_each_entry(pos, &image_instance_list, node)
+		if (pos->handle == h)
+			return pos;
+
+	return NULL;
+}
+
+/* no free path */
+struct efi_pe_instance *allocate_pe_instance(char *file_base,
+		unsigned long file_size)
+{
+	struct efi_pe_instance *inst;
+
+	inst = aligned_alloc(8, sizeof(struct efi_pe_instance));
+	/* identity */
+	inst->handle = (efi_handle_t)inst;
+	inst->image_file_buf = file_base;
+	inst->image_file_size = file_size;
+	emulator_list_add(&inst->node, &image_instance_list);
+
+	return inst;
+}
+
+/* The 1st kernel convert cmdline to utf16 and pass to emulator */
+static efi_status_t handle_protocol_loaded_image(efi_handle_t h, void **data)
+{
+	void *base;
+
+	loaded_image.load_options = emulator_param->cmdline;
+	loaded_image.load_options_size = emulator_param->sz_in_byte;
+
+	/* loaded address */
+	base = (void *)find_image_base_for_handle(h);
+	loaded_image.image_base = base;
+
+	*data = &loaded_image;
+	return EFI_SUCCESS;
+
+}
+
+
+static efi_status_t __efiapi emulator_handle_protocol(efi_handle_t h,
+				efi_guid_t *uuid, void **data)
+{
+	if (!efi_guidcmp(*uuid, LOADED_IMAGE_PROTOCOL_GUID))
+		return handle_protocol_loaded_image(h, data);
+	
+	if (!efi_guidcmp(*uuid, EFI_LOAD_FILE2_PROTOCOL_GUID))
+		return device_handle_protocol(h, uuid, data);
+
+	return EFI_UNSUPPORTED;
+}
+
+/*
+ * LocateProtocol() finds the first device handle that support Protocol, and
+ * returns a pointer to the protocol interface from that handle in Interface.
+ * If no protocol instances are found, then Interface is set to NULL
+ */
+static efi_status_t __efiapi emulator_locate_protocol(efi_guid_t *uuid,
+				void *registration, void **interface)
+{
+	if (!efi_guidcmp(*uuid, EFI_TCG2_PROTOCOL_GUID)) {
+		return EFI_UNSUPPORTED;
+	} else if (!efi_guidcmp(*uuid, EFI_CC_MEASUREMENT_PROTOCOL_GUID)) {
+		return EFI_UNSUPPORTED;
+	} else if (!efi_guidcmp(*uuid, EFI_RNG_PROTOCOL_GUID)) {
+		*interface = &emulator_rng;
+		return EFI_SUCCESS;
+	}
+
+	return EFI_UNSUPPORTED;
+}
+
+/* each pair is {efi_guid_t *, void *} */
+static efi_status_t __efiapi emulator_install_multiple_protocol_interfaces(efi_handle_t *handle, ...)
+{
+	efi_status_t ret = EFI_SUCCESS;
+	efi_guid_t *guid;
+	void *proto;
+	va_list args;
+	int i;
+
+	if (*handle == 0)
+		ret = device_create_handle(handle);
+
+	va_start(args, handle);
+	for (i = 0; ret == EFI_SUCCESS; i++) {
+		/* If protocol is NULL, then it's the end of the list */
+		guid = va_arg(args, efi_guid_t *);
+		if (guid == NULL)
+			break;
+		proto = va_arg(args, void *);
+	
+		if (!efi_guidcmp(*guid, EFI_DEVICE_PATH_PROTOCOL_GUID)) {
+			ret = device_attach_dev_path(*handle, proto);
+			continue;
+		}
+		
+		/* install one protocol on the device */
+		ret = device_register_protocol(*handle, *guid, proto);
+	}
+	va_end(args);
+
+	return ret;
+}
+
+static efi_status_t __efiapi emulator_uninstall_multiple_protocol_interfaces(efi_handle_t, ...)
+{
+	return EFI_UNSUPPORTED;
+}
+
+
+// 2do
+static efi_status_t __efiapi emulator_allocate_pages(int alloc_type, int mem_type,
+			unsigned long nr_pages, efi_physical_addr_t *addr)
+{
+	return __emulator_allocate_pages(alloc_type, mem_type, nr_pages, addr);
+}
+
+// 2do
+static efi_status_t __efiapi emulator_free_pages(efi_physical_addr_t addr,
+			unsigned long nr_4KB)
+{
+	return EFI_SUCCESS;
+
+}
+
+static efi_status_t __efiapi emulator_allocate_pool(int mem_type, unsigned long sz,
+				       void **pool)
+{
+	return __emulator_allocate_pool(mem_type, sz, pool);
+
+}
+
+static efi_status_t __efiapi emulator_free_pool(void *pool)
+{
+	return EFI_SUCCESS;
+
+}
+
+/* memmove() alias as memcpy() */
+static void __efiapi emulator_copy_mem(void *dest, const void *src, unsigned long count)
+{
+	char *tmp;
+	const char *s;
+
+	if (dest <= src) {
+		tmp = dest;
+		s = src;
+		while (count--)
+			*tmp++ = *s++;
+	} else {
+		tmp = dest;
+		tmp += count;
+		s = src;
+		s += count;
+		while (count--)
+			*--tmp = *--s;
+	}
+
+}
+
+static void __efiapi emulator_set_mem(void *dst, unsigned long cnt, unsigned char val)
+{
+	unsigned char *dst_ptr = (char *)dst;
+	unsigned long i;
+
+	for (i = 0; i < cnt; i++)
+		dst_ptr[i] = val;
+}
+
+static efi_status_t __efiapi emulator_stall(unsigned long ms)
+{
+
+	return EFI_SUCCESS;
+}
+
+static efi_status_t __efiapi emulator_locate_handle(int, efi_guid_t *,
+				       void *, unsigned long *,
+				       efi_handle_t *)
+{
+	return EFI_UNSUPPORTED;
+}
+
+/*
+ * locates all devices on DevicePath that support Protocol and returns the
+ * handle to the device that is closest to DevicePath
+ */
+static efi_status_t __efiapi emulator_locate_device_path(efi_guid_t *guid,
+		efi_device_path_protocol_t **dp, efi_handle_t *handle)
+{
+	efi_status_t ret;
+		/* Only one device implements this protocol, so dp can be ignored */
+	if (!efi_guidcmp(*guid, EFI_LOAD_FILE2_PROTOCOL_GUID)) {
+		ret = device_find_handle_by_path(dp, handle);
+		return ret;
+	}
+
+	return EFI_NOT_FOUND;
+}
+
+static efi_status_t __efiapi emulator_install_configuration_table(efi_guid_t *uuid,
+								     void *table)
+{
+	efi_config_table_t *t = (efi_config_table_t *)systabs.tables;
+	int i;
+
+	for (i = 0; i < systabs.nr_tables; i++, t++) {
+		if (!efi_guidcmp(t->guid, *uuid))
+			return conjoin_table(uuid, table, t);
+	}
+	t->guid = *uuid;
+	t->table = table;
+	systabs.nr_tables++;
+
+	return EFI_SUCCESS;
+}
+
+/*
+ * For UKI, systemd-stub loads linux image and start image.
+ * @path: The DeviceHandle specific file path from which the image is loaded
+ */
+static efi_status_t __efiapi emulator_load_image(bool boot_policy,
+		efi_handle_t parent_image, efi_device_path_protocol_t *path,
+		void *src_buf, unsigned long src_sz,
+		efi_handle_t *handle)
+{
+	struct efi_pe_instance *inst;
+	char *dst;
+	
+	/* copy the in-memory image */
+	if (!!src_buf) {
+		dst = aligned_alloc(8, src_sz);
+		if (!dst) {
+			printf("OOM\n");
+			return EFI_OUT_OF_RESOURCES;
+		}
+		emulator_copy_mem(dst, src_buf, src_sz);
+		inst = allocate_pe_instance(dst, src_sz);
+		inst->handle = inst;
+		*handle = inst->handle;
+	/* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or EFI_LOAD_FILE_PROTOCOL */
+	} else {
+
+	}
+	return EFI_SUCCESS;
+}
+
+static	efi_status_t __efiapi emulator_start_image(efi_handle_t handle,
+		unsigned long *exit_data_sz, efi_char16_t **exit_data)
+{
+
+	struct efi_pe_instance *inst;
+
+	inst = get_instance_by_handle(handle);
+	if (unlikely(!inst)) {
+		printf("error: can not find image\n");
+		return EFI_NOT_FOUND;
+	}
+	load_kernel_pe(inst, &systabs);
+
+	return EFI_SUCCESS;
+}
+
+/*
+ * As the final stage, destroy the boottime context, e.g. release the memory
+ * occupied by some data struct.
+ */
+static efi_status_t __efiapi emulator_exit_boot_services(efi_handle_t handle,
+							    unsigned long map_key)
+{
+	return EFI_SUCCESS;
+}
+
+static efi_boot_services_t bt_services = {
+	.handle_protocol = emulator_handle_protocol,
+	.locate_protocol = emulator_locate_protocol,
+	.install_multiple_protocol_interfaces = emulator_install_multiple_protocol_interfaces,
+	.uninstall_multiple_protocol_interfaces = emulator_uninstall_multiple_protocol_interfaces,
+
+	.allocate_pool = emulator_allocate_pool,
+	.free_pool = emulator_free_pool,
+	.allocate_pages = emulator_allocate_pages,
+	.free_pages = emulator_free_pages,
+	.copy_mem = emulator_copy_mem,
+	.set_mem = emulator_set_mem,
+	.get_memory_map = emulator_get_memory_map,
+
+	.stall = emulator_stall,
+
+	.locate_handle = emulator_locate_handle,
+	.locate_device_path = emulator_locate_device_path,
+	.install_configuration_table = emulator_install_configuration_table,
+	.load_image = emulator_load_image,
+	.start_image = emulator_start_image,
+	.exit_boot_services = emulator_exit_boot_services,
+};
+
+static efi_char16_t vendor[] = u"Linux Kexec";
+
+static efi_status_t unsupported_func(void)
+{
+	return EFI_UNSUPPORTED;
+}
+
+efi_system_table_t systabs = {
+	.hdr = {
+		.signature = EFI_SYSTEM_TABLE_SIGNATURE,
+	},
+	.fw_vendor = (unsigned long)vendor,
+	.fw_revision = 0x10001,
+	.con_in_handle = 0x0,
+	.con_in = (efi_simple_text_input_protocol_t *)unsupported_func,
+	.con_out_handle = 0x0,
+	.con_out = &text_out,
+	.stderr_handle = 0x0,
+	/* Per specification, A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL */
+	.stderr = (unsigned long)unsupported_func,
+	/* Passed in by the 1st kernel */
+	.runtime = NULL,
+	.boottime = &bt_services,
+	.nr_tables = 0,
+	.tables = 0,
+};
+
+static efi_rt_properties_table_t rt_support = {
+	.runtime_services_supported = 0,
+};
+
+int initialize_emulator_service(struct efi_emulator_param *param)
+{
+
+	efi_config_table_t *tables;
+	unsigned int i;
+
+	printf("initialize_emulator_service, dtb=0x%lx, mempool_start=0x%lx, end:0x%lx\n",
+			param->dtb, param->mempool_start, param->mempool_start + param->mempool_sz);
+	emulator_param = param;
+	print_enabled = param->print_enabled;
+	i = param->rt_info.systab_nr_tables;
+	systabs.tables = (unsigned long)&param->rt_info.systab_tables;
+	tables = param->rt_info.systab_tables;
+	tables[i].guid = DEVICE_TREE_GUID;
+	tables[i].table = (void *)param->dtb;
+	i++;
+	if (!param->noefi_boot) {
+		rt_support.runtime_services_supported = param->rt_info.runtime_supported_mask;
+	}
+	tables[i].guid = EFI_RT_PROPERTIES_TABLE_GUID;
+	tables[i].table = (void *)&rt_support;
+	i++;
+	systabs.nr_tables = i;
+
+	systabs.runtime = (efi_runtime_services_t *)param->rt_info.runtime;
+	return 0;
+}
diff --git a/drivers/firmware/efi/efi_emulator/device_handle.c b/drivers/firmware/efi/efi_emulator/device_handle.c
new file mode 100644
index 0000000000000..6e15979f62e9a
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/device_handle.c
@@ -0,0 +1,138 @@
+//SPDX-License-Identifier: GPL-2.0
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include "emulator.h"
+
+static LIST_HEAD(devices_list);
+
+struct protocol_entry {
+	efi_guid_t guid;
+	void *proto;
+};
+
+/*
+ * Drivers can implement their own version of efi_load_file_protocol_t. This represents one.
+ * For example, refer to systemd-stub initrd_load_file()
+ *
+ * BS->InstallMultipleProtocolInterfaces(handle, ...)
+ * BS->LocateDevicePath(guid, dp, handle)
+ * BS->HandleProtocol(handle, guid, interface)
+ * interface->func()
+ * This struct can be abstracted to serve EFI_BOOT_SERVICES.LocateDevicePath(guid, dp, handle)
+ */
+struct device_instance {
+	struct list_head node;
+	efi_handle_t handle;
+	/*
+	 * Quote UEFI specification:
+	 * 'It is illegal to have two handles in the handle database with identical device paths'
+	 */
+	efi_device_path_protocol_t *dp;
+	/* For simplity, keep the capacity at 8 for the time being */
+	struct protocol_entry entries[8];
+};
+
+static struct device_instance *find_device_by_handle(efi_handle_t h)
+{
+	struct device_instance *inst;
+
+	list_for_each_entry(inst, &devices_list, node) {
+		if (inst->handle == h)
+			return inst;
+	}
+
+	return NULL;
+}
+
+efi_status_t device_create_handle(efi_handle_t *handle)
+{
+	struct device_instance *inst;
+	int sz;
+
+	sz = sizeof(struct device_instance);
+	inst = aligned_alloc(4, sz);
+	memset(inst, 0, sz);
+	emulator_list_add(&inst->node, &devices_list);
+	inst->handle = (efi_handle_t)inst;
+	*handle = inst->handle;
+
+	return EFI_SUCCESS;
+}
+
+efi_status_t device_attach_dev_path(efi_handle_t h, efi_device_path_protocol_t *dp)
+{
+	struct device_instance *inst = (struct device_instance *)h;
+	int sz;
+
+	sz = efi_device_path_size(dp);
+	inst->dp = aligned_alloc(4, sz);
+	/* clone the device path */
+	efi_device_path_clone(inst->dp, dp);
+
+	return EFI_SUCCESS;
+}
+
+/*
+ * BS->InstallMultipleProtocolInterfaces() calls down to here.
+ *
+ * A driver implements its own efi_load_file_protocol_t.
+ *
+ * According to EFI_LOAD_FILE2_PROTOCOL.LoadFile(), only
+ * efi_device_path_protocol_t is required.
+ */
+efi_status_t device_register_protocol(efi_handle_t handle, efi_guid_t guid,
+		void *proto)
+{
+	struct device_instance *inst;
+
+	inst = find_device_by_handle(handle);
+	if (!inst)
+		return EFI_NOT_FOUND;
+
+	for (int i = 0; i < 8; i++) {
+		if (!efi_guidcmp(inst->entries[i].guid, NULL_GUID)) {
+			inst->entries[i].guid = guid;
+			inst->entries[i].proto = proto;
+			return EFI_SUCCESS;
+		}
+	}
+
+	return EFI_OUT_OF_RESOURCES;
+}
+
+efi_status_t device_find_handle_by_path(efi_device_path_protocol_t **dp,
+		efi_handle_t *h)
+{
+	struct device_instance *inst;
+	int ret = -1;
+
+	list_for_each_entry(inst, &devices_list, node) {
+		ret = efi_device_path_compare(*dp, inst->dp);
+		if (!ret) {
+			*h = inst->handle;
+			return EFI_SUCCESS;
+		}
+	}
+
+	return EFI_NOT_FOUND;
+}
+
+efi_status_t device_handle_protocol(efi_handle_t h, efi_guid_t *uuid, void **data)
+{
+	struct device_instance *inst;
+
+	list_for_each_entry(inst, &devices_list, node) {
+		if (inst->handle == h) {
+			for (int i = 0; i < 8; i++) {
+				if (!efi_guidcmp(inst->entries[i].guid, *uuid)) {
+					*data = inst->entries[i].proto;
+					return EFI_SUCCESS;
+				}
+			}
+			/* no need to try other handles */
+			return EFI_NOT_FOUND;
+		}
+	}
+
+	return EFI_NOT_FOUND;
+}
diff --git a/drivers/firmware/efi/efi_emulator/earlycon.h b/drivers/firmware/efi/efi_emulator/earlycon.h
new file mode 100644
index 0000000000000..189af549d5af2
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/earlycon.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/efi_emulator.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm-generic/io.h>
+
+struct earlycon {
+	bool (*match)(struct efi_emulator_param *param, const char *name);
+	int (*put_str)(const char *str, void *data);
+	void (*reset)(void *data);
+	void *data;
+	const char *name;
+};
+
+extern struct earlycon pl011;
+
+extern int pl011_puts(const char *str);
+void setup_earlycon(struct efi_emulator_param *param);
diff --git a/drivers/firmware/efi/efi_emulator/efi_emulator.S b/drivers/firmware/efi/efi_emulator/efi_emulator.S
new file mode 100644
index 0000000000000..fb52593ba3b2e
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/efi_emulator.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+	.section .rodata, "a"
+
+	.align	8
+_efi_emulator_start:
+	.globl	_efi_emulator_start
+	.incbin	"drivers/firmware/efi/efi_emulator/emulator.raw"
+
+	.align	8
+_efi_emulator_end:
+	.globl	_efi_emulator_end
diff --git a/drivers/firmware/efi/efi_emulator/emulator.h b/drivers/firmware/efi/efi_emulator/emulator.h
new file mode 100644
index 0000000000000..9b38d1ee69cea
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/emulator.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/nls.h>
+#include <linux/efi_emulator.h>
+
+/* Included from drivers/firmware/efi/libstub */
+#include <efistub.h>
+
+#define EMULATOR_BASE_ADDR 0
+
+typedef union efi_rng_protocol efi_rng_protocol_t;
+
+union efi_rng_protocol {
+	struct {
+		efi_status_t (__efiapi *get_info)(efi_rng_protocol_t *,
+						  unsigned long *,
+						  efi_guid_t *);
+		efi_status_t (__efiapi *get_rng)(efi_rng_protocol_t *,
+						 efi_guid_t *, unsigned long,
+						 u8 *out);
+	};
+	struct {
+		u32 get_info;
+		u32 get_rng;
+	} mixed_mode;
+};
+
+typedef efi_status_t (*uefi_pe_entry)(efi_handle_t handle, efi_system_table_t *systab);
+
+struct efi_pe_instance {
+	struct list_head node;
+	efi_handle_t handle;
+	char *image_file_buf;
+	unsigned long image_file_size;
+	/* load address for the instance */
+	unsigned long image_base;
+	unsigned long image_size;
+	uefi_pe_entry entry;
+};
+
+static inline void __emulator_list_add(struct list_head *new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	WRITE_ONCE(prev->next, new);
+}
+
+static inline void emulator_list_add(struct list_head *new, struct list_head *head)
+{
+	__emulator_list_add(new, head, head->next);
+}
+
+extern bool print_enabled;
+extern struct efi_emulator_param *emulator_param;
+extern efi_tcg2_protocol_t emulator_tcg2;
+extern efi_cc_protocol_t emulator_cc;
+extern efi_rng_protocol_t emulator_rng;
+extern efi_simple_text_output_protocol_t text_out;
+extern efi_system_table_t systabs;
+extern char *heap_start, *heap_end, *heap_cur;
+
+void *aligned_alloc(size_t alignment, size_t size);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+int strcmp(const char *cs, const char *ct);
+size_t wcslen(const wchar_t *str);
+int wcscmp(const wchar_t *s1, const wchar_t *s2);
+int printf(const char *format, ...);
+void print_ucs2_string(efi_char16_t* ucs2_str);
+extern unsigned long find_image_base_for_handle(efi_handle_t handle);
+
+efi_status_t device_create_handle(efi_handle_t *handle);
+efi_status_t device_attach_dev_path(efi_handle_t h, efi_device_path_protocol_t *dp);
+efi_status_t device_register_protocol(efi_handle_t handle, efi_guid_t guid,
+		void *proto);
+efi_status_t device_find_handle_by_path(efi_device_path_protocol_t **dp,
+		efi_handle_t *h);
+efi_status_t device_handle_protocol(efi_handle_t h, efi_guid_t *uuid,
+		void **data);
+
+int efi_device_path_compare(efi_device_path_protocol_t *path1,
+		efi_device_path_protocol_t *path2);
+size_t efi_device_path_size(efi_device_path_protocol_t *path);
+int efi_device_path_clone(efi_device_path_protocol_t *dst,
+		efi_device_path_protocol_t *dp);
+
+efi_status_t __emulator_allocate_pages(int alloc_type, int mem_type,
+			unsigned long nr_pages, efi_physical_addr_t *addr);
+efi_status_t __emulator_allocate_pool(int mem_type, unsigned long sz,
+				       void **pool);
+efi_status_t emulator_get_memory_map(unsigned long *map_sz,
+	void *memmap, unsigned long *map_key, unsigned long *desc_sz,
+	unsigned int *desc_version);
+
+efi_status_t conjoin_table(efi_guid_t *uuid, void *table, efi_config_table_t *t);
+
+struct efi_pe_instance *get_instance_by_handle(efi_handle_t h);
+struct efi_pe_instance *allocate_pe_instance(char *file_buf, unsigned long size);
+int initialize_emulator_service(struct efi_emulator_param *param);
+void initialize_heap(struct efi_emulator_param *param);
+void load_kernel_pe(struct efi_pe_instance *inst, efi_system_table_t *systabs);
+void emulator_main(struct efi_emulator_param *param);
+void emulator_entry(struct efi_emulator_param *param);
+
diff --git a/drivers/firmware/efi/efi_emulator/entry.c b/drivers/firmware/efi/efi_emulator/entry.c
new file mode 100644
index 0000000000000..e5a31bd303858
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/entry.c
@@ -0,0 +1,61 @@
+//SPDX-License-Identifier: GPL-2.0
+#include <linux/types.h>
+#include <linux/efi_emulator.h>
+#include <asm/barrier.h>
+#include <asm/sysreg.h>
+#include <asm/elf.h>
+#include <uapi/linux/elf.h>
+
+#include "emulator.h"
+#include "earlycon.h"
+
+extern void enable_sctlr_el1(unsigned long scratch_reg);
+static void arch_handle_mmu(struct efi_emulator_param *param)
+{
+	if (!param->mmu_on && param->pgd_root) {
+	}
+}
+
+extern const Elf64_Rela _rela_start[], _rela_end[];
+
+static void noinline arch_reloc_fixup(long delta)
+{
+	unsigned long *apply_addr, res;
+	Elf64_Rela *rela;
+
+	/* fix rela */
+	for (rela = (Elf64_Rela *)_rela_start; rela < _rela_end; rela++) {
+		//todo counterpart of R_AARCH64_RELATIVE on riscv
+		if (ELF64_R_TYPE(rela->r_info) != R_AARCH64_RELATIVE)
+			continue;
+		apply_addr = (unsigned long *)(rela->r_offset + delta);
+		res = rela->r_addend + delta;
+		*apply_addr = res;
+	}
+	// todo flush cache
+
+}
+
+/* 
+ * Ensure this entry and @param is in the mapping before jump to it.
+ * It should be PIC and at the beginning of emulator.
+ * It should be memory aligned
+ */
+void emulator_main(struct efi_emulator_param *param)
+{
+	long delta = param->load_address - EMULATOR_BASE_ADDR;
+	struct efi_pe_instance *inst;
+
+	arch_handle_mmu(param);
+	arch_reloc_fixup(delta);
+	setup_earlycon(param);
+	printf("param:0x%lx, delta=0x%lx\n", (unsigned long)param, delta);
+	printf("kernel_img_start:0x%lx, sz:0x%lx\n", (unsigned long)param->kernel_img_start, (unsigned long)param->kernel_img_sz);
+	initialize_emulator_service(param);
+	initialize_heap(param);
+	printf(" load_kernel_pe\n");
+
+	inst = allocate_pe_instance((char *)param->kernel_img_start,
+					param->kernel_img_sz);
+	load_kernel_pe(inst, &systabs);
+}
diff --git a/drivers/firmware/efi/efi_emulator/head.S b/drivers/firmware/efi/efi_emulator/head.S
new file mode 100644
index 0000000000000..705ff131e5fab
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/head.S
@@ -0,0 +1,10 @@
+//SPDX-License-Identifier: GPL-2.0
+.section        ".head.text","ax"
+
+/* x0 holds the physical address of emulator_param */
+emulator_entry:
+	ldr	x1, [x0]
+	mov	sp, x1
+	adrp	x2, emulator_main
+	add	x2, x2, #:lo12:emulator_main
+	br	x2
diff --git a/drivers/firmware/efi/efi_emulator/lib.c b/drivers/firmware/efi/efi_emulator/lib.c
new file mode 100644
index 0000000000000..f12aa40405650
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/lib.c
@@ -0,0 +1,73 @@
+//SPDX-License-Identifier: GPL-2.0
+#include "emulator.h"
+
+void *memcpy(void *dest, const void *src, size_t count)
+{
+	char *tmp = dest;
+	const char *s = src;
+
+	while (count--)
+		*tmp++ = *s++;
+	return dest;
+}
+
+void *memset(void *s, int c, size_t count)
+{
+	char *xs = s;
+
+	while (count--)
+		*xs++ = c;
+	return s;
+}
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+	const unsigned char *su1, *su2;
+	int res = 0;
+
+	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+		if ((res = *su1 - *su2) != 0)
+			break;
+	return res;
+}
+
+size_t strlen(const char *s)
+{
+	const char *sc;
+
+	for (sc = s; *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+	unsigned char c1, c2;
+
+	while (1) {
+		c1 = *cs++;
+		c2 = *ct++;
+		if (c1 != c2)
+			return c1 < c2 ? -1 : 1;
+		if (!c1)
+			break;
+	}
+	return 0;
+}
+
+int wcscmp(const wchar_t *s1, const wchar_t *s2)
+{
+    while (*s1 && (*s1 == *s2)) {
+        s1++;
+        s2++;
+    }
+    return (int)(*s1 - *s2);
+}
+
+size_t wcslen(const wchar_t *str)
+{
+    const wchar_t *s;
+
+    for (s = str; *s; ++s);
+    return (s - str);
+}
diff --git a/drivers/firmware/efi/efi_emulator/memory.c b/drivers/firmware/efi/efi_emulator/memory.c
new file mode 100644
index 0000000000000..518ab7f30020e
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/memory.c
@@ -0,0 +1,27 @@
+//SPDX-License-Identifier: GPL-2.0
+#include "emulator.h"
+
+char *heap_start, *heap_end, *heap_cur;
+
+void initialize_heap(struct efi_emulator_param *param)
+{
+	heap_start = (char *)param->mempool_start;
+	heap_end = heap_start + param->mempool_sz;
+	heap_cur = heap_start;
+}
+
+//2do, the memory management is more complicated since we need to distinguish EFI_BOOT_SERVICE, RUNTIME, LOADER memory descr
+
+void *aligned_alloc(size_t alignment, size_t size)
+{
+	char *p;
+
+	p = (char *)ALIGN((unsigned long)heap_cur, alignment);
+	heap_cur = p + size;
+
+	//todo, update the efi_memory_desc to include this page, if it crosses the PAGE boundary
+	//as EFI_BOOT_SERVICE,
+	return p;
+}
+
+
diff --git a/drivers/firmware/efi/efi_emulator/memory_api.c b/drivers/firmware/efi/efi_emulator/memory_api.c
new file mode 100644
index 0000000000000..bd57942cb0410
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/memory_api.c
@@ -0,0 +1,74 @@
+//SPDX-License-Identifier: GPL-2.0
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "emulator.h"
+
+/*
+ * mem_type affects the allocated chunk in efi_memory_desc_t's type. Later,
+ * kernel can know whether to reclaim them.
+ */
+efi_status_t __emulator_allocate_pages(int alloc_type, int mem_type,
+			unsigned long nr_pages, efi_physical_addr_t *addr)
+{
+	efi_physical_addr_t res;
+	efi_status_t status;
+
+	if (alloc_type == EFI_ALLOCATE_ANY_PAGES) {
+		res = (efi_physical_addr_t)aligned_alloc(PAGE_SIZE, nr_pages << PAGE_SHIFT);
+		*addr = res;
+		status = EFI_SUCCESS;
+	} else if (alloc_type == EFI_ALLOCATE_MAX_ADDRESS) {
+		//tmp
+		res = (efi_physical_addr_t)aligned_alloc(PAGE_SIZE, nr_pages << PAGE_SHIFT);
+		*addr = res;
+		status = EFI_SUCCESS;
+	/* e.g. aarch64 kimage loaded alignment */
+	} else if (alloc_type == EFI_ALLOCATE_ADDRESS) {
+		//tmp, just aligned on 2MB as aarch64 boot protocol
+		res = (efi_physical_addr_t)aligned_alloc(1<<21, nr_pages << PAGE_SHIFT);
+		*addr = res;
+		status = EFI_SUCCESS;
+	}
+
+	return status;
+}
+
+//todo
+efi_status_t __emulator_allocate_pool(int mem_type, unsigned long sz,
+				       void **pool)
+{
+	void *res;
+
+	res = aligned_alloc(sizeof(unsigned long), sz);
+	*pool = res;
+	return EFI_SUCCESS;
+}
+
+/* @memmap: only holds efi_memory_desc */
+efi_status_t emulator_get_memory_map(unsigned long *map_sz,
+	void *memmap, unsigned long *map_key, unsigned long *desc_sz,
+	unsigned int *desc_version)
+{
+	//todo rt_info.memmap will be accessed by kernel, so it should be marked as reserved
+	struct efi_boot_memmap *p = &emulator_param->rt_info.memmap;
+	//efi_memory_desc_t *desc = p->map;
+
+	if (!map_sz || !desc_sz)
+		return EFI_INVALID_PARAMETER;
+	if (*map_sz < p->map_size || !memmap) {
+		*map_sz = p->map_size;
+		*desc_sz = p->desc_size;
+		return EFI_BUFFER_TOO_SMALL;
+	}
+
+	/* desc range size*/
+	*map_sz = p->map_size;
+	memcpy(memmap, p->map, p->map_size);
+	if (!!desc_sz)
+		*desc_sz = p->desc_size;
+	if (!!desc_version)
+		*desc_version = p->desc_ver;
+
+	return EFI_SUCCESS;
+}
diff --git a/drivers/firmware/efi/efi_emulator/misc.c b/drivers/firmware/efi/efi_emulator/misc.c
new file mode 100644
index 0000000000000..0d6e92bc539cf
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/misc.c
@@ -0,0 +1,43 @@
+//SPDX-License-Identifier: GPL-2.0
+
+#include <linux/efi.h>
+#include <asm/efi.h>
+
+#include "emulator.h"
+
+static efi_status_t __efiapi emulator_get_rng(efi_rng_protocol_t * this,
+						 efi_guid_t *uuid, unsigned long size,
+						 u8 *out)
+{
+	/* in fact, disable aslr */
+	*out = 0;
+	return EFI_SUCCESS;
+}
+
+efi_rng_protocol_t emulator_rng = {
+	.get_rng = emulator_get_rng,
+};
+
+static efi_status_t __efiapi emulator_get_memory_attributes(
+	efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64 *)
+{
+	return EFI_SUCCESS;
+}
+
+static efi_status_t __efiapi emulator_set_memory_attributes(
+	efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64)
+{
+	return EFI_SUCCESS;
+}
+
+static efi_status_t __efiapi emulator_clear_memory_attributes(
+	efi_memory_attribute_protocol_t *, efi_physical_addr_t, u64, u64)
+{
+	return EFI_SUCCESS;
+}
+
+efi_memory_attribute_protocol_t emulator_memory_attribute = {
+	.get_memory_attributes = emulator_get_memory_attributes,
+	.set_memory_attributes = emulator_set_memory_attributes,
+	.clear_memory_attributes = emulator_clear_memory_attributes,
+};
diff --git a/drivers/firmware/efi/efi_emulator/pe_loader.c b/drivers/firmware/efi/efi_emulator/pe_loader.c
new file mode 100644
index 0000000000000..9113827fd7c9a
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/pe_loader.c
@@ -0,0 +1,173 @@
+//SPDX-License-Identifier: GPL-2.0
+#include <linux/pe.h>
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include "emulator.h"
+
+#define VALID_PAYLOAD (IMAGE_SCN_CNT_CODE |IMAGE_SCN_CNT_INITIALIZED_DATA |IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+
+/* Refer to PECOFF spec, 'Base Relocation Types' */
+#define IMAGE_REL_BASED_ABSOLUTE	0
+#define IMAGE_REL_BASED_DIR64	10
+
+unsigned long find_image_base_for_handle(efi_handle_t handle)
+{
+	struct efi_pe_instance *inst;
+
+	inst = get_instance_by_handle(handle);
+	if (!inst)
+		return (unsigned long)-1;
+	return inst->image_base;
+}
+
+typedef struct __packed base_relocation_block {
+	uint32_t page_rva;
+	uint32_t block_size;
+	struct {
+	        uint16_t offset : 12;
+	        uint16_t type : 4;	/* higher 4-bits in Word */
+	} entries[];
+} base_relocation_block_t;
+
+static int pe_image_handle_base_relocation(unsigned long base_reloc_table,
+		unsigned long sz, unsigned long load_addr, unsigned long delta)
+{
+	base_relocation_block_t *blk = (base_relocation_block_t *)base_reloc_table;	
+	unsigned long page_addr, *target_addr, value;
+	uint32_t i, array_num;
+
+	for (; (unsigned long)blk < (base_reloc_table + sz);
+	     blk = (base_relocation_block_t *)((unsigned char*)blk + blk->block_size)) {
+
+		/* block_size includes the total base_relocation_block structure */
+		array_num = (blk->block_size - sizeof(base_relocation_block_t)) >> 1;
+		page_addr = blk->page_rva + load_addr;
+		for (i = 0; i < array_num; i++) {
+			switch (blk->entries[i].type) {
+				case IMAGE_REL_BASED_ABSOLUTE:
+					continue;
+				case IMAGE_REL_BASED_DIR64:
+					target_addr = (unsigned long *)(page_addr + blk->entries[i].offset);
+					value = *target_addr + delta;
+					*target_addr = value;
+					continue;
+				default:
+					printf("ERR: unhandled reloc type: %d\n");
+					return -1; 
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * @pe_hdr_offset supplies the size of Dos Header and Stub.
+ */ 
+static int load_pe(char *file_buf, unsigned long buf_sz, unsigned long pe_hdr_offset,
+			struct efi_pe_instance *inst)
+{
+	unsigned long exec_sz, load_addr, delta;
+	unsigned long base_reloc_table, sz;
+	struct pe_hdr *pe_hdr;
+	struct pe32plus_opt_hdr *opt_hdr;
+	struct data_directory *dir;
+	struct data_dirent *dirent;
+	struct section_header *sect_hdr;
+	int section_nr, i;
+	char *pe_part_buf, *src, *dst;
+	printf("load_pe\n");
+	pe_part_buf = file_buf + pe_hdr_offset;
+	pe_hdr = (struct pe_hdr *)pe_part_buf;
+	if (pe_hdr->opt_hdr_size == 0) {
+		printf("ERR: optional header is missing\n");
+		return -1;
+	}
+	section_nr = pe_hdr->sections;
+	opt_hdr = (struct pe32plus_opt_hdr *)(pe_part_buf + sizeof(struct pe_hdr));
+	sect_hdr = (struct section_header *)((char *)opt_hdr + pe_hdr->opt_hdr_size);
+	exec_sz = opt_hdr->image_size;
+
+	/*
+	 * PE header must be loaded since some efi stubs parse them e.g. systemd-stub
+	 */
+	load_addr = (unsigned long)aligned_alloc(opt_hdr->section_align, exec_sz);
+
+	/*
+	 * Each section has the same delta. Got the delta based on the first
+	 * section's RVA.
+	 */
+	delta = load_addr - opt_hdr->image_base;
+	/* copy PE headers */
+	memcpy((void *)load_addr, file_buf, opt_hdr->header_size);
+
+ 	/* copy section to segment */
+	for (i = 0; i < section_nr; i++) {
+		printf("section: %s, relocs: %u\n", sect_hdr->name, sect_hdr->num_relocs);
+		if (!(sect_hdr->flags & VALID_PAYLOAD)) {
+			sect_hdr++;
+			continue;
+		}
+		/* data_addr is relative to the whole file */
+		src = file_buf + sect_hdr->data_addr;
+		dst = (char *)(sect_hdr->virtual_address + load_addr);
+		memcpy(dst, src, sect_hdr->raw_data_size);
+		printf("virtual_address: 0x%u, src: %u, dst: %u\n", sect_hdr->virtual_address, src, dst);
+		/*
+		 * The SizeOfRawData is rounded but the VirtualSize is not, hence
+		 * the former can be greater than latter.
+		 */
+		if (sect_hdr->virtual_size > sect_hdr->raw_data_size)
+			memset(dst + sect_hdr->raw_data_size, 0, sect_hdr->virtual_size - sect_hdr->raw_data_size);
+		sect_hdr++;
+	}
+
+	/* If there are relocs */
+	if (pe_hdr->opt_hdr_size >
+	    (offsetof(struct data_directory, base_relocations) + sizeof(struct pe32plus_opt_hdr))) {
+		dir = (void *)pe_hdr + sizeof(struct pe_hdr) + sizeof(struct pe32plus_opt_hdr);
+		dirent = &dir->base_relocations;
+		base_reloc_table = dirent->virtual_address + load_addr;
+		sz = dirent->size;
+		pe_image_handle_base_relocation(base_reloc_table, sz, load_addr, delta);
+	}
+
+	/* Since gcc adheres to ABI, using the current SP is fine for new image instance */
+
+	inst->entry = (uefi_pe_entry)(opt_hdr->entry_point + load_addr);
+	inst->image_base = load_addr;
+	inst->image_size = opt_hdr->image_size;
+
+	printf("entry_point:0x%lx, delta:0x%lx, final inst's entry at:0x%lx\n",
+		opt_hdr->entry_point, delta, inst->entry);
+	return 0;
+}
+
+static int parse_kernel_pe(struct efi_pe_instance *inst)
+{
+	char *buf = (char *)inst->image_file_buf;
+	u32 pe_hdr_offset;
+
+	pe_hdr_offset = *((u32 *)(buf + 0x3c));
+	buf += pe_hdr_offset;
+	if (!!memcmp(buf, "PE\0\0", 4)) {
+		printf("Not a PE file\n");
+		return -1;
+	}
+
+	load_pe((char *)inst->image_file_buf, inst->image_file_size,
+			pe_hdr_offset, inst);
+
+	return 0;
+}
+
+void load_kernel_pe(struct efi_pe_instance *inst, efi_system_table_t *systabs)
+{
+	int ret;
+
+	ret = parse_kernel_pe(inst);
+	if (ret < 0)
+		return;
+	(*(inst->entry))(inst->handle, systabs);
+
+}
diff --git a/drivers/firmware/efi/efi_emulator/printf.c b/drivers/firmware/efi/efi_emulator/printf.c
new file mode 100644
index 0000000000000..4d8daf91b426b
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/printf.c
@@ -0,0 +1,373 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* The most of this file is copied from arch/x86/boot/printf.c */
+
+#include <linux/ctype.h>
+#include <linux/efi.h>
+
+#include "earlycon.h"
+#include "emulator.h"
+
+static int skip_atoi(const char **s)
+{
+	int i = 0;
+
+	while (isdigit(**s))
+		i = i * 10 + *((*s)++) - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SMALL	32		/* Must be 32 == 0x20 */
+#define SPECIAL	64		/* 0x */
+
+#define __do_div(n, base) ({ \
+int __res; \
+__res = ((unsigned long) n) % (unsigned) base; \
+n = ((unsigned long) n) / (unsigned) base; \
+__res; })
+
+static char *number(char *str, long num, int base, int size, int precision,
+		    int type)
+{
+	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
+	static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
+
+	char tmp[66];
+	char c, sign, locase;
+	int i;
+
+	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
+	 * produces same digits or (maybe lowercased) letters */
+	locase = (type & SMALL);
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 16)
+		return NULL;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++] = '0';
+	else
+		while (num != 0)
+			tmp[i++] = (digits[__do_div(num, base)] | locase);
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type & (ZEROPAD + LEFT)))
+		while (size-- > 0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base == 8)
+			*str++ = '0';
+		else if (base == 16) {
+			*str++ = '0';
+			*str++ = ('X' | locase);
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+size_t strnlen(const char *s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long num;
+	int i, base;
+	char *str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+
+	for (str = buf; *fmt; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+
+		/* process flags */
+		flags = 0;
+	      repeat:
+		++fmt;		/* this also skips first '%' */
+		switch (*fmt) {
+		case '-':
+			flags |= LEFT;
+			goto repeat;
+		case '+':
+			flags |= PLUS;
+			goto repeat;
+		case ' ':
+			flags |= SPACE;
+			goto repeat;
+		case '#':
+			flags |= SPECIAL;
+			goto repeat;
+		case '0':
+			flags |= ZEROPAD;
+			goto repeat;
+		}
+
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char)va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2 * sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				     (unsigned long)va_arg(args, void *), 16,
+				     field_width, precision, flags);
+			continue;
+
+		case 'n':
+			if (qualifier == 'l') {
+				long *ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else {
+				int *ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+			/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'x':
+			flags |= SMALL;
+			fallthrough;
+		case 'X':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'l')
+			num = va_arg(args, unsigned long);
+		else if (qualifier == 'h') {
+			num = (unsigned short)va_arg(args, int);
+			if (flags & SIGN)
+				num = (short)num;
+		} else if (flags & SIGN)
+			num = va_arg(args, int);
+		else
+			num = va_arg(args, unsigned int);
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str - buf;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i = vsprintf(buf, fmt, args);
+	va_end(args);
+	return i;
+}
+
+static struct earlycon *con;
+
+static int puts(const char *s)
+{
+	if (con)
+		return con->put_str(s, con->data);
+	else
+		return 0;
+}
+
+int printf(const char *fmt, ...)
+{
+	char printf_buf[1024];
+	va_list args;
+	int printed;
+
+	va_start(args, fmt);
+	printed = vsprintf(printf_buf, fmt, args);
+	va_end(args);
+
+	puts(printf_buf);
+
+	return printed;
+}
+
+static char *ucs2_to_ascii(char *ascii_str, efi_char16_t *ucs2_str)
+{
+	size_t len = 0;
+
+	while (ucs2_str[len] != 0) {
+		len++;
+	}
+
+	/* Convert each UCS-2 character to ASCII */
+	for (size_t i = 0; i < len; i++) {
+		if (ucs2_str[i] <= 127) {
+			/* Character is in ASCII range */
+			ascii_str[i] = (char)ucs2_str[i];
+		} else {
+			/* Character is outside ASCII range */
+			ascii_str[i] = '?';
+		}
+	}
+	/* Enforce a null-terminate the ASCII string */
+	ascii_str[len] = '\0';
+
+	return ascii_str;
+}
+
+
+/* Convert the UCS-2 string to a ascii string */
+void print_ucs2_string(efi_char16_t *ucs2_str)
+{
+	char ascii_str[1024];
+	char* p = ascii_str;
+
+	ucs2_to_ascii(p, ucs2_str);
+	/* Print the ascii string */
+	printf("%s\n", ascii_str);
+}
+
+static struct earlycon *all_con_types[] = { &pl011, };
+
+void setup_earlycon(struct efi_emulator_param *param)
+{
+	struct earlycon *p;
+	int i;
+
+	for (i = 0; i < sizeof(all_con_types) / sizeof(struct earlycon *); i++) {
+
+		p = all_con_types[i];
+		if (p->match(param, p->name)) {
+			con = p;
+			p->reset(p->data);
+			break;
+		}
+	}
+}
diff --git a/drivers/firmware/efi/efi_emulator/protocol_device_path.c b/drivers/firmware/efi/efi_emulator/protocol_device_path.c
new file mode 100644
index 0000000000000..c31dcb8d0016b
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/protocol_device_path.c
@@ -0,0 +1,75 @@
+//SPDX-License-Identifier: GPL-2.0
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include "emulator.h"
+
+static inline bool is_end_node(efi_device_path_protocol_t *node)
+{
+	return node->type == EFI_DEV_END_PATH &&
+		node->sub_type == EFI_DEV_END_ENTIRE;
+}
+
+static inline efi_device_path_protocol_t *
+	next_device_path_node(efi_device_path_protocol_t *node)
+{
+    return (efi_device_path_protocol_t *)((u8 *)node + node->length);
+}
+
+/*
+ * efi_device_path_compare - Compare two EFI device paths
+ *
+ * Return: 0 if equal, otherwise non-zero
+ */
+int efi_device_path_compare(efi_device_path_protocol_t *path1,
+		efi_device_path_protocol_t *path2)
+{
+	efi_device_path_protocol_t *node1 = path1;
+	efi_device_path_protocol_t *node2 = path2;
+
+	while (!is_end_node(node1) && !is_end_node(node2)) {
+		if (node1->type != node2->type ||
+		    node1->sub_type != node2->sub_type ||
+		    node1->length != node2->length)
+			return 1;
+
+		node1 = next_device_path_node(node1);
+		node2 = next_device_path_node(node2);
+	}
+
+	/* Check if both reached the end */
+	if (is_end_node(node1) && is_end_node(node2))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * efi_device_path_size - Calculate the total size of an EFI device path
+ * @path: Pointer to the first EFI_DEVICE_PATH structure
+ *
+ * Return: Total size of the EFI device path
+ */
+size_t efi_device_path_size(efi_device_path_protocol_t *path)
+{
+	efi_device_path_protocol_t *node = path;
+	size_t total_size = 0;
+
+	while (!is_end_node(node)) {
+		total_size += node->length;
+		node = next_device_path_node(node);
+	}
+
+	/* Include the size of the end node */
+	total_size += node->length;
+
+	return total_size;
+}
+
+int efi_device_path_clone(efi_device_path_protocol_t *dst,
+		efi_device_path_protocol_t *dp)
+{
+	size_t sz = efi_device_path_size(dp);
+
+	memcpy((void *)dst, (void *)dp, sz);
+	return 0;
+}
diff --git a/drivers/firmware/efi/efi_emulator/protocol_simple_text_output.c b/drivers/firmware/efi/efi_emulator/protocol_simple_text_output.c
new file mode 100644
index 0000000000000..6544bfc7f43dc
--- /dev/null
+++ b/drivers/firmware/efi/efi_emulator/protocol_simple_text_output.c
@@ -0,0 +1,50 @@
+//SPDX-License-Identifier: GPL-2.0
+
+#include "emulator.h"
+
+/* UCS-2 (Universal Coded Character Set) */
+static efi_status_t __efiapi output_string(efi_simple_text_output_protocol_t *simple,
+						       efi_char16_t *str)
+{
+	if (print_enabled)
+		print_ucs2_string(str);
+	return EFI_SUCCESS;
+}
+
+struct simple_text_output_mode {
+	int32_t	max_mode;
+	int32_t	mode;
+	int32_t	attribute;
+	int32_t	cursor_column;
+	int32_t	cursor_row;
+	bool	cursor_visible;
+};
+
+struct simple_text_output_mode output_mode;
+
+static efi_status_t __efiapi  text_reset(
+		efi_simple_text_output_protocol_t *this,
+		bool extended_verification)
+{
+	return EFI_UNSUPPORTED;
+}
+
+static efi_status_t __efiapi text_set_attribute(
+		efi_simple_text_output_protocol_t *this,
+		unsigned int attribute)
+{
+	return EFI_UNSUPPORTED;
+}
+
+efi_simple_text_output_protocol_t text_out = {
+	
+	.reset = text_reset,
+	.output_string = output_string,
+	.query_mode = NULL,
+	.set_mode = NULL,
+	.set_attribute = text_set_attribute,
+	.clean_screen = NULL,
+	.set_cursor_pos = NULL,
+	.enable_cursor = NULL,
+	.mode	= &output_mode,
+};
diff --git a/include/linux/efi_emulator.h b/include/linux/efi_emulator.h
new file mode 100644
index 0000000000000..ef235861f3a85
--- /dev/null
+++ b/include/linux/efi_emulator.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_EFI_EMULATOR_H
+#define _LINUX_EFI_EMULATOR_H
+
+#include <linux/types.h>
+#include <linux/nls.h>
+#include <linux/efi.h>
+
+//todo, arch abstraction, for x86, it is efi_info
+struct efi_rt_info {
+	const efi_runtime_services_t	*runtime;	/* EFI runtime services table */
+	unsigned int runtime_version;	/* Runtime services version */
+	u32 runtime_supported_mask;
+	/* Build systab tables from the following */
+	unsigned int systab_nr_tables;
+	efi_config_table_t systab_tables[20];
+	struct efi_boot_memmap	memmap;
+};
+
+/* 1st kernel passes information through this struct */
+struct efi_emulator_param {
+	unsigned long sp;
+	/* Should be page-aligned */
+	unsigned long load_address;
+	unsigned int sz_in_byte;
+	wchar_t cmdline[512];
+	bool noefi_boot;
+	bool print_enabled;
+	char earlycon_name[16];
+	phys_addr_t earlycon_reg_base;
+	unsigned long earlycon_reg_sz;
+
+	bool mmu_on;
+	/* root of pgtable */
+	phys_addr_t pgd_root;
+	phys_addr_t kernel_img_start;
+	unsigned long kernel_img_sz;
+	phys_addr_t dtb;
+	phys_addr_t mempool_start;
+	unsigned long mempool_sz;
+	/* The last struct */
+	struct efi_rt_info rt_info;
+};
+
+extern unsigned char _efi_emulator_start[], _efi_emulator_end[];
+#endif
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index f0e9f8eda7a3c..cff6b6869498b 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -325,6 +325,7 @@ struct kimage {
 	unsigned int hotplug_support:1;
 #endif
 
+	bool is_pe;
 #ifdef ARCH_HAS_KIMAGE_ARCH
 	struct kimage_arch arch;
 #endif
@@ -462,6 +463,7 @@ static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, g
 static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { }
 #endif
 
+extern phys_addr_t arch_emulator_prepare_pgtable(struct kimage *kimage);
 extern bool kexec_file_dbg_print;
 
 #define kexec_dprintk(fmt, arg...) \
-- 
2.41.0



From mzxreary at 0pointer.de  Wed Aug 21 07:27:12 2024
From: mzxreary at 0pointer.de (Lennart Poettering)
Date: Wed, 21 Aug 2024 16:27:12 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <ZsX5QNie3pzocSfT@gardel-login>

On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:

> *** Background ***
>
> As more PE format kernel images are introduced, it post challenge to kexec to
> cope with the new format.
>
> In my attempt to add support for arm64 zboot image in the kernel [1],
> Ard suggested using an emulator to tackle this issue.  Last year, when
> Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> emulator approach again [3]

Hmm, systemd's systemd-stub code tries to load certain "side-car"
files placed next to the UKI, via the UEFI file system APIs. What's
your intention with the UEFI emulator regarding that? The sidecars are
somewhat important, because that's how we parameterize otherwise
strictly sealed, immutable UKIs.

Hence, what's the story there? implement some form of fs driver (for
what fs precisely?) in the emulator too?

And regarding tpm? tpms require drivers and i guess at the moment uefi
emulator would run those aren't available anymore? but we really
should do a separator measurement then. (also there needs to be some
way to pass over measurement log of that measurement?)

Lennart

--
Lennart Poettering, Berlin


From piliu at redhat.com  Wed Aug 21 22:42:14 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Thu, 22 Aug 2024 13:42:14 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <ZsX5QNie3pzocSfT@gardel-login>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
Message-ID: <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>

On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
<mzxreary at 0pointer.de> wrote:
>
> On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
>
> > *** Background ***
> >
> > As more PE format kernel images are introduced, it post challenge to kexec to
> > cope with the new format.
> >
> > In my attempt to add support for arm64 zboot image in the kernel [1],
> > Ard suggested using an emulator to tackle this issue.  Last year, when
> > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > emulator approach again [3]
>
> Hmm, systemd's systemd-stub code tries to load certain "side-car"
> files placed next to the UKI, via the UEFI file system APIs. What's
> your intention with the UEFI emulator regarding that? The sidecars are
> somewhat important, because that's how we parameterize otherwise
> strictly sealed, immutable UKIs.
>
IIUC, you are referring to UKI addons.

> Hence, what's the story there? implement some form of fs driver (for
> what fs precisely?) in the emulator too?
>
As for addon, that is a missing part in this series. I have overlooked
this issue. Originally, I thought that there was no need to implement
a disk driver and vfat file system, just preload them into memory, and
finally present them through the uefi API. I will take a closer look
at it and chew on it.

> And regarding tpm? tpms require drivers and i guess at the moment uefi
> emulator would run those aren't available anymore? but we really
> should do a separator measurement then. (also there needs to be some
> way to pass over measurement log of that measurement?)
>

It is a pity that it is a common issue persistent with kexec-reboot
kernel nowadays.
I am not familiar with TPM and have no clear idea for the time being.
(emulating Platform Configuration Registers ?).  But since this
emulator is held inside a linux kernel image, and the UKI's signature
is checked during kexec_file_load. All of them are safe from
modification, this security is not an urgent issue.

Thanks for sharing your thoughts and insights.

Best Regards,

Pingfan

> Lennart
>
> --
> Lennart Poettering, Berlin
>



From dyoung at redhat.com  Wed Aug 21 23:16:52 2024
From: dyoung at redhat.com (Dave Young)
Date: Thu, 22 Aug 2024 14:16:52 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
Message-ID: <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com>

On Thu, 22 Aug 2024 at 13:42, Pingfan Liu <piliu at redhat.com> wrote:
>
> On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> <mzxreary at 0pointer.de> wrote:
> >
> > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> >
> > > *** Background ***
> > >
> > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > cope with the new format.
> > >
> > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > emulator approach again [3]
> >
> > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > files placed next to the UKI, via the UEFI file system APIs. What's
> > your intention with the UEFI emulator regarding that? The sidecars are
> > somewhat important, because that's how we parameterize otherwise
> > strictly sealed, immutable UKIs.
> >
> IIUC, you are referring to UKI addons.
>
> > Hence, what's the story there? implement some form of fs driver (for
> > what fs precisely?) in the emulator too?
> >
> As for addon, that is a missing part in this series. I have overlooked
> this issue. Originally, I thought that there was no need to implement
> a disk driver and vfat file system, just preload them into memory, and
> finally present them through the uefi API. I will take a closer look
> at it and chew on it.
>

Hi Pingfan,

If more and more stuff needs coming in,  not only the limited boot
services then it will be way too complicated and hard to maintain and
debug,  also the two kexec code paths are duplicated somehow. It is
really bad..

I forgot why we can not just extract the kernel from UKI and then load
it directly,  if the embedded kernel is also signed it should be good?

Thanks
Dave



From k-hagio-ab at nec.com  Wed Aug 21 23:25:19 2024
From: k-hagio-ab at nec.com (=?utf-8?B?SEFHSU8gS0FaVUhJVE8o6JCp5bC+44CA5LiA5LuBKQ==?=)
Date: Thu, 22 Aug 2024 06:25:19 +0000
Subject: [PATCH 1/2] makedumpfile: Add ftruncate error handling
In-Reply-To: <2874031e-bb32-43dc-8220-7756dc2b36a2@nokia.com>
References: <20240815141733.4050230-2-stefan.wiehler@nokia.com>
 <db15a94c-3fa5-47e6-8c8d-59665bb119a8@nec.com>
 <2874031e-bb32-43dc-8220-7756dc2b36a2@nokia.com>
Message-ID: <9f75a7be-f7ec-4987-b0f2-d65dbccc9a3d@nec.com>

On 2024/08/21 16:30, Stefan Wiehler wrote:
>> I tried to reproduce those warnings, but could not get either one
>> with a plain make command and gcc 14.1 (or clang 18.1).
>>
>> out of curiosity, what compiler version and build command do you use?
> 
> We use GCC 12.2.0 and build via the BitBake recipe:
> 
> https://layers.openembedded.org/layerindex/recipe/52214/
> 
> The recipe removes hardcoded CFLAGS in the Makefile, so it is not
> obvious to me right now if we get these error warnings due to additional
> CFLAGS we inject by default to each recipe or due to below patch alone:
> 
> https://git.openembedded.org/meta-openembedded/tree/meta-oe/recipes-kernel/makedumpfile/makedumpfile/0001-makedumpfile-replace-hardcode-CFLAGS.patch?h=master

Thanks for the reply.

I found that the 1/2 warning is reproduced with -D_FORTIFY_SOURCE.  The 2/2
warning is still not reproduced, but the patches look good to me, so applied.

https://github.com/makedumpfile/makedumpfile/commit/3de748452194e9363042b27ae069c779059a12f7
https://github.com/makedumpfile/makedumpfile/commit/bd30437c629220d26824a8f1ef28b2e47e0529e5

Thanks,
Kazu

From glaubitz at physik.fu-berlin.de  Thu Aug 22 00:33:56 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Thu, 22 Aug 2024 09:33:56 +0200
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related
 config items
In-Reply-To: <20240124051254.67105-6-bhe@redhat.com>
References: <20240124051254.67105-1-bhe@redhat.com>
	 <20240124051254.67105-6-bhe@redhat.com>
Message-ID: <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>

Hi Baoquan,

On Wed, 2024-01-24 at 13:12 +0800, Baoquan He wrote:
> By splitting CRASH_RESERVE and VMCORE_INFO out from CRASH_CORE, cleaning
> up the dependency of FA_DMUMP on CRASH_DUMP, and moving crash codes from
> kexec_core.c to crash_core.c, now we can rearrange CRASH_DUMP to
> depend on KEXEC_CORE, and make CRASH_DUMP select CRASH_RESERVE and
> VMCORE_INFO.
> 
> KEXEC_CORE won't select CRASH_RESERVE and VMCORE_INFO any more because
> KEXEC_CORE enables codes which allocate control pages, copy
> kexec/kdump segments, and prepare for switching. These codes are shared
> by both kexec reboot and crash dumping.
> 
> Doing this makes codes and the corresponding config items more
> logical (the right item depends on or is selected by the left item).
> 
> PROC_KCORE -----------> VMCORE_INFO
> 
>            |----------> VMCORE_INFO
> FA_DUMP----|
>            |----------> CRASH_RESERVE
> 
>                                                 ---->VMCORE_INFO
>                                                /
>                                                |---->CRASH_RESERVE
> KEXEC      --|                                /|
>              |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
> KEXEC_FILE --|                               \ |
>                                                \---->CRASH_HOTPLUG
> 
> KEXEC      --|
>              |--> KEXEC_CORE--> kexec reboot
> KEXEC_FILE --|
> 
> Signed-off-by: Baoquan He <bhe at redhat.com>
> ---
>  kernel/Kconfig.kexec | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 8faf27043432..6c34e63c88ff 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -9,8 +9,6 @@ config VMCORE_INFO
>  	bool
>  
>  config KEXEC_CORE
> -	select VMCORE_INFO
> -	select CRASH_RESERVE
>  	bool
>  
>  config KEXEC_ELF
> @@ -99,8 +97,11 @@ config KEXEC_JUMP
>  
>  config CRASH_DUMP
>  	bool "kernel crash dumps"
> +	default y
>  	depends on ARCH_SUPPORTS_CRASH_DUMP
> -	select KEXEC_CORE
> +	depends on KEXEC_CORE
> +	select VMCORE_INFO
> +	select CRASH_RESERVE
>  	help
>  	  Generate crash dump after being started by kexec.
>  	  This should be normally only set in special crash dump kernels

The change to enable CONFIG_CRASH_DUMP by default apparently broke the boot
on 32-bit Power Macintosh systems which fail after GRUB with:

	"Error: You can't boot a kdump kernel from OF!"

We may have to turn this off for 32-bit Power Macintosh systems.

See this thread on debian-powerpc ML: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html

Thanks,
Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From mzxreary at 0pointer.de  Thu Aug 22 01:23:38 2024
From: mzxreary at 0pointer.de (Lennart Poettering)
Date: Thu, 22 Aug 2024 10:23:38 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com>
 <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
Message-ID: <Zsb1isJ2cYRp2jpj@gardel-login>

On Do, 22.08.24 13:42, Pingfan Liu (piliu at redhat.com) wrote:

 > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> <mzxreary at 0pointer.de> wrote:
> >
> > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> >
> > > *** Background ***
> > >
> > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > cope with the new format.
> > >
> > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > emulator approach again [3]
> >
> > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > files placed next to the UKI, via the UEFI file system APIs. What's
> > your intention with the UEFI emulator regarding that? The sidecars are
> > somewhat important, because that's how we parameterize otherwise
> > strictly sealed, immutable UKIs.
> >
> IIUC, you are referring to UKI addons.

Yeah, UKI addons, as well as credential files, and sysext/confext
DDIs.

The addons are the most interesting btw, because we load them into
memory as PE files, and ask the UEFI to authenticate them.

> > Hence, what's the story there? implement some form of fs driver (for
> > what fs precisely?) in the emulator too?
> >
> As for addon, that is a missing part in this series. I have overlooked
> this issue. Originally, I thought that there was no need to implement
> a disk driver and vfat file system, just preload them into memory, and
> finally present them through the uefi API. I will take a closer look
> at it and chew on it.

It doesn't have to be VFAT btw. It just has to be something. For
example, it might suffice to take these files, pack them up as cpio or
so and pass them along with the UEFI execution. The UEFI emulator
would then have to expose them as a file system then.

We are not talking of a bazillion of files here, it's mostly a
smallish number of sidecar files I'd expect.

> > And regarding tpm? tpms require drivers and i guess at the moment uefi
> > emulator would run those aren't available anymore? but we really
> > should do a separator measurement then. (also there needs to be some
> > way to pass over measurement log of that measurement?)
>
> It is a pity that it is a common issue persistent with kexec-reboot
> kernel nowadays.
> I am not familiar with TPM and have no clear idea for the time being.
> (emulating Platform Configuration Registers ?).  But since this
> emulator is held inside a linux kernel image, and the UKI's signature
> is checked during kexec_file_load. All of them are safe from
> modification, this security is not an urgent issue.

Hmm, I'd really think about this with some priority. The measurement
stuff should not be an afterthought, it typically has major
implications on how you design your transitions, because measurements
of some component always need to happen *before* you pass control to
it, otherwise they are pointless.

Lennart

--
Lennart Poettering, Berlin


From bhe at redhat.com  Thu Aug 22 02:17:36 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 22 Aug 2024 17:17:36 +0800
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
Message-ID: <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>

On 08/22/24 at 09:33am, John Paul Adrian Glaubitz wrote:
> Hi Baoquan,
> 
> On Wed, 2024-01-24 at 13:12 +0800, Baoquan He wrote:
> > By splitting CRASH_RESERVE and VMCORE_INFO out from CRASH_CORE, cleaning
> > up the dependency of FA_DMUMP on CRASH_DUMP, and moving crash codes from
> > kexec_core.c to crash_core.c, now we can rearrange CRASH_DUMP to
> > depend on KEXEC_CORE, and make CRASH_DUMP select CRASH_RESERVE and
> > VMCORE_INFO.
> > 
> > KEXEC_CORE won't select CRASH_RESERVE and VMCORE_INFO any more because
> > KEXEC_CORE enables codes which allocate control pages, copy
> > kexec/kdump segments, and prepare for switching. These codes are shared
> > by both kexec reboot and crash dumping.
> > 
> > Doing this makes codes and the corresponding config items more
> > logical (the right item depends on or is selected by the left item).
> > 
> > PROC_KCORE -----------> VMCORE_INFO
> > 
> >            |----------> VMCORE_INFO
> > FA_DUMP----|
> >            |----------> CRASH_RESERVE
> > 
> >                                                 ---->VMCORE_INFO
> >                                                /
> >                                                |---->CRASH_RESERVE
> > KEXEC      --|                                /|
> >              |--> KEXEC_CORE--> CRASH_DUMP-->/-|---->PROC_VMCORE
> > KEXEC_FILE --|                               \ |
> >                                                \---->CRASH_HOTPLUG
> > 
> > KEXEC      --|
> >              |--> KEXEC_CORE--> kexec reboot
> > KEXEC_FILE --|
> > 
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >  kernel/Kconfig.kexec | 7 ++++---
> >  1 file changed, 4 insertions(+), 3 deletions(-)
> > 
> > diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> > index 8faf27043432..6c34e63c88ff 100644
> > --- a/kernel/Kconfig.kexec
> > +++ b/kernel/Kconfig.kexec
> > @@ -9,8 +9,6 @@ config VMCORE_INFO
> >  	bool
> >  
> >  config KEXEC_CORE
> > -	select VMCORE_INFO
> > -	select CRASH_RESERVE
> >  	bool
> >  
> >  config KEXEC_ELF
> > @@ -99,8 +97,11 @@ config KEXEC_JUMP
> >  
> >  config CRASH_DUMP
> >  	bool "kernel crash dumps"
> > +	default y
> >  	depends on ARCH_SUPPORTS_CRASH_DUMP
> > -	select KEXEC_CORE
> > +	depends on KEXEC_CORE
> > +	select VMCORE_INFO
> > +	select CRASH_RESERVE
> >  	help
> >  	  Generate crash dump after being started by kexec.
> >  	  This should be normally only set in special crash dump kernels
> 
> The change to enable CONFIG_CRASH_DUMP by default apparently broke the boot
> on 32-bit Power Macintosh systems which fail after GRUB with:
> 
> 	"Error: You can't boot a kdump kernel from OF!"
> 
> We may have to turn this off for 32-bit Power Macintosh systems.
> 
> See this thread on debian-powerpc ML: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html

If so, fix need be made.

We may need change in ARCH_SUPPORTS_CRASH_DUMP of ppc, can you or anyone
post a patch? I don't know how to identify 32-bit Power Macintosh.

arch/powerpc/Kconfig:
===
config ARCH_SUPPORTS_CRASH_DUMP
        def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
        
config ARCH_SELECTS_CRASH_DUMP
        def_bool y
        depends on CRASH_DUMP
        select RELOCATABLE if PPC64 || 44x || PPC_85xx
......
config PHYSICAL_START
        hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL
        default "0x02000000" if PPC_BOOK3S && CRASH_DUMP && !NONSTATIC_KERNEL
        default "0x00000000"



From leitao at debian.org  Thu Aug 22 02:28:03 2024
From: leitao at debian.org (Breno Leitao)
Date: Thu, 22 Aug 2024 02:28:03 -0700
Subject: arm64: Kexec: Warning: virt_to_phys used for non-linear address
In-Reply-To: <20240624113614.GA8361@willie-the-truck>
References: <ZnFKEtqfqJkYflwL@gmail.com>
 <ZnFxI-jCoJcO8WPw@J2N7QTR9R3>
 <20240624113614.GA8361@willie-the-truck>
Message-ID: <ZscEo8KJfn4xfm6X@gmail.com>

On Mon, Jun 24, 2024 at 12:36:14PM +0100, Will Deacon wrote:
> On Tue, Jun 18, 2024 at 12:36:03PM +0100, Mark Rutland wrote:
> > On Tue, Jun 18, 2024 at 01:49:22AM -0700, Breno Leitao wrote:

> > > Since __pa() is a macro to __virt_to_phys():
> > > 
> > > 	#define __pa(x)                 __virt_to_phys((unsigned long)(x))
> > > 
> > > I am curious why this address is special that makes __virt_to_phys()
> > > unhappy.
> > 
> > It's a fixmap address rather than a linear-map address. Confusingly
> > 'virt' generally means the linear map rather than any virtual address,
> > and usually virt_to_*() only work on linear map addresses.
> > 
> > I'm not sure how to fix this; the major reason we fixmap the FDT is so
> > that it can be anywhere in memory (and e.g. may not be in the linear map
> > at all), so we can't always generate a linear map VA.
> > 
> > We could stash the PA at boot time, and pass this as an argument to
> > of_kexec_alloc_and_setup_fdt().
> 
> Yeah, if it was passed as an additional argument to early_init_dt_scan(),
> then the core could could track it. Alternatively, we'd need a helper
> macro to get the PA and have an arm64-variant for the fixmap (everybody
> else could use __pa()).
> 
> > Rob, any thoughts? I couldn't see a neat way of doing this, but maybe we
> > could initialise an initial_boot_params_phys at setup time, with a bit
> > of churn to early_init_dt_verify() and friends?
> 
> Rob?

Hello, is there anything I can do or test to have this moving?

Thanks


From glaubitz at physik.fu-berlin.de  Thu Aug 22 02:37:09 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Thu, 22 Aug 2024 11:37:09 +0200
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related
 config items
In-Reply-To: <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
References: <20240124051254.67105-1-bhe@redhat.com>
	 <20240124051254.67105-6-bhe@redhat.com>
	 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
	 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
Message-ID: <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>

Hi Baoquan,

On Thu, 2024-08-22 at 17:17 +0800, Baoquan He wrote:
> > The change to enable CONFIG_CRASH_DUMP by default apparently broke the boot
> > on 32-bit Power Macintosh systems which fail after GRUB with:
> > 
> > 	"Error: You can't boot a kdump kernel from OF!"
> > 
> > We may have to turn this off for 32-bit Power Macintosh systems.
> > 
> > See this thread on debian-powerpc ML: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
> 
> If so, fix need be made.
> 
> We may need change in ARCH_SUPPORTS_CRASH_DUMP of ppc, can you or anyone
> post a patch? I don't know how to identify 32-bit Power Macintosh.
> 
> arch/powerpc/Kconfig:
> ===
> config ARCH_SUPPORTS_CRASH_DUMP
>         def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
>         
> config ARCH_SELECTS_CRASH_DUMP
>         def_bool y
>         depends on CRASH_DUMP
>         select RELOCATABLE if PPC64 || 44x || PPC_85xx
> ......
> config PHYSICAL_START
>         hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL
>         default "0x02000000" if PPC_BOOK3S && CRASH_DUMP && !NONSTATIC_KERNEL
>         default "0x00000000"

I think the architecture does support crash dumps, but I think the kernel has to
be booted from kexec in this case. Booting a kernel with CRASH_DUMP enabled won't
work from Open Firmware. So, I think CRASH_DUMP should just be disabled for
PPC_BOOK3S_32 by default and users who want to use it on these systems, will have to
enable it explicitly.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From piliu at redhat.com  Thu Aug 22 03:45:38 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Thu, 22 Aug 2024 18:45:38 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <Zsb1isJ2cYRp2jpj@gardel-login>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com> <Zsb1isJ2cYRp2jpj@gardel-login>
Message-ID: <CAF+s44TauSXk-gDgRHn=6CsQrAv8Q-QyGXkDJO+_sTh_yKde5w@mail.gmail.com>

On Thu, Aug 22, 2024 at 4:23?PM Lennart Poettering <mzxreary at 0pointer.de> wrote:
>
> On Do, 22.08.24 13:42, Pingfan Liu (piliu at redhat.com) wrote:
>
>  > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> > <mzxreary at 0pointer.de> wrote:
> > >
> > > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> > >
> > > > *** Background ***
> > > >
> > > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > > cope with the new format.
> > > >
> > > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > > emulator approach again [3]
> > >
> > > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > > files placed next to the UKI, via the UEFI file system APIs. What's
> > > your intention with the UEFI emulator regarding that? The sidecars are
> > > somewhat important, because that's how we parameterize otherwise
> > > strictly sealed, immutable UKIs.
> > >
> > IIUC, you are referring to UKI addons.
>
> Yeah, UKI addons, as well as credential files, and sysext/confext
> DDIs.
>
> The addons are the most interesting btw, because we load them into
> memory as PE files, and ask the UEFI to authenticate them.
>
> > > Hence, what's the story there? implement some form of fs driver (for
> > > what fs precisely?) in the emulator too?
> > >
> > As for addon, that is a missing part in this series. I have overlooked
> > this issue. Originally, I thought that there was no need to implement
> > a disk driver and vfat file system, just preload them into memory, and
> > finally present them through the uefi API. I will take a closer look
> > at it and chew on it.
>
> It doesn't have to be VFAT btw. It just has to be something. For
> example, it might suffice to take these files, pack them up as cpio or
> so and pass them along with the UEFI execution. The UEFI emulator
> would then have to expose them as a file system then.
>
> We are not talking of a bazillion of files here, it's mostly a
> smallish number of sidecar files I'd expect.
>
Yes, I think about using <key, value>, where key is the file path,
value is the file content.

> > > And regarding tpm? tpms require drivers and i guess at the moment uefi
> > > emulator would run those aren't available anymore? but we really
> > > should do a separator measurement then. (also there needs to be some
> > > way to pass over measurement log of that measurement?)
> >
> > It is a pity that it is a common issue persistent with kexec-reboot
> > kernel nowadays.
> > I am not familiar with TPM and have no clear idea for the time being.
> > (emulating Platform Configuration Registers ?).  But since this
> > emulator is held inside a linux kernel image, and the UKI's signature
> > is checked during kexec_file_load. All of them are safe from
> > modification, this security is not an urgent issue.
>
> Hmm, I'd really think about this with some priority. The measurement
> stuff should not be an afterthought, it typically has major
> implications on how you design your transitions, because measurements
> of some component always need to happen *before* you pass control to
> it, otherwise they are pointless.
>

OK, I will look into the details of TPM to see how to bail out.

Thanks,

Pingfan



From piliu at redhat.com  Thu Aug 22 03:51:02 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Thu, 22 Aug 2024 18:51:02 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com> <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com>
Message-ID: <CAF+s44TCvG3knnqyRbw=reaCRfh0_J76HO=ykF+J=ZFyoYZOCA@mail.gmail.com>

On Thu, Aug 22, 2024 at 2:17?PM Dave Young <dyoung at redhat.com> wrote:
>
> On Thu, 22 Aug 2024 at 13:42, Pingfan Liu <piliu at redhat.com> wrote:
> >
> > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> > <mzxreary at 0pointer.de> wrote:
> > >
> > > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> > >
> > > > *** Background ***
> > > >
> > > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > > cope with the new format.
> > > >
> > > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > > emulator approach again [3]
> > >
> > > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > > files placed next to the UKI, via the UEFI file system APIs. What's
> > > your intention with the UEFI emulator regarding that? The sidecars are
> > > somewhat important, because that's how we parameterize otherwise
> > > strictly sealed, immutable UKIs.
> > >
> > IIUC, you are referring to UKI addons.
> >
> > > Hence, what's the story there? implement some form of fs driver (for
> > > what fs precisely?) in the emulator too?
> > >
> > As for addon, that is a missing part in this series. I have overlooked
> > this issue. Originally, I thought that there was no need to implement
> > a disk driver and vfat file system, just preload them into memory, and
> > finally present them through the uefi API. I will take a closer look
> > at it and chew on it.
> >
>
> Hi Pingfan,
>
> If more and more stuff needs coming in,  not only the limited boot
> services then it will be way too complicated and hard to maintain and
> debug,  also the two kexec code paths are duplicated somehow. It is
> really bad..
>
OK, I will try to keep things easier. And what do you mean about " two
kexec code paths"?

> I forgot why we can not just extract the kernel from UKI and then load
> it directly,  if the embedded kernel is also signed it should be good?
>

I think the main concern is about the signature.

Thanks,

Pingfan



From kernel at jfarr.cc  Thu Aug 22 03:56:07 2024
From: kernel at jfarr.cc (Jan Hendrik Farr)
Date: Thu, 22 Aug 2024 12:56:07 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com>
 <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com>
Message-ID: <ec8befa0-f193-4de3-acea-8e37f8437c7e@app.fastmail.com>

Hi Dave,

> I forgot why we can not just extract the kernel from UKI and then load
> it directly,  if the embedded kernel is also signed it should be good?

The problem is that in the basic usecase for UKI you only sign the entire
UKI PE file and not the included kernel, because you only want that kernel
to be run with that one initrd and that one kernel cmdline.

So at a minimum you have to have the signature on the whole UKI checked by
the kernel and than have the kernel extract UKI into its parts unless you
somehow want to extent trust into userspace to have a helper program do that.

That's what my UKI support implementation from last year did.

v1: https://lore.kernel.org/lkml/20230909161851.223627-1-kernel at jfarr.cc/
v2: https://lore.kernel.org/lkml/20230911052535.335770-1-kernel at jfarr.cc/
v3-wip: https://github.com/Cydox/linux/blob/2908db6d8556fa617298cfb713355edaa9e4b095/arch/x86/kernel/kexec-uki.c

It however also lacks support for the "side-car" files. One option to add them
would be to load them using subsequent calls to kexec_file_load with a special
flag maybe.

TPM measurements are also not done although they are way easier to
implement with this approach as we still have the rest of the kernel around.

However TPM measurements in this case would be implemented by the kexec loader
in the kernel not by the UKI deciding what to measure. So we would have to
have a very firm agreement on what to measure.

Going the UEFI emulator route gives the UKI format (and other (future) formats)
way more flexibility. The cost is to potentially implementing a large portion
of the UEFI spec, especially if the goal is to support future unknown formats
which IIRC was one of the reasons this approach was suggested.

Kind regards,
Jan


From kernel at jfarr.cc  Thu Aug 22 04:42:04 2024
From: kernel at jfarr.cc (Jan Hendrik Farr)
Date: Thu, 22 Aug 2024 13:42:04 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CAF+s44TauSXk-gDgRHn=6CsQrAv8Q-QyGXkDJO+_sTh_yKde5w@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com>
 <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <Zsb1isJ2cYRp2jpj@gardel-login>
 <CAF+s44TauSXk-gDgRHn=6CsQrAv8Q-QyGXkDJO+_sTh_yKde5w@mail.gmail.com>
Message-ID: <gnym722ge3bgzz765u7plh65kq2tk7odw7hs4nq5ufxdp5xauf@bgb32wlzcchc>

On 22 18:45:38, Pingfan Liu wrote:
> On Thu, Aug 22, 2024 at 4:23?PM Lennart Poettering <mzxreary at 0pointer.de> wrote:
> >
> > On Do, 22.08.24 13:42, Pingfan Liu (piliu at redhat.com) wrote:
> >
> >  > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> > > <mzxreary at 0pointer.de> wrote:
> > > >
> > > > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> > > >
> > > > > *** Background ***
> > > > >
> > > > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > > > cope with the new format.
> > > > >
> > > > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > > > emulator approach again [3]
> > > >
> > > > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > > > files placed next to the UKI, via the UEFI file system APIs. What's
> > > > your intention with the UEFI emulator regarding that? The sidecars are
> > > > somewhat important, because that's how we parameterize otherwise
> > > > strictly sealed, immutable UKIs.
> > > >
> > > IIUC, you are referring to UKI addons.
> >
> > Yeah, UKI addons, as well as credential files, and sysext/confext
> > DDIs.
> >
> > The addons are the most interesting btw, because we load them into
> > memory as PE files, and ask the UEFI to authenticate them.
> >
> > > > Hence, what's the story there? implement some form of fs driver (for
> > > > what fs precisely?) in the emulator too?
> > > >
> > > As for addon, that is a missing part in this series. I have overlooked
> > > this issue. Originally, I thought that there was no need to implement
> > > a disk driver and vfat file system, just preload them into memory, and
> > > finally present them through the uefi API. I will take a closer look
> > > at it and chew on it.
> >
> > It doesn't have to be VFAT btw. It just has to be something. For
> > example, it might suffice to take these files, pack them up as cpio or
> > so and pass them along with the UEFI execution. The UEFI emulator
> > would then have to expose them as a file system then.
> >
> > We are not talking of a bazillion of files here, it's mostly a
> > smallish number of sidecar files I'd expect.
> >
> Yes, I think about using <key, value>, where key is the file path,
> value is the file content.
> 
> > > > And regarding tpm? tpms require drivers and i guess at the moment uefi
> > > > emulator would run those aren't available anymore? but we really
> > > > should do a separator measurement then. (also there needs to be some
> > > > way to pass over measurement log of that measurement?)
> > >
> > > It is a pity that it is a common issue persistent with kexec-reboot
> > > kernel nowadays.
> > > I am not familiar with TPM and have no clear idea for the time being.
> > > (emulating Platform Configuration Registers ?).  But since this
> > > emulator is held inside a linux kernel image, and the UKI's signature
> > > is checked during kexec_file_load. All of them are safe from
> > > modification, this security is not an urgent issue.
> >
> > Hmm, I'd really think about this with some priority. The measurement
> > stuff should not be an afterthought, it typically has major
> > implications on how you design your transitions, because measurements
> > of some component always need to happen *before* you pass control to
> > it, otherwise they are pointless.
> >
> 
> OK, I will look into the details of TPM to see how to bail out.

This issue is why I thought a different approach to the UEFI emulator
might be useful:

(1) On "kexec -l" execute the EFI binary inside the kernel as a kthread
until it exits boot services and record all TPM measurements into a
buffer
(2) On "kexec -e" use the kernels tpm driver to actually perform all the
prerecorded measurements.
(3) Transition into a "purgatory" that will
clean up the address space to make sure we get to an identity
mapping.
(4) Return control to the EFI app at the point it exited boot services

Additional advantage is that we have filesystem access during (1) so it's
simple to load additional sidecar files for the UKI.

I have two questions:

1: Does the systemd-stub only perform measurements before exiting boot
services or also afterwards?

2: Is it okay to just go to an identity mapping when boot services are
exited or is the identidy mapping actually required for the entire
execution of the EFI app (I know the UEFI spec calls for this, but I
think it should be possible to clean up the address space in a purgatory)?


I played around with this approach last year and got the start of the
kernels EFI stub executing in a kthread and calling into provided boot
services, but the difficult part is memory allocation and cleaning up
the address space in a purgatory.

> 
> Thanks,
> 
> Pingfan
> 

Kind regards,
Jan


From mzxreary at 0pointer.de  Thu Aug 22 04:45:37 2024
From: mzxreary at 0pointer.de (Lennart Poettering)
Date: Thu, 22 Aug 2024 13:45:37 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <gnym722ge3bgzz765u7plh65kq2tk7odw7hs4nq5ufxdp5xauf@bgb32wlzcchc>
References: <20240819145417.23367-1-piliu@redhat.com>
 <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <Zsb1isJ2cYRp2jpj@gardel-login>
 <CAF+s44TauSXk-gDgRHn=6CsQrAv8Q-QyGXkDJO+_sTh_yKde5w@mail.gmail.com>
 <gnym722ge3bgzz765u7plh65kq2tk7odw7hs4nq5ufxdp5xauf@bgb32wlzcchc>
Message-ID: <Zsck4U9xmzz5w5tl@gardel-login>

On Do, 22.08.24 13:42, Jan Hendrik Farr (kernel at jfarr.cc) wrote:

> I have two questions:
>
> 1: Does the systemd-stub only perform measurements before exiting boot
> services or also afterwards?

Nope. we pass control to the kernel's own stub, and that calls EBS(),
not systemd-stub. Hence, no, we are just measuring a things before
EBS(), not after.

Lennart

--
Lennart Poettering, Berlin


From dyoung at redhat.com  Thu Aug 22 04:54:12 2024
From: dyoung at redhat.com (Dave Young)
Date: Thu, 22 Aug 2024 19:54:12 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CAF+s44TCvG3knnqyRbw=reaCRfh0_J76HO=ykF+J=ZFyoYZOCA@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com> <CAF+s44TCvG3knnqyRbw=reaCRfh0_J76HO=ykF+J=ZFyoYZOCA@mail.gmail.com>
Message-ID: <CALu+AoRMFRjnp5CB1zyCrEePmqbwoWjpABNmfxRrJA8b9nv9qA@mail.gmail.com>

On Thu, 22 Aug 2024 at 18:51, Pingfan Liu <piliu at redhat.com> wrote:
>
> On Thu, Aug 22, 2024 at 2:17?PM Dave Young <dyoung at redhat.com> wrote:
> >
> > On Thu, 22 Aug 2024 at 13:42, Pingfan Liu <piliu at redhat.com> wrote:
> > >
> > > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> > > <mzxreary at 0pointer.de> wrote:
> > > >
> > > > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> > > >
> > > > > *** Background ***
> > > > >
> > > > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > > > cope with the new format.
> > > > >
> > > > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > > > emulator approach again [3]
> > > >
> > > > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > > > files placed next to the UKI, via the UEFI file system APIs. What's
> > > > your intention with the UEFI emulator regarding that? The sidecars are
> > > > somewhat important, because that's how we parameterize otherwise
> > > > strictly sealed, immutable UKIs.
> > > >
> > > IIUC, you are referring to UKI addons.
> > >
> > > > Hence, what's the story there? implement some form of fs driver (for
> > > > what fs precisely?) in the emulator too?
> > > >
> > > As for addon, that is a missing part in this series. I have overlooked
> > > this issue. Originally, I thought that there was no need to implement
> > > a disk driver and vfat file system, just preload them into memory, and
> > > finally present them through the uefi API. I will take a closer look
> > > at it and chew on it.
> > >
> >
> > Hi Pingfan,
> >
> > If more and more stuff needs coming in,  not only the limited boot
> > services then it will be way too complicated and hard to maintain and
> > debug,  also the two kexec code paths are duplicated somehow. It is
> > really bad..
> >
> OK, I will try to keep things easier. And what do you mean about " two
> kexec code paths"?

I mean we have the EFI and non-EFI kexec implementation. Also for the
EFI kexec code for X86 there is something we passed from 1st kernel to
2nd kernel due to no EFI firmware phase, anyway this part can be
cleaned up if the emulator can be done gracefully.

>
> > I forgot why we can not just extract the kernel from UKI and then load
> > it directly,  if the embedded kernel is also signed it should be good?
> >
>
> I think the main concern is about the signature.

I thought for the minimum case of kdump, we may just live with kernel
signed only and leave the initrd/cmdline unsigned.   Anyway for kexec
reboot it is a problem.

>
> Thanks,
>
> Pingfan
>



From dyoung at redhat.com  Thu Aug 22 05:04:58 2024
From: dyoung at redhat.com (Dave Young)
Date: Thu, 22 Aug 2024 20:04:58 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <ec8befa0-f193-4de3-acea-8e37f8437c7e@app.fastmail.com>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <CALu+AoQRdxJUpNK_eCjKJ=ydRZ4av2S3xBaz3CYJZp12xqm=jQ@mail.gmail.com> <ec8befa0-f193-4de3-acea-8e37f8437c7e@app.fastmail.com>
Message-ID: <CALu+AoR3=a6suS0KyC7HJBOca8zBA0Y2AteF4=b=21j=pVKm1g@mail.gmail.com>

On Thu, 22 Aug 2024 at 18:56, Jan Hendrik Farr <kernel at jfarr.cc> wrote:
>
> Hi Dave,
>
> > I forgot why we can not just extract the kernel from UKI and then load
> > it directly,  if the embedded kernel is also signed it should be good?
>
> The problem is that in the basic usecase for UKI you only sign the entire
> UKI PE file and not the included kernel, because you only want that kernel
> to be run with that one initrd and that one kernel cmdline.

Hmm,  as replied to Pinfan I thought that both the included kernel and
UKI can be signed, and for kdump case kexec_file_load can be used
simply.

>
> So at a minimum you have to have the signature on the whole UKI checked by
> the kernel and than have the kernel extract UKI into its parts unless you
> somehow want to extent trust into userspace to have a helper program do that.

extend trust into userspace is hard, previously when Vivek created the
kexec_file_load this has been explored and he gave up this option. :(

Pingfan,  nice to see you have something done as POC at least, and
good to see this topic is live. I just have some worries about the
complexity of the emulator though.

Thanks
Dave



From piliu at redhat.com  Thu Aug 22 07:29:31 2024
From: piliu at redhat.com (Pingfan Liu)
Date: Thu, 22 Aug 2024 22:29:31 +0800
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <Zsb1isJ2cYRp2jpj@gardel-login>
References: <20240819145417.23367-1-piliu@redhat.com> <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com> <Zsb1isJ2cYRp2jpj@gardel-login>
Message-ID: <CAF+s44SQtRxZz=2eSJ-xP44ORLqvq0doEQ8qrw+1RaKFhoje8w@mail.gmail.com>

On Thu, Aug 22, 2024 at 4:23?PM Lennart Poettering <mzxreary at 0pointer.de> wrote:
>
> On Do, 22.08.24 13:42, Pingfan Liu (piliu at redhat.com) wrote:
>
>  > On Wed, Aug 21, 2024 at 10:27?PM Lennart Poettering
> > <mzxreary at 0pointer.de> wrote:
> > >
> > > On Mo, 19.08.24 22:53, Pingfan Liu (piliu at redhat.com) wrote:
> > >
> > > > *** Background ***
> > > >
> > > > As more PE format kernel images are introduced, it post challenge to kexec to
> > > > cope with the new format.
> > > >
> > > > In my attempt to add support for arm64 zboot image in the kernel [1],
> > > > Ard suggested using an emulator to tackle this issue.  Last year, when
> > > > Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> > > > emulator approach again [3]
> > >
> > > Hmm, systemd's systemd-stub code tries to load certain "side-car"
> > > files placed next to the UKI, via the UEFI file system APIs. What's
> > > your intention with the UEFI emulator regarding that? The sidecars are
> > > somewhat important, because that's how we parameterize otherwise
> > > strictly sealed, immutable UKIs.
> > >
> > IIUC, you are referring to UKI addons.
>
> Yeah, UKI addons, as well as credential files, and sysext/confext
> DDIs.
>
> The addons are the most interesting btw, because we load them into
> memory as PE files, and ask the UEFI to authenticate them.
>
> > > Hence, what's the story there? implement some form of fs driver (for
> > > what fs precisely?) in the emulator too?
> > >
> > As for addon, that is a missing part in this series. I have overlooked
> > this issue. Originally, I thought that there was no need to implement
> > a disk driver and vfat file system, just preload them into memory, and
> > finally present them through the uefi API. I will take a closer look
> > at it and chew on it.
>
> It doesn't have to be VFAT btw. It just has to be something. For
> example, it might suffice to take these files, pack them up as cpio or
> so and pass them along with the UEFI execution. The UEFI emulator
> would then have to expose them as a file system then.
>
> We are not talking of a bazillion of files here, it's mostly a
> smallish number of sidecar files I'd expect.
>
> > > And regarding tpm? tpms require drivers and i guess at the moment uefi
> > > emulator would run those aren't available anymore? but we really
> > > should do a separator measurement then. (also there needs to be some
> > > way to pass over measurement log of that measurement?)
> >
> > It is a pity that it is a common issue persistent with kexec-reboot
> > kernel nowadays.
> > I am not familiar with TPM and have no clear idea for the time being.
> > (emulating Platform Configuration Registers ?).  But since this
> > emulator is held inside a linux kernel image, and the UKI's signature
> > is checked during kexec_file_load. All of them are safe from
> > modification, this security is not an urgent issue.
>
> Hmm, I'd really think about this with some priority. The measurement
> stuff should not be an afterthought, it typically has major
> implications on how you design your transitions, because measurements
> of some component always need to happen *before* you pass control to
> it, otherwise they are pointless.
>

At present, my emulator returns false to is_efi_secure_boot(), so
systemd-stub does not care about the measurement, and moves on.

Could you enlighten me about how systemd utilizes the measurement? I
grepped 'TPM2_PCR_KERNEL_CONFIG', and saw the systemd-stub asks to
extend PCR. But where is the value checked? I guess the systemd will
hang if the check fails.

Thanks,

Pingfan



From dpsmith at apertussolutions.com  Thu Aug 22 11:29:48 2024
From: dpsmith at apertussolutions.com (Daniel P. Smith)
Date: Thu, 22 Aug 2024 14:29:48 -0400
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <87ttflli09.ffs@tglx>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
Message-ID: <281c3bb3-13f6-47a2-9a9a-134e397bf686@apertussolutions.com>

On 8/15/24 15:10, Thomas Gleixner wrote:
> On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
>> On 5/31/24 09:54, Eric W. Biederman wrote:
>>> Eric Biggers <ebiggers at kernel.org> writes:
>>>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
>>>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
>>>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
>>>> but why would you not at least *prefer* SHA-256?
>>>
>>> Yes.  Please prefer to use SHA-256.
>>>
>>> Have you considered implementing I think it is SHA1-DC (as git has) that
>>> is compatible with SHA1 but blocks the known class of attacks where
>>> sha1 is actively broken at this point?
>>
>> We are using the kernel's implementation, addressing what the kernel
>> provides is beyond our efforts. Perhaps someone who is interested in
>> improving the kernel's SHA1 could submit a patch implementing/replacing
>> it with SHA1-DC, as I am sure the maintainers would welcome the help.
> 
> Well, someone who is interested to get his "secure" code merged should
> have a vested interested to have a non-broken SHA1 implementation if
> there is a sensible requirement to use SHA1 in that new "secure" code,
> no?
> 
> Just for the record. The related maintainers can rightfully decide to
> reject known broken "secure" code on a purely technical argument.
> 
> Thanks,
> 
>          tglx
> 

There is one simple question, does allowing the Secure Launch code to 
record SHA1 measurements make the system insecure, and the answer is 
absolutely not.

The role of the Secure Launch code base in the context of the larger 
launch process is to function as observer. Within this role, its only 
responsibility is continuing the trust chain(s) that were started by the 
CPU/Hardware. It does so by measuring the components and configuration 
it is responsible for loading and applying, i.e. in TCG parlance, it is 
continuing the construction of the transitive trust for the system. In 
this aspect, the only degradation of security that can affect the 
kernel's role is whether all the necessary entities are safely measured 
and not what algorithms are used.

If the system integrator, whether that be the OEM, your employer, the 
distro maintainer, the system administrator, or the end user, configures 
the DL preamble to only use SHA1 or used older hardware that has a 
TPM1.2, then they are accepting the risk it creates in their solution. 
In fact, a greater threat to the security of the launch is the 
misconfiguration of the IOMMU, which risks the kernel's ability to 
safely make measurements, as compared to the use of SHA1. Yet it was 
insisted in past reviews that we allow the user to specify an incorrect 
IOMMU policy.

In the end, the "security" of an RTM solution is how and what 
measurements are used to assess the health of a system. Thus bringing it 
back to the opening question, if SHA1 measurements are made but not 
used, i.e. the attestation enforcement only uses SHA2, then it has zero 
impact on the security of the system.

Another fact to consider is that the current Intel's TXT MLE 
specification dictates SHA1 as a valid configuration. Secure Launch's 
use of SHA1 is therefore to comply with Intel's specification for TXT. 
And like the IOMMU situation, having the option available allows the 
user to determine how they ultimately want to integrate Secure Launch 
into their integrity management. And because Secure Launch will only 
attempt SHA1 if it was in the TXT configuration, when either Intel 
removes SHA1 from the MLE specification or firmware manufactures begin 
disabling the SHA1 banks, this will obviously mean that Secure Launch 
will not produce SHA1 measurements.

On a side note, with my remote attestation hat on, the SHA1 measurements 
can in fact be extremely useful. If an attestation was made containing 
both SHA1 and SHA2 chains, and the SHA1 of an event was correct but the 
SHA2 was not, either a natural collision happened or someone maliciously 
caused a collision. The former has an extremely low probability, while 
the latter is highly probable.

Thus, with this information alone, it is possible to make the reasonable 
determination the device is compromised. Whereas if both hashes are 
mismatched, without any additional information it is equally probable of 
either misconfiguration or compromise. And to state the obvious, with 
only SHA2, further information is needed to distinguish between 
misconfiguration and compromise.

V/r,
Daniel P. Smith


From bhe at redhat.com  Thu Aug 22 17:04:06 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 23 Aug 2024 08:04:06 +0800
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
Message-ID: <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>

On 08/22/24 at 11:37am, John Paul Adrian Glaubitz wrote:
> Hi Baoquan,
> 
> On Thu, 2024-08-22 at 17:17 +0800, Baoquan He wrote:
> > > The change to enable CONFIG_CRASH_DUMP by default apparently broke the boot
> > > on 32-bit Power Macintosh systems which fail after GRUB with:
> > > 
> > > 	"Error: You can't boot a kdump kernel from OF!"
> > > 
> > > We may have to turn this off for 32-bit Power Macintosh systems.
> > > 
> > > See this thread on debian-powerpc ML: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
> > 
> > If so, fix need be made.
> > 
> > We may need change in ARCH_SUPPORTS_CRASH_DUMP of ppc, can you or anyone
> > post a patch? I don't know how to identify 32-bit Power Macintosh.
> > 
> > arch/powerpc/Kconfig:
> > ===
> > config ARCH_SUPPORTS_CRASH_DUMP
> >         def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
> >         
> > config ARCH_SELECTS_CRASH_DUMP
> >         def_bool y
> >         depends on CRASH_DUMP
> >         select RELOCATABLE if PPC64 || 44x || PPC_85xx
> > ......
> > config PHYSICAL_START
> >         hex "Physical address where the kernel is loaded" if PHYSICAL_START_BOOL
> >         default "0x02000000" if PPC_BOOK3S && CRASH_DUMP && !NONSTATIC_KERNEL
> >         default "0x00000000"
> 
> I think the architecture does support crash dumps, but I think the kernel has to
> be booted from kexec in this case. Booting a kernel with CRASH_DUMP enabled won't
> work from Open Firmware. So, I think CRASH_DUMP should just be disabled for
> PPC_BOOK3S_32 by default and users who want to use it on these systems, will have to
> enable it explicitly.

If so, below patch possiblly can fix it. Can you help check if it's OK?

>From dd5318dc5dcd66521b31214f0e5921f258532ef8 Mon Sep 17 00:00:00 2001
From: Baoquan He <bhe at redhat.com>
Date: Fri, 23 Aug 2024 07:37:38 +0800
Subject: [PATCH] powerpc/crash: do not default to enable CRASH_DUMP for
 PPC_BOOK3S_32 system
Content-type: text/plain

Recently it's reported that PowerPC macMini system failed to boot up.
It's because CONFIG_CRASH_DUMP=y is set by default on the system since
kernel 6.9, and that makes CONFIG_PHYSICAL_START not equaling 0 any
more and causes failure of normal kernel bootup.

The link of error report can be found here:

https://lists.debian.org/debian-powerpc/2024/07/msg00001.html

And copy the code snippet here for reference:
arch/powerpc/Kconfig:
==================
config KERNEL_START
        hex "Virtual address of kernel base" if KERNEL_START_BOOL
        default PAGE_OFFSET if PAGE_OFFSET_BOOL
        default "0xc2000000" if CRASH_DUMP && !NONSTATIC_KERNEL
        default "0xc0000000"

So let's stop enabling CRASH_DUMP by default on PPC_BOOK3S_32.

Signed-off-by: Baoquan He <bhe at redhat.com>
---
 arch/powerpc/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d7b09b064a8a..dc5ca58be1d6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -680,7 +680,7 @@ config RELOCATABLE_TEST
 	  relocation code.
 
 config ARCH_SUPPORTS_CRASH_DUMP
-	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
+	def_bool PPC64 || PPC_85xx || (44x && !SMP)
 
 config ARCH_SELECTS_CRASH_DUMP
 	def_bool y
-- 
2.41.0



From dave at vasilevsky.ca  Thu Aug 22 17:41:40 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Thu, 22 Aug 2024 20:41:40 -0400
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
 <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
Message-ID: <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>

On 2024-08-22 20:04, Baoquan He wrote:
> If so, below patch possiblly can fix it. Can you help check if it's OK?

That removes the possibility of enabling CRASH_DUMP on PPC_BOOK3S_32, even when booting via other mechanisms. Maybe it would be best to just make it not-default? Please take a look at this patch:


>From d6e5fe3a45f46f1aa01914648c443291d956de9e Mon Sep 17 00:00:00 2001
From: Dave Vasilevsky <dave at vasilevsky.ca>
Date: Thu, 22 Aug 2024 20:13:46 -0400
Subject: [PATCH] powerpc: Default to CRASH_DUMP=n when Open Firmware boot is
 likely
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Open Firmware is unable to boot a kernel where PHYSICAL_START is
non-zero, which occurs when CRASH_DUMP is on.

On PPC_BOOK3S_32, the most common way of booting is Open Firmware, so
most users probably don't want CRASH_DUMP. Users booting via some
other mechanism can turn it on explicitly.

Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
Fixes: 75bc255a7444
---
 arch/arm/Kconfig       | 3 +++
 arch/arm64/Kconfig     | 3 +++
 arch/loongarch/Kconfig | 3 +++
 arch/mips/Kconfig      | 3 +++
 arch/powerpc/Kconfig   | 4 ++++
 arch/riscv/Kconfig     | 3 +++
 arch/s390/Kconfig      | 3 +++
 arch/sh/Kconfig        | 3 +++
 arch/x86/Kconfig       | 3 +++
 kernel/Kconfig.kexec   | 2 +-
 10 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 54b2bb817a7f..200995052690 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1597,6 +1597,9 @@ config ATAGS_PROC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config AUTO_ZRELADDR
 	bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
 	default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a2f8ff354ca6..43e08cc8204f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1558,6 +1558,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 	def_bool CRASH_RESERVE
 
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 70f169210b52..ce232ddcd27d 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_SELECTS_CRASH_DUMP
 	def_bool y
 	depends on CRASH_DUMP
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 60077e576935..b547f4304d0c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config PHYSICAL_START
 	hex "Physical address where the kernel is loaded"
 	default "0xffffffff84000000"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d7b09b064a8a..0f3c1f958eac 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -682,6 +682,10 @@ config RELOCATABLE_TEST
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
 
+config ARCH_DEFAULT_CRASH_DUMP
+	bool
+	default y if !PPC_BOOK3S_32
+
 config ARCH_SELECTS_CRASH_DUMP
 	def_bool y
 	depends on CRASH_DUMP
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 0f3cd7c3a436..eb247b5ee569 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -880,6 +880,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 	def_bool CRASH_RESERVE
 
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index a822f952f64a..05a1fb408471 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
 	  This option also enables s390 zfcpdump.
 	  See also <file:Documentation/arch/s390/zfcpdump.rst>
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 menu "Processor type and features"
 
 config HAVE_MARCH_Z10_FEATURES
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1aa3c4a0c5b2..3a6338962636 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool BROKEN_ON_SMP
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_SUPPORTS_KEXEC_JUMP
 	def_bool y
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 007bab9f2a0e..aa4666bb9e9c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool X86_64 || (X86_32 && HIGHMEM)
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_SUPPORTS_CRASH_HOTPLUG
 	def_bool y
 
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 6c34e63c88ff..4d111f871951 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -97,7 +97,7 @@ config KEXEC_JUMP
 
 config CRASH_DUMP
 	bool "kernel crash dumps"
-	default y
+	default ARCH_DEFAULT_CRASH_DUMP
 	depends on ARCH_SUPPORTS_CRASH_DUMP
 	depends on KEXEC_CORE
 	select VMCORE_INFO
-- 
2.34.1



From bhe at redhat.com  Thu Aug 22 18:58:49 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 23 Aug 2024 09:58:49 +0800
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
 <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
 <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
Message-ID: <Zsfs2VhE0lTY2tpO@MiWiFi-R3L-srv>

On 08/22/24 at 08:41pm, Dave Vasilevsky wrote:
> On 2024-08-22 20:04, Baoquan He wrote:
> > If so, below patch possiblly can fix it. Can you help check if it's OK?
> 
> That removes the possibility of enabling CRASH_DUMP on PPC_BOOK3S_32, even when booting via other mechanisms. Maybe it would be best to just make it not-default? Please take a look at this patch:
> 

This is a good mimic of ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG and the
correspondent KEXEC_IMAGE_VERIFY_SIG. It looks good to me, as long as no
one complain we introduce too many knobs.

Can you post this formally so that people can review it?

> 
> From d6e5fe3a45f46f1aa01914648c443291d956de9e Mon Sep 17 00:00:00 2001
> From: Dave Vasilevsky <dave at vasilevsky.ca>
> Date: Thu, 22 Aug 2024 20:13:46 -0400
> Subject: [PATCH] powerpc: Default to CRASH_DUMP=n when Open Firmware boot is
>  likely
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> Open Firmware is unable to boot a kernel where PHYSICAL_START is
> non-zero, which occurs when CRASH_DUMP is on.
> 
> On PPC_BOOK3S_32, the most common way of booting is Open Firmware, so
> most users probably don't want CRASH_DUMP. Users booting via some
> other mechanism can turn it on explicitly.
> 
> Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
> Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
> Fixes: 75bc255a7444
> ---
>  arch/arm/Kconfig       | 3 +++
>  arch/arm64/Kconfig     | 3 +++
>  arch/loongarch/Kconfig | 3 +++
>  arch/mips/Kconfig      | 3 +++
>  arch/powerpc/Kconfig   | 4 ++++
>  arch/riscv/Kconfig     | 3 +++
>  arch/s390/Kconfig      | 3 +++
>  arch/sh/Kconfig        | 3 +++
>  arch/x86/Kconfig       | 3 +++
>  kernel/Kconfig.kexec   | 2 +-
>  10 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 54b2bb817a7f..200995052690 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1597,6 +1597,9 @@ config ATAGS_PROC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config AUTO_ZRELADDR
>  	bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
>  	default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index a2f8ff354ca6..43e08cc8204f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1558,6 +1558,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 70f169210b52..ce232ddcd27d 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 60077e576935..b547f4304d0c 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config PHYSICAL_START
>  	hex "Physical address where the kernel is loaded"
>  	default "0xffffffff84000000"
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d7b09b064a8a..0f3c1f958eac 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -682,6 +682,10 @@ config RELOCATABLE_TEST
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	bool
> +	default y if !PPC_BOOK3S_32
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 0f3cd7c3a436..eb247b5ee569 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -880,6 +880,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index a822f952f64a..05a1fb408471 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
>  	  This option also enables s390 zfcpdump.
>  	  See also <file:Documentation/arch/s390/zfcpdump.rst>
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  menu "Processor type and features"
>  
>  config HAVE_MARCH_Z10_FEATURES
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 1aa3c4a0c5b2..3a6338962636 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool BROKEN_ON_SMP
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SUPPORTS_KEXEC_JUMP
>  	def_bool y
>  
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 007bab9f2a0e..aa4666bb9e9c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool X86_64 || (X86_32 && HIGHMEM)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SUPPORTS_CRASH_HOTPLUG
>  	def_bool y
>  
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 6c34e63c88ff..4d111f871951 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>  
>  config CRASH_DUMP
>  	bool "kernel crash dumps"
> -	default y
> +	default ARCH_DEFAULT_CRASH_DUMP
>  	depends on ARCH_SUPPORTS_CRASH_DUMP
>  	depends on KEXEC_CORE
>  	select VMCORE_INFO
> -- 
> 2.34.1
> 



From glaubitz at physik.fu-berlin.de  Fri Aug 23 00:16:19 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Fri, 23 Aug 2024 09:16:19 +0200
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related
 config items
In-Reply-To: <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
References: <20240124051254.67105-1-bhe@redhat.com>
	 <20240124051254.67105-6-bhe@redhat.com>
	 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
	 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
	 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
	 <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
	 <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
Message-ID: <c74e24213fd98b252a2a1ff02a107005e50f4f7b.camel@physik.fu-berlin.de>

On Thu, 2024-08-22 at 20:41 -0400, Dave Vasilevsky wrote:
> From d6e5fe3a45f46f1aa01914648c443291d956de9e Mon Sep 17 00:00:00 2001
> From: Dave Vasilevsky <dave at vasilevsky.ca>
> Date: Thu, 22 Aug 2024 20:13:46 -0400
> Subject: [PATCH] powerpc: Default to CRASH_DUMP=n when Open Firmware boot is
>  likely
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> Open Firmware is unable to boot a kernel where PHYSICAL_START is
> non-zero, which occurs when CRASH_DUMP is on.
> 
> On PPC_BOOK3S_32, the most common way of booting is Open Firmware, so
> most users probably don't want CRASH_DUMP. Users booting via some
> other mechanism can turn it on explicitly.
> 
> Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
> Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
> Fixes: 75bc255a7444
> ---
>  arch/arm/Kconfig       | 3 +++
>  arch/arm64/Kconfig     | 3 +++
>  arch/loongarch/Kconfig | 3 +++
>  arch/mips/Kconfig      | 3 +++
>  arch/powerpc/Kconfig   | 4 ++++
>  arch/riscv/Kconfig     | 3 +++
>  arch/s390/Kconfig      | 3 +++
>  arch/sh/Kconfig        | 3 +++
>  arch/x86/Kconfig       | 3 +++
>  kernel/Kconfig.kexec   | 2 +-
>  10 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 54b2bb817a7f..200995052690 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1597,6 +1597,9 @@ config ATAGS_PROC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config AUTO_ZRELADDR
>  	bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
>  	default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index a2f8ff354ca6..43e08cc8204f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1558,6 +1558,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 70f169210b52..ce232ddcd27d 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 60077e576935..b547f4304d0c 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config PHYSICAL_START
>  	hex "Physical address where the kernel is loaded"
>  	default "0xffffffff84000000"
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d7b09b064a8a..0f3c1f958eac 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -682,6 +682,10 @@ config RELOCATABLE_TEST
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	bool
> +	default y if !PPC_BOOK3S_32
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 0f3cd7c3a436..eb247b5ee569 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -880,6 +880,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index a822f952f64a..05a1fb408471 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
>  	  This option also enables s390 zfcpdump.
>  	  See also <file:Documentation/arch/s390/zfcpdump.rst>
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  menu "Processor type and features"
>  
>  config HAVE_MARCH_Z10_FEATURES
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 1aa3c4a0c5b2..3a6338962636 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool BROKEN_ON_SMP
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SUPPORTS_KEXEC_JUMP
>  	def_bool y
>  
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 007bab9f2a0e..aa4666bb9e9c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool X86_64 || (X86_32 && HIGHMEM)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SUPPORTS_CRASH_HOTPLUG
>  	def_bool y
>  
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 6c34e63c88ff..4d111f871951 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>  
>  config CRASH_DUMP
>  	bool "kernel crash dumps"
> -	default y
> +	default ARCH_DEFAULT_CRASH_DUMP
>  	depends on ARCH_SUPPORTS_CRASH_DUMP
>  	depends on KEXEC_CORE
>  	select VMCORE_INFO

It should be disabled on m68k and sh by default as well.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From sourabhjain at linux.ibm.com  Fri Aug 23 04:52:26 2024
From: sourabhjain at linux.ibm.com (Sourabh Jain)
Date: Fri, 23 Aug 2024 17:22:26 +0530
Subject: [PATCH] [RFC] crash: Lock-free crash hotplug support reporting
Message-ID: <20240823115226.835865-1-sourabhjain@linux.ibm.com>

On a CPU/Memory hotplug event, the kexec lock is taken to update the
kdump image. At the same time, this lock is also required to report
the support for crash hotplug to user-space via the
/sys/devices/system/[cpu|memory]/crash_hotplug sysfs interface, to
avoid kdump reload.

The kexec lock is needed to report crash hotplug support because the
crash_hotplug variable, which tracks crash hotplug support, is part of
the kdump image, and the kdump image needs to be updated during a
hotplug event.

Given that only one kdump image can be loaded at any given time, the
crash_hotplug variable can be placed outside the kdump image and set or
reset during kdump image load and unload. This allows crash hotplug
support to be reported without taking the kexec lock.

This would help in situation where CPU/Memory resource are hotplug from
system in bulk.

Commit e2a8f20dd8e9 ("Crash: add lock to serialize crash hotplug
handling") introduced to serialize the kexec lock during bulk CPU/Memory
hotplug events. However, with these changes, the kexec lock for crash
hotplug support reporting can be avoided altogether.

Cc: Hari Bathini <hbathini at linux.ibm.com>
Cc: Mahesh Salgaonkar <mahesh at linux.ibm.com>
Cc: kexec at lists.infradead.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-kernel at vger.kernel.org
Cc: x86 at kernel.org
Signed-off-by: Sourabh Jain <sourabhjain at linux.ibm.com>
---
 include/linux/kexec.h | 11 ++++-------
 kernel/crash_core.c   | 27 +++++++++------------------
 kernel/kexec.c        |  5 ++++-
 kernel/kexec_file.c   |  7 ++++++-
 4 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index f0e9f8eda7a3..bd755ba6bac4 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -318,13 +318,6 @@ struct kimage {
 	unsigned int preserve_context : 1;
 	/* If set, we are using file mode kexec syscall */
 	unsigned int file_mode:1;
-#ifdef CONFIG_CRASH_HOTPLUG
-	/* If set, it is safe to update kexec segments that are
-	 * excluded from SHA calculation.
-	 */
-	unsigned int hotplug_support:1;
-#endif
-
 #ifdef ARCH_HAS_KIMAGE_ARCH
 	struct kimage_arch arch;
 #endif
@@ -370,6 +363,10 @@ struct kimage {
 	unsigned long elf_load_addr;
 };
 
+#ifdef CONFIG_CRASH_HOTPLUG
+extern unsigned int crash_hotplug_support;
+#endif
+
 /* kexec interface functions */
 extern void machine_kexec(struct kimage *image);
 extern int machine_kexec_prepare(struct kimage *image);
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 63cf89393c6e..3428deba0070 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -30,6 +30,13 @@
 #include "kallsyms_internal.h"
 #include "kexec_internal.h"
 
+#ifdef CONFIG_CRASH_HOTPLUG
+/* if set, it is safe to update kexec segments that are
+ * excluded from sha calculation.
+ */
+unsigned int crash_hotplug_support;
+#endif
+
 /* Per cpu memory for storing cpu states in case of system crash. */
 note_buf_t __percpu *crash_notes;
 
@@ -500,23 +507,7 @@ static DEFINE_MUTEX(__crash_hotplug_lock);
  */
 int crash_check_hotplug_support(void)
 {
-	int rc = 0;
-
-	crash_hotplug_lock();
-	/* Obtain lock while reading crash information */
-	if (!kexec_trylock()) {
-		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
-		crash_hotplug_unlock();
-		return 0;
-	}
-	if (kexec_crash_image) {
-		rc = kexec_crash_image->hotplug_support;
-	}
-	/* Release lock now that update complete */
-	kexec_unlock();
-	crash_hotplug_unlock();
-
-	return rc;
+	return crash_hotplug_support;
 }
 
 /*
@@ -552,7 +543,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
 	image = kexec_crash_image;
 
 	/* Check that kexec segments update is permitted */
-	if (!image->hotplug_support)
+	if (!crash_hotplug_support)
 		goto out;
 
 	if (hp_action == KEXEC_CRASH_HP_ADD_CPU ||
diff --git a/kernel/kexec.c b/kernel/kexec.c
index a6b3f96bb50c..d5c6b51eaa8b 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -116,6 +116,9 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
 		/* Uninstall image */
 		kimage_free(xchg(dest_image, NULL));
 		ret = 0;
+#ifdef CONFIG_CRASH_HOTPLUG
+		crash_hotplug_support = 0;
+#endif
 		goto out_unlock;
 	}
 	if (flags & KEXEC_ON_CRASH) {
@@ -136,7 +139,7 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
 
 #ifdef CONFIG_CRASH_HOTPLUG
 	if ((flags & KEXEC_ON_CRASH) && arch_crash_hotplug_support(image, flags))
-		image->hotplug_support = 1;
+		crash_hotplug_support = 1;
 #endif
 
 	ret = machine_kexec_prepare(image);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 3d64290d24c9..b326edb90fd7 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -378,7 +378,7 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 
 #ifdef CONFIG_CRASH_HOTPLUG
 	if ((flags & KEXEC_FILE_ON_CRASH) && arch_crash_hotplug_support(image, flags))
-		image->hotplug_support = 1;
+		crash_hotplug_support = 1;
 #endif
 
 	ret = machine_kexec_prepare(image);
@@ -432,6 +432,11 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 		arch_kexec_protect_crashkres();
 #endif
 
+#ifdef CONFIG_CRASH_HOTPLUG
+	if (flags & KEXEC_FILE_UNLOAD)
+		crash_hotplug_support = 0;
+#endif
+
 	kexec_unlock();
 	kimage_free(image);
 	return ret;
-- 
2.46.0



From dave at vasilevsky.ca  Fri Aug 23 04:58:44 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Fri, 23 Aug 2024 07:58:44 -0400
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <c74e24213fd98b252a2a1ff02a107005e50f4f7b.camel@physik.fu-berlin.de>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
 <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
 <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
 <c74e24213fd98b252a2a1ff02a107005e50f4f7b.camel@physik.fu-berlin.de>
Message-ID: <dc4a1941-6671-4e89-90c2-3a1c19fd3e1c@vasilevsky.ca>

On 2024-08-23 03:16, John Paul Adrian Glaubitz wrote:
> It should be disabled on m68k and sh by default as well.

Sure, I can change that. What's the reasoning, so I can explain in my commit message?

-Dave


From dave at vasilevsky.ca  Fri Aug 23 05:05:43 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Fri, 23 Aug 2024 08:05:43 -0400
Subject: [PATCH linux-next v3 05/14] crash: clean up kdump related config
 items
In-Reply-To: <dc4a1941-6671-4e89-90c2-3a1c19fd3e1c@vasilevsky.ca>
References: <20240124051254.67105-1-bhe@redhat.com>
 <20240124051254.67105-6-bhe@redhat.com>
 <a9d9ecd1ed8d62eae47ec26257093495e6cbd44a.camel@physik.fu-berlin.de>
 <ZscCMLfNbj2MDiaB@MiWiFi-R3L-srv>
 <c5e9996e4d2ba2a0849d65f68e3dce94fffc5828.camel@physik.fu-berlin.de>
 <ZsfR9rdMt8yn1+Bz@MiWiFi-R3L-srv>
 <768dfe3e-c437-40cc-96a5-6c5b34b2d19d@vasilevsky.ca>
 <c74e24213fd98b252a2a1ff02a107005e50f4f7b.camel@physik.fu-berlin.de>
 <dc4a1941-6671-4e89-90c2-3a1c19fd3e1c@vasilevsky.ca>
Message-ID: <e7629e1e-ab41-4400-85c4-e3b39cf5be2f@vasilevsky.ca>

On 2024-08-23 07:58, Dave Vasilevsky wrote:
> On 2024-08-23 03:16, John Paul Adrian Glaubitz wrote:
>> It should be disabled on m68k and sh by default as well.
> 
> Sure, I can change that. What's the reasoning, so I can explain in my commit message?

Oh I don't think m68k even has ARCH_SUPPORTS_CRASH_DUMP, so it will always be off. My question still stands for sh though.

-Dave 


From dave at vasilevsky.ca  Fri Aug 23 05:51:56 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Fri, 23 Aug 2024 08:51:56 -0400
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is unlikely
Message-ID: <20240823125156.104775-1-dave@vasilevsky.ca>

Fixes boot failures on 6.9 on PPC_BOOK3S_32 machines using
Open Firmware. On these machines, the kernel refuses to boot
from non-zero PHYSICAL_START, which occurs when CRASH_DUMP is on.

Since most PPC_BOOK3S_32 machines boot via Open Firmware, it should
default to off for them. Users booting via some other mechanism
can still turn it on explicitly.

Also defaults to CRASH_DUMP=n on sh.

Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
Closes: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
Fixes: 75bc255a7444 ("crash: clean up kdump related config items")
---
 arch/arm/Kconfig       | 3 +++
 arch/arm64/Kconfig     | 3 +++
 arch/loongarch/Kconfig | 3 +++
 arch/mips/Kconfig      | 3 +++
 arch/powerpc/Kconfig   | 4 ++++
 arch/riscv/Kconfig     | 3 +++
 arch/s390/Kconfig      | 3 +++
 arch/sh/Kconfig        | 3 +++
 arch/x86/Kconfig       | 3 +++
 kernel/Kconfig.kexec   | 2 +-
 10 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 54b2bb817a7f..200995052690 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1597,6 +1597,9 @@ config ATAGS_PROC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config AUTO_ZRELADDR
 	bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
 	default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a2f8ff354ca6..43e08cc8204f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1558,6 +1558,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 	def_bool CRASH_RESERVE
 
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 70f169210b52..ce232ddcd27d 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_SELECTS_CRASH_DUMP
 	def_bool y
 	depends on CRASH_DUMP
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 60077e576935..b547f4304d0c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config PHYSICAL_START
 	hex "Physical address where the kernel is loaded"
 	default "0xffffffff84000000"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d7b09b064a8a..0f3c1f958eac 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -682,6 +682,10 @@ config RELOCATABLE_TEST
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
 
+config ARCH_DEFAULT_CRASH_DUMP
+	bool
+	default y if !PPC_BOOK3S_32
+
 config ARCH_SELECTS_CRASH_DUMP
 	def_bool y
 	depends on CRASH_DUMP
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 0f3cd7c3a436..eb247b5ee569 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -880,6 +880,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool y
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 	def_bool CRASH_RESERVE
 
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index a822f952f64a..05a1fb408471 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
 	  This option also enables s390 zfcpdump.
 	  See also <file:Documentation/arch/s390/zfcpdump.rst>
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 menu "Processor type and features"
 
 config HAVE_MARCH_Z10_FEATURES
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1aa3c4a0c5b2..b04cfa23378c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool BROKEN_ON_SMP
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool n
+
 config ARCH_SUPPORTS_KEXEC_JUMP
 	def_bool y
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 007bab9f2a0e..aa4666bb9e9c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
 config ARCH_SUPPORTS_CRASH_DUMP
 	def_bool X86_64 || (X86_32 && HIGHMEM)
 
+config ARCH_DEFAULT_CRASH_DUMP
+	def_bool y
+
 config ARCH_SUPPORTS_CRASH_HOTPLUG
 	def_bool y
 
diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
index 6c34e63c88ff..4d111f871951 100644
--- a/kernel/Kconfig.kexec
+++ b/kernel/Kconfig.kexec
@@ -97,7 +97,7 @@ config KEXEC_JUMP
 
 config CRASH_DUMP
 	bool "kernel crash dumps"
-	default y
+	default ARCH_DEFAULT_CRASH_DUMP
 	depends on ARCH_SUPPORTS_CRASH_DUMP
 	depends on KEXEC_CORE
 	select VMCORE_INFO
-- 
2.34.1



From geert at linux-m68k.org  Fri Aug 23 06:13:42 2024
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 23 Aug 2024 15:13:42 +0200
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is unlikely
In-Reply-To: <20240823125156.104775-1-dave@vasilevsky.ca>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
Message-ID: <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>

Hi Dave,

On Fri, Aug 23, 2024 at 2:54?PM Dave Vasilevsky <dave at vasilevsky.ca> wrote:
> Fixes boot failures on 6.9 on PPC_BOOK3S_32 machines using
> Open Firmware. On these machines, the kernel refuses to boot
> from non-zero PHYSICAL_START, which occurs when CRASH_DUMP is on.
>
> Since most PPC_BOOK3S_32 machines boot via Open Firmware, it should
> default to off for them. Users booting via some other mechanism
> can still turn it on explicitly.
>
> Also defaults to CRASH_DUMP=n on sh.
>
> Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
> Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
> Closes: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
> Fixes: 75bc255a7444 ("crash: clean up kdump related config items")

Thanks for your patch!

> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>
>  config CRASH_DUMP
>         bool "kernel crash dumps"
> -       default y
> +       default ARCH_DEFAULT_CRASH_DUMP
>         depends on ARCH_SUPPORTS_CRASH_DUMP
>         depends on KEXEC_CORE
>         select VMCORE_INFO

IMHO CRASH_DUMP should just default to n, like most kernel options, as
it enables non-trivial extra functionality: the kernel source tree has
more than 100 locations that check if CONFIG_CRASH_DUMP is enabled.

Letting it default to enabled also conflicts with the spirit of the
help text for the symbol:

          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          which are loaded in the main kernel with kexec-tools into
          a specially reserved region and then later executed after
          a crash by kdump/kexec. The crash dump kernel must be compiled
          to a memory address not used by the main kernel or BIOS using
          PHYSICAL_START, or it must be built as a relocatable image
          (CONFIG_RELOCATABLE=y).
          For more details see Documentation/admin-guide/kdump/kdump.rst

          For s390, this option also enables zfcpdump.
          See also <file:Documentation/arch/s390/zfcpdump.rst>

What is so special about CRASH_DUMP, that it should be enabled by
default?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From will at kernel.org  Fri Aug 23 06:38:42 2024
From: will at kernel.org (Will Deacon)
Date: Fri, 23 Aug 2024 14:38:42 +0100
Subject: arm64: Kexec: Warning: virt_to_phys used for non-linear address
In-Reply-To: <ZscEo8KJfn4xfm6X@gmail.com>
References: <ZnFKEtqfqJkYflwL@gmail.com>
 <ZnFxI-jCoJcO8WPw@J2N7QTR9R3>
 <20240624113614.GA8361@willie-the-truck>
 <ZscEo8KJfn4xfm6X@gmail.com>
Message-ID: <20240823133842.GE32156@willie-the-truck>

On Thu, Aug 22, 2024 at 02:28:03AM -0700, Breno Leitao wrote:
> On Mon, Jun 24, 2024 at 12:36:14PM +0100, Will Deacon wrote:
> > On Tue, Jun 18, 2024 at 12:36:03PM +0100, Mark Rutland wrote:
> > > On Tue, Jun 18, 2024 at 01:49:22AM -0700, Breno Leitao wrote:
> 
> > > > Since __pa() is a macro to __virt_to_phys():
> > > > 
> > > > 	#define __pa(x)                 __virt_to_phys((unsigned long)(x))
> > > > 
> > > > I am curious why this address is special that makes __virt_to_phys()
> > > > unhappy.
> > > 
> > > It's a fixmap address rather than a linear-map address. Confusingly
> > > 'virt' generally means the linear map rather than any virtual address,
> > > and usually virt_to_*() only work on linear map addresses.
> > > 
> > > I'm not sure how to fix this; the major reason we fixmap the FDT is so
> > > that it can be anywhere in memory (and e.g. may not be in the linear map
> > > at all), so we can't always generate a linear map VA.
> > > 
> > > We could stash the PA at boot time, and pass this as an argument to
> > > of_kexec_alloc_and_setup_fdt().
> > 
> > Yeah, if it was passed as an additional argument to early_init_dt_scan(),
> > then the core could could track it. Alternatively, we'd need a helper
> > macro to get the PA and have an arm64-variant for the fixmap (everybody
> > else could use __pa()).
> > 
> > > Rob, any thoughts? I couldn't see a neat way of doing this, but maybe we
> > > could initialise an initial_boot_params_phys at setup time, with a bit
> > > of churn to early_init_dt_verify() and friends?
> > 
> > Rob?
> 
> Hello, is there anything I can do or test to have this moving?

I've not seen anything from Rob, so the best bet is probably to see if
you can hack up a patch to fix it yourself and then cc the rest of us
when you post it.

Will


From glaubitz at physik.fu-berlin.de  Fri Aug 23 11:16:35 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Fri, 23 Aug 2024 20:16:35 +0200
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
	 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
Message-ID: <09c29a3c4879d4ce5d8b97fd60d8ba5e38bed979.camel@physik.fu-berlin.de>

Hi Geert,

On Fri, 2024-08-23 at 15:13 +0200, Geert Uytterhoeven wrote:
> IMHO CRASH_DUMP should just default to n, like most kernel options, as
> it enables non-trivial extra functionality: the kernel source tree has
> more than 100 locations that check if CONFIG_CRASH_DUMP is enabled.

I guess we should then revert that part of Baoquan's original patch.

> What is so special about CRASH_DUMP, that it should be enabled by
> default?

Let's ask Baoquan who made the original change to enable CRASH_DUMP by default.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From jacekt at dug.com  Fri Aug 23 19:06:48 2024
From: jacekt at dug.com (Jacek Tomaka)
Date: Fri, 23 Aug 2024 21:06:48 -0500
Subject: [PATCH] Add support for soft reserved memory range
In-Reply-To: <20240814053313.35251-1-jacekt@dugeo.com>
References: <20240814052024.25731-1-jacekt@dugeo.com> <20240814053313.35251-1-jacekt@dugeo.com>
Message-ID: <CAKVxXCXr_7FAVSThRm2s+EWH8H_JuBLBXgwwWfGdAm0n_igErg@mail.gmail.com>

A friendly ping.

On Wed, Aug 14, 2024 at 12:33?AM Jacek Tomaka <jacekt at dugeo.com> wrote:
>
> Essentially catch up with e820 related changes in the kernel.
> Intel Sapphire Rappids MAX has high bandwidth memory which is
> precious resource that is better not allocated by the kernel.
>
> Userspace later can enable soft reserved range using daxctl.
>
> Signed-off-by: Jacek Tomaka <jacek.tomaka at poczta.fm>
> ---
>  include/x86/x86-linux.h               | 2 ++
>  kexec/arch/i386/crashdump-x86.c       | 7 +++++++
>  kexec/arch/i386/kexec-multiboot-x86.c | 1 +
>  kexec/arch/i386/kexec-x86-common.c    | 5 +++++
>  kexec/arch/i386/x86-linux-setup.c     | 3 +++
>  kexec/firmware_memmap.c               | 2 ++
>  kexec/kexec.h                         | 1 +
>  7 files changed, 21 insertions(+)
>
> diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
> index 9646102835..fbde93df94 100644
> --- a/include/x86/x86-linux.h
> +++ b/include/x86/x86-linux.h
> @@ -23,6 +23,8 @@ struct e820entry {
>  #define E820_NVS       4
>  #define E820_PMEM       7
>  #define E820_PRAM       12
> +#define E820_SOFT_RESERVED 0xefffffff
> +
>  } __attribute__((packed));
>  #endif
>
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index a01031e570..49108b2032 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -288,6 +288,10 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
>                         type = RANGE_RESERVED;
>                 } else if (memcmp(str, "Reserved\n", 9) == 0) {
>                         type = RANGE_RESERVED;
> +               } else if (memcmp(str, "soft reserved\n", 14) == 0 ) {
> +                       type = RANGE_SOFT_RESERVED;
> +               } else if (memcmp(str, "Soft Reserved\n", 14) == 0 ) {
> +                       type = RANGE_SOFT_RESERVED;
>                 } else if (memcmp(str, "GART\n", 5) == 0) {
>                         gart_start = start;
>                         gart_end = end;
> @@ -615,6 +619,8 @@ static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk,
>                 strcat (str_mmap, "K@");
>         else if (type == RANGE_RESERVED)
>                 strcat (str_mmap, "K$");
> +       else if (type == RANGE_SOFT_RESERVED)
> +               strcat (str_mmap, "K*");
>         else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
>                 strcat (str_mmap, "K#");
>         else if (type == RANGE_PRAM)
> @@ -985,6 +991,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
>                 if ( !( mem_range[i].type == RANGE_ACPI
>                         || mem_range[i].type == RANGE_ACPI_NVS
>                         || mem_range[i].type == RANGE_RESERVED
> +                       || mem_range[i].type == RANGE_SOFT_RESERVED
>                         || mem_range[i].type == RANGE_PMEM
>                         || mem_range[i].type == RANGE_PRAM))
>                         continue;
> diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c
> index 33c885a2fa..49d57cb5ae 100644
> --- a/kexec/arch/i386/kexec-multiboot-x86.c
> +++ b/kexec/arch/i386/kexec-multiboot-x86.c
> @@ -379,6 +379,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
>                         mmap[i].Type = 4;
>                         break;
>                 case RANGE_RESERVED:
> +               case RANGE_SOFT_RESERVED:
>                 default:
>                         mmap[i].Type = 2;  /* Not RAM (reserved) */
>                 }
> diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
> index ffc95a9e43..116c4f4fd3 100644
> --- a/kexec/arch/i386/kexec-x86-common.c
> +++ b/kexec/arch/i386/kexec-x86-common.c
> @@ -99,6 +99,9 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges
>                 else if (strncasecmp(str, "reserved\n", 9) == 0) {
>                         type = RANGE_RESERVED;
>                 }
> +               else if (strncasecmp(str, "soft reserved\n", 9) == 0) {
> +                       type = RANGE_SOFT_RESERVED;
> +               }
>                 else if (memcmp(str, "ACPI Tables\n", 12) == 0) {
>                         type = RANGE_ACPI;
>                 }
> @@ -170,6 +173,8 @@ unsigned xen_e820_to_kexec_type(uint32_t type)
>                         return RANGE_PMEM;
>                 case E820_PRAM:
>                         return RANGE_PRAM;
> +               case E820_SOFT_RESERVED;
> +                       return RANGE_SOFT_RESERVED;
>                 case E820_RESERVED:
>                 default:
>                         return RANGE_RESERVED;
> diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
> index 73251b9339..afc83fe729 100644
> --- a/kexec/arch/i386/x86-linux-setup.c
> +++ b/kexec/arch/i386/x86-linux-setup.c
> @@ -755,6 +755,9 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode,
>                         case RANGE_PRAM:
>                                 e820[i].type = E820_PRAM;
>                                 break;
> +                       case RANGE_SOFT_RESERVED:
> +                               e820[i].type = E820_SOFT_RESERVED;
> +                               break;
>                         default:
>                         case RANGE_RESERVED:
>                                 e820[i].type = E820_RESERVED;
> diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c
> index 457c3dc9a6..fa0c22140a 100644
> --- a/kexec/firmware_memmap.c
> +++ b/kexec/firmware_memmap.c
> @@ -182,6 +182,8 @@ static int parse_memmap_entry(const char *entry, struct memory_range *range)
>                 range->type = RANGE_RESERVED;
>         else if (strcmp(type, "Reserved") == 0)
>                 range->type = RANGE_RESERVED;
> +        else if (strcmp(type, "Soft Reserved") == 0)
> +                range->type = RANGE_SOFT_RESERVED;
>         else if (strcmp(type, "Unknown E820 type") == 0)
>                 range->type = RANGE_RESERVED;
>         else if (strcmp(type, "ACPI Non-volatile Storage") == 0)
> diff --git a/kexec/kexec.h b/kexec/kexec.h
> index 31c323f674..dbb27a7607 100644
> --- a/kexec/kexec.h
> +++ b/kexec/kexec.h
> @@ -139,6 +139,7 @@ struct memory_range {
>  #define RANGE_UNCACHED 4
>  #define RANGE_PMEM             6
>  #define RANGE_PRAM             11
> +#define RANGE_SOFT_RESERVED 0xefffffff
>  };
>
>  struct memory_ranges {
> --
> 2.17.0
>


-- 
Jacek Tomaka
Principal Software Engineer

76 Kings Park Road
West Perth 6005 WA, Australia
tel +61 8 9287 4143
jacekt at dug.com
www.dug.com
www.dug.comwww.dug.com


From mpe at ellerman.id.au  Sun Aug 25 19:02:59 2024
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Mon, 26 Aug 2024 12:02:59 +1000
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
Message-ID: <87frqsghws.fsf@mail.lhotse>

Geert Uytterhoeven <geert at linux-m68k.org> writes:
> Hi Dave,
>
> On Fri, Aug 23, 2024 at 2:54?PM Dave Vasilevsky <dave at vasilevsky.ca> wrote:
>> Fixes boot failures on 6.9 on PPC_BOOK3S_32 machines using
>> Open Firmware. On these machines, the kernel refuses to boot
>> from non-zero PHYSICAL_START, which occurs when CRASH_DUMP is on.
>>
>> Since most PPC_BOOK3S_32 machines boot via Open Firmware, it should
>> default to off for them. Users booting via some other mechanism
>> can still turn it on explicitly.
>>
>> Also defaults to CRASH_DUMP=n on sh.
>>
>> Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
>> Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
>> Closes: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
>> Fixes: 75bc255a7444 ("crash: clean up kdump related config items")
>
> Thanks for your patch!
>
>> --- a/kernel/Kconfig.kexec
>> +++ b/kernel/Kconfig.kexec
>> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>>
>>  config CRASH_DUMP
>>         bool "kernel crash dumps"
>> -       default y
>> +       default ARCH_DEFAULT_CRASH_DUMP
>>         depends on ARCH_SUPPORTS_CRASH_DUMP
>>         depends on KEXEC_CORE
>>         select VMCORE_INFO
>
> IMHO CRASH_DUMP should just default to n, like most kernel options, as
> it enables non-trivial extra functionality: the kernel source tree has
> more than 100 locations that check if CONFIG_CRASH_DUMP is enabled.
>
> Letting it default to enabled also conflicts with the spirit of the
> help text for the symbol:
>
>           Generate crash dump after being started by kexec.
>           This should be normally only set in special crash dump kernels
>           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>           which are loaded in the main kernel with kexec-tools into
>           a specially reserved region and then later executed after
>           a crash by kdump/kexec. The crash dump kernel must be compiled
>           to a memory address not used by the main kernel or BIOS using
>           PHYSICAL_START, or it must be built as a relocatable image
>           (CONFIG_RELOCATABLE=y).
>           For more details see Documentation/admin-guide/kdump/kdump.rst
>
>           For s390, this option also enables zfcpdump.
>           See also <file:Documentation/arch/s390/zfcpdump.rst>
>
> What is so special about CRASH_DUMP, that it should be enabled by
> default?
 
The reality is that essentially all distros enable it. Because they
don't want to manage separate kernel / crash-kernel packages.

So IMHO having it enabled by default in upstream does make sense,
because it more closely matches what distros/users actually run.

cheers


From bhe at redhat.com  Sun Aug 25 19:44:57 2024
From: bhe at redhat.com (Baoquan He)
Date: Mon, 26 Aug 2024 10:44:57 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system when CONFIG_IMA_KEXEC=y
Message-ID: <20240826024457.22423-1-bhe@redhat.com>

Recently, it's reported that kdump kernel is broken during bootup on
SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
IMA measurement log on kexec"). Just nobody ever tested it on SME
system when enabling CONFIG_IMA_KEXEC.

--------------------------------------------------
 ima: No TPM chip found, activating TPM-bypass!
 Loading compiled-in module X.509 certificates
 Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
 ima: Allocated hash algorithm: sha256
 Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
 CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
 Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
 RIP: 0010:ima_restore_measurement_list+0xdc/0x420
 Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
 RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
 RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
 RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
 RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
 R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
 R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
 FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
 Call Trace:
  <TASK>
  ? show_trace_log_lvl+0x1b0/0x2f0
  ? show_trace_log_lvl+0x1b0/0x2f0
  ? ima_load_kexec_buffer+0x6e/0xf0
  ? __die_body.cold+0x8/0x12
  ? die_addr+0x3c/0x60
  ? exc_general_protection+0x178/0x410
  ? asm_exc_general_protection+0x26/0x30
  ? ima_restore_measurement_list+0xdc/0x420
  ? vprintk_emit+0x1f0/0x270
  ? ima_load_kexec_buffer+0x6e/0xf0
  ima_load_kexec_buffer+0x6e/0xf0
  ima_init+0x52/0xb0
  ? __pfx_init_ima+0x10/0x10
  init_ima+0x26/0xc0
  ? __pfx_init_ima+0x10/0x10
  do_one_initcall+0x5b/0x300
  do_initcalls+0xdf/0x100
  ? __pfx_kernel_init+0x10/0x10
  kernel_init_freeable+0x147/0x1a0
  kernel_init+0x1a/0x140
  ret_from_fork+0x34/0x50
  ? __pfx_kernel_init+0x10/0x10
  ret_from_fork_asm+0x1a/0x30
  </TASK>
 Modules linked in:
 ---[ end trace 0000000000000000 ]---
 RIP: 0010:ima_restore_measurement_list+0xdc/0x420
 Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
 RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
 RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
 RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
 RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
 R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
 R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
 FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
 Kernel panic - not syncing: Fatal exception
 Kernel Offset: disabled
 Rebooting in 10 seconds..

>From debugging printing, the stored addr and size of ima_kexec buffer
are not decrypted correctly like:
 ------
 ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
 ------

There are three pieces of setup_data info passed to kexec/kdump kernel:
SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
ima_kexec buffer suffered from the incorrect decryption. After
debugging, it's because of the code bug in early_memremap_is_setup_data()
where checking the embedded content inside setup_data takes wrong range
calculation.

The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
and the length of setup_data is 0x10. When checking if data is inside
the embedded conent of setup_data, the starting address of efi data and
rng_seed happened to land in the wrong calculated range. While the
ima_kexec's starting address unluckily doesn't pass the checking, then
error occurred.

Here fix the code bug to make kexec/kdump kernel boot up successfully.

Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
Signed-off-by: Baoquan He <bhe at redhat.com>
---
 arch/x86/mm/ioremap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index aa7d279321ea..7953c4a1d28d 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 		paddr_next = data->next;
 		len = data->len;
 
-		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+		if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
 			early_memunmap(data, sizeof(*data));
 			return true;
 		}
-- 
2.41.0



From glaubitz at physik.fu-berlin.de  Sun Aug 25 22:38:53 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Mon, 26 Aug 2024 07:38:53 +0200
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <87frqsghws.fsf@mail.lhotse>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
	 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
	 <87frqsghws.fsf@mail.lhotse>
Message-ID: <c1fd73a3941c54e58420d7555524cd6baeebfb96.camel@physik.fu-berlin.de>

Hi Michael,

On Mon, 2024-08-26 at 12:02 +1000, Michael Ellerman wrote:
> > What is so special about CRASH_DUMP, that it should be enabled by
> > default?
>  
> The reality is that essentially all distros enable it. Because they
> don't want to manage separate kernel / crash-kernel packages.
> 
> So IMHO having it enabled by default in upstream does make sense,
> because it more closely matches what distros/users actually run.

Well, at least Debian did not enable it by default as otherwise we wouldn't
have noticed this change downstream.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From dave at vasilevsky.ca  Sun Aug 25 23:03:44 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Mon, 26 Aug 2024 02:03:44 -0400
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <c1fd73a3941c54e58420d7555524cd6baeebfb96.camel@physik.fu-berlin.de>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
 <87frqsghws.fsf@mail.lhotse>
 <c1fd73a3941c54e58420d7555524cd6baeebfb96.camel@physik.fu-berlin.de>
Message-ID: <94540d05-12ab-49b8-9e37-04a29f5cdf77@vasilevsky.ca>

On 2024-08-26 01:38, John Paul Adrian Glaubitz wrote:
> On Mon, 2024-08-26 at 12:02 +1000, Michael Ellerman wrote:
>> So IMHO having it enabled by default in upstream does make sense,
>> because it more closely matches what distros/users actually run.
> 
> Well, at least Debian did not enable it by default as otherwise we wouldn't
> have noticed this change downstream.

Debian does enable it explicitly on some supported architectures, but not all: https://salsa.debian.org/search?group_id=2107&nav_source=navbar&project_id=18670&repository_ref=master&scope=blobs&search=path%3Aconfig+CRASH_DUMP&search_code=true

By my count, 6.9's new default affected mips, powerpc (32-bit), riscv, and sh in Debian.

-Dave


From kuan-ying.lee at canonical.com  Sun Aug 25 23:52:02 2024
From: kuan-ying.lee at canonical.com (Kuan-Ying Lee)
Date: Mon, 26 Aug 2024 14:52:02 +0800
Subject: [PATCH] arm64/vmcore: Add pgtable_l5_enabled information in vmcoreinfo
Message-ID: <20240826065219.305963-1-kuan-ying.lee@canonical.com>

Since arm64 supports 5-level page tables, we need to add this
information to vmcoreinfo to make debug tools know if 5-level
page table is enabled or not.

Missing this information will break the debug tool like crash [1].

[1] https://github.com/crash-utility/crash

Signed-off-by: Kuan-Ying Lee <kuan-ying.lee at canonical.com>
---
 Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 ++++++
 arch/arm64/kernel/vmcore_info.c                | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
index 0f714fc945ac..557a1cbe5098 100644
--- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
+++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
@@ -466,6 +466,12 @@ Used to get the correct ranges:
 	VMALLOC_START ~ VMALLOC_END-1 : vmalloc() / ioremap() space.
 	VMEMMAP_START ~ VMEMMAP_END-1 : vmemmap region, used for struct page array.
 
+pgtable_l5_enabled
+------------------
+
+User-space tools need to know whether the crash kernel was in 5-level
+paging mode.
+
 arm
 ===
 
diff --git a/arch/arm64/kernel/vmcore_info.c b/arch/arm64/kernel/vmcore_info.c
index b19d5d6cb8b3..be65d664bdb7 100644
--- a/arch/arm64/kernel/vmcore_info.c
+++ b/arch/arm64/kernel/vmcore_info.c
@@ -7,6 +7,7 @@
 #include <linux/vmcore_info.h>
 #include <asm/cpufeature.h>
 #include <asm/memory.h>
+#include <asm/pgtable.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pointer_auth.h>
 
@@ -36,4 +37,6 @@ void arch_crash_save_vmcoreinfo(void)
 	vmcoreinfo_append_str("NUMBER(KERNELPACMASK)=0x%llx\n",
 						system_supports_address_auth() ?
 						ptrauth_kernel_pac_mask() : 0);
+	vmcoreinfo_append_str("NUMBER(pgtable_l5_enabled)=%d\n",
+						pgtable_l5_enabled());
 }
-- 
2.43.0



From mzxreary at 0pointer.de  Mon Aug 26 06:39:59 2024
From: mzxreary at 0pointer.de (Lennart Poettering)
Date: Mon, 26 Aug 2024 15:39:59 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <CAF+s44SQtRxZz=2eSJ-xP44ORLqvq0doEQ8qrw+1RaKFhoje8w@mail.gmail.com>
References: <20240819145417.23367-1-piliu@redhat.com>
 <ZsX5QNie3pzocSfT@gardel-login>
 <CAF+s44S2Ph1_nFcZYy3j0Jr4yuHayb5zdNu1YXg8ce_Lf3TOgQ@mail.gmail.com>
 <Zsb1isJ2cYRp2jpj@gardel-login>
 <CAF+s44SQtRxZz=2eSJ-xP44ORLqvq0doEQ8qrw+1RaKFhoje8w@mail.gmail.com>
Message-ID: <ZsyFr8V6yizMiBTw@gardel-login>

On Do, 22.08.24 22:29, Pingfan Liu (piliu at redhat.com) wrote:

> > Hmm, I'd really think about this with some priority. The measurement
> > stuff should not be an afterthought, it typically has major
> > implications on how you design your transitions, because measurements
> > of some component always need to happen *before* you pass control to
> > it, otherwise they are pointless.
> >
>
> At present, my emulator returns false to is_efi_secure_boot(), so
> systemd-stub does not care about the measurement, and moves on.
>
> Could you enlighten me about how systemd utilizes the measurement? I
> grepped 'TPM2_PCR_KERNEL_CONFIG', and saw the systemd-stub asks to
> extend PCR. But where is the value checked? I guess the systemd will
> hang if the check fails.

systemd's "systemd-pcrlock" tool will look for measurements like that
and generate disk encryption TPM policies from that.

Lennart

--
Lennart Poettering, Berlin


From thomas.lendacky at amd.com  Mon Aug 26 07:24:10 2024
From: thomas.lendacky at amd.com (Tom Lendacky)
Date: Mon, 26 Aug 2024 09:24:10 -0500
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <20240826024457.22423-1-bhe@redhat.com>
References: <20240826024457.22423-1-bhe@redhat.com>
Message-ID: <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>

On 8/25/24 21:44, Baoquan He wrote:
> Recently, it's reported that kdump kernel is broken during bootup on
> SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> IMA measurement log on kexec"). Just nobody ever tested it on SME
> system when enabling CONFIG_IMA_KEXEC.
> 
> --------------------------------------------------
>  ima: No TPM chip found, activating TPM-bypass!
>  Loading compiled-in module X.509 certificates
>  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
>  ima: Allocated hash algorithm: sha256
>  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
>  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
>  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
>  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
>  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
>  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
>  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
>  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
>  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
>  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
>  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
>  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
>  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
>  Call Trace:
>   <TASK>
>   ? show_trace_log_lvl+0x1b0/0x2f0
>   ? show_trace_log_lvl+0x1b0/0x2f0
>   ? ima_load_kexec_buffer+0x6e/0xf0
>   ? __die_body.cold+0x8/0x12
>   ? die_addr+0x3c/0x60
>   ? exc_general_protection+0x178/0x410
>   ? asm_exc_general_protection+0x26/0x30
>   ? ima_restore_measurement_list+0xdc/0x420
>   ? vprintk_emit+0x1f0/0x270
>   ? ima_load_kexec_buffer+0x6e/0xf0
>   ima_load_kexec_buffer+0x6e/0xf0
>   ima_init+0x52/0xb0
>   ? __pfx_init_ima+0x10/0x10
>   init_ima+0x26/0xc0
>   ? __pfx_init_ima+0x10/0x10
>   do_one_initcall+0x5b/0x300
>   do_initcalls+0xdf/0x100
>   ? __pfx_kernel_init+0x10/0x10
>   kernel_init_freeable+0x147/0x1a0
>   kernel_init+0x1a/0x140
>   ret_from_fork+0x34/0x50
>   ? __pfx_kernel_init+0x10/0x10
>   ret_from_fork_asm+0x1a/0x30
>   </TASK>
>  Modules linked in:
>  ---[ end trace 0000000000000000 ]---
>  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
>  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
>  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
>  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
>  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
>  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
>  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
>  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
>  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
>  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
>  Kernel panic - not syncing: Fatal exception
>  Kernel Offset: disabled
>  Rebooting in 10 seconds..
> 
> From debugging printing, the stored addr and size of ima_kexec buffer
> are not decrypted correctly like:
>  ------
>  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
>  ------
> 
> There are three pieces of setup_data info passed to kexec/kdump kernel:
> SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> ima_kexec buffer suffered from the incorrect decryption. After
> debugging, it's because of the code bug in early_memremap_is_setup_data()
> where checking the embedded content inside setup_data takes wrong range
> calculation.
> 
> The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> and the length of setup_data is 0x10. When checking if data is inside
> the embedded conent of setup_data, the starting address of efi data and
> rng_seed happened to land in the wrong calculated range. While the
> ima_kexec's starting address unluckily doesn't pass the checking, then
> error occurred.
> 
> Here fix the code bug to make kexec/kdump kernel boot up successfully.
> 
> Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")

The check that was modified was added by:
	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")

The SETUP_INDIRECT patches seem to be the issue here.

> Signed-off-by: Baoquan He <bhe at redhat.com>
> ---
>  arch/x86/mm/ioremap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index aa7d279321ea..7953c4a1d28d 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
>  		paddr_next = data->next;
>  		len = data->len;
>  
> -		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> +		if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {

I don't think this is correct. You are adding the requested size to the
length of the setup data element. The length is the true length of the
setup data and should not be increased.

It looks like there were some major changes to this function to support
SETUP_INDIRECT. Is the IMA log setup data marked SETUP_INDIRECT?

It might be helpful to instrument the code to see exactly what is
happening during the execution of that function for the IMA log address.

Thanks,
Tom

>  			early_memunmap(data, sizeof(*data));
>  			return true;
>  		}


From ross.philipson at oracle.com  Mon Aug 26 15:38:17 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:17 -0700
Subject: [PATCH v10 02/20] x86: Secure Launch Kconfig
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-3-ross.philipson@oracle.com>

Initial bits to bring in Secure Launch functionality. Add Kconfig
options for compiling in/out the Secure Launch code.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 007bab9f2a0e..24df5f468fdc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2056,6 +2056,17 @@ config EFI_RUNTIME_MAP
 
 	  See also Documentation/ABI/testing/sysfs-firmware-efi-runtime-map.
 
+config SECURE_LAUNCH
+	bool "Secure Launch support"
+	depends on X86_64 && X86_X2APIC && TCG_TPM && CRYPTO_LIB_SHA1 && CRYPTO_LIB_SHA256
+	help
+	   The Secure Launch feature allows a kernel to be loaded
+	   directly through an Intel TXT measured launch. Intel TXT
+	   establishes a Dynamic Root of Trust for Measurement (DRTM)
+	   where the CPU measures the kernel image. This feature then
+	   continues the measurement chain over kernel configuration
+	   information and init images.
+
 source "kernel/Kconfig.hz"
 
 config ARCH_SUPPORTS_KEXEC
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:18 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:18 -0700
Subject: [PATCH v10 03/20] x86: Secure Launch Resource Table header file
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-4-ross.philipson@oracle.com>

Introduce the Secure Launch Resource Table which forms the formal
interface between the pre and post launch code.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 include/linux/slr_table.h | 276 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 276 insertions(+)
 create mode 100644 include/linux/slr_table.h

diff --git a/include/linux/slr_table.h b/include/linux/slr_table.h
new file mode 100644
index 000000000000..a44fd6fbce23
--- /dev/null
+++ b/include/linux/slr_table.h
@@ -0,0 +1,276 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TrenchBoot Secure Launch Resource Table
+ *
+ * The Secure Launch Resource Table is TrenchBoot project defined
+ * specfication to provide cross-architecture compatibility. See
+ * TrenchBoot Secure Launch kernel documentation for details.
+ *
+ * Copyright (c) 2024 Apertus Solutions, LLC
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+
+#ifndef _LINUX_SLR_TABLE_H
+#define _LINUX_SLR_TABLE_H
+
+/* Put this in efi.h if it becomes a standard */
+#define SLR_TABLE_GUID				EFI_GUID(0x877a9b2a, 0x0385, 0x45d1, 0xa0, 0x34, 0x9d, 0xac, 0x9c, 0x9e, 0x56, 0x5f)
+
+/* SLR table header values */
+#define SLR_TABLE_MAGIC		0x4452544d
+#define SLR_TABLE_REVISION	1
+
+/* Current revisions for the policy and UEFI config */
+#define SLR_POLICY_REVISION		1
+#define SLR_UEFI_CONFIG_REVISION	1
+
+/* SLR defined architectures */
+#define SLR_INTEL_TXT		1
+#define SLR_AMD_SKINIT		2
+
+/* SLR defined bootloaders */
+#define SLR_BOOTLOADER_INVALID	0
+#define SLR_BOOTLOADER_GRUB	1
+
+/* Log formats */
+#define SLR_DRTM_TPM12_LOG	1
+#define SLR_DRTM_TPM20_LOG	2
+
+/* DRTM Policy Entry Flags */
+#define SLR_POLICY_FLAG_MEASURED	0x1
+#define SLR_POLICY_IMPLICIT_SIZE	0x2
+
+/* Array Lengths */
+#define TPM_EVENT_INFO_LENGTH		32
+#define TXT_VARIABLE_MTRRS_LENGTH	32
+
+/* Tags */
+#define SLR_ENTRY_INVALID	0x0000
+#define SLR_ENTRY_DL_INFO	0x0001
+#define SLR_ENTRY_LOG_INFO	0x0002
+#define SLR_ENTRY_ENTRY_POLICY	0x0003
+#define SLR_ENTRY_INTEL_INFO	0x0004
+#define SLR_ENTRY_AMD_INFO	0x0005
+#define SLR_ENTRY_ARM_INFO	0x0006
+#define SLR_ENTRY_UEFI_INFO	0x0007
+#define SLR_ENTRY_UEFI_CONFIG	0x0008
+#define SLR_ENTRY_END		0xffff
+
+/* Entity Types */
+#define SLR_ET_UNSPECIFIED	0x0000
+#define SLR_ET_SLRT		0x0001
+#define SLR_ET_BOOT_PARAMS	0x0002
+#define SLR_ET_SETUP_DATA	0x0003
+#define SLR_ET_CMDLINE		0x0004
+#define SLR_ET_UEFI_MEMMAP	0x0005
+#define SLR_ET_RAMDISK		0x0006
+#define SLR_ET_TXT_OS2MLE	0x0010
+#define SLR_ET_UNUSED		0xffff
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Primary Secure Launch Resource Table Header
+ */
+struct slr_table {
+	u32 magic;
+	u16 revision;
+	u16 architecture;
+	u32 size;
+	u32 max_size;
+	/* table entries */
+} __packed;
+
+/*
+ * Common SLRT Table Header
+ */
+struct slr_entry_hdr {
+	u32 tag;
+	u32 size;
+} __packed;
+
+/*
+ * Boot loader context
+ */
+struct slr_bl_context {
+	u16 bootloader;
+	u16 reserved[3];
+	u64 context;
+} __packed;
+
+/*
+ * Dynamic Launch Callback Function type
+ */
+typedef void (*dl_handler_func)(struct slr_bl_context *bl_context);
+
+/*
+ * DRTM Dynamic Launch Configuration
+ */
+struct slr_entry_dl_info {
+	struct slr_entry_hdr hdr;
+	u64 dce_size;
+	u64 dce_base;
+	u64 dlme_size;
+	u64 dlme_base;
+	u64 dlme_entry;
+	struct slr_bl_context bl_context;
+	u64 dl_handler;
+} __packed;
+
+/*
+ * TPM Log Information
+ */
+struct slr_entry_log_info {
+	struct slr_entry_hdr hdr;
+	u16 format;
+	u16 reserved;
+	u32 size;
+	u64 addr;
+} __packed;
+
+/*
+ * DRTM Measurement Entry
+ */
+struct slr_policy_entry {
+	u16 pcr;
+	u16 entity_type;
+	u16 flags;
+	u16 reserved;
+	u64 size;
+	u64 entity;
+	char evt_info[TPM_EVENT_INFO_LENGTH];
+} __packed;
+
+/*
+ * DRTM Measurement Policy
+ */
+struct slr_entry_policy {
+	struct slr_entry_hdr hdr;
+	u16 reserved[2];
+	u16 revision;
+	u16 nr_entries;
+	struct slr_policy_entry policy_entries[];
+} __packed;
+
+/*
+ * Secure Launch defined MTRR saving structures
+ */
+struct slr_txt_mtrr_pair {
+	u64 mtrr_physbase;
+	u64 mtrr_physmask;
+} __packed;
+
+struct slr_txt_mtrr_state {
+	u64 default_mem_type;
+	u64 mtrr_vcnt;
+	struct slr_txt_mtrr_pair mtrr_pair[TXT_VARIABLE_MTRRS_LENGTH];
+} __packed;
+
+/*
+ * Intel TXT Info table
+ */
+struct slr_entry_intel_info {
+	struct slr_entry_hdr hdr;
+	u64 txt_heap;
+	u64 saved_misc_enable_msr;
+	struct slr_txt_mtrr_state saved_bsp_mtrrs;
+} __packed;
+
+/*
+ * UEFI config measurement entry
+ */
+struct slr_uefi_cfg_entry {
+	u16 pcr;
+	u16 reserved;
+	u32 size;
+	u64 cfg; /* address or value */
+	char evt_info[TPM_EVENT_INFO_LENGTH];
+} __packed;
+
+/*
+ * UEFI config measurements
+ */
+struct slr_entry_uefi_config {
+	struct slr_entry_hdr hdr;
+	u16 reserved[2];
+	u16 revision;
+	u16 nr_entries;
+	struct slr_uefi_cfg_entry uefi_cfg_entries[];
+} __packed;
+
+static inline void *slr_end_of_entries(struct slr_table *table)
+{
+	return (void *)table + table->size;
+}
+
+static inline void *
+slr_next_entry(struct slr_table *table,
+	       struct slr_entry_hdr *curr)
+{
+	struct slr_entry_hdr *next = (struct slr_entry_hdr *)((u8 *)curr + curr->size);
+
+	if ((void *)next >= slr_end_of_entries(table))
+		return NULL;
+	if (next->tag == SLR_ENTRY_END)
+		return NULL;
+
+	return next;
+}
+
+static inline void *
+slr_next_entry_by_tag(struct slr_table *table,
+		      struct slr_entry_hdr *entry,
+		      u16 tag)
+{
+	if (!entry) /* Start from the beginning */
+		entry = (struct slr_entry_hdr *)(((u8 *)table) + sizeof(*table));
+
+	for ( ; ; ) {
+		if (entry->tag == tag)
+			return entry;
+
+		entry = slr_next_entry(table, entry);
+		if (!entry)
+			return NULL;
+	}
+
+	return NULL;
+}
+
+static inline int
+slr_add_entry(struct slr_table *table,
+	      struct slr_entry_hdr *entry)
+{
+	struct slr_entry_hdr *end;
+
+	if ((table->size + entry->size) > table->max_size)
+		return -1;
+
+	memcpy((u8 *)table + table->size - sizeof(*end), entry, entry->size);
+	table->size += entry->size;
+
+	end  = (struct slr_entry_hdr *)((u8 *)table + table->size - sizeof(*end));
+	end->tag = SLR_ENTRY_END;
+	end->size = sizeof(*end);
+
+	return 0;
+}
+
+static inline void
+slr_init_table(struct slr_table *slrt, u16 architecture, u32 max_size)
+{
+	struct slr_entry_hdr *end;
+
+	slrt->magic = SLR_TABLE_MAGIC;
+	slrt->revision = SLR_TABLE_REVISION;
+	slrt->architecture = architecture;
+	slrt->size = sizeof(*slrt) + sizeof(*end);
+	slrt->max_size = max_size;
+	end = (struct slr_entry_hdr *)((u8 *)slrt + sizeof(*slrt));
+	end->tag = SLR_ENTRY_END;
+	end->size = sizeof(*end);
+}
+
+#endif /* !__ASSEMBLY */
+
+#endif /* _LINUX_SLR_TABLE_H */
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:20 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:20 -0700
Subject: [PATCH v10 05/20] x86: Add early SHA-1 support for Secure Launch early measurements
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-6-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

Secure Launch is written to be compliant with the Intel TXT Measured Launch
Developer's Guide. The MLE Guide dictates that the system can be configured to
use both the SHA-1 and SHA-2 hashing algorithms.

Regardless of the preference towards SHA-2, if the firmware elected to start
with the SHA-1 and SHA-2 banks active and the dynamic launch was configured to
include SHA-1, Secure Launch is obligated to record measurements for all
algorithms requested in the launch configuration.

The user environment or the integrity management does not desire to use SHA-1,
it is free to just ignore the SHA-1 bank in any integrity operation with the
TPM. If there is a larger concern about the SHA-1 bank being active, it is free
to deliberately cap the SHA-1 PCRs, recording the event in the D-RTM log.

The SHA-1 code here has its origins in the code from the main kernel:

commit c4d5b9f ("crypto: sha1 - implement base layer for SHA-1")

A modified version of this code was introduced to the lib/crypto/sha1.c to bring
it in line with the SHA-256 code and allow it to be pulled into the setup kernel
in the same manner as SHA-256 is.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/boot/compressed/Makefile |  2 +
 arch/x86/boot/compressed/sha1.c   |  6 +++
 include/crypto/sha1.h             |  1 +
 lib/crypto/sha1.c                 | 82 +++++++++++++++++++++++++++++++
 4 files changed, 91 insertions(+)
 create mode 100644 arch/x86/boot/compressed/sha1.c

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index f2051644de94..7eb03afb841b 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -107,6 +107,8 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
 vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
 vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
+vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/sha1.o
+
 $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
 	$(call if_changed,ld)
 
diff --git a/arch/x86/boot/compressed/sha1.c b/arch/x86/boot/compressed/sha1.c
new file mode 100644
index 000000000000..d754489941ac
--- /dev/null
+++ b/arch/x86/boot/compressed/sha1.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Apertus Solutions, LLC.
+ */
+
+#include "../../../../lib/crypto/sha1.c"
diff --git a/include/crypto/sha1.h b/include/crypto/sha1.h
index 044ecea60ac8..d715dd5332e1 100644
--- a/include/crypto/sha1.h
+++ b/include/crypto/sha1.h
@@ -42,5 +42,6 @@ extern int crypto_sha1_finup(struct shash_desc *desc, const u8 *data,
 #define SHA1_WORKSPACE_WORDS	16
 void sha1_init(__u32 *buf);
 void sha1_transform(__u32 *digest, const char *data, __u32 *W);
+void sha1(const u8 *data, unsigned int len, u8 *out);
 
 #endif /* _CRYPTO_SHA1_H */
diff --git a/lib/crypto/sha1.c b/lib/crypto/sha1.c
index 6d2922747cab..edec3f43581f 100644
--- a/lib/crypto/sha1.c
+++ b/lib/crypto/sha1.c
@@ -137,5 +137,87 @@ void sha1_init(__u32 *buf)
 }
 EXPORT_SYMBOL(sha1_init);
 
+static void __sha1_transform(u32 *digest, const char *data)
+{
+	u32 ws[SHA1_WORKSPACE_WORDS];
+
+	sha1_transform(digest, data, ws);
+
+	/* Ensure local data for generating digest is cleared in all cases */
+	memzero_explicit(ws, sizeof(ws));
+}
+
+static void sha1_update(struct sha1_state *sctx, const u8 *data, unsigned int len)
+{
+	unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+	int blocks;
+
+	sctx->count += len;
+
+	if (unlikely((partial + len) < SHA1_BLOCK_SIZE))
+		goto out;
+
+
+	if (partial) {
+		int p = SHA1_BLOCK_SIZE - partial;
+
+		memcpy(sctx->buffer + partial, data, p);
+		data += p;
+		len -= p;
+
+		__sha1_transform(sctx->state, sctx->buffer);
+	}
+
+	blocks = len / SHA1_BLOCK_SIZE;
+	len %= SHA1_BLOCK_SIZE;
+
+	if (blocks) {
+		while (blocks--) {
+			__sha1_transform(sctx->state, data);
+			data += SHA1_BLOCK_SIZE;
+		}
+	}
+	partial = 0;
+
+out:
+	memcpy(sctx->buffer + partial, data, len);
+}
+
+static void sha1_final(struct sha1_state *sctx, u8 *out)
+{
+	const int bit_offset = SHA1_BLOCK_SIZE - sizeof(__be64);
+	unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
+	__be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
+	__be32 *digest = (__be32 *)out;
+	int i;
+
+	sctx->buffer[partial++] = 0x80;
+	if (partial > bit_offset) {
+		memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial);
+		partial = 0;
+
+		__sha1_transform(sctx->state, sctx->buffer);
+	}
+
+	memset(sctx->buffer + partial, 0x0, bit_offset - partial);
+	*bits = cpu_to_be64(sctx->count << 3);
+	__sha1_transform(sctx->state, sctx->buffer);
+
+	for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++)
+		put_unaligned_be32(sctx->state[i], digest++);
+
+	*sctx = (struct sha1_state){};
+}
+
+void sha1(const u8 *data, unsigned int len, u8 *out)
+{
+	struct sha1_state sctx = {0};
+
+	sha1_init(sctx.state);
+	sha1_update(&sctx, data, len);
+	sha1_final(&sctx, out);
+}
+EXPORT_SYMBOL(sha1);
+
 MODULE_DESCRIPTION("SHA-1 Algorithm");
 MODULE_LICENSE("GPL");
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:21 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:21 -0700
Subject: [PATCH v10 06/20] x86: Add early SHA-256 support for Secure Launch early measurements
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-7-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

The SHA-256 algorithm is necessary to measure configuration information into
the TPM as early as possible before using the values. This implementation
uses the established approach of #including the SHA-256 libraries directly in
the code since the compressed kernel is not uncompressed at this point.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/boot/compressed/Makefile | 2 +-
 arch/x86/boot/compressed/sha256.c | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/boot/compressed/sha256.c

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 7eb03afb841b..40dc0b9babd5 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -107,7 +107,7 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
 vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
 vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
-vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/sha1.o
+vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/sha1.o $(obj)/sha256.o
 
 $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
 	$(call if_changed,ld)
diff --git a/arch/x86/boot/compressed/sha256.c b/arch/x86/boot/compressed/sha256.c
new file mode 100644
index 000000000000..293742a90ddc
--- /dev/null
+++ b/arch/x86/boot/compressed/sha256.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Apertus Solutions, LLC
+ */
+
+#include "../../../../lib/crypto/sha256.c"
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:22 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:22 -0700
Subject: [PATCH v10 07/20] x86/msr: Add variable MTRR base/mask and x2apic ID registers
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-8-ross.philipson@oracle.com>

These values are needed by Secure Launch to locate particular CPUs
during AP startup and to restore the MTRR state after a TXT launch.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/include/asm/msr-index.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 82c6a4d350e0..9fbc0e554f99 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -348,6 +348,9 @@
 #define MSR_IA32_RTIT_OUTPUT_BASE	0x00000560
 #define MSR_IA32_RTIT_OUTPUT_MASK	0x00000561
 
+#define MSR_MTRRphysBase0		0x00000200
+#define MSR_MTRRphysMask0		0x00000201
+
 #define MSR_MTRRfix64K_00000		0x00000250
 #define MSR_MTRRfix16K_80000		0x00000258
 #define MSR_MTRRfix16K_A0000		0x00000259
@@ -859,6 +862,8 @@
 #define MSR_IA32_APICBASE_ENABLE	(1<<11)
 #define MSR_IA32_APICBASE_BASE		(0xfffff<<12)
 
+#define MSR_IA32_X2APIC_APICID		0x00000802
+
 #define MSR_IA32_UCODE_WRITE		0x00000079
 #define MSR_IA32_UCODE_REV		0x0000008b
 
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:23 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:23 -0700
Subject: [PATCH v10 08/20] x86/boot: Place TXT MLE header in the kernel_info section
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-9-ross.philipson@oracle.com>

The MLE (measured launch environment) header must be locatable by the
boot loader and TXT must be setup to do a launch with this header's
location. While the offset to the kernel_info structure does not need
to be at a fixed offset, the offsets in the header must be relative
offsets from the start of the setup kernel. The support in the linker
file achieves this.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
Suggested-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/x86/boot/compressed/kernel_info.S | 50 +++++++++++++++++++++++---
 arch/x86/boot/compressed/vmlinux.lds.S |  7 ++++
 2 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/arch/x86/boot/compressed/kernel_info.S b/arch/x86/boot/compressed/kernel_info.S
index f818ee8fba38..a0604a0d1756 100644
--- a/arch/x86/boot/compressed/kernel_info.S
+++ b/arch/x86/boot/compressed/kernel_info.S
@@ -1,12 +1,20 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 
+#include <linux/linkage.h>
 #include <asm/bootparam.h>
 
-	.section ".rodata.kernel_info", "a"
+/*
+ * The kernel_info structure is not placed at a fixed offest in the
+ * kernel image. So this macro and the support in the linker file
+ * allow the relative offsets for the MLE header within the kernel
+ * image to be configured at build time.
+ */
+#define roffset(X) ((X) - kernel_info)
 
-	.global kernel_info
+	.section ".rodata.kernel_info", "a"
 
-kernel_info:
+	.balign	16
+SYM_DATA_START(kernel_info)
 	/* Header, Linux top (structure). */
 	.ascii	"LToP"
 	/* Size. */
@@ -17,6 +25,40 @@ kernel_info:
 	/* Maximal allowed type for setup_data and setup_indirect structs. */
 	.long	SETUP_TYPE_MAX
 
+	/* Offset to the MLE header structure */
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+	.long	roffset(mle_header_offset)
+#else
+	.long	0
+#endif
+
 kernel_info_var_len_data:
 	/* Empty for time being... */
-kernel_info_end:
+SYM_DATA_END_LABEL(kernel_info, SYM_L_LOCAL, kernel_info_end)
+
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+	/*
+	 * The MLE Header per the TXT Specification, section 2.1
+	 * MLE capabilities, see table 4. Capabilities set:
+	 * bit 0: Support for GETSEC[WAKEUP] for RLP wakeup
+	 * bit 1: Support for RLP wakeup using MONITOR address
+	 * bit 2: The ECX register will contain the pointer to the MLE page table
+	 * bit 5: TPM 1.2 family: Details/authorities PCR usage support
+	 * bit 9: Supported format of TPM 2.0 event log - TCG compliant
+	 */
+SYM_DATA_START(mle_header)
+	.long	0x9082ac5a  /* UUID0 */
+	.long	0x74a7476f  /* UUID1 */
+	.long	0xa2555c0f  /* UUID2 */
+	.long	0x42b651cb  /* UUID3 */
+	.long	0x00000034  /* MLE header size */
+	.long	0x00020002  /* MLE version 2.2 */
+	.long	roffset(sl_stub_entry_offset) /* Linear entry point of MLE (virt. address) */
+	.long	0x00000000  /* First valid page of MLE */
+	.long	0x00000000  /* Offset within binary of first byte of MLE */
+	.long	roffset(_edata_offset) /* Offset within binary of last byte + 1 of MLE */
+	.long	0x00000227  /* Bit vector of MLE-supported capabilities */
+	.long	0x00000000  /* Starting linear address of command line (unused) */
+	.long	0x00000000  /* Ending linear address of command line (unused) */
+SYM_DATA_END(mle_header)
+#endif
diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S
index 083ec6d7722a..f82184801462 100644
--- a/arch/x86/boot/compressed/vmlinux.lds.S
+++ b/arch/x86/boot/compressed/vmlinux.lds.S
@@ -118,3 +118,10 @@ SECTIONS
 	}
 	ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
 }
+
+#ifdef CONFIG_SECURE_LAUNCH
+PROVIDE(kernel_info_offset      = ABSOLUTE(kernel_info - startup_32));
+PROVIDE(mle_header_offset       = kernel_info_offset + ABSOLUTE(mle_header - startup_32));
+PROVIDE(sl_stub_entry_offset    = kernel_info_offset + ABSOLUTE(sl_stub_entry - startup_32));
+PROVIDE(_edata_offset           = kernel_info_offset + ABSOLUTE(_edata - startup_32));
+#endif
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:25 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:25 -0700
Subject: [PATCH v10 10/20] x86: Secure Launch kernel late boot stub
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-11-ross.philipson@oracle.com>

The routine slaunch_setup is called out of the x86 specific setup_arch()
routine during early kernel boot. After determining what platform is
present, various operations specific to that platform occur. This
includes finalizing setting for the platform late launch and verifying
that memory protections are in place.

Intel VT-d/IOMMU hardware provides special registers called Protected
Memory Regions (PMRs) that allow all memory to be protected from
DMA during a TXT DRTM launch. This coverage is validated during the
late setup process to ensure DMA protection is in place prior to
the IOMMUs being initialized and configured by the mainline kernel.
See the Intel Trusted Execution Technology - Measured Launch Environment
Developer's Guide for more details.

For TXT, this code also reserves the original compressed kernel setup
area where the APs were left looping so that this memory cannot be used.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/setup.c    |   3 +
 arch/x86/kernel/slaunch.c  | 524 +++++++++++++++++++++++++++++++++++++
 drivers/iommu/intel/dmar.c |   4 +
 4 files changed, 532 insertions(+)
 create mode 100644 arch/x86/kernel/slaunch.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index a847180836e4..a18a8239bde5 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_X86_32)		+= tls.o
 obj-$(CONFIG_IA32_EMULATION)	+= tls.o
 obj-y				+= step.o
 obj-$(CONFIG_INTEL_TXT)		+= tboot.o
+obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
 obj-$(CONFIG_ISA_DMA_API)	+= i8237.o
 obj-y				+= stacktrace.o
 obj-y				+= cpu/
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 6129dc2ba784..d915f21306aa 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -21,6 +21,7 @@
 #include <linux/root_dev.h>
 #include <linux/hugetlb.h>
 #include <linux/tboot.h>
+#include <linux/slaunch.h>
 #include <linux/usb/xhci-dbgp.h>
 #include <linux/static_call.h>
 #include <linux/swiotlb.h>
@@ -938,6 +939,8 @@ void __init setup_arch(char **cmdline_p)
 	early_gart_iommu_check();
 #endif
 
+	slaunch_setup_txt();
+
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
new file mode 100644
index 000000000000..9fbe96d1ec71
--- /dev/null
+++ b/arch/x86/kernel/slaunch.c
@@ -0,0 +1,524 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure Launch late validation/setup and finalization support.
+ *
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/security.h>
+#include <linux/memblock.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/e820/api.h>
+#include <asm/setup.h>
+#include <asm/realmode.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+
+static u32 sl_flags __ro_after_init;
+static struct sl_ap_wake_info ap_wake_info __ro_after_init;
+static u64 evtlog_addr __ro_after_init;
+static u32 evtlog_size __ro_after_init;
+static u64 vtd_pmr_lo_size __ro_after_init;
+
+/* This should be plenty of room */
+static u8 txt_dmar[PAGE_SIZE] __aligned(16);
+
+/*
+ * Get the Secure Launch flags that indicate what kind of launch is being done.
+ * E.g. a TXT launch is in progress or no Secure Launch is happening.
+ */
+u32 slaunch_get_flags(void)
+{
+	return sl_flags;
+}
+
+/*
+ * Return the AP wakeup information used in the SMP boot code to start up
+ * the APs that are parked using MONITOR/MWAIT.
+ */
+struct sl_ap_wake_info *slaunch_get_ap_wake_info(void)
+{
+	return &ap_wake_info;
+}
+
+/*
+ * On Intel platforms, TXT passes a safe copy of the DMAR ACPI table to the
+ * DRTM. The DRTM is supposed to use this instead of the one found in the
+ * ACPI tables.
+ */
+struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
+{
+	/* The DMAR is only stashed and provided via TXT on Intel systems */
+	if (memcmp(txt_dmar, "DMAR", 4))
+		return dmar;
+
+	return (struct acpi_table_header *)(txt_dmar);
+}
+
+/*
+ * If running within a TXT established DRTM, this is the proper way to reset
+ * the system if a failure occurs or a security issue is found.
+ */
+void __noreturn slaunch_txt_reset(void __iomem *txt,
+				  const char *msg, u64 error)
+{
+	u64 one = 1, val;
+
+	pr_err("%s", msg);
+
+	/*
+	 * This performs a TXT reset with a sticky error code. The reads of
+	 * TXT_CR_E2STS act as barriers.
+	 */
+	memcpy_toio(txt + TXT_CR_ERRORCODE, &error, sizeof(error));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_NO_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_UNLOCK_MEM_CONFIG, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_RESET, &one, sizeof(one));
+
+	for ( ; ; )
+		asm volatile ("hlt");
+
+	unreachable();
+}
+
+/*
+ * The TXT heap is too big to map all at once with early_ioremap
+ * so it is done a table at a time.
+ */
+static void __init *txt_early_get_heap_table(void __iomem *txt, u32 type,
+					     u32 bytes)
+{
+	u64 base, size, offset = 0;
+	void *heap;
+	int i;
+
+	if (type > TXT_SINIT_TABLE_MAX)
+		slaunch_txt_reset(txt, "Error invalid table type for early heap walk\n",
+				  SL_ERROR_HEAP_WALK);
+
+	memcpy_fromio(&base, txt + TXT_CR_HEAP_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_HEAP_SIZE, sizeof(size));
+
+	/* Iterate over heap tables looking for table of "type" */
+	for (i = 0; i < type; i++) {
+		base += offset;
+		heap = early_memremap(base, sizeof(u64));
+		if (!heap)
+			slaunch_txt_reset(txt, "Error early_memremap of heap for heap walk\n",
+					  SL_ERROR_HEAP_MAP);
+
+		offset = *((u64 *)heap);
+
+		/*
+		 * After the first iteration, any offset of zero is invalid and
+		 * implies the TXT heap is corrupted.
+		 */
+		if (!offset)
+			slaunch_txt_reset(txt, "Error invalid 0 offset in heap walk\n",
+					  SL_ERROR_HEAP_ZERO_OFFSET);
+
+		early_memunmap(heap, sizeof(u64));
+	}
+
+	/* Skip the size field at the head of each table */
+	base += sizeof(u64);
+	heap = early_memremap(base, bytes);
+	if (!heap)
+		slaunch_txt_reset(txt, "Error early_memremap of heap section\n",
+				  SL_ERROR_HEAP_MAP);
+
+	return heap;
+}
+
+static void __init txt_early_put_heap_table(void *addr, unsigned long size)
+{
+	early_memunmap(addr, size);
+}
+
+/*
+ * TXT uses a special set of VTd registers to protect all of memory from DMA
+ * until the IOMMU can be programmed to protect memory. There is the low
+ * memory PMR that can protect all memory up to 4G. The high memory PRM can
+ * be setup to protect all memory beyond 4Gb. Validate that these values cover
+ * what is expected.
+ */
+static void __init slaunch_verify_pmrs(void __iomem *txt)
+{
+	struct txt_os_sinit_data *os_sinit_data;
+	u32 field_offset, err = 0;
+	const char *errmsg = "";
+	unsigned long last_pfn;
+
+	field_offset = offsetof(struct txt_os_sinit_data, lcp_po_base);
+	os_sinit_data = txt_early_get_heap_table(txt, TXT_OS_SINIT_DATA_TABLE,
+						 field_offset);
+
+	/* Save a copy */
+	vtd_pmr_lo_size = os_sinit_data->vtd_pmr_lo_size;
+
+	last_pfn = e820__end_of_ram_pfn();
+
+	/*
+	 * First make sure the hi PMR covers all memory above 4G. In the
+	 * unlikely case where there is < 4G on the system, the hi PMR will
+	 * not be set.
+	 */
+	if (os_sinit_data->vtd_pmr_hi_base != 0x0ULL) {
+		if (os_sinit_data->vtd_pmr_hi_base != 0x100000000ULL) {
+			err = SL_ERROR_HI_PMR_BASE;
+			errmsg =  "Error hi PMR base\n";
+			goto out;
+		}
+
+		if (PFN_PHYS(last_pfn) > os_sinit_data->vtd_pmr_hi_base +
+		    os_sinit_data->vtd_pmr_hi_size) {
+			err = SL_ERROR_HI_PMR_SIZE;
+			errmsg = "Error hi PMR size\n";
+			goto out;
+		}
+	}
+
+	/*
+	 * Lo PMR base should always be 0. This was already checked in
+	 * early stub.
+	 */
+
+	/*
+	 * Check that if the kernel was loaded below 4G, that it is protected
+	 * by the lo PMR. Note this is the decompressed kernel. The ACM would
+	 * have ensured the compressed kernel (the MLE image) was protected.
+	 */
+	if (__pa_symbol(_end) < 0x100000000ULL && __pa_symbol(_end) > os_sinit_data->vtd_pmr_lo_size) {
+		err = SL_ERROR_LO_PMR_MLE;
+		errmsg = "Error lo PMR does not cover MLE kernel\n";
+	}
+
+	/*
+	 * Other regions of interest like boot param, AP wake block, cmdline
+	 * already checked for PMR coverage in the early stub code.
+	 */
+
+out:
+	txt_early_put_heap_table(os_sinit_data, field_offset);
+
+	if (err)
+		slaunch_txt_reset(txt, errmsg, err);
+}
+
+static void __init slaunch_txt_reserve_range(u64 base, u64 size)
+{
+	int type;
+
+	type = e820__get_entry_type(base, base + size - 1);
+	if (type == E820_TYPE_RAM) {
+		pr_info("memblock reserve base: %llx size: %llx\n", base, size);
+		memblock_reserve(base, size);
+	}
+}
+
+/*
+ * For Intel, certain regions of memory must be marked as reserved by putting
+ * them on the memblock reserved list if they are not already e820 reserved.
+ * This includes:
+ *  - The TXT HEAP
+ *  - The ACM area
+ *  - The TXT private register bank
+ *  - The MDR list sent to the MLE by the ACM (see TXT specification)
+ *  (Normally the above are properly reserved by firmware but if it was not
+ *  done, reserve them now)
+ *  - The AP wake block
+ *  - TPM log external to the TXT heap
+ *
+ * Also if the low PMR doesn't cover all memory < 4G, any RAM regions above
+ * the low PMR must be reserved too.
+ */
+static void __init slaunch_txt_reserve(void __iomem *txt)
+{
+	struct txt_sinit_memory_descriptor_record *mdr;
+	struct txt_sinit_mle_data *sinit_mle_data;
+	u64 base, size, heap_base, heap_size;
+	u32 mdrnum, mdroffset, mdrslen;
+	u32 field_offset, i;
+	void *mdrs;
+
+	base = TXT_PRIV_CONFIG_REGS_BASE;
+	size = TXT_PUB_CONFIG_REGS_BASE - TXT_PRIV_CONFIG_REGS_BASE;
+	slaunch_txt_reserve_range(base, size);
+
+	memcpy_fromio(&heap_base, txt + TXT_CR_HEAP_BASE, sizeof(heap_base));
+	memcpy_fromio(&heap_size, txt + TXT_CR_HEAP_SIZE, sizeof(heap_size));
+	slaunch_txt_reserve_range(heap_base, heap_size);
+
+	memcpy_fromio(&base, txt + TXT_CR_SINIT_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_SINIT_SIZE, sizeof(size));
+	slaunch_txt_reserve_range(base, size);
+
+	field_offset = offsetof(struct txt_sinit_mle_data,
+				sinit_vtd_dmar_table_size);
+	sinit_mle_data = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+						  field_offset);
+
+	mdrnum = sinit_mle_data->num_of_sinit_mdrs;
+	mdroffset = sinit_mle_data->sinit_mdrs_table_offset;
+
+	txt_early_put_heap_table(sinit_mle_data, field_offset);
+
+	if (!mdrnum)
+		goto nomdr;
+
+	mdrslen = mdrnum * sizeof(struct txt_sinit_memory_descriptor_record);
+
+	mdrs = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+					mdroffset + mdrslen - 8);
+
+	mdr = mdrs + mdroffset - 8;
+
+	for (i = 0; i < mdrnum; i++, mdr++) {
+		/* Spec says some entries can have length 0, ignore them */
+		if (mdr->type > 0 && mdr->length > 0)
+			slaunch_txt_reserve_range(mdr->address, mdr->length);
+	}
+
+	txt_early_put_heap_table(mdrs, mdroffset + mdrslen - 8);
+
+nomdr:
+	slaunch_txt_reserve_range(ap_wake_info.ap_wake_block,
+				  ap_wake_info.ap_wake_block_size);
+
+	/*
+	 * Earlier checks ensured that the event log was properly situated
+	 * either inside the TXT heap or outside. This is a check to see if the
+	 * event log needs to be reserved. If it is in the TXT heap, it is
+	 * already reserved.
+	 */
+	if (evtlog_addr < heap_base || evtlog_addr > (heap_base + heap_size))
+		slaunch_txt_reserve_range(evtlog_addr, evtlog_size);
+
+	for (i = 0; i < e820_table->nr_entries; i++) {
+		base = e820_table->entries[i].addr;
+		size = e820_table->entries[i].size;
+		if (base >= vtd_pmr_lo_size && base < 0x100000000ULL)
+			slaunch_txt_reserve_range(base, size);
+		else if (base < vtd_pmr_lo_size && base + size > vtd_pmr_lo_size)
+			slaunch_txt_reserve_range(vtd_pmr_lo_size,
+						  base + size - vtd_pmr_lo_size);
+	}
+}
+
+/*
+ * TXT stashes a safe copy of the DMAR ACPI table to prevent tampering.
+ * It is stored in the TXT heap. Fetch it from there and make it available
+ * to the IOMMU driver.
+ */
+static void __init slaunch_copy_dmar_table(void __iomem *txt)
+{
+	struct txt_sinit_mle_data *sinit_mle_data;
+	u32 field_offset, dmar_size, dmar_offset;
+	void *dmar;
+
+	field_offset = offsetof(struct txt_sinit_mle_data,
+				processor_scrtm_status);
+	sinit_mle_data = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+						  field_offset);
+
+	dmar_size = sinit_mle_data->sinit_vtd_dmar_table_size;
+	dmar_offset = sinit_mle_data->sinit_vtd_dmar_table_offset;
+
+	txt_early_put_heap_table(sinit_mle_data, field_offset);
+
+	if (!dmar_size || !dmar_offset)
+		slaunch_txt_reset(txt, "Error invalid DMAR table values\n",
+				  SL_ERROR_HEAP_INVALID_DMAR);
+
+	if (unlikely(dmar_size > PAGE_SIZE))
+		slaunch_txt_reset(txt, "Error DMAR too big to store\n",
+				  SL_ERROR_HEAP_DMAR_SIZE);
+
+	dmar = txt_early_get_heap_table(txt, TXT_SINIT_MLE_DATA_TABLE,
+					dmar_offset + dmar_size - 8);
+	if (!dmar)
+		slaunch_txt_reset(txt, "Error early_ioremap of DMAR\n",
+				  SL_ERROR_HEAP_DMAR_MAP);
+
+	memcpy(txt_dmar, dmar + dmar_offset - 8, dmar_size);
+
+	txt_early_put_heap_table(dmar, dmar_offset + dmar_size - 8);
+}
+
+/*
+ * The location of the safe AP wake code block is stored in the TXT heap.
+ * Fetch needed values here in the early init code for later use in SMP
+ * startup.
+ *
+ * Also get the TPM event log values are in the SLRT and have to be fetched.
+ * They will be put on the memblock reserve list later.
+ */
+static void __init slaunch_fetch_values(void __iomem *txt)
+{
+	struct txt_os_mle_data *os_mle_data;
+	struct slr_entry_log_info *log_info;
+	u8 *jmp_offset, *stacks_offset;
+	struct slr_table *slrt;
+	u32 size;
+
+	os_mle_data = txt_early_get_heap_table(txt, TXT_OS_MLE_DATA_TABLE,
+					       sizeof(*os_mle_data));
+
+	ap_wake_info.ap_wake_block = os_mle_data->ap_wake_block;
+	ap_wake_info.ap_wake_block_size = os_mle_data->ap_wake_block_size;
+
+	jmp_offset = os_mle_data->mle_scratch + SL_SCRATCH_AP_JMP_OFFSET;
+	ap_wake_info.ap_jmp_offset = *((u32 *)jmp_offset);
+
+	stacks_offset = os_mle_data->mle_scratch + SL_SCRATCH_AP_STACKS_OFFSET;
+	ap_wake_info.ap_stacks_offset = *((u32 *)stacks_offset);
+
+	slrt = (struct slr_table *)early_memremap(os_mle_data->slrt, sizeof(*slrt));
+	if (!slrt)
+		slaunch_txt_reset(txt, "Error early_memremap of SLRT failed\n",
+				  SL_ERROR_SLRT_MAP);
+
+	size = slrt->size;
+	early_memunmap(slrt, sizeof(*slrt));
+
+	slrt = (struct slr_table *)early_memremap(os_mle_data->slrt, size);
+	if (!slrt)
+		slaunch_txt_reset(txt, "Error early_memremap of SLRT failed\n",
+				  SL_ERROR_SLRT_MAP);
+
+	log_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO);
+
+	if (!log_info)
+		slaunch_txt_reset(txt, "SLRT missing logging info entry\n",
+				  SL_ERROR_SLRT_MISSING_ENTRY);
+
+	evtlog_addr = log_info->addr;
+	evtlog_size = log_info->size;
+
+	early_memunmap(slrt, size);
+
+	txt_early_put_heap_table(os_mle_data, sizeof(*os_mle_data));
+}
+
+/*
+ * Called to fix the long jump address for the waiting APs to vector to
+ * the correct startup location in the Secure Launch stub in the rmpiggy.
+ */
+void __init slaunch_fixup_jump_vector(void)
+{
+	struct sl_ap_wake_info *ap_wake_info;
+	u32 *ap_jmp_ptr;
+
+	if (!slaunch_is_txt_launch())
+		return;
+
+	ap_wake_info = slaunch_get_ap_wake_info();
+
+	ap_jmp_ptr = (u32 *)__va(ap_wake_info->ap_wake_block +
+				 ap_wake_info->ap_jmp_offset);
+
+	*ap_jmp_ptr = real_mode_header->sl_trampoline_start32;
+
+	pr_info("TXT AP startup vector address updated\n");
+}
+
+/*
+ * Intel TXT specific late stub setup and validation called from within
+ * x86 specific setup_arch().
+ */
+void __init slaunch_setup_txt(void)
+{
+	u64 one = TXT_REGVALUE_ONE, val;
+	void __iomem *txt;
+
+	if (!boot_cpu_has(X86_FEATURE_SMX))
+		return;
+
+	/*
+	 * If booted through secure launch entry point, the loadflags
+	 * option will be set.
+	 */
+	if (!(boot_params.hdr.loadflags & SLAUNCH_FLAG))
+		return;
+
+	/*
+	 * See if SENTER was done by reading the status register in the
+	 * public space. If the public register space cannot be read, TXT may
+	 * be disabled.
+	 */
+	txt = early_ioremap(TXT_PUB_CONFIG_REGS_BASE,
+			    TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+	if (!txt)
+		panic("Error early_ioremap in TXT setup failed\n");
+
+	memcpy_fromio(&val, txt + TXT_CR_STS, sizeof(val));
+	early_iounmap(txt, TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+
+	/* SENTER should have been done */
+	if (!(val & TXT_SENTER_DONE_STS))
+		panic("Error TXT.STS SENTER_DONE not set\n");
+
+	/* SEXIT should have been cleared */
+	if (val & TXT_SEXIT_DONE_STS)
+		panic("Error TXT.STS SEXIT_DONE set\n");
+
+	/* Now we want to use the private register space */
+	txt = early_ioremap(TXT_PRIV_CONFIG_REGS_BASE,
+			    TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+	if (!txt) {
+		/* This is really bad, no where to go from here */
+		panic("Error early_ioremap of TXT priv registers\n");
+	}
+
+	/*
+	 * Try to read the Intel VID from the TXT private registers to see if
+	 * TXT measured launch happened properly and the private space is
+	 * available.
+	 */
+	memcpy_fromio(&val, txt + TXT_CR_DIDVID, sizeof(val));
+	if ((val & 0xffff) != 0x8086) {
+		/*
+		 * Can't do a proper TXT reset since it appears something is
+		 * wrong even though SENTER happened and it should be in SMX
+		 * mode.
+		 */
+		panic("Invalid TXT vendor ID, not in SMX mode\n");
+	}
+
+	/* Set flags so subsequent code knows the status of the launch */
+	sl_flags |= (SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT);
+
+	/*
+	 * Reading the proper DIDVID from the private register space means we
+	 * are in SMX mode and private registers are open for read/write.
+	 */
+
+	/* On Intel, have to handle TPM localities via TXT */
+	memcpy_toio(txt + TXT_CR_CMD_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+	memcpy_toio(txt + TXT_CR_CMD_OPEN_LOCALITY1, &one, sizeof(one));
+	memcpy_fromio(&val, txt + TXT_CR_E2STS, sizeof(val));
+
+	slaunch_fetch_values(txt);
+
+	slaunch_verify_pmrs(txt);
+
+	slaunch_txt_reserve(txt);
+
+	slaunch_copy_dmar_table(txt);
+
+	early_iounmap(txt, TXT_NR_CONFIG_PAGES * PAGE_SIZE);
+
+	pr_info("Intel TXT setup complete\n");
+}
diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
index 1c8d3141cb55..64800545cf88 100644
--- a/drivers/iommu/intel/dmar.c
+++ b/drivers/iommu/intel/dmar.c
@@ -28,6 +28,7 @@
 #include <linux/iommu.h>
 #include <linux/numa.h>
 #include <linux/limits.h>
+#include <linux/slaunch.h>
 #include <asm/irq_remapping.h>
 
 #include "iommu.h"
@@ -661,6 +662,9 @@ parse_dmar_table(void)
 	 */
 	dmar_tbl = tboot_get_dmar_table(dmar_tbl);
 
+	/* If Secure Launch is active, it has similar logic */
+	dmar_tbl = slaunch_get_dmar_table(dmar_tbl);
+
 	dmar = (struct acpi_table_dmar *)dmar_tbl;
 	if (!dmar)
 		return -ENODEV;
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:26 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:26 -0700
Subject: [PATCH v10 11/20] x86: Secure Launch SMP bringup support
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-12-ross.philipson@oracle.com>

On Intel, the APs are left in a well documented state after TXT performs
the late launch. Specifically they cannot have #INIT asserted on them so
a standard startup via INIT/SIPI/SIPI cannot be performed. Instead the
early SL stub code uses MONITOR and MWAIT to park the APs. The realmode/init.c
code updates the jump address for the waiting APs with the location of the
Secure Launch entry point in the RM piggy after it is loaded and fixed up.
As the APs are woken up by writing the monitor, the APs jump to the Secure
Launch entry point in the RM piggy which mimics what the real mode code would
do then jumps to the standard RM piggy protected mode entry point.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/include/asm/realmode.h      |  3 ++
 arch/x86/kernel/smpboot.c            | 43 ++++++++++++++++++++++++++--
 arch/x86/realmode/init.c             |  3 ++
 arch/x86/realmode/rm/header.S        |  3 ++
 arch/x86/realmode/rm/trampoline_64.S | 32 +++++++++++++++++++++
 5 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
index 87e5482acd0d..339b48e2543d 100644
--- a/arch/x86/include/asm/realmode.h
+++ b/arch/x86/include/asm/realmode.h
@@ -38,6 +38,9 @@ struct real_mode_header {
 #ifdef CONFIG_X86_64
 	u32	machine_real_restart_seg;
 #endif
+#ifdef CONFIG_SECURE_LAUNCH
+	u32	sl_trampoline_start32;
+#endif
 };
 
 /* This must match data at realmode/rm/trampoline_{32,64}.S */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 0c35207320cb..0c915e105a9b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -60,6 +60,7 @@
 #include <linux/stackprotector.h>
 #include <linux/cpuhotplug.h>
 #include <linux/mc146818rtc.h>
+#include <linux/slaunch.h>
 
 #include <asm/acpi.h>
 #include <asm/cacheinfo.h>
@@ -868,6 +869,41 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
+#ifdef CONFIG_SECURE_LAUNCH
+
+/*
+ * TXT AP startup is quite different than normal. The APs cannot have #INIT
+ * asserted on them or receive SIPIs. The early Secure Launch code has parked
+ * the APs using monitor/mwait. This will wake the APs by writing the monitor
+ * and have them jump to the protected mode code in the rmpiggy where the rest
+ * of the SMP boot of the AP will proceed normally.
+ */
+static void slaunch_wakeup_cpu_from_txt(int cpu, int apicid)
+{
+	struct sl_ap_stack_and_monitor *stack_monitor;
+	struct sl_ap_wake_info *ap_wake_info;
+
+	ap_wake_info = slaunch_get_ap_wake_info();
+
+	stack_monitor = (struct sl_ap_stack_and_monitor *)__va(ap_wake_info->ap_wake_block +
+							       ap_wake_info->ap_stacks_offset);
+
+	for (unsigned int i = TXT_MAX_CPUS - 1; i >= 0; i--) {
+		if (stack_monitor[i].apicid == apicid) {
+			stack_monitor[i].monitor = 1;
+			break;
+		}
+	}
+}
+
+#else
+
+static inline void slaunch_wakeup_cpu_from_txt(int cpu, int apicid)
+{
+}
+
+#endif  /* !CONFIG_SECURE_LAUNCH */
+
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -877,7 +913,7 @@ int common_cpu_up(unsigned int cpu, struct task_struct *idle)
 static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
 {
 	unsigned long start_ip = real_mode_header->trampoline_start;
-	int ret;
+	int ret = 0;
 
 #ifdef CONFIG_X86_64
 	/* If 64-bit wakeup method exists, use the 64-bit mode trampoline IP */
@@ -922,12 +958,15 @@ static int do_boot_cpu(u32 apicid, int cpu, struct task_struct *idle)
 
 	/*
 	 * Wake up a CPU in difference cases:
+	 * - Intel TXT DRTM launch uses its own method to wake the APs
 	 * - Use a method from the APIC driver if one defined, with wakeup
 	 *   straight to 64-bit mode preferred over wakeup to RM.
 	 * Otherwise,
 	 * - Use an INIT boot APIC message
 	 */
-	if (apic->wakeup_secondary_cpu_64)
+	if (slaunch_is_txt_launch())
+		slaunch_wakeup_cpu_from_txt(cpu, apicid);
+	else if (apic->wakeup_secondary_cpu_64)
 		ret = apic->wakeup_secondary_cpu_64(apicid, start_ip);
 	else if (apic->wakeup_secondary_cpu)
 		ret = apic->wakeup_secondary_cpu(apicid, start_ip);
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index f9bc444a3064..d95776cb30d3 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -4,6 +4,7 @@
 #include <linux/memblock.h>
 #include <linux/cc_platform.h>
 #include <linux/pgtable.h>
+#include <linux/slaunch.h>
 
 #include <asm/set_memory.h>
 #include <asm/realmode.h>
@@ -210,6 +211,8 @@ void __init init_real_mode(void)
 
 	setup_real_mode();
 	set_real_mode_permissions();
+
+	slaunch_fixup_jump_vector();
 }
 
 static int __init do_init_real_mode(void)
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S
index 2eb62be6d256..3b5cbcbbfc90 100644
--- a/arch/x86/realmode/rm/header.S
+++ b/arch/x86/realmode/rm/header.S
@@ -37,6 +37,9 @@ SYM_DATA_START(real_mode_header)
 #ifdef CONFIG_X86_64
 	.long	__KERNEL32_CS
 #endif
+#ifdef CONFIG_SECURE_LAUNCH
+	.long	pa_sl_trampoline_start32
+#endif
 SYM_DATA_END(real_mode_header)
 
 	/* End signature, used to verify integrity */
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index 14d9c7daf90f..b0ce6205d7ea 100644
--- a/arch/x86/realmode/rm/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -122,6 +122,38 @@ SYM_CODE_END(sev_es_trampoline_start)
 
 	.section ".text32","ax"
 	.code32
+#ifdef CONFIG_SECURE_LAUNCH
+	.balign 4
+SYM_CODE_START(sl_trampoline_start32)
+	/*
+	 * The early secure launch stub AP wakeup code has taken care of all
+	 * the vagaries of launching out of TXT. This bit just mimics what the
+	 * 16b entry code does and jumps off to the real startup_32.
+	 */
+	cli
+	wbinvd
+
+	/*
+	 * The %ebx provided is not terribly useful since it is the physical
+	 * address of tb_trampoline_start and not the base of the image.
+	 * Use pa_real_mode_base, which is fixed up, to get a run time
+	 * base register to use for offsets to location that do not have
+	 * pa_ symbols.
+	 */
+	movl    $pa_real_mode_base, %ebx
+
+	LOCK_AND_LOAD_REALMODE_ESP lock_pa=1
+
+	lgdt    tr_gdt(%ebx)
+	lidt    tr_idt(%ebx)
+
+	movw	$__KERNEL_DS, %dx	# Data segment descriptor
+
+	/* Jump to where the 16b code would have jumped */
+	ljmpl	$__KERNEL32_CS, $pa_startup_32
+SYM_CODE_END(sl_trampoline_start32)
+#endif
+
 	.balign 4
 SYM_CODE_START(startup_32)
 	movl	%edx, %ss
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:27 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:27 -0700
Subject: [PATCH v10 12/20] kexec: Secure Launch kexec SEXIT support
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-13-ross.philipson@oracle.com>

Prior to running the next kernel via kexec, the Secure Launch code
closes down private SMX resources and does an SEXIT. This allows the
next kernel to start normally without any issues starting the APs etc.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/kernel/slaunch.c | 72 +++++++++++++++++++++++++++++++++++++++
 kernel/kexec_core.c       |  4 +++
 2 files changed, 76 insertions(+)

diff --git a/arch/x86/kernel/slaunch.c b/arch/x86/kernel/slaunch.c
index 9fbe96d1ec71..d9be68325ae1 100644
--- a/arch/x86/kernel/slaunch.c
+++ b/arch/x86/kernel/slaunch.c
@@ -522,3 +522,75 @@ void __init slaunch_setup_txt(void)
 
 	pr_info("Intel TXT setup complete\n");
 }
+
+static inline void smx_getsec_sexit(void)
+{
+	asm volatile ("getsec\n"
+		      : : "a" (SMX_X86_GETSEC_SEXIT));
+}
+
+/*
+ * Used during kexec and on reboot paths to finalize the TXT state
+ * and do an SEXIT exiting the DRTM and disabling SMX mode.
+ */
+void slaunch_finalize(int do_sexit)
+{
+	u64 one = TXT_REGVALUE_ONE, val;
+	void __iomem *config;
+
+	if (!slaunch_is_txt_launch())
+		return;
+
+	config = ioremap(TXT_PRIV_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES *
+			 PAGE_SIZE);
+	if (!config) {
+		pr_emerg("Error SEXIT failed to ioremap TXT private reqs\n");
+		return;
+	}
+
+	/* Clear secrets bit for SEXIT */
+	memcpy_toio(config + TXT_CR_CMD_NO_SECRETS, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/* Unlock memory configurations */
+	memcpy_toio(config + TXT_CR_CMD_UNLOCK_MEM_CONFIG, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/* Close the TXT private register space */
+	memcpy_toio(config + TXT_CR_CMD_CLOSE_PRIVATE, &one, sizeof(one));
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	/*
+	 * Calls to iounmap are not being done because of the state of the
+	 * system this late in the kexec process. Local IRQs are disabled and
+	 * iounmap causes a TLB flush which in turn causes a warning. Leaving
+	 * thse mappings is not an issue since the next kernel is going to
+	 * completely re-setup memory management.
+	 */
+
+	/* Map public registers and do a final read fence */
+	config = ioremap(TXT_PUB_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES *
+			 PAGE_SIZE);
+	if (!config) {
+		pr_emerg("Error SEXIT failed to ioremap TXT public reqs\n");
+		return;
+	}
+
+	memcpy_fromio(&val, config + TXT_CR_E2STS, sizeof(val));
+
+	pr_emerg("TXT clear secrets bit and unlock memory complete.\n");
+
+	if (!do_sexit)
+		return;
+
+	if (smp_processor_id() != 0)
+		panic("Error TXT SEXIT must be called on CPU 0\n");
+
+	/* In case SMX mode was disabled, enable it for SEXIT */
+	cr4_set_bits(X86_CR4_SMXE);
+
+	/* Do the SEXIT SMX operation */
+	smx_getsec_sexit();
+
+	pr_info("TXT SEXIT complete.\n");
+}
diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index c0caa14880c3..53d5ae8326a3 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -40,6 +40,7 @@
 #include <linux/hugetlb.h>
 #include <linux/objtool.h>
 #include <linux/kmsg_dump.h>
+#include <linux/slaunch.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -1045,6 +1046,9 @@ int kernel_kexec(void)
 		cpu_hotplug_enable();
 		pr_notice("Starting new kernel\n");
 		machine_shutdown();
+
+		/* Finalize TXT registers and do SEXIT */
+		slaunch_finalize(1);
 	}
 
 	kmsg_dump(KMSG_DUMP_SHUTDOWN);
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:28 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:28 -0700
Subject: [PATCH v10 13/20] x86/reboot: Secure Launch SEXIT support on reboot paths
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-14-ross.philipson@oracle.com>

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 at oracle.com>
---
 arch/x86/kernel/reboot.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 0e0a4cf6b5eb..c66e8896d516 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -13,6 +13,7 @@
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
 #include <linux/kexec.h>
+#include <linux/slaunch.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -778,6 +779,7 @@ static void native_machine_restart(char *__unused)
 
 	if (!reboot_force)
 		machine_shutdown();
+	slaunch_finalize(!reboot_force);
 	__machine_emergency_restart(0);
 }
 
@@ -788,6 +790,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);
 }
 
@@ -796,8 +801,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);
 }
@@ -825,6 +834,7 @@ void machine_shutdown(void)
 
 void machine_emergency_restart(void)
 {
+	slaunch_finalize(0);
 	__machine_emergency_restart(1);
 }
 
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:29 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:29 -0700
Subject: [PATCH v10 14/20] tpm: Protect against locality counter underflow
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-15-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

Commit 933bfc5ad213 introduced the use of a locality counter to control when a
locality request is allowed to be sent to the TPM. In the commit, the counter
is indiscriminately decremented. Thus creating a situation for an integer
underflow of the counter.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
Reported-by: Kanth Ghatraju <kanth.ghatraju at oracle.com>
---
 drivers/char/tpm/tpm_tis_core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index fdef214b9f6b..a6967f312837 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -180,7 +180,10 @@ static int tpm_tis_relinquish_locality(struct tpm_chip *chip, int l)
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
 
 	mutex_lock(&priv->locality_count_mutex);
-	priv->locality_count--;
+	if (priv->locality_count > 0)
+		priv->locality_count--;
+	else
+		pr_info("Invalid: locality count dropped below zero\n");
 	if (priv->locality_count == 0)
 		__tpm_tis_relinquish_locality(priv, l);
 	mutex_unlock(&priv->locality_count_mutex);
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:30 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:30 -0700
Subject: [PATCH v10 15/20] tpm: Ensure tpm is in known state at startup
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-16-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

When tis_tis_core initializes, it assumes all localities are closed. There
are cases when this may not be the case. This commit addresses this by
ensuring all localities are closed before initializing begins.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 drivers/char/tpm/tpm_tis_core.c | 11 ++++++++++-
 include/linux/tpm.h             |  6 ++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index a6967f312837..22ebf679ea69 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -1107,7 +1107,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 	u32 intmask;
 	u32 clkrun_val;
 	u8 rid;
-	int rc, probe;
+	int rc, probe, i;
 	struct tpm_chip *chip;
 
 	chip = tpmm_chip_alloc(dev, &tpm_tis);
@@ -1169,6 +1169,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
 		goto out_err;
 	}
 
+	/*
+	 * There are environments, for example, those that comply with the TCG D-RTM
+	 * specification that requires the TPM to be left in Locality 2.
+	 */
+	for (i = 0; i <= TPM_MAX_LOCALITY; i++) {
+		if (check_locality(chip, i))
+			tpm_tis_relinquish_locality(chip, i);
+	}
+
 	/* Take control of the TPM's interrupt hardware and shut it off */
 	rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
 	if (rc < 0)
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index e93ee8d936a9..98f2c7c1c52e 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -147,6 +147,12 @@ struct tpm_chip_seqops {
  */
 #define TPM2_MAX_CONTEXT_SIZE 4096
 
+/*
+ * The maximum locality (0 - 4) for a TPM, as defined in section 3.2 of the
+ * Client Platform Profile Specification.
+ */
+#define TPM_MAX_LOCALITY		4
+
 struct tpm_chip {
 	struct device dev;
 	struct device devs;
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:31 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:31 -0700
Subject: [PATCH v10 16/20] tpm: Make locality requests return consistent values
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-17-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

The function tpm_tis_request_locality() is expected to return the locality
value that was requested, or a negative error code upon failure. If it is called
while locality_count of struct tis_data is non-zero, no actual locality request
will be sent. Because the ret variable is initially set to 0, the
locality_count will still get increased, and the function will return 0. For a
caller, this would indicate that locality 0 was successfully requested and not
the state changes just mentioned.

Additionally, the function __tpm_tis_request_locality() provides inconsistent
error codes. It will provide either a failed IO write or a -1 should it have
timed out waiting for locality request to succeed.

This commit changes __tpm_tis_request_locality() to return valid negative error
codes to reflect the reason it fails. It then adjusts the return value check in
tpm_tis_request_locality() to check for a non-negative return value before
incrementing locality_cout. In addition, the initial value of the ret value is
set to a negative error to ensure the check does not pass if
__tpm_tis_request_locality() is not called.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 drivers/char/tpm/tpm_tis_core.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 22ebf679ea69..20a8b341be0d 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -210,7 +210,7 @@ static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
 again:
 		timeout = stop - jiffies;
 		if ((long)timeout <= 0)
-			return -1;
+			return -EBUSY;
 		rc = wait_event_interruptible_timeout(priv->int_queue,
 						      (check_locality
 						       (chip, l)),
@@ -229,18 +229,21 @@ static int __tpm_tis_request_locality(struct tpm_chip *chip, int l)
 			tpm_msleep(TPM_TIMEOUT);
 		} while (time_before(jiffies, stop));
 	}
-	return -1;
+	return -EBUSY;
 }
 
 static int tpm_tis_request_locality(struct tpm_chip *chip, int l)
 {
 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
-	int ret = 0;
+	int ret = -EBUSY;
+
+	if (l < 0 || l > TPM_MAX_LOCALITY)
+		return -EINVAL;
 
 	mutex_lock(&priv->locality_count_mutex);
 	if (priv->locality_count == 0)
 		ret = __tpm_tis_request_locality(chip, l);
-	if (!ret)
+	if (ret >= 0)
 		priv->locality_count++;
 	mutex_unlock(&priv->locality_count_mutex);
 	return ret;
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:32 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:32 -0700
Subject: [PATCH v10 17/20] tpm: Add ability to set the default locality the TPM chip uses
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-18-ross.philipson@oracle.com>

Curently the locality is hard coded to 0 but for DRTM support, access
is needed to localities 1 through 4.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 drivers/char/tpm/tpm-chip.c | 24 +++++++++++++++++++++++-
 include/linux/tpm.h         |  4 ++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 854546000c92..1ca390a742ed 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -44,7 +44,7 @@ static int tpm_request_locality(struct tpm_chip *chip)
 	if (!chip->ops->request_locality)
 		return 0;
 
-	rc = chip->ops->request_locality(chip, 0);
+	rc = chip->ops->request_locality(chip, chip->default_locality);
 	if (rc < 0)
 		return rc;
 
@@ -143,6 +143,27 @@ void tpm_chip_stop(struct tpm_chip *chip)
 }
 EXPORT_SYMBOL_GPL(tpm_chip_stop);
 
+/**
+ * tpm_chip_set_default_locality() - set the TPM chip default locality to open
+ * @chip:	a TPM chip to use
+ * @locality:   the default locality to set
+ *
+ * Return:
+ * * true      - Preferred locality set
+ * * false     - Invalid locality specified
+ */
+bool tpm_chip_set_default_locality(struct tpm_chip *chip, int locality)
+{
+	if (locality < 0 || locality >=TPM_MAX_LOCALITY)
+		return false;
+
+	mutex_lock(&chip->tpm_mutex);
+	chip->default_locality = locality;
+	mutex_unlock(&chip->tpm_mutex);
+	return true;
+}
+EXPORT_SYMBOL_GPL(tpm_chip_set_default_locality);
+
 /**
  * tpm_try_get_ops() - Get a ref to the tpm_chip
  * @chip: Chip to ref
@@ -374,6 +395,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
 	}
 
 	chip->locality = -1;
+	chip->default_locality = 0;
 	return chip;
 
 out:
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 98f2c7c1c52e..83e94b2f0cef 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -219,6 +219,9 @@ struct tpm_chip {
 	u8 null_ec_key_y[EC_PT_SZ];
 	struct tpm2_auth *auth;
 #endif
+
+	/* preferred locality - default 0 */
+	int default_locality;
 };
 
 #define TPM_HEADER_SIZE		10
@@ -446,6 +449,7 @@ static inline u32 tpm2_rc_value(u32 rc)
 extern int tpm_is_tpm2(struct tpm_chip *chip);
 extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
 extern void tpm_put_ops(struct tpm_chip *chip);
+extern bool tpm_chip_set_default_locality(struct tpm_chip *chip, int locality);
 extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
 				size_t min_rsp_body_length, const char *desc);
 extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:33 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:33 -0700
Subject: [PATCH v10 18/20] tpm: Add sysfs interface to allow setting and querying the default locality
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-19-ross.philipson@oracle.com>

Expose a sysfs interface to allow user mode to set and query the default
locality set for the TPM chip.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 drivers/char/tpm/tpm-sysfs.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 94231f052ea7..185a2f57d4cb 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -324,6 +324,34 @@ static ssize_t null_name_show(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR_RO(null_name);
 #endif
 
+static ssize_t default_locality_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct tpm_chip *chip = to_tpm_chip(dev);
+
+	return sprintf(buf, "%d\n", chip->default_locality);
+}
+
+static ssize_t default_locality_store(struct device *dev, struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct tpm_chip *chip = to_tpm_chip(dev);
+	unsigned int locality;
+
+	if (kstrtouint(buf, 0, &locality))
+		return -ERANGE;
+
+	if (locality >= TPM_MAX_LOCALITY)
+		return -ERANGE;
+
+	if (tpm_chip_set_default_locality(chip, (int)locality))
+		return count;
+	else
+		return 0;
+}
+
+static DEVICE_ATTR_RW(default_locality);
+
 static struct attribute *tpm1_dev_attrs[] = {
 	&dev_attr_pubek.attr,
 	&dev_attr_pcrs.attr,
@@ -336,6 +364,7 @@ static struct attribute *tpm1_dev_attrs[] = {
 	&dev_attr_durations.attr,
 	&dev_attr_timeouts.attr,
 	&dev_attr_tpm_version_major.attr,
+	&dev_attr_default_locality.attr,
 	NULL,
 };
 
@@ -344,6 +373,7 @@ static struct attribute *tpm2_dev_attrs[] = {
 #ifdef CONFIG_TCG_TPM2_HMAC
 	&dev_attr_null_name.attr,
 #endif
+	&dev_attr_default_locality.attr,
 	NULL
 };
 
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:34 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:34 -0700
Subject: [PATCH v10 19/20] x86: Secure Launch late initcall platform module
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-20-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

The Secure Launch platform module is a late init module. During the
init call, the TPM event log is read and measurements taken in the
early boot stub code are located. These measurements are extended
into the TPM PCRs using the mainline TPM kernel driver.

The platform module also registers the securityfs nodes to allow
access to TXT register fields on Intel along with the fetching of
and writing events to the late launch TPM log.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: garnetgrimm <grimmg at ainfosec.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/slmodule.c | 509 +++++++++++++++++++++++++++++++++++++
 2 files changed, 510 insertions(+)
 create mode 100644 arch/x86/kernel/slmodule.c

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index a18a8239bde5..6028903d6661 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_IA32_EMULATION)	+= tls.o
 obj-y				+= step.o
 obj-$(CONFIG_INTEL_TXT)		+= tboot.o
 obj-$(CONFIG_SECURE_LAUNCH)	+= slaunch.o
+obj-$(CONFIG_SECURE_LAUNCH)	+= slmodule.o
 obj-$(CONFIG_ISA_DMA_API)	+= i8237.o
 obj-y				+= stacktrace.o
 obj-y				+= cpu/
diff --git a/arch/x86/kernel/slmodule.c b/arch/x86/kernel/slmodule.c
new file mode 100644
index 000000000000..46a8f86ea061
--- /dev/null
+++ b/arch/x86/kernel/slmodule.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure Launch late validation/setup, securityfs exposure and finalization.
+ *
+ * Copyright (c) 2024 Apertus Solutions, LLC
+ * Copyright (c) 2024 Assured Information Security, Inc.
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/security.h>
+#include <linux/memblock.h>
+#include <linux/tpm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+#include <crypto/sha2.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+
+/*
+ * The macro DECLARE_TXT_PUB_READ_U is used to read values from the TXT
+ * public registers as unsigned values.
+ */
+#define DECLARE_TXT_PUB_READ_U(size, fmt, msg_size)			\
+static ssize_t txt_pub_read_u##size(unsigned int offset,		\
+		loff_t *read_offset,					\
+		size_t read_len,					\
+		char __user *buf)					\
+{									\
+	char msg_buffer[msg_size];					\
+	u##size reg_value = 0;						\
+	void __iomem *txt;						\
+									\
+	txt = ioremap(TXT_PUB_CONFIG_REGS_BASE,				\
+			TXT_NR_CONFIG_PAGES * PAGE_SIZE);		\
+	if (!txt)							\
+		return -EFAULT;						\
+	memcpy_fromio(&reg_value, txt + offset, sizeof(u##size));	\
+	iounmap(txt);							\
+	snprintf(msg_buffer, msg_size, fmt, reg_value);			\
+	return simple_read_from_buffer(buf, read_len, read_offset,	\
+			&msg_buffer, msg_size);				\
+}
+
+DECLARE_TXT_PUB_READ_U(8, "%#04x\n", 6);
+DECLARE_TXT_PUB_READ_U(32, "%#010x\n", 12);
+DECLARE_TXT_PUB_READ_U(64, "%#018llx\n", 20);
+
+#define DECLARE_TXT_FOPS(reg_name, reg_offset, reg_size)		\
+static ssize_t txt_##reg_name##_read(struct file *flip,			\
+		char __user *buf, size_t read_len, loff_t *read_offset)	\
+{									\
+	return txt_pub_read_u##reg_size(reg_offset, read_offset,	\
+			read_len, buf);					\
+}									\
+static const struct file_operations reg_name##_ops = {			\
+	.read = txt_##reg_name##_read,					\
+}
+
+DECLARE_TXT_FOPS(sts, TXT_CR_STS, 64);
+DECLARE_TXT_FOPS(ests, TXT_CR_ESTS, 8);
+DECLARE_TXT_FOPS(errorcode, TXT_CR_ERRORCODE, 32);
+DECLARE_TXT_FOPS(didvid, TXT_CR_DIDVID, 64);
+DECLARE_TXT_FOPS(e2sts, TXT_CR_E2STS, 64);
+DECLARE_TXT_FOPS(ver_emif, TXT_CR_VER_EMIF, 32);
+DECLARE_TXT_FOPS(scratchpad, TXT_CR_SCRATCHPAD, 64);
+
+/*
+ * Securityfs exposure
+ */
+struct memfile {
+	char *name;
+	void *addr;
+	size_t size;
+};
+
+static struct memfile sl_evtlog = {"eventlog", NULL, 0};
+static void *txt_heap;
+static struct txt_heap_event_log_pointer2_1_element *evtlog21;
+static DEFINE_MUTEX(sl_evt_log_mutex);
+
+static ssize_t sl_evtlog_read(struct file *file, char __user *buf,
+			      size_t count, loff_t *pos)
+{
+	ssize_t size;
+
+	if (!sl_evtlog.addr)
+		return 0;
+
+	mutex_lock(&sl_evt_log_mutex);
+	size = simple_read_from_buffer(buf, count, pos, sl_evtlog.addr,
+				       sl_evtlog.size);
+	mutex_unlock(&sl_evt_log_mutex);
+
+	return size;
+}
+
+static ssize_t sl_evtlog_write(struct file *file, const char __user *buf,
+			       size_t datalen, loff_t *ppos)
+{
+	ssize_t result;
+	char *data;
+
+	if (!sl_evtlog.addr)
+		return 0;
+
+	/* No partial writes. */
+	result = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	data = memdup_user(buf, datalen);
+	if (IS_ERR(data)) {
+		result = PTR_ERR(data);
+		goto out;
+	}
+
+	mutex_lock(&sl_evt_log_mutex);
+	if (evtlog21)
+		result = tpm2_log_event(evtlog21, sl_evtlog.addr,
+					sl_evtlog.size, datalen, data);
+	else
+		result = tpm_log_event(sl_evtlog.addr, sl_evtlog.size,
+				       datalen, data);
+	mutex_unlock(&sl_evt_log_mutex);
+
+	kfree(data);
+out:
+	return result;
+}
+
+static const struct file_operations sl_evtlog_ops = {
+	.read = sl_evtlog_read,
+	.write = sl_evtlog_write,
+	.llseek	= default_llseek,
+};
+
+struct sfs_file {
+	const char *name;
+	const struct file_operations *fops;
+};
+
+#define SL_TXT_ENTRY_COUNT	7
+static const struct sfs_file sl_txt_files[] = {
+	{ "sts", &sts_ops },
+	{ "ests", &ests_ops },
+	{ "errorcode", &errorcode_ops },
+	{ "didvid", &didvid_ops },
+	{ "ver_emif", &ver_emif_ops },
+	{ "scratchpad", &scratchpad_ops },
+	{ "e2sts", &e2sts_ops }
+};
+
+/* sysfs file handles */
+static struct dentry *slaunch_dir;
+static struct dentry *event_file;
+static struct dentry *txt_dir;
+static struct dentry *txt_entries[SL_TXT_ENTRY_COUNT];
+
+static long slaunch_expose_securityfs(void)
+{
+	long ret = 0;
+	int i;
+
+	slaunch_dir = securityfs_create_dir("slaunch", NULL);
+	if (IS_ERR(slaunch_dir))
+		return PTR_ERR(slaunch_dir);
+
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		txt_dir = securityfs_create_dir("txt", slaunch_dir);
+		if (IS_ERR(txt_dir)) {
+			ret = PTR_ERR(txt_dir);
+			goto remove_slaunch;
+		}
+
+		for (i = 0; i < ARRAY_SIZE(sl_txt_files); i++) {
+			txt_entries[i] = securityfs_create_file(
+						sl_txt_files[i].name, 0440,
+						txt_dir, NULL,
+						sl_txt_files[i].fops);
+			if (IS_ERR(txt_entries[i])) {
+				ret = PTR_ERR(txt_entries[i]);
+				goto remove_files;
+			}
+		}
+	}
+
+	if (sl_evtlog.addr) {
+		event_file = securityfs_create_file(sl_evtlog.name, 0440,
+						    slaunch_dir, NULL,
+						    &sl_evtlog_ops);
+		if (IS_ERR(event_file)) {
+			ret = PTR_ERR(event_file);
+			goto remove_files;
+		}
+	}
+
+	return 0;
+
+remove_files:
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		while (--i >= 0)
+			securityfs_remove(txt_entries[i]);
+		securityfs_remove(txt_dir);
+	}
+
+remove_slaunch:
+	securityfs_remove(slaunch_dir);
+
+	return ret;
+}
+
+static void slaunch_teardown_securityfs(void)
+{
+	int i;
+
+	securityfs_remove(event_file);
+	if (sl_evtlog.addr) {
+		memunmap(sl_evtlog.addr);
+		sl_evtlog.addr = NULL;
+	}
+	sl_evtlog.size = 0;
+
+	if (slaunch_get_flags() & SL_FLAG_ARCH_TXT) {
+		for (i = 0; i < ARRAY_SIZE(sl_txt_files); i++)
+			securityfs_remove(txt_entries[i]);
+
+		securityfs_remove(txt_dir);
+
+		if (txt_heap) {
+			memunmap(txt_heap);
+			txt_heap = NULL;
+		}
+	}
+
+	securityfs_remove(slaunch_dir);
+}
+
+static void slaunch_intel_evtlog(void __iomem *txt)
+{
+	struct slr_entry_log_info *log_info;
+	struct txt_os_mle_data *params;
+	struct slr_table *slrt;
+	void *os_sinit_data;
+	u64 base, size;
+
+	memcpy_fromio(&base, txt + TXT_CR_HEAP_BASE, sizeof(base));
+	memcpy_fromio(&size, txt + TXT_CR_HEAP_SIZE, sizeof(size));
+
+	/* now map TXT heap */
+	txt_heap = memremap(base, size, MEMREMAP_WB);
+	if (!txt_heap)
+		slaunch_txt_reset(txt, "Error failed to memremap TXT heap\n",
+				  SL_ERROR_HEAP_MAP);
+
+	params = (struct txt_os_mle_data *)txt_os_mle_data_start(txt_heap);
+
+	/* Get the SLRT and remap it */
+	slrt = memremap(params->slrt, sizeof(*slrt), MEMREMAP_WB);
+	if (!slrt)
+		slaunch_txt_reset(txt, "Error failed to memremap SLR Table\n",
+				  SL_ERROR_SLRT_MAP);
+	size = slrt->size;
+	memunmap(slrt);
+
+	slrt = memremap(params->slrt, size, MEMREMAP_WB);
+	if (!slrt)
+		slaunch_txt_reset(txt, "Error failed to memremap SLR Table\n",
+				  SL_ERROR_SLRT_MAP);
+
+	log_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO);
+	if (!log_info)
+		slaunch_txt_reset(txt, "Error failed to memremap SLR Table\n",
+				  SL_ERROR_SLRT_MISSING_ENTRY);
+
+	sl_evtlog.size = log_info->size;
+	sl_evtlog.addr = memremap(log_info->addr, log_info->size,
+				  MEMREMAP_WB);
+	if (!sl_evtlog.addr)
+		slaunch_txt_reset(txt, "Error failed to memremap TPM event log\n",
+				  SL_ERROR_EVENTLOG_MAP);
+
+	memunmap(slrt);
+
+	/* Determine if this is TPM 1.2 or 2.0 event log */
+	if (memcmp(sl_evtlog.addr + sizeof(struct tcg_pcr_event),
+		    TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
+		return; /* looks like it is not 2.0 */
+
+	/* For TPM 2.0 logs, the extended heap element must be located */
+	os_sinit_data = txt_os_sinit_data_start(txt_heap);
+
+	evtlog21 = tpm2_find_log2_1_element(os_sinit_data);
+
+	/*
+	 * If this fails, things are in really bad shape. Any attempt to write
+	 * events to the log will fail.
+	 */
+	if (!evtlog21)
+		slaunch_txt_reset(txt, "Error failed to find TPM20 event log element\n",
+				  SL_ERROR_TPM_INVALID_LOG20);
+}
+
+static void slaunch_tpm2_extend_event(struct tpm_chip *tpm, void __iomem *txt,
+				      struct tcg_pcr_event2_head *event)
+{
+	u16 *alg_id_field = (u16 *)((u8 *)event + sizeof(struct tcg_pcr_event2_head));
+	struct tpm_digest *digests;
+	u8 *dptr;
+	u32 i, j;
+	int ret;
+
+	digests = kcalloc(tpm->nr_allocated_banks, sizeof(*digests),
+			  GFP_KERNEL);
+	if (!digests)
+		slaunch_txt_reset(txt, "Failed to allocate array of digests\n",
+				  SL_ERROR_GENERIC);
+
+	for (i = 0; i < tpm->nr_allocated_banks; i++)
+		digests[i].alg_id = tpm->allocated_banks[i].alg_id;
+
+	/* Early SL code ensured there was a max count of 2 digests */
+	for (i = 0; i < event->count; i++) {
+		dptr = (u8 *)alg_id_field + sizeof(u16);
+
+		for (j = 0; j < tpm->nr_allocated_banks; j++) {
+			if (digests[j].alg_id != *alg_id_field)
+				continue;
+
+			switch (digests[j].alg_id) {
+			case TPM_ALG_SHA256:
+				memcpy(&digests[j].digest[0], dptr,
+				       SHA256_DIGEST_SIZE);
+				alg_id_field = (u16 *)((u8 *)alg_id_field +
+					SHA256_DIGEST_SIZE + sizeof(u16));
+				break;
+			case TPM_ALG_SHA1:
+				memcpy(&digests[j].digest[0], dptr,
+				       SHA1_DIGEST_SIZE);
+				alg_id_field = (u16 *)((u8 *)alg_id_field +
+					SHA1_DIGEST_SIZE + sizeof(u16));
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	ret = tpm_pcr_extend(tpm, event->pcr_idx, digests);
+	if (ret) {
+		pr_err("Error extending TPM20 PCR, result: %d\n", ret);
+		slaunch_txt_reset(txt, "Failed to extend TPM20 PCR\n",
+				  SL_ERROR_TPM_EXTEND);
+	}
+
+	kfree(digests);
+}
+
+static void slaunch_tpm2_extend(struct tpm_chip *tpm, void __iomem *txt)
+{
+	struct tcg_pcr_event *event_header;
+	struct tcg_pcr_event2_head *event;
+	int start = 0, end = 0, size;
+
+	event_header = (struct tcg_pcr_event *)(sl_evtlog.addr +
+						evtlog21->first_record_offset);
+
+	/* Skip first TPM 1.2 event to get to first TPM 2.0 event */
+	event = (struct tcg_pcr_event2_head *)((u8 *)event_header +
+						sizeof(struct tcg_pcr_event) +
+						event_header->event_size);
+
+	while ((void  *)event < sl_evtlog.addr + evtlog21->next_record_offset) {
+		size = __calc_tpm2_event_size(event, event_header, false);
+		if (!size)
+			slaunch_txt_reset(txt, "TPM20 invalid event in event log\n",
+					  SL_ERROR_TPM_INVALID_EVENT);
+
+		/*
+		 * Marker events indicate where the Secure Launch early stub
+		 * started and ended adding post launch events.
+		 */
+		if (event->event_type == TXT_EVTYPE_SLAUNCH_END) {
+			end = 1;
+			break;
+		} else if (event->event_type == TXT_EVTYPE_SLAUNCH_START) {
+			start = 1;
+			goto next;
+		}
+
+		if (start)
+			slaunch_tpm2_extend_event(tpm, txt, event);
+
+next:
+		event = (struct tcg_pcr_event2_head *)((u8 *)event + size);
+	}
+
+	if (!start || !end)
+		slaunch_txt_reset(txt, "Missing start or end events for extending TPM20 PCRs\n",
+				  SL_ERROR_TPM_EXTEND);
+}
+
+static void slaunch_tpm_extend(struct tpm_chip *tpm, void __iomem *txt)
+{
+	struct tpm_event_log_header *event_header;
+	struct tcg_pcr_event *event;
+	struct tpm_digest digest;
+	int start = 0, end = 0;
+	int size, ret;
+
+	event_header = (struct tpm_event_log_header *)sl_evtlog.addr;
+	event = (struct tcg_pcr_event *)((u8 *)event_header +
+				sizeof(struct tpm_event_log_header));
+
+	while ((void  *)event < sl_evtlog.addr + event_header->next_event_offset) {
+		size = sizeof(struct tcg_pcr_event) + event->event_size;
+
+		/*
+		 * Marker events indicate where the Secure Launch early stub
+		 * started and ended adding post launch events.
+		 */
+		if (event->event_type == TXT_EVTYPE_SLAUNCH_END) {
+			end = 1;
+			break;
+		} else if (event->event_type == TXT_EVTYPE_SLAUNCH_START) {
+			start = 1;
+			goto next;
+		}
+
+		if (start) {
+			memset(&digest.digest[0], 0, TPM_MAX_DIGEST_SIZE);
+			digest.alg_id = TPM_ALG_SHA1;
+			memcpy(&digest.digest[0], &event->digest[0],
+			       SHA1_DIGEST_SIZE);
+
+			ret = tpm_pcr_extend(tpm, event->pcr_idx, &digest);
+			if (ret) {
+				pr_err("Error extending TPM12 PCR, result: %d\n", ret);
+				slaunch_txt_reset(txt, "Failed to extend TPM12 PCR\n",
+						  SL_ERROR_TPM_EXTEND);
+			}
+		}
+
+next:
+		event = (struct tcg_pcr_event *)((u8 *)event + size);
+	}
+
+	if (!start || !end)
+		slaunch_txt_reset(txt, "Missing start or end events for extending TPM12 PCRs\n",
+				  SL_ERROR_TPM_EXTEND);
+}
+
+static void slaunch_pcr_extend(void __iomem *txt)
+{
+	struct tpm_chip *tpm;
+
+	tpm = tpm_default_chip();
+	if (!tpm)
+		slaunch_txt_reset(txt, "Could not get default TPM chip\n",
+				  SL_ERROR_TPM_INIT);
+
+	if (!tpm_chip_set_default_locality(tpm, 2))
+		slaunch_txt_reset(txt, "Could not set TPM chip locality 2\n",
+				  SL_ERROR_TPM_INIT);
+
+	if (evtlog21)
+		slaunch_tpm2_extend(tpm, txt);
+	else
+		slaunch_tpm_extend(tpm, txt);
+
+	tpm_chip_set_default_locality(tpm, 0);
+}
+
+static int __init slaunch_module_init(void)
+{
+	void __iomem *txt;
+
+	/* Check to see if Secure Launch happened */
+	if ((slaunch_get_flags() & (SL_FLAG_ACTIVE|SL_FLAG_ARCH_TXT)) !=
+	    (SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT))
+		return 0;
+
+	txt = ioremap(TXT_PRIV_CONFIG_REGS_BASE, TXT_NR_CONFIG_PAGES *
+		      PAGE_SIZE);
+	if (!txt)
+		panic("Error ioremap of TXT priv registers\n");
+
+	/* Only Intel TXT is supported at this point */
+	slaunch_intel_evtlog(txt);
+	slaunch_pcr_extend(txt);
+	iounmap(txt);
+
+	return slaunch_expose_securityfs();
+}
+
+static void __exit slaunch_module_exit(void)
+{
+	slaunch_teardown_securityfs();
+}
+
+late_initcall(slaunch_module_init);
+__exitcall(slaunch_module_exit);
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:35 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:35 -0700
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-21-ross.philipson@oracle.com>

This support allows the DRTM launch to be initiated after an EFI stub
launch of the Linux kernel is done. This is accomplished by providing
a handler to jump to when a Secure Launch is in progress. This has to be
called after the EFI stub does Exit Boot Services.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 drivers/firmware/efi/libstub/efistub.h  |  8 ++
 drivers/firmware/efi/libstub/x86-stub.c | 98 +++++++++++++++++++++++++
 2 files changed, 106 insertions(+)

diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index d33ccbc4a2c6..baf42d6d0796 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -135,6 +135,14 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
 	*hi = upper_32_bits(data);
 }
 
+static inline
+void efi_set_u64_form(u32 lo, u32 hi, u64 *data)
+{
+	u64 upper = hi;
+
+	*data = lo | upper << 32;
+}
+
 /*
  * Allocation types for calls to boottime->allocate_pages.
  */
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index f8e465da344d..04786c1b3b5d 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -9,6 +9,8 @@
 #include <linux/efi.h>
 #include <linux/pci.h>
 #include <linux/stddef.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
 
 #include <asm/efi.h>
 #include <asm/e820/types.h>
@@ -923,6 +925,99 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
 	return efi_adjust_memory_range_protection(addr, kernel_text_size);
 }
 
+static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
+						 struct boot_params *boot_params)
+{
+	struct slr_entry_intel_info *txt_info;
+	struct slr_entry_policy *policy;
+	struct txt_os_mle_data *os_mle;
+	bool updated = false;
+	int i;
+
+	txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
+	if (!txt_info)
+		return false;
+
+	os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
+	if (!os_mle)
+		return false;
+
+	os_mle->boot_params_addr = (u64)boot_params;
+
+	policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
+	if (!policy)
+		return false;
+
+	for (i = 0; i < policy->nr_entries; i++) {
+		if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
+			policy->policy_entries[i].entity = (u64)boot_params;
+			updated = true;
+			break;
+		}
+	}
+
+	/*
+	 * If this is a PE entry into EFI stub the mocked up boot params will
+	 * be missing some of the setup header data needed for the second stage
+	 * of the Secure Launch boot.
+	 */
+	if (image) {
+		struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
+					    offsetof(struct boot_params, hdr));
+		u64 cmdline_ptr;
+
+		boot_params->hdr.setup_sects = hdr->setup_sects;
+		boot_params->hdr.syssize = hdr->syssize;
+		boot_params->hdr.version = hdr->version;
+		boot_params->hdr.loadflags = hdr->loadflags;
+		boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
+		boot_params->hdr.min_alignment = hdr->min_alignment;
+		boot_params->hdr.xloadflags = hdr->xloadflags;
+		boot_params->hdr.init_size = hdr->init_size;
+		boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
+		efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
+				 &cmdline_ptr);
+		boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
+	}
+
+	return updated;
+}
+
+static void efi_secure_launch(struct boot_params *boot_params)
+{
+	struct slr_entry_dl_info *dlinfo;
+	efi_guid_t guid = SLR_TABLE_GUID;
+	dl_handler_func handler_callback;
+	struct slr_table *slrt;
+
+	if (!IS_ENABLED(CONFIG_SECURE_LAUNCH))
+		return;
+
+	/*
+	 * The presence of this table indicated a Secure Launch
+	 * is being requested.
+	 */
+	slrt = (struct slr_table *)get_efi_config_table(guid);
+	if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
+		return;
+
+	/*
+	 * Since the EFI stub library creates its own boot_params on entry, the
+	 * SLRT and TXT heap have to be updated with this version.
+	 */
+	if (!efi_secure_launch_update_boot_params(slrt, boot_params))
+		return;
+
+	/* Jump through DL stub to initiate Secure Launch */
+	dlinfo = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
+
+	handler_callback = (dl_handler_func)dlinfo->dl_handler;
+
+	handler_callback(&dlinfo->bl_context);
+
+	unreachable();
+}
+
 static void __noreturn enter_kernel(unsigned long kernel_addr,
 				    struct boot_params *boot_params)
 {
@@ -1050,6 +1145,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
 		goto fail;
 	}
 
+	/* If a Secure Launch is in progress, this never returns */
+	efi_secure_launch(boot_params);
+
 	/*
 	 * Call the SEV init code while still running with the firmware's
 	 * GDT/IDT, so #VC exceptions will be handled by EFI.
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:15 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:15 -0700
Subject: [PATCH v10 00/20] x86: Trenchboot secure dynamic launch Linux kernel support
Message-ID: <20240826223835.3928819-1-ross.philipson@oracle.com>

The larger focus of the TrenchBoot project (https://github.com/TrenchBoot) is to
enhance the boot security and integrity in a unified manner. The first area of
focus has been on the Trusted Computing Group's Dynamic Launch for establishing
a hardware Root of Trust for Measurement, also know as DRTM (Dynamic Root of
Trust for Measurement). The project has been and continues to work on providing
a unified means to Dynamic Launch that is a cross-platform (Intel and AMD) and
cross-architecture (x86 and Arm), with our recent involvment in the upcoming
Arm DRTM specification. The order of introducing DRTM to the Linux kernel
follows the maturity of DRTM in the architectures. Intel's Trusted eXecution
Technology (TXT) is present today and only requires a preamble loader, e.g. a
boot loader, and an OS kernel that is TXT-aware. AMD DRTM implementation has
been present since the introduction of AMD-V but requires an additional
component that is AMD specific and referred to in the specification as the
Secure Loader, which the TrenchBoot project has an active prototype in
development. Finally Arm's implementation is in specification development stage
and the project is looking to support it when it becomes available.

This patchset provides detailed documentation of DRTM, the approach used for
adding the capbility, and relevant API/ABI documentation. In addition to the
documentation the patch set introduces Intel TXT support as the first platform
for Linux Secure Launch.

A quick note on terminology. The larger open source project itself is called
TrenchBoot, which is hosted on Github (links below). The kernel feature enabling
the use of Dynamic Launch technology is referred to as "Secure Launch" within
the kernel code. As such the prefixes sl_/SL_ or slaunch/SLAUNCH will be seen
in the code. The stub code discussed above is referred to as the SL stub.

Links:

The TrenchBoot project including documentation:

https://trenchboot.org

The TrenchBoot project on Github:

https://github.com/trenchboot

Intel TXT is documented in its own specification and in the SDM Instruction Set volume:

https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf
https://software.intel.com/en-us/articles/intel-sdm

AMD SKINIT is documented in the System Programming manual:

https://www.amd.com/system/files/TechDocs/24593.pdf

The TrenchBoot project provides a quick start guide to help get a system
up and running with Secure Launch for Linux:

https://github.com/TrenchBoot/documentation/blob/master/QUICKSTART.md

Patch set based on commit:

torvalds/master/b311c1b497e51a628aa89e7cb954481e5f9dced2

Thanks
Ross Philipson and Daniel P. Smith

Changes in v2:

 - Modified 32b entry code to prevent causing relocations in the compressed
   kernel.
 - Dropped patches for compressed kernel TPM PCR extender.
 - Modified event log code to insert log delimiter events and not rely
   on TPM access.
 - Stop extending PCRs in the early Secure Launch stub code.
 - Removed Kconfig options for hash algorithms and use the algorithms the
   ACM used.
 - Match Secure Launch measurement algorithm use to those reported in the
   TPM 2.0 event log.
 - Read the TPM events out of the TPM and extend them into the PCRs using
   the mainline TPM driver. This is done in the late initcall module.
 - Allow use of alternate PCR 19 and 20 for post ACM measurements.
 - Add Kconfig constraints needed by Secure Launch (disable KASLR
   and add x2apic dependency).
 - Fix testing of SL_FLAGS when determining if Secure Launch is active
   and the architecture is TXT.
 - Use SYM_DATA_START_LOCAL macros in early entry point code.
 - Security audit changes:
   - Validate buffers passed to MLE do not overlap the MLE and are
     properly laid out.
   - Validate buffers and memory regions used by the MLE are
     protected by IOMMU PMRs.
 - Force IOMMU to not use passthrough mode during a Secure Launch.
 - Prevent KASLR use during a Secure Launch.

Changes in v3:

 - Introduce x86 documentation patch to provide background, overview
   and configuration/ABI information for the Secure Launch kernel
   feature.
 - Remove the IOMMU patch with special cases for disabling IOMMU
   passthrough. Configuring the IOMMU is now a documentation matter
   in the previously mentioned new patch.
 - Remove special case KASLR disabling code. Configuring KASLR is now
   a documentation matter in the previously mentioned new patch.
 - Fix incorrect panic on TXT public register read.
 - Properly handle and measure setup_indirect bootparams in the early
   launch code.
 - Use correct compressed kernel image base address when testing buffers
   in the early launch stub code. This bug was introduced by the changes
   to avoid relocation in the compressed kernel.
 - Use CPUID feature bits instead of CPUID vendor strings to determine
   if SMX mode is supported and the system is Intel.
 - Remove early NMI re-enable on the BSP. This can be safely done later
   on the BSP after an IDT is setup.

Changes in v4:
 - Expand the cover letter to provide more context to the order that DRTM
   support will be added.
 - Removed debug tracing in TPM request locality funciton and fixed
   local variable declarations.
 - Fixed missing break in default case in slmodule.c.
 - Reworded commit messages in patches 1 and 2 per suggestions.

Changes in v5:
 - Comprehensive documentation rewrite.
 - Use boot param loadflags to communicate Secure Launch status to
   kernel proper.
 - Fix incorrect check of X86_FEATURE_BIT_SMX bit.
 - Rename the alternate details and authorities PCR support.
 - Refactor the securityfs directory and file setup in slmodule.c.
 - Misc. cleanup from internal code reviews.
 - Use reverse fir tree format for variables.

Changes in v6:
 - Support for the new Secure Launch Resourse Table that standardizes
   the information passed and forms the ABI between the pre and post
   launch code.
 - Support for booting Linux through the EFI stub entry point and
   then being able to do a Secure Launch once EFI stub is done and EBS
   is called.
 - Updates to the documentation to reflect the previous two items listed.

Changes in v7:
 - Switch to using MONITOR/MWAIT instead of NMIs to park the APs for
   later bringup by the SMP code.
 - Use static inline dummy functions instead of macros when the Secure
   Launch feature is disabled.
 - Move early SHA1 code to lib/crypto and pull it in from there.
 - Numerous formatting fixes from comments on LKML.
 - Remove efi-stub/DL stub patch temporarily for redesign/rework.

Changes in v8:
 - Reintroduce efi-stub Linux kernel booting through the dynamic launch
   stub (DL stub).
 - Add new approach to setting localities > 0 through kernel and sysfs
   interfaces in the TPM mainline driver.
 - General code cleanup from v7 post comments.

Changes in v9:
 - Updated DL stub support for recent changes to EFI stub in the kernel.
 - Added patches to fix locality changing support in the TPM driver
   (these patches originally were posted as a separate set).
 - Enhanced Secure Launch TPM locality 2 setting in the TPM driver.
 - Added locality setting support through sysfs for user land to access.
 - Split up SHA1 and SHA256 changes into separate patches and updated
   the commit messages to be more clear (per request from upstream
   review).
 - Fix Clang compile issues detected by kernel test robot.
 - Modifications to the Secure Launch Resource Table ABI:
   . Use flex arrays in table structures.
   . Update and move fields in tables to make everything 8b aligned.
   . Add 2 new DLME fields and a txt_heap address field.
   . Remove platform specific tables that are not defined yet (AMD/ARM).
 - Update Kconfig dependencies for Secure Launch with SHA1/SHA256/TPM.
 - Remove push/pop of rsi since boot params is now stored in r15.
 - Update outdated kernel documentation.
 - Misc. comment fixes for type-os and mispellings.

Changes in v10:
 - Removed patch #1 from previous set that forced the kernel_info
   section at a fixed offset.
 - Add changes from Ard Biesheuvel to use the link step to generate the
   proper relative offsets for the MLE header in the kernel_info
   section.
 - Fix sizes and alignment slightly in the SLR table. Add comments to
   the SLR header to indicate it is defined by the TrenchBoot project.
 - Remove incorrect extra pop instruction noted in the head_64.S
   changes.
 - Use the prefix tpm/tpm2 to distinguish between TPM versions as is
   done in the rest of the TPM related code.
 - Rework the TPM locality setting/reporting changes to use "default"
   locality as opposed to "preferred". Remove uneeded extra locality
   function in the TPM interface (call the chip function directly).
 - Adopt comment/documentation changes to code and commit message per
   requests from the community.
 - Use u64 for the boot params physical address to avoid truncating
   pointers during casts.
 - Split adding of new MSR registers into its own patch.
 - Attempt to further address justification for using SHA-1 algorithm.
   Pick up some code suggestions for the SHA-1 patch.
 - Introduct slaunch_is_txt_launch() function per Jarkko Sakkinen's
   suggestion.
 - Implement minor changes to the EFI stub code per suggestions.

Daniel P. Smith (7):
  Documentation/x86: Secure Launch kernel documentation
  x86: Add early SHA-1 support for Secure Launch early measurements
  x86: Add early SHA-256 support for Secure Launch early measurements
  tpm: Protect against locality counter underflow
  tpm: Ensure tpm is in known state at startup
  tpm: Make locality requests return consistent values
  x86: Secure Launch late initcall platform module

Ross Philipson (13):
  x86: Secure Launch Kconfig
  x86: Secure Launch Resource Table header file
  x86: Secure Launch main header file
  x86/msr: Add variable MTRR base/mask and x2apic ID registers
  x86/boot: Place TXT MLE header in the kernel_info section
  x86: Secure Launch kernel early boot stub
  x86: Secure Launch kernel late boot stub
  x86: Secure Launch SMP bringup support
  kexec: Secure Launch kexec SEXIT support
  x86/reboot: Secure Launch SEXIT support on reboot paths
  tpm: Add ability to set the default locality the TPM chip uses
  tpm: Add sysfs interface to allow setting and querying the default
    locality
  x86/efi: EFI stub DRTM launch support for Secure Launch

 Documentation/arch/x86/boot.rst               |  21 +
 Documentation/security/index.rst              |   1 +
 .../security/launch-integrity/index.rst       |  11 +
 .../security/launch-integrity/principles.rst  | 320 ++++++++
 .../secure_launch_details.rst                 | 587 ++++++++++++++
 .../secure_launch_overview.rst                | 227 ++++++
 arch/x86/Kconfig                              |  11 +
 arch/x86/boot/compressed/Makefile             |   3 +
 arch/x86/boot/compressed/head_64.S            |  29 +
 arch/x86/boot/compressed/kernel_info.S        |  50 +-
 arch/x86/boot/compressed/sha1.c               |   6 +
 arch/x86/boot/compressed/sha256.c             |   6 +
 arch/x86/boot/compressed/sl_main.c            | 588 ++++++++++++++
 arch/x86/boot/compressed/sl_stub.S            | 726 ++++++++++++++++++
 arch/x86/boot/compressed/vmlinux.lds.S        |   7 +
 arch/x86/include/asm/msr-index.h              |   5 +
 arch/x86/include/asm/realmode.h               |   3 +
 arch/x86/include/uapi/asm/bootparam.h         |   1 +
 arch/x86/kernel/Makefile                      |   2 +
 arch/x86/kernel/asm-offsets.c                 |  20 +
 arch/x86/kernel/reboot.c                      |  10 +
 arch/x86/kernel/setup.c                       |   3 +
 arch/x86/kernel/slaunch.c                     | 596 ++++++++++++++
 arch/x86/kernel/slmodule.c                    | 509 ++++++++++++
 arch/x86/kernel/smpboot.c                     |  43 +-
 arch/x86/realmode/init.c                      |   3 +
 arch/x86/realmode/rm/header.S                 |   3 +
 arch/x86/realmode/rm/trampoline_64.S          |  32 +
 drivers/char/tpm/tpm-chip.c                   |  24 +-
 drivers/char/tpm/tpm-sysfs.c                  |  30 +
 drivers/char/tpm/tpm_tis_core.c               |  27 +-
 drivers/firmware/efi/libstub/efistub.h        |   8 +
 drivers/firmware/efi/libstub/x86-stub.c       |  98 +++
 drivers/iommu/intel/dmar.c                    |   4 +
 include/crypto/sha1.h                         |   1 +
 include/linux/slaunch.h                       | 548 +++++++++++++
 include/linux/slr_table.h                     | 276 +++++++
 include/linux/tpm.h                           |  10 +
 kernel/kexec_core.c                           |   4 +
 lib/crypto/sha1.c                             |  82 ++
 40 files changed, 4922 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/security/launch-integrity/index.rst
 create mode 100644 Documentation/security/launch-integrity/principles.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_details.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_overview.rst
 create mode 100644 arch/x86/boot/compressed/sha1.c
 create mode 100644 arch/x86/boot/compressed/sha256.c
 create mode 100644 arch/x86/boot/compressed/sl_main.c
 create mode 100644 arch/x86/boot/compressed/sl_stub.S
 create mode 100644 arch/x86/kernel/slaunch.c
 create mode 100644 arch/x86/kernel/slmodule.c
 create mode 100644 include/linux/slaunch.h
 create mode 100644 include/linux/slr_table.h

-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:38:19 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 15:38:19 -0700
Subject: [PATCH v10 04/20] x86: Secure Launch main header file
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-5-ross.philipson@oracle.com>

Introduce the main Secure Launch header file used in the early SL stub
and the early setup code.

Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
---
 include/linux/slaunch.h | 548 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 548 insertions(+)
 create mode 100644 include/linux/slaunch.h

diff --git a/include/linux/slaunch.h b/include/linux/slaunch.h
new file mode 100644
index 000000000000..efb1235b3e1b
--- /dev/null
+++ b/include/linux/slaunch.h
@@ -0,0 +1,548 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Main Secure Launch header file.
+ *
+ * Copyright (c) 2024 Apertus Solutions, LLC
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+
+#ifndef _LINUX_SLAUNCH_H
+#define _LINUX_SLAUNCH_H
+
+/*
+ * Secure Launch Defined State Flags
+ */
+#define SL_FLAG_ACTIVE		0x00000001
+#define SL_FLAG_ARCH_TXT	0x00000002
+
+/*
+ * Secure Launch CPU Type
+ */
+#define SL_CPU_INTEL	1
+
+#define __SL32_CS	0x0008
+#define __SL32_DS	0x0010
+
+/*
+ * Intel Safer Mode Extensions (SMX)
+ *
+ * Intel SMX provides a programming interface to establish a Measured Launched
+ * Environment (MLE). The measurement and protection mechanisms supported by the
+ * capabilities of an Intel Trusted Execution Technology (TXT) platform. SMX is
+ * the processor?s programming interface in an Intel TXT platform.
+ *
+ * See:
+ *   Intel SDM Volume 2 - 6.1 "Safer Mode Extensions Reference"
+ *   Intel Trusted Execution Technology - Measured Launch Environment Developer?s Guide
+ */
+
+/*
+ * SMX GETSEC Leaf Functions
+ */
+#define SMX_X86_GETSEC_SEXIT	5
+#define SMX_X86_GETSEC_SMCTRL	7
+#define SMX_X86_GETSEC_WAKEUP	8
+
+/*
+ * Intel Trusted Execution Technology MMIO Registers Banks
+ */
+#define TXT_PUB_CONFIG_REGS_BASE	0xfed30000
+#define TXT_PRIV_CONFIG_REGS_BASE	0xfed20000
+#define TXT_NR_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE - \
+				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
+
+/*
+ * Intel Trusted Execution Technology (TXT) Registers
+ */
+#define TXT_CR_STS			0x0000
+#define TXT_CR_ESTS			0x0008
+#define TXT_CR_ERRORCODE		0x0030
+#define TXT_CR_CMD_RESET		0x0038
+#define TXT_CR_CMD_CLOSE_PRIVATE	0x0048
+#define TXT_CR_DIDVID			0x0110
+#define TXT_CR_VER_EMIF			0x0200
+#define TXT_CR_CMD_UNLOCK_MEM_CONFIG	0x0218
+#define TXT_CR_SINIT_BASE		0x0270
+#define TXT_CR_SINIT_SIZE		0x0278
+#define TXT_CR_MLE_JOIN			0x0290
+#define TXT_CR_HEAP_BASE		0x0300
+#define TXT_CR_HEAP_SIZE		0x0308
+#define TXT_CR_SCRATCHPAD		0x0378
+#define TXT_CR_CMD_OPEN_LOCALITY1	0x0380
+#define TXT_CR_CMD_CLOSE_LOCALITY1	0x0388
+#define TXT_CR_CMD_OPEN_LOCALITY2	0x0390
+#define TXT_CR_CMD_CLOSE_LOCALITY2	0x0398
+#define TXT_CR_CMD_SECRETS		0x08e0
+#define TXT_CR_CMD_NO_SECRETS		0x08e8
+#define TXT_CR_E2STS			0x08f0
+
+/* TXT default register value */
+#define TXT_REGVALUE_ONE		0x1ULL
+
+/* TXTCR_STS status bits */
+#define TXT_SENTER_DONE_STS		BIT(0)
+#define TXT_SEXIT_DONE_STS		BIT(1)
+
+/*
+ * SINIT/MLE Capabilities Field Bit Definitions
+ */
+#define TXT_SINIT_MLE_CAP_WAKE_GETSEC	0
+#define TXT_SINIT_MLE_CAP_WAKE_MONITOR	1
+
+/*
+ * OS/MLE Secure Launch Specific Definitions
+ */
+#define TXT_OS_MLE_STRUCT_VERSION	1
+#define TXT_OS_MLE_MAX_VARIABLE_MTRRS	32
+
+/*
+ * TXT Heap Table Enumeration
+ */
+#define TXT_BIOS_DATA_TABLE		1
+#define TXT_OS_MLE_DATA_TABLE		2
+#define TXT_OS_SINIT_DATA_TABLE		3
+#define TXT_SINIT_MLE_DATA_TABLE	4
+#define TXT_SINIT_TABLE_MAX		TXT_SINIT_MLE_DATA_TABLE
+
+/*
+ * Secure Launch Defined Error Codes used in MLE-initiated TXT resets.
+ *
+ * TXT Specification
+ * Appendix I ACM Error Codes
+ */
+#define SL_ERROR_GENERIC		0xc0008001
+#define SL_ERROR_TPM_INIT		0xc0008002
+#define SL_ERROR_TPM_INVALID_LOG20	0xc0008003
+#define SL_ERROR_TPM_LOGGING_FAILED	0xc0008004
+#define SL_ERROR_REGION_STRADDLE_4GB	0xc0008005
+#define SL_ERROR_TPM_EXTEND		0xc0008006
+#define SL_ERROR_MTRR_INV_VCNT		0xc0008007
+#define SL_ERROR_MTRR_INV_DEF_TYPE	0xc0008008
+#define SL_ERROR_MTRR_INV_BASE		0xc0008009
+#define SL_ERROR_MTRR_INV_MASK		0xc000800a
+#define SL_ERROR_MSR_INV_MISC_EN	0xc000800b
+#define SL_ERROR_INV_AP_INTERRUPT	0xc000800c
+#define SL_ERROR_INTEGER_OVERFLOW	0xc000800d
+#define SL_ERROR_HEAP_WALK		0xc000800e
+#define SL_ERROR_HEAP_MAP		0xc000800f
+#define SL_ERROR_REGION_ABOVE_4GB	0xc0008010
+#define SL_ERROR_HEAP_INVALID_DMAR	0xc0008011
+#define SL_ERROR_HEAP_DMAR_SIZE		0xc0008012
+#define SL_ERROR_HEAP_DMAR_MAP		0xc0008013
+#define SL_ERROR_HI_PMR_BASE		0xc0008014
+#define SL_ERROR_HI_PMR_SIZE		0xc0008015
+#define SL_ERROR_LO_PMR_BASE		0xc0008016
+#define SL_ERROR_LO_PMR_MLE		0xc0008017
+#define SL_ERROR_INITRD_TOO_BIG		0xc0008018
+#define SL_ERROR_HEAP_ZERO_OFFSET	0xc0008019
+#define SL_ERROR_WAKE_BLOCK_TOO_SMALL	0xc000801a
+#define SL_ERROR_MLE_BUFFER_OVERLAP	0xc000801b
+#define SL_ERROR_BUFFER_BEYOND_PMR	0xc000801c
+#define SL_ERROR_OS_SINIT_BAD_VERSION	0xc000801d
+#define SL_ERROR_EVENTLOG_MAP		0xc000801e
+#define SL_ERROR_TPM_NUMBER_ALGS	0xc000801f
+#define SL_ERROR_TPM_UNKNOWN_DIGEST	0xc0008020
+#define SL_ERROR_TPM_INVALID_EVENT	0xc0008021
+#define SL_ERROR_INVALID_SLRT		0xc0008022
+#define SL_ERROR_SLRT_MISSING_ENTRY	0xc0008023
+#define SL_ERROR_SLRT_MAP		0xc0008024
+
+/*
+ * Secure Launch Defined Limits
+ */
+#define TXT_MAX_CPUS		512
+#define TXT_BOOT_STACK_SIZE	128
+
+/*
+ * Secure Launch event log entry type. The TXT specification defines the
+ * base event value as 0x400 for DRTM values.
+ */
+#define TXT_EVTYPE_BASE			0x400
+#define TXT_EVTYPE_SLAUNCH		(TXT_EVTYPE_BASE + 0x102)
+#define TXT_EVTYPE_SLAUNCH_START	(TXT_EVTYPE_BASE + 0x103)
+#define TXT_EVTYPE_SLAUNCH_END		(TXT_EVTYPE_BASE + 0x104)
+
+/*
+ * MLE scratch area offsets
+ */
+#define SL_SCRATCH_AP_EBX		0
+#define SL_SCRATCH_AP_JMP_OFFSET	4
+#define SL_SCRATCH_AP_STACKS_OFFSET	8
+
+#ifndef __ASSEMBLY__
+
+#include <linux/io.h>
+#include <linux/tpm.h>
+#include <linux/tpm_eventlog.h>
+
+/*
+ * Secure Launch AP stack and monitor block
+ */
+struct sl_ap_stack_and_monitor {
+	u32 monitor;
+	u32 cache_pad[15];
+	u32 stack_pad[15];
+	u32 apicid;
+} __packed;
+
+/*
+ * Secure Launch AP wakeup information fetched in SMP boot code.
+ */
+struct sl_ap_wake_info {
+	u32 ap_wake_block;
+	u32 ap_wake_block_size;
+	u32 ap_jmp_offset;
+	u32 ap_stacks_offset;
+};
+
+/*
+ * TXT heap extended data elements.
+ */
+struct txt_heap_ext_data_element {
+	u32 type;
+	u32 size;
+	/* Data */
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_END			0
+
+struct txt_heap_end_element {
+	u32 type;
+	u32 size;
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR		5
+
+struct txt_heap_event_log_element {
+	u64 event_log_phys_addr;
+} __packed;
+
+#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1	8
+
+struct txt_heap_event_log_pointer2_1_element {
+	u64 phys_addr;
+	u32 allocated_event_container_size;
+	u32 first_record_offset;
+	u32 next_record_offset;
+} __packed;
+
+/*
+ * Secure Launch defined OS/MLE TXT Heap table
+ */
+struct txt_os_mle_data {
+	u32 version;
+	u32 reserved;
+	u64 boot_params_addr;
+	u64 slrt;
+	u64 txt_info;
+	u32 ap_wake_block;
+	u32 ap_wake_block_size;
+	u8 mle_scratch[64];
+} __packed;
+
+/*
+ * TXT specification defined BIOS data TXT Heap table
+ */
+struct txt_bios_data {
+	u32 version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */
+	u32 bios_sinit_size;
+	u64 reserved1;
+	u64 reserved2;
+	u32 num_logical_procs;
+	/* Versions >= 5 with updates in version 6 */
+	u32 sinit_flags;
+	u32 mle_flags;
+	/* Versions >= 4 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT specification defined OS/SINIT TXT Heap table
+ */
+struct txt_os_sinit_data {
+	u32 version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */
+	u32 flags;
+	u64 mle_ptab;
+	u64 mle_size;
+	u64 mle_hdr_base;
+	u64 vtd_pmr_lo_base;
+	u64 vtd_pmr_lo_size;
+	u64 vtd_pmr_hi_base;
+	u64 vtd_pmr_hi_size;
+	u64 lcp_po_base;
+	u64 lcp_po_size;
+	u32 capabilities;
+	/* Version = 5 */
+	u64 efi_rsdt_ptr;
+	/* Versions >= 6 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT specification defined SINIT/MLE TXT Heap table
+ */
+struct txt_sinit_mle_data {
+	u32 version;             /* Current values are 6 through 9 */
+	/* Versions <= 8 */
+	u8 bios_acm_id[20];
+	u32 edx_senter_flags;
+	u64 mseg_valid;
+	u8 sinit_hash[20];
+	u8 mle_hash[20];
+	u8 stm_hash[20];
+	u8 lcp_policy_hash[20];
+	u32 lcp_policy_control;
+	/* Versions >= 7 */
+	u32 rlp_wakeup_addr;
+	u32 reserved;
+	u32 num_of_sinit_mdrs;
+	u32 sinit_mdrs_table_offset;
+	u32 sinit_vtd_dmar_table_size;
+	u32 sinit_vtd_dmar_table_offset;
+	/* Versions >= 8 */
+	u32 processor_scrtm_status;
+	/* Versions >= 9 */
+	/* Ext Data Elements */
+} __packed;
+
+/*
+ * TXT data reporting structure for memory types
+ */
+struct txt_sinit_memory_descriptor_record {
+	u64 address;
+	u64 length;
+	u8 type;
+	u8 reserved[7];
+} __packed;
+
+/*
+ * TXT data structure used by a responsive local processor (RLP) to start
+ * execution in response to a GETSEC[WAKEUP].
+ */
+struct smx_rlp_mle_join {
+	u32 rlp_gdt_limit;
+	u32 rlp_gdt_base;
+	u32 rlp_seg_sel;     /* cs (ds, es, ss are seg_sel+8) */
+	u32 rlp_entry_point; /* phys addr */
+} __packed;
+
+/*
+ * TPM event log structures defined in both the TXT specification and
+ * the TCG documentation.
+ */
+#define TPM_EVTLOG_SIGNATURE "TXT Event Container"
+
+struct tpm_event_log_header {
+	char signature[20];
+	char reserved[12];
+	u8 container_ver_major;
+	u8 container_ver_minor;
+	u8 pcr_event_ver_major;
+	u8 pcr_event_ver_minor;
+	u32 container_size;
+	u32 pcr_events_offset;
+	u32 next_event_offset;
+	/* PCREvents[] */
+} __packed;
+
+/*
+ * Functions to extract data from the Intel TXT Heap Memory. The layout
+ * of the heap is as follows:
+ *  +----------------------------+
+ *  | Size Bios Data table (u64) |
+ *  +----------------------------+
+ *  | Bios Data table            |
+ *  +----------------------------+
+ *  | Size OS MLE table (u64)    |
+ *  +----------------------------+
+ *  | OS MLE table               |
+ *  +--------------------------- +
+ *  | Size OS SINIT table (u64)  |
+ *  +----------------------------+
+ *  | OS SINIT table             |
+ *  +----------------------------+
+ *  | Size SINIT MLE table (u64) |
+ *  +----------------------------+
+ *  | SINIT MLE table            |
+ *  +----------------------------+
+ *
+ *  NOTE: the table size fields include the 8 byte size field itself.
+ */
+static inline u64 txt_bios_data_size(void *heap)
+{
+	return *((u64 *)heap);
+}
+
+static inline void *txt_bios_data_start(void *heap)
+{
+	return heap + sizeof(u64);
+}
+
+static inline u64 txt_os_mle_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap)));
+}
+
+static inline void *txt_os_mle_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) + sizeof(u64);
+}
+
+static inline u64 txt_os_sinit_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap) +
+			txt_os_mle_data_size(heap)));
+}
+
+static inline void *txt_os_sinit_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) +
+		txt_os_mle_data_size(heap) + sizeof(u64);
+}
+
+static inline u64 txt_sinit_mle_data_size(void *heap)
+{
+	return *((u64 *)(heap + txt_bios_data_size(heap) +
+			txt_os_mle_data_size(heap) +
+			txt_os_sinit_data_size(heap)));
+}
+
+static inline void *txt_sinit_mle_data_start(void *heap)
+{
+	return heap + txt_bios_data_size(heap) +
+		txt_os_mle_data_size(heap) +
+		txt_os_sinit_data_size(heap) + sizeof(u64);
+}
+
+#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
+
+/*
+ * TPM event logging functions.
+ */
+static inline struct txt_heap_event_log_pointer2_1_element*
+tpm2_find_log2_1_element(struct txt_os_sinit_data *os_sinit_data)
+{
+	struct txt_heap_ext_data_element *ext_elem;
+
+	/* The extended element array as at the end of this table */
+	ext_elem = (struct txt_heap_ext_data_element *)
+		((u8 *)os_sinit_data + sizeof(struct txt_os_sinit_data));
+
+	while (ext_elem->type != TXT_HEAP_EXTDATA_TYPE_END) {
+		if (ext_elem->type ==
+		    TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1) {
+			return (struct txt_heap_event_log_pointer2_1_element *)
+				((u8 *)ext_elem +
+					sizeof(struct txt_heap_ext_data_element));
+		}
+		ext_elem =
+			(struct txt_heap_ext_data_element *)
+			((u8 *)ext_elem + ext_elem->size);
+	}
+
+	return NULL;
+}
+
+static inline int tpm_log_event(void *evtlog_base, u32 evtlog_size,
+				u32 event_size, void *event)
+{
+	struct tpm_event_log_header *evtlog =
+		(struct tpm_event_log_header *)evtlog_base;
+
+	if (memcmp(evtlog->signature, TPM_EVTLOG_SIGNATURE,
+		   sizeof(TPM_EVTLOG_SIGNATURE)))
+		return -EINVAL;
+
+	if (evtlog->container_size > evtlog_size)
+		return -EINVAL;
+
+	if (evtlog->next_event_offset + event_size > evtlog->container_size)
+		return -E2BIG;
+
+	memcpy(evtlog_base + evtlog->next_event_offset, event, event_size);
+	evtlog->next_event_offset += event_size;
+
+	return 0;
+}
+
+static inline int tpm2_log_event(struct txt_heap_event_log_pointer2_1_element *elem,
+				 void *evtlog_base, u32 evtlog_size,
+				 u32 event_size, void *event)
+{
+	struct tcg_pcr_event *header =
+		(struct tcg_pcr_event *)evtlog_base;
+
+	/* Has to be at least big enough for the signature */
+	if (header->event_size < sizeof(TCG_SPECID_SIG))
+		return -EINVAL;
+
+	if (memcmp((u8 *)header + sizeof(struct tcg_pcr_event),
+		   TCG_SPECID_SIG, sizeof(TCG_SPECID_SIG)))
+		return -EINVAL;
+
+	if (elem->allocated_event_container_size > evtlog_size)
+		return -EINVAL;
+
+	if (elem->next_record_offset + event_size >
+	    elem->allocated_event_container_size)
+		return -E2BIG;
+
+	memcpy(evtlog_base + elem->next_record_offset, event, event_size);
+	elem->next_record_offset += event_size;
+
+	return 0;
+}
+
+/*
+ * External functions avalailable in mainline kernel.
+ */
+void slaunch_setup_txt(void);
+void slaunch_fixup_jump_vector(void);
+u32 slaunch_get_flags(void);
+struct sl_ap_wake_info *slaunch_get_ap_wake_info(void);
+struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar);
+void __noreturn slaunch_txt_reset(void __iomem *txt,
+					 const char *msg, u64 error);
+void slaunch_finalize(int do_sexit);
+
+static inline bool slaunch_is_txt_launch(void)
+{
+	u32 mask =  SL_FLAG_ACTIVE | SL_FLAG_ARCH_TXT;
+
+	return (slaunch_get_flags() & mask) == mask;
+}
+
+#else
+
+static inline void slaunch_setup_txt(void)
+{
+}
+
+static inline void slaunch_fixup_jump_vector(void)
+{
+}
+
+static inline u32 slaunch_get_flags(void)
+{
+	return 0;
+}
+
+static inline struct acpi_table_header *slaunch_get_dmar_table(struct acpi_table_header *dmar)
+{
+	return dmar;
+}
+
+static inline void slaunch_finalize(int do_sexit)
+{
+}
+
+static inline bool slaunch_is_txt_launch(void)
+{
+	return false;
+}
+
+#endif /* !IS_ENABLED(CONFIG_SECURE_LAUNCH) */
+
+#endif /* !__ASSEMBLY */
+
+#endif /* _LINUX_SLAUNCH_H */
-- 
2.39.3



From dyoung at redhat.com  Mon Aug 26 18:39:10 2024
From: dyoung at redhat.com (Dave Young)
Date: Tue, 27 Aug 2024 09:39:10 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com> <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
Message-ID: <CALu+AoQdKyeJBRzucdai5+KihMMOdWJeg0nAmw4K_Pd4DRt3_Q@mail.gmail.com>

On Mon, 26 Aug 2024 at 22:24, Tom Lendacky <thomas.lendacky at amd.com> wrote:
>
> On 8/25/24 21:44, Baoquan He wrote:
> > Recently, it's reported that kdump kernel is broken during bootup on
> > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > system when enabling CONFIG_IMA_KEXEC.
> >
> > --------------------------------------------------
> >  ima: No TPM chip found, activating TPM-bypass!
> >  Loading compiled-in module X.509 certificates
> >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> >  ima: Allocated hash algorithm: sha256
> >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Call Trace:
> >   <TASK>
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ? __die_body.cold+0x8/0x12
> >   ? die_addr+0x3c/0x60
> >   ? exc_general_protection+0x178/0x410
> >   ? asm_exc_general_protection+0x26/0x30
> >   ? ima_restore_measurement_list+0xdc/0x420
> >   ? vprintk_emit+0x1f0/0x270
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ima_load_kexec_buffer+0x6e/0xf0
> >   ima_init+0x52/0xb0
> >   ? __pfx_init_ima+0x10/0x10
> >   init_ima+0x26/0xc0
> >   ? __pfx_init_ima+0x10/0x10
> >   do_one_initcall+0x5b/0x300
> >   do_initcalls+0xdf/0x100
> >   ? __pfx_kernel_init+0x10/0x10
> >   kernel_init_freeable+0x147/0x1a0
> >   kernel_init+0x1a/0x140
> >   ret_from_fork+0x34/0x50
> >   ? __pfx_kernel_init+0x10/0x10
> >   ret_from_fork_asm+0x1a/0x30
> >   </TASK>
> >  Modules linked in:
> >  ---[ end trace 0000000000000000 ]---
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Kernel panic - not syncing: Fatal exception
> >  Kernel Offset: disabled
> >  Rebooting in 10 seconds..
> >
> > From debugging printing, the stored addr and size of ima_kexec buffer
> > are not decrypted correctly like:
> >  ------
> >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> >  ------
> >
> > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > ima_kexec buffer suffered from the incorrect decryption. After
> > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > where checking the embedded content inside setup_data takes wrong range
> > calculation.
> >
> > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > and the length of setup_data is 0x10. When checking if data is inside
> > the embedded conent of setup_data, the starting address of efi data and
> > rng_seed happened to land in the wrong calculated range. While the
> > ima_kexec's starting address unluckily doesn't pass the checking, then
> > error occurred.
> >
> > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> >
> > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
>
> The check that was modified was added by:
>         b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
>
> The SETUP_INDIRECT patches seem to be the issue here.
>
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >  arch/x86/mm/ioremap.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > index aa7d279321ea..7953c4a1d28d 100644
> > --- a/arch/x86/mm/ioremap.c
> > +++ b/arch/x86/mm/ioremap.c
> > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> >               paddr_next = data->next;
> >               len = data->len;
> >
> > -             if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > +             if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
>
> I don't think this is correct. You are adding the requested size to the
> length of the setup data element. The length is the true length of the
> setup data and should not be increased.

I think here size should be sizeof(struct setup_data) instead like below:
        if ((phys_addr > paddr) && (phys_addr < (paddr + sizeof(struct
setup_data) + len)))

Baoquan, does the above work?
>
> It looks like there were some major changes to this function to support
> SETUP_INDIRECT. Is the IMA log setup data marked SETUP_INDIRECT?
>
> It might be helpful to instrument the code to see exactly what is
> happening during the execution of that function for the IMA log address.
>
> Thanks,
> Tom
>
> >                       early_memunmap(data, sizeof(*data));
> >                       return true;
> >               }
>



From dyoung at redhat.com  Mon Aug 26 18:41:42 2024
From: dyoung at redhat.com (Dave Young)
Date: Tue, 27 Aug 2024 09:41:42 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <CALu+AoQdKyeJBRzucdai5+KihMMOdWJeg0nAmw4K_Pd4DRt3_Q@mail.gmail.com>
References: <20240826024457.22423-1-bhe@redhat.com> <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <CALu+AoQdKyeJBRzucdai5+KihMMOdWJeg0nAmw4K_Pd4DRt3_Q@mail.gmail.com>
Message-ID: <CALu+AoTpWZGZm0sR4eayDDfcfPM6dcRcn9kTWw4jsgDUXh=z=Q@mail.gmail.com>

On Tue, 27 Aug 2024 at 09:39, Dave Young <dyoung at redhat.com> wrote:
>
> On Mon, 26 Aug 2024 at 22:24, Tom Lendacky <thomas.lendacky at amd.com> wrote:
> >
> > On 8/25/24 21:44, Baoquan He wrote:
> > > Recently, it's reported that kdump kernel is broken during bootup on
> > > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > > system when enabling CONFIG_IMA_KEXEC.
> > >
> > > --------------------------------------------------
> > >  ima: No TPM chip found, activating TPM-bypass!
> > >  Loading compiled-in module X.509 certificates
> > >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> > >  ima: Allocated hash algorithm: sha256
> > >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> > >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> > >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > >  Call Trace:
> > >   <TASK>
> > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > >   ? __die_body.cold+0x8/0x12
> > >   ? die_addr+0x3c/0x60
> > >   ? exc_general_protection+0x178/0x410
> > >   ? asm_exc_general_protection+0x26/0x30
> > >   ? ima_restore_measurement_list+0xdc/0x420
> > >   ? vprintk_emit+0x1f0/0x270
> > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > >   ima_load_kexec_buffer+0x6e/0xf0
> > >   ima_init+0x52/0xb0
> > >   ? __pfx_init_ima+0x10/0x10
> > >   init_ima+0x26/0xc0
> > >   ? __pfx_init_ima+0x10/0x10
> > >   do_one_initcall+0x5b/0x300
> > >   do_initcalls+0xdf/0x100
> > >   ? __pfx_kernel_init+0x10/0x10
> > >   kernel_init_freeable+0x147/0x1a0
> > >   kernel_init+0x1a/0x140
> > >   ret_from_fork+0x34/0x50
> > >   ? __pfx_kernel_init+0x10/0x10
> > >   ret_from_fork_asm+0x1a/0x30
> > >   </TASK>
> > >  Modules linked in:
> > >  ---[ end trace 0000000000000000 ]---
> > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > >  Kernel panic - not syncing: Fatal exception
> > >  Kernel Offset: disabled
> > >  Rebooting in 10 seconds..
> > >
> > > From debugging printing, the stored addr and size of ima_kexec buffer
> > > are not decrypted correctly like:
> > >  ------
> > >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> > >  ------
> > >
> > > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > > ima_kexec buffer suffered from the incorrect decryption. After
> > > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > > where checking the embedded content inside setup_data takes wrong range
> > > calculation.
> > >
> > > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > > and the length of setup_data is 0x10. When checking if data is inside
> > > the embedded conent of setup_data, the starting address of efi data and
> > > rng_seed happened to land in the wrong calculated range. While the
> > > ima_kexec's starting address unluckily doesn't pass the checking, then
> > > error occurred.
> > >
> > > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> > >
> > > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> >
> > The check that was modified was added by:
> >         b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> >
> > The SETUP_INDIRECT patches seem to be the issue here.
> >
> > > Signed-off-by: Baoquan He <bhe at redhat.com>
> > > ---
> > >  arch/x86/mm/ioremap.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > > index aa7d279321ea..7953c4a1d28d 100644
> > > --- a/arch/x86/mm/ioremap.c
> > > +++ b/arch/x86/mm/ioremap.c
> > > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> > >               paddr_next = data->next;
> > >               len = data->len;
> > >
> > > -             if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > > +             if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> >
> > I don't think this is correct. You are adding the requested size to the
> > length of the setup data element. The length is the true length of the
> > setup data and should not be increased.
>
> I think here size should be sizeof(struct setup_data) instead like below:
>         if ((phys_addr > paddr) && (phys_addr < (paddr + sizeof(struct
> setup_data) + len)))

Hmm, strictly it should be (webmail wrapped the line, please ignore that):
if ((phys_addr >= paddr) && (phys_addr < (paddr + sizeof(struct
setup_data) + len)))

>
> Baoquan, does the above work?
> >
> > It looks like there were some major changes to this function to support
> > SETUP_INDIRECT. Is the IMA log setup data marked SETUP_INDIRECT?
> >
> > It might be helpful to instrument the code to see exactly what is
> > happening during the execution of that function for the IMA log address.
> >
> > Thanks,
> > Tom
> >
> > >                       early_memunmap(data, sizeof(*data));
> > >                       return true;
> > >               }
> >



From bhe at redhat.com  Mon Aug 26 20:19:09 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 11:19:09 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
Message-ID: <Zs1FrZVuZK14Je7z@MiWiFi-R3L-srv>

On 08/26/24 at 09:24am, Tom Lendacky wrote:
> On 8/25/24 21:44, Baoquan He wrote:
> > Recently, it's reported that kdump kernel is broken during bootup on
> > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > system when enabling CONFIG_IMA_KEXEC.
> > 
> > --------------------------------------------------
> >  ima: No TPM chip found, activating TPM-bypass!
> >  Loading compiled-in module X.509 certificates
> >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> >  ima: Allocated hash algorithm: sha256
> >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Call Trace:
> >   <TASK>
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ? __die_body.cold+0x8/0x12
> >   ? die_addr+0x3c/0x60
> >   ? exc_general_protection+0x178/0x410
> >   ? asm_exc_general_protection+0x26/0x30
> >   ? ima_restore_measurement_list+0xdc/0x420
> >   ? vprintk_emit+0x1f0/0x270
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ima_load_kexec_buffer+0x6e/0xf0
> >   ima_init+0x52/0xb0
> >   ? __pfx_init_ima+0x10/0x10
> >   init_ima+0x26/0xc0
> >   ? __pfx_init_ima+0x10/0x10
> >   do_one_initcall+0x5b/0x300
> >   do_initcalls+0xdf/0x100
> >   ? __pfx_kernel_init+0x10/0x10
> >   kernel_init_freeable+0x147/0x1a0
> >   kernel_init+0x1a/0x140
> >   ret_from_fork+0x34/0x50
> >   ? __pfx_kernel_init+0x10/0x10
> >   ret_from_fork_asm+0x1a/0x30
> >   </TASK>
> >  Modules linked in:
> >  ---[ end trace 0000000000000000 ]---
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Kernel panic - not syncing: Fatal exception
> >  Kernel Offset: disabled
> >  Rebooting in 10 seconds..
> > 
> > From debugging printing, the stored addr and size of ima_kexec buffer
> > are not decrypted correctly like:
> >  ------
> >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> >  ------
> > 
> > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > ima_kexec buffer suffered from the incorrect decryption. After
> > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > where checking the embedded content inside setup_data takes wrong range
> > calculation.
> > 
> > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > and the length of setup_data is 0x10. When checking if data is inside
> > the embedded conent of setup_data, the starting address of efi data and
> > rng_seed happened to land in the wrong calculated range. While the
> > ima_kexec's starting address unluckily doesn't pass the checking, then
> > error occurred.
> > 
> > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> > 
> > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> 
> The check that was modified was added by:
> 	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> 
> The SETUP_INDIRECT patches seem to be the issue here.

Hmm, I didn't check it carefully, thanks for addding this info. While
after checking commit b3c72fc9a78e, I feel the adding code was trying to
fix your original early_memremap_is_setup_data(). Even though
SETUP_INDIRECT type of setup_data has been added, the original
early_memremap_is_setup_data() only check the starting address and
the content of struct setup_data, that's obviously wrong.

arch/x86/include/uapi/asm/setup_data.h:
/* extensible setup data list node */
struct setup_data {
        __u64 next;
        __u32 type;
        __u32 len;
        __u8 data[];
};

As you can see, the zero-length will embed the carried data which is
actually expected and adjacent to its carrier, the struct setup_data.

> 
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >  arch/x86/mm/ioremap.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > index aa7d279321ea..7953c4a1d28d 100644
> > --- a/arch/x86/mm/ioremap.c
> > +++ b/arch/x86/mm/ioremap.c
> > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> >  		paddr_next = data->next;
> >  		len = data->len;
> >  
> > -		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > +		if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> 
> I don't think this is correct. You are adding the requested size to the
> length of the setup data element. The length is the true length of the
> setup data and should not be increased.

Please see the inline comment among code lines.

static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
                                                unsigned long size)
{
        struct setup_indirect *indirect;
        struct setup_data *data;
        u64 paddr, paddr_next;

        paddr = boot_params.hdr.setup_data; //paddr point at struct steup_data;
        while (paddr) {
                unsigned int len, size;

                if (phys_addr == paddr) // check the starting addr of setup_data
                        return true;

		data = early_memremap_decrypted(paddr, sizeof(*data));
                if (!data) {
                        pr_warn("failed to early memremap setup_data entry\n");
                        return false;
                }

                size = sizeof(*data); //size is the length of struct setup_data

                paddr_next = data->next;
                len = data->len; // len is the length of carried data,
                                 //e.g sizeof(ima_setup_data) if ima_kexec buffer
                                 // or sizeof(struct setup_indirect) if
                                 // it's SETUP_INDIRECT type. Note that SETUP_INDIRECT
				 //data is also setup_data info even
				 //though it's intermideate info.


		//Here I check if phys_addr is inside (paddr, paddr + sizeof(struct setup_data) + len)	
                //means it check if phys_addr is inside struct
                //setup_data or struct ima_setup_data if ima_kexec case.
                if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
                        early_memunmap(data, sizeof(*data));
                        return true;
                }

		if (data->type == SETUP_INDIRECT) {
			......
			if (indirect->type != SETUP_INDIRECT) {
                                paddr = indirect->addr;
                                len = indirect->len;
                        }
			// it's checking the indirect dat, and the paddr
			// is adjusted here. Wondering if indirect data
			//can be nested, e.g 
 			//setup_data->indirect->indirect->acutal data
		}
	...
	}
	...
}


> 
> It looks like there were some major changes to this function to support
> SETUP_INDIRECT. Is the IMA log setup data marked SETUP_INDIRECT?

No, ima_kexec buffer is marked as SETUP_IMA, it's not indirect data.

arch/x86/kernel/kexec-bzimage64.c:
bzImage64_load()
    ->setup_boot_parameters()
        ->setup_ima_state()

> 
> It might be helpful to instrument the code to see exactly what is
> happening during the execution of that function for the IMA log address.

I almost have printed all needed information because kexec/kdump passed
three types of setup_data, but only ima_kexec buffer is not got right.
The behaviour is very bizarre at the beginning.



From bhe at redhat.com  Mon Aug 26 20:19:34 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 11:19:34 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <CALu+AoTpWZGZm0sR4eayDDfcfPM6dcRcn9kTWw4jsgDUXh=z=Q@mail.gmail.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <CALu+AoQdKyeJBRzucdai5+KihMMOdWJeg0nAmw4K_Pd4DRt3_Q@mail.gmail.com>
 <CALu+AoTpWZGZm0sR4eayDDfcfPM6dcRcn9kTWw4jsgDUXh=z=Q@mail.gmail.com>
Message-ID: <Zs1FxiRtPP48oniO@MiWiFi-R3L-srv>

On 08/27/24 at 09:41am, Dave Young wrote:
> On Tue, 27 Aug 2024 at 09:39, Dave Young <dyoung at redhat.com> wrote:
> >
> > On Mon, 26 Aug 2024 at 22:24, Tom Lendacky <thomas.lendacky at amd.com> wrote:
> > >
> > > On 8/25/24 21:44, Baoquan He wrote:
> > > > Recently, it's reported that kdump kernel is broken during bootup on
> > > > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > > > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > > > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > > > system when enabling CONFIG_IMA_KEXEC.
> > > >
> > > > --------------------------------------------------
> > > >  ima: No TPM chip found, activating TPM-bypass!
> > > >  Loading compiled-in module X.509 certificates
> > > >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> > > >  ima: Allocated hash algorithm: sha256
> > > >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> > > >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> > > >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> > > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > > >  Call Trace:
> > > >   <TASK>
> > > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > > >   ? __die_body.cold+0x8/0x12
> > > >   ? die_addr+0x3c/0x60
> > > >   ? exc_general_protection+0x178/0x410
> > > >   ? asm_exc_general_protection+0x26/0x30
> > > >   ? ima_restore_measurement_list+0xdc/0x420
> > > >   ? vprintk_emit+0x1f0/0x270
> > > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > > >   ima_load_kexec_buffer+0x6e/0xf0
> > > >   ima_init+0x52/0xb0
> > > >   ? __pfx_init_ima+0x10/0x10
> > > >   init_ima+0x26/0xc0
> > > >   ? __pfx_init_ima+0x10/0x10
> > > >   do_one_initcall+0x5b/0x300
> > > >   do_initcalls+0xdf/0x100
> > > >   ? __pfx_kernel_init+0x10/0x10
> > > >   kernel_init_freeable+0x147/0x1a0
> > > >   kernel_init+0x1a/0x140
> > > >   ret_from_fork+0x34/0x50
> > > >   ? __pfx_kernel_init+0x10/0x10
> > > >   ret_from_fork_asm+0x1a/0x30
> > > >   </TASK>
> > > >  Modules linked in:
> > > >  ---[ end trace 0000000000000000 ]---
> > > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > > >  Kernel panic - not syncing: Fatal exception
> > > >  Kernel Offset: disabled
> > > >  Rebooting in 10 seconds..
> > > >
> > > > From debugging printing, the stored addr and size of ima_kexec buffer
> > > > are not decrypted correctly like:
> > > >  ------
> > > >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> > > >  ------
> > > >
> > > > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > > > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > > > ima_kexec buffer suffered from the incorrect decryption. After
> > > > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > > > where checking the embedded content inside setup_data takes wrong range
> > > > calculation.
> > > >
> > > > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > > > and the length of setup_data is 0x10. When checking if data is inside
> > > > the embedded conent of setup_data, the starting address of efi data and
> > > > rng_seed happened to land in the wrong calculated range. While the
> > > > ima_kexec's starting address unluckily doesn't pass the checking, then
> > > > error occurred.
> > > >
> > > > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> > > >
> > > > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> > >
> > > The check that was modified was added by:
> > >         b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> > >
> > > The SETUP_INDIRECT patches seem to be the issue here.
> > >
> > > > Signed-off-by: Baoquan He <bhe at redhat.com>
> > > > ---
> > > >  arch/x86/mm/ioremap.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > > > index aa7d279321ea..7953c4a1d28d 100644
> > > > --- a/arch/x86/mm/ioremap.c
> > > > +++ b/arch/x86/mm/ioremap.c
> > > > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> > > >               paddr_next = data->next;
> > > >               len = data->len;
> > > >
> > > > -             if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > > > +             if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> > >
> > > I don't think this is correct. You are adding the requested size to the
> > > length of the setup data element. The length is the true length of the
> > > setup data and should not be increased.
> >
> > I think here size should be sizeof(struct setup_data) instead like below:
> >         if ((phys_addr > paddr) && (phys_addr < (paddr + sizeof(struct
> > setup_data) + len)))
> 
> Hmm, strictly it should be (webmail wrapped the line, please ignore that):
> if ((phys_addr >= paddr) && (phys_addr < (paddr + sizeof(struct
> setup_data) + len)))
> 
> >
> > Baoquan, does the above work?

Both of my change and above change work because they are almost equal. I 
changed like below at the very beginning, but using 'size' is simpler.
Please see below comment.

static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
                                                unsigned long size)
{
	struct setup_indirect *indirect;
        struct setup_data *data;
        u64 paddr, paddr_next;

	paddr = boot_params.hdr.setup_data;
        while (paddr) {
		......
		size = sizeof(*data); // size = sizeof(stuct setup_data);
		.......	
	}
	...
}

> > >
> > > It looks like there were some major changes to this function to support
> > > SETUP_INDIRECT. Is the IMA log setup data marked SETUP_INDIRECT?
> > >
> > > It might be helpful to instrument the code to see exactly what is
> > > happening during the execution of that function for the IMA log address.
> > >
> > > Thanks,
> > > Tom
> > >
> > > >                       early_memunmap(data, sizeof(*data));
> > > >                       return true;
> > > >               }
> > >
> 



From bhe at redhat.com  Mon Aug 26 22:27:59 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 13:27:59 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
Message-ID: <Zs1j31JGB/5EJatz@MiWiFi-R3L-srv>

On 08/26/24 at 09:24am, Tom Lendacky wrote:
> On 8/25/24 21:44, Baoquan He wrote:
> > Recently, it's reported that kdump kernel is broken during bootup on
> > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > system when enabling CONFIG_IMA_KEXEC.
> > 
> > --------------------------------------------------
> >  ima: No TPM chip found, activating TPM-bypass!
> >  Loading compiled-in module X.509 certificates
> >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> >  ima: Allocated hash algorithm: sha256
> >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Call Trace:
> >   <TASK>
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ? __die_body.cold+0x8/0x12
> >   ? die_addr+0x3c/0x60
> >   ? exc_general_protection+0x178/0x410
> >   ? asm_exc_general_protection+0x26/0x30
> >   ? ima_restore_measurement_list+0xdc/0x420
> >   ? vprintk_emit+0x1f0/0x270
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ima_load_kexec_buffer+0x6e/0xf0
> >   ima_init+0x52/0xb0
> >   ? __pfx_init_ima+0x10/0x10
> >   init_ima+0x26/0xc0
> >   ? __pfx_init_ima+0x10/0x10
> >   do_one_initcall+0x5b/0x300
> >   do_initcalls+0xdf/0x100
> >   ? __pfx_kernel_init+0x10/0x10
> >   kernel_init_freeable+0x147/0x1a0
> >   kernel_init+0x1a/0x140
> >   ret_from_fork+0x34/0x50
> >   ? __pfx_kernel_init+0x10/0x10
> >   ret_from_fork_asm+0x1a/0x30
> >   </TASK>
> >  Modules linked in:
> >  ---[ end trace 0000000000000000 ]---
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Kernel panic - not syncing: Fatal exception
> >  Kernel Offset: disabled
> >  Rebooting in 10 seconds..
> > 
> > From debugging printing, the stored addr and size of ima_kexec buffer
> > are not decrypted correctly like:
> >  ------
> >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> >  ------
> > 
> > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > ima_kexec buffer suffered from the incorrect decryption. After
> > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > where checking the embedded content inside setup_data takes wrong range
> > calculation.
> > 
> > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > and the length of setup_data is 0x10. When checking if data is inside
> > the embedded conent of setup_data, the starting address of efi data and
> > rng_seed happened to land in the wrong calculated range. While the
> > ima_kexec's starting address unluckily doesn't pass the checking, then
> > error occurred.
> > 
> > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> > 
> > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> 
> The check that was modified was added by:
> 	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> 
> The SETUP_INDIRECT patches seem to be the issue here.
> 
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >  arch/x86/mm/ioremap.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > index aa7d279321ea..7953c4a1d28d 100644
> > --- a/arch/x86/mm/ioremap.c
> > +++ b/arch/x86/mm/ioremap.c
> > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> >  		paddr_next = data->next;
> >  		len = data->len;
> >  
> > -		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > +		if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> 
> I don't think this is correct. You are adding the requested size to the
> length of the setup data element. The length is the true length of the
> setup data and should not be increased.

I talked to Dave, he reminded me that people could mix the passed in
parameter 'size' and the local variable 'size' defined inside the while
loop, not sure which 'size' you are referring to.



From dyoung at redhat.com  Mon Aug 26 22:41:25 2024
From: dyoung at redhat.com (Dave Young)
Date: Tue, 27 Aug 2024 13:41:25 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <Zs1j31JGB/5EJatz@MiWiFi-R3L-srv>
References: <20240826024457.22423-1-bhe@redhat.com> <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1j31JGB/5EJatz@MiWiFi-R3L-srv>
Message-ID: <CALu+AoTNtzVGFyG=GLAtT=VEWJG7FNbx6jD_Ye+4ORYXOiMekw@mail.gmail.com>

On Tue, 27 Aug 2024 at 13:28, Baoquan He <bhe at redhat.com> wrote:
>
> On 08/26/24 at 09:24am, Tom Lendacky wrote:
> > On 8/25/24 21:44, Baoquan He wrote:
> > > Recently, it's reported that kdump kernel is broken during bootup on
> > > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > > system when enabling CONFIG_IMA_KEXEC.
> > >
> > > --------------------------------------------------
> > >  ima: No TPM chip found, activating TPM-bypass!
> > >  Loading compiled-in module X.509 certificates
> > >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> > >  ima: Allocated hash algorithm: sha256
> > >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> > >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> > >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > >  Call Trace:
> > >   <TASK>
> > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > >   ? show_trace_log_lvl+0x1b0/0x2f0
> > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > >   ? __die_body.cold+0x8/0x12
> > >   ? die_addr+0x3c/0x60
> > >   ? exc_general_protection+0x178/0x410
> > >   ? asm_exc_general_protection+0x26/0x30
> > >   ? ima_restore_measurement_list+0xdc/0x420
> > >   ? vprintk_emit+0x1f0/0x270
> > >   ? ima_load_kexec_buffer+0x6e/0xf0
> > >   ima_load_kexec_buffer+0x6e/0xf0
> > >   ima_init+0x52/0xb0
> > >   ? __pfx_init_ima+0x10/0x10
> > >   init_ima+0x26/0xc0
> > >   ? __pfx_init_ima+0x10/0x10
> > >   do_one_initcall+0x5b/0x300
> > >   do_initcalls+0xdf/0x100
> > >   ? __pfx_kernel_init+0x10/0x10
> > >   kernel_init_freeable+0x147/0x1a0
> > >   kernel_init+0x1a/0x140
> > >   ret_from_fork+0x34/0x50
> > >   ? __pfx_kernel_init+0x10/0x10
> > >   ret_from_fork_asm+0x1a/0x30
> > >   </TASK>
> > >  Modules linked in:
> > >  ---[ end trace 0000000000000000 ]---
> > >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> > >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> > >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> > >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> > >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> > >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> > >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> > >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> > >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> > >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> > >  Kernel panic - not syncing: Fatal exception
> > >  Kernel Offset: disabled
> > >  Rebooting in 10 seconds..
> > >
> > > From debugging printing, the stored addr and size of ima_kexec buffer
> > > are not decrypted correctly like:
> > >  ------
> > >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> > >  ------
> > >
> > > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > > ima_kexec buffer suffered from the incorrect decryption. After
> > > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > > where checking the embedded content inside setup_data takes wrong range
> > > calculation.
> > >
> > > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > > and the length of setup_data is 0x10. When checking if data is inside
> > > the embedded conent of setup_data, the starting address of efi data and
> > > rng_seed happened to land in the wrong calculated range. While the
> > > ima_kexec's starting address unluckily doesn't pass the checking, then
> > > error occurred.
> > >
> > > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> > >
> > > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> >
> > The check that was modified was added by:
> >       b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> >
> > The SETUP_INDIRECT patches seem to be the issue here.
> >
> > > Signed-off-by: Baoquan He <bhe at redhat.com>
> > > ---
> > >  arch/x86/mm/ioremap.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > > index aa7d279321ea..7953c4a1d28d 100644
> > > --- a/arch/x86/mm/ioremap.c
> > > +++ b/arch/x86/mm/ioremap.c
> > > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> > >             paddr_next = data->next;
> > >             len = data->len;
> > >
> > > -           if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > > +           if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> >
> > I don't think this is correct. You are adding the requested size to the
> > length of the setup data element. The length is the true length of the
> > setup data and should not be increased.
>
> I talked to Dave, he reminded me that people could mix the passed in
> parameter 'size' and the local variable 'size' defined inside the while
> loop, not sure which 'size' you are referring to.
>
Baoquan, you are right, but I think I mistakenly read the code in
memremap_is_setup_data instead of early_memremap_is_setup_data.  You
can check the memremap_is_setup_data, no "size = sizeof (*data)",  so
these two functions could both need fixes.

Otherwise it would be better to change the function internal variable
name, it could cause confusion even if the actual result is correct.

Thanks
Dave



From bhe at redhat.com  Mon Aug 26 23:22:28 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 14:22:28 +0800
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <09c29a3c4879d4ce5d8b97fd60d8ba5e38bed979.camel@physik.fu-berlin.de>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
 <09c29a3c4879d4ce5d8b97fd60d8ba5e38bed979.camel@physik.fu-berlin.de>
Message-ID: <Zs1wpHxfTcwKr517@MiWiFi-R3L-srv>

On 08/23/24 at 08:16pm, John Paul Adrian Glaubitz wrote:
> Hi Geert,
> 
> On Fri, 2024-08-23 at 15:13 +0200, Geert Uytterhoeven wrote:
> > IMHO CRASH_DUMP should just default to n, like most kernel options, as
> > it enables non-trivial extra functionality: the kernel source tree has
> > more than 100 locations that check if CONFIG_CRASH_DUMP is enabled.
> 
> I guess we should then revert that part of Baoquan's original patch.
> 
> > What is so special about CRASH_DUMP, that it should be enabled by
> > default?
> 
> Let's ask Baoquan who made the original change to enable CRASH_DUMP by default.

Sorry for late reply.

It's me who enabled it by default when I clean up the messy Kconfig items
related to kexec/kdump. Before the clean up, CONFIG_CRASH_DUMP only
controlled a very small file including sevearl functions and macro
definitions. But kernel codes took CRASH_DUMP as switch of kdump.

About why it's enabled by default, as Michael has explained in another
thread, distros usualy needs to enable it by default because vmcore
dumping is a very important feature on servers, even guest instances. 
Even though kdump codes are enabled to built in, not providing
crashkernel= value won't make vmcore dumping take effect, it won't cost
system resources in that case.

Thanks
Baoquan



From glaubitz at physik.fu-berlin.de  Mon Aug 26 23:37:22 2024
From: glaubitz at physik.fu-berlin.de (John Paul Adrian Glaubitz)
Date: Tue, 27 Aug 2024 08:37:22 +0200
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <Zs1wpHxfTcwKr517@MiWiFi-R3L-srv>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
	 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
	 <09c29a3c4879d4ce5d8b97fd60d8ba5e38bed979.camel@physik.fu-berlin.de>
	 <Zs1wpHxfTcwKr517@MiWiFi-R3L-srv>
Message-ID: <f355e26eead641f5f281372aadf9dee7de19a4c7.camel@physik.fu-berlin.de>

On Tue, 2024-08-27 at 14:22 +0800, Baoquan He wrote:
> About why it's enabled by default, as Michael has explained in another
> thread, distros usualy needs to enable it by default because vmcore
> dumping is a very important feature on servers, even guest instances. 
> Even though kdump codes are enabled to built in, not providing
> crashkernel= value won't make vmcore dumping take effect, it won't cost
> system resources in that case.

OK, thanks for the explanation. But as we have found out in the mean time,
the assumption was wrong to enable it by default for all architectures as
some architectures cannot boot a crash dump kernel with their default bootloader
but only through kexec.

Can we have a follow-up patch to disable crash dump kernels where they're
not needed? I mean, not every platform supported by Linux is obviously a
x86-based or POWER-based server.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913


From bhe at redhat.com  Tue Aug 27 02:01:58 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 17:01:58 +0800
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <f355e26eead641f5f281372aadf9dee7de19a4c7.camel@physik.fu-berlin.de>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <CAMuHMdVYNhFJ+qBDP3_fi9oeHsgOL0vqPe1YqE18+M8n1onssw@mail.gmail.com>
 <09c29a3c4879d4ce5d8b97fd60d8ba5e38bed979.camel@physik.fu-berlin.de>
 <Zs1wpHxfTcwKr517@MiWiFi-R3L-srv>
 <f355e26eead641f5f281372aadf9dee7de19a4c7.camel@physik.fu-berlin.de>
Message-ID: <Zs2WBgtADYxzVMyt@MiWiFi-R3L-srv>

On 08/27/24 at 08:37am, John Paul Adrian Glaubitz wrote:
> On Tue, 2024-08-27 at 14:22 +0800, Baoquan He wrote:
> > About why it's enabled by default, as Michael has explained in another
> > thread, distros usualy needs to enable it by default because vmcore
> > dumping is a very important feature on servers, even guest instances. 
> > Even though kdump codes are enabled to built in, not providing
> > crashkernel= value won't make vmcore dumping take effect, it won't cost
> > system resources in that case.
> 
> OK, thanks for the explanation. But as we have found out in the mean time,
> the assumption was wrong to enable it by default for all architectures as
> some architectures cannot boot a crash dump kernel with their default bootloader
> but only through kexec.
> 
> Can we have a follow-up patch to disable crash dump kernels where they're
> not needed? I mean, not every platform supported by Linux is obviously a
> x86-based or POWER-based server.

Yes, while isn't Dave's patch a good one to fix it? In Dave's patch, the
default enabling of CRASH_DUMP has been taken off, change to rely on
ARCH_DEFAULT_CRASH_DUMP provided by each arch.

 config CRASH_DUMP
        bool "kernel crash dumps"
-       default y
+       default ARCH_DEFAULT_CRASH_DUMP



From bhe at redhat.com  Tue Aug 27 02:33:28 2024
From: bhe at redhat.com (Baoquan He)
Date: Tue, 27 Aug 2024 17:33:28 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <CALu+AoTNtzVGFyG=GLAtT=VEWJG7FNbx6jD_Ye+4ORYXOiMekw@mail.gmail.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1j31JGB/5EJatz@MiWiFi-R3L-srv>
 <CALu+AoTNtzVGFyG=GLAtT=VEWJG7FNbx6jD_Ye+4ORYXOiMekw@mail.gmail.com>
Message-ID: <Zs2daJ9FHA8vPkPP@MiWiFi-R3L-srv>

On 08/27/24 at 01:41pm, Dave Young wrote:
> On Tue, 27 Aug 2024 at 13:28, Baoquan He <bhe at redhat.com> wrote:
> >
> > On 08/26/24 at 09:24am, Tom Lendacky wrote:
> > > On 8/25/24 21:44, Baoquan He wrote:
......
> > > > ---
> > > >  arch/x86/mm/ioremap.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > > > index aa7d279321ea..7953c4a1d28d 100644
> > > > --- a/arch/x86/mm/ioremap.c
> > > > +++ b/arch/x86/mm/ioremap.c
> > > > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> > > >             paddr_next = data->next;
> > > >             len = data->len;
> > > >
> > > > -           if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > > > +           if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
> > >
> > > I don't think this is correct. You are adding the requested size to the
> > > length of the setup data element. The length is the true length of the
> > > setup data and should not be increased.
> >
> > I talked to Dave, he reminded me that people could mix the passed in
> > parameter 'size' and the local variable 'size' defined inside the while
> > loop, not sure which 'size' you are referring to.
> >
> Baoquan, you are right, but I think I mistakenly read the code in
> memremap_is_setup_data instead of early_memremap_is_setup_data.  You
> can check the memremap_is_setup_data, no "size = sizeof (*data)",  so
> these two functions could both need fixes.

Agree, memremap_is_setup_data() has the same drawback in code.

> 
> Otherwise it would be better to change the function internal variable
> name, it could cause confusion even if the actual result is correct.

Ok, will consider to change when spinning v2.



From ardb at kernel.org  Tue Aug 27 03:28:10 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 27 Aug 2024 12:28:10 +0200
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <20240826223835.3928819-21-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com> <20240826223835.3928819-21-ross.philipson@oracle.com>
Message-ID: <CAMj1kXEyStoqmvvQirxt_GXTnO2qQjOxtQGzHzQeCdRCYzT7uA@mail.gmail.com>

On Tue, 27 Aug 2024 at 00:44, Ross Philipson <ross.philipson at oracle.com> wrote:
>
> This support allows the DRTM launch to be initiated after an EFI stub
> launch of the Linux kernel is done. This is accomplished by providing
> a handler to jump to when a Secure Launch is in progress. This has to be
> called after the EFI stub does Exit Boot Services.
>
> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

> ---
>  drivers/firmware/efi/libstub/efistub.h  |  8 ++
>  drivers/firmware/efi/libstub/x86-stub.c | 98 +++++++++++++++++++++++++
>  2 files changed, 106 insertions(+)
>
> diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
> index d33ccbc4a2c6..baf42d6d0796 100644
> --- a/drivers/firmware/efi/libstub/efistub.h
> +++ b/drivers/firmware/efi/libstub/efistub.h
> @@ -135,6 +135,14 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
>         *hi = upper_32_bits(data);
>  }
>
> +static inline
> +void efi_set_u64_form(u32 lo, u32 hi, u64 *data)
> +{
> +       u64 upper = hi;
> +
> +       *data = lo | upper << 32;
> +}
> +
>  /*
>   * Allocation types for calls to boottime->allocate_pages.
>   */
> diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
> index f8e465da344d..04786c1b3b5d 100644
> --- a/drivers/firmware/efi/libstub/x86-stub.c
> +++ b/drivers/firmware/efi/libstub/x86-stub.c
> @@ -9,6 +9,8 @@
>  #include <linux/efi.h>
>  #include <linux/pci.h>
>  #include <linux/stddef.h>
> +#include <linux/slr_table.h>
> +#include <linux/slaunch.h>
>
>  #include <asm/efi.h>
>  #include <asm/e820/types.h>
> @@ -923,6 +925,99 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
>         return efi_adjust_memory_range_protection(addr, kernel_text_size);
>  }
>
> +static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
> +                                                struct boot_params *boot_params)
> +{
> +       struct slr_entry_intel_info *txt_info;
> +       struct slr_entry_policy *policy;
> +       struct txt_os_mle_data *os_mle;
> +       bool updated = false;
> +       int i;
> +
> +       txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
> +       if (!txt_info)
> +               return false;
> +
> +       os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
> +       if (!os_mle)
> +               return false;
> +
> +       os_mle->boot_params_addr = (u64)boot_params;
> +
> +       policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
> +       if (!policy)
> +               return false;
> +
> +       for (i = 0; i < policy->nr_entries; i++) {
> +               if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
> +                       policy->policy_entries[i].entity = (u64)boot_params;
> +                       updated = true;
> +                       break;
> +               }
> +       }
> +
> +       /*
> +        * If this is a PE entry into EFI stub the mocked up boot params will
> +        * be missing some of the setup header data needed for the second stage
> +        * of the Secure Launch boot.
> +        */
> +       if (image) {
> +               struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
> +                                           offsetof(struct boot_params, hdr));
> +               u64 cmdline_ptr;
> +
> +               boot_params->hdr.setup_sects = hdr->setup_sects;
> +               boot_params->hdr.syssize = hdr->syssize;
> +               boot_params->hdr.version = hdr->version;
> +               boot_params->hdr.loadflags = hdr->loadflags;
> +               boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
> +               boot_params->hdr.min_alignment = hdr->min_alignment;
> +               boot_params->hdr.xloadflags = hdr->xloadflags;
> +               boot_params->hdr.init_size = hdr->init_size;
> +               boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
> +               efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
> +                                &cmdline_ptr);
> +               boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
> +       }
> +
> +       return updated;
> +}
> +
> +static void efi_secure_launch(struct boot_params *boot_params)
> +{
> +       struct slr_entry_dl_info *dlinfo;
> +       efi_guid_t guid = SLR_TABLE_GUID;
> +       dl_handler_func handler_callback;
> +       struct slr_table *slrt;
> +
> +       if (!IS_ENABLED(CONFIG_SECURE_LAUNCH))
> +               return;
> +
> +       /*
> +        * The presence of this table indicated a Secure Launch
> +        * is being requested.
> +        */
> +       slrt = (struct slr_table *)get_efi_config_table(guid);
> +       if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
> +               return;
> +
> +       /*
> +        * Since the EFI stub library creates its own boot_params on entry, the
> +        * SLRT and TXT heap have to be updated with this version.
> +        */
> +       if (!efi_secure_launch_update_boot_params(slrt, boot_params))
> +               return;
> +
> +       /* Jump through DL stub to initiate Secure Launch */
> +       dlinfo = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
> +
> +       handler_callback = (dl_handler_func)dlinfo->dl_handler;
> +
> +       handler_callback(&dlinfo->bl_context);
> +
> +       unreachable();
> +}
> +
>  static void __noreturn enter_kernel(unsigned long kernel_addr,
>                                     struct boot_params *boot_params)
>  {
> @@ -1050,6 +1145,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
>                 goto fail;
>         }
>
> +       /* If a Secure Launch is in progress, this never returns */
> +       efi_secure_launch(boot_params);
> +
>         /*
>          * Call the SEV init code while still running with the firmware's
>          * GDT/IDT, so #VC exceptions will be handled by EFI.
> --
> 2.39.3
>


From ardb at kernel.org  Tue Aug 27 03:29:59 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 27 Aug 2024 12:29:59 +0200
Subject: [PATCH v10 08/20] x86/boot: Place TXT MLE header in the
 kernel_info section
In-Reply-To: <20240826223835.3928819-9-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com> <20240826223835.3928819-9-ross.philipson@oracle.com>
Message-ID: <CAMj1kXGMMsB6BMAC9eWd2gKdEHHXGCLTXjavAK70dCz=-OyJug@mail.gmail.com>

On Tue, 27 Aug 2024 at 00:42, Ross Philipson <ross.philipson at oracle.com> wrote:
>
> The MLE (measured launch environment) header must be locatable by the
> boot loader and TXT must be setup to do a launch with this header's
> location. While the offset to the kernel_info structure does not need
> to be at a fixed offset, the offsets in the header must be relative
> offsets from the start of the setup kernel. The support in the linker
> file achieves this.
>
> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
> Suggested-by: Ard Biesheuvel <ardb at kernel.org>

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

> ---
>  arch/x86/boot/compressed/kernel_info.S | 50 +++++++++++++++++++++++---
>  arch/x86/boot/compressed/vmlinux.lds.S |  7 ++++
>  2 files changed, 53 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/kernel_info.S b/arch/x86/boot/compressed/kernel_info.S
> index f818ee8fba38..a0604a0d1756 100644
> --- a/arch/x86/boot/compressed/kernel_info.S
> +++ b/arch/x86/boot/compressed/kernel_info.S
> @@ -1,12 +1,20 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>
> +#include <linux/linkage.h>
>  #include <asm/bootparam.h>
>
> -       .section ".rodata.kernel_info", "a"
> +/*
> + * The kernel_info structure is not placed at a fixed offest in the
> + * kernel image. So this macro and the support in the linker file
> + * allow the relative offsets for the MLE header within the kernel
> + * image to be configured at build time.
> + */
> +#define roffset(X) ((X) - kernel_info)
>
> -       .global kernel_info
> +       .section ".rodata.kernel_info", "a"
>
> -kernel_info:
> +       .balign 16
> +SYM_DATA_START(kernel_info)
>         /* Header, Linux top (structure). */
>         .ascii  "LToP"
>         /* Size. */
> @@ -17,6 +25,40 @@ kernel_info:
>         /* Maximal allowed type for setup_data and setup_indirect structs. */
>         .long   SETUP_TYPE_MAX
>
> +       /* Offset to the MLE header structure */
> +#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
> +       .long   roffset(mle_header_offset)
> +#else
> +       .long   0
> +#endif
> +
>  kernel_info_var_len_data:
>         /* Empty for time being... */
> -kernel_info_end:
> +SYM_DATA_END_LABEL(kernel_info, SYM_L_LOCAL, kernel_info_end)
> +
> +#if IS_ENABLED(CONFIG_SECURE_LAUNCH)
> +       /*
> +        * The MLE Header per the TXT Specification, section 2.1
> +        * MLE capabilities, see table 4. Capabilities set:
> +        * bit 0: Support for GETSEC[WAKEUP] for RLP wakeup
> +        * bit 1: Support for RLP wakeup using MONITOR address
> +        * bit 2: The ECX register will contain the pointer to the MLE page table
> +        * bit 5: TPM 1.2 family: Details/authorities PCR usage support
> +        * bit 9: Supported format of TPM 2.0 event log - TCG compliant
> +        */
> +SYM_DATA_START(mle_header)
> +       .long   0x9082ac5a  /* UUID0 */
> +       .long   0x74a7476f  /* UUID1 */
> +       .long   0xa2555c0f  /* UUID2 */
> +       .long   0x42b651cb  /* UUID3 */
> +       .long   0x00000034  /* MLE header size */
> +       .long   0x00020002  /* MLE version 2.2 */
> +       .long   roffset(sl_stub_entry_offset) /* Linear entry point of MLE (virt. address) */
> +       .long   0x00000000  /* First valid page of MLE */
> +       .long   0x00000000  /* Offset within binary of first byte of MLE */
> +       .long   roffset(_edata_offset) /* Offset within binary of last byte + 1 of MLE */
> +       .long   0x00000227  /* Bit vector of MLE-supported capabilities */
> +       .long   0x00000000  /* Starting linear address of command line (unused) */
> +       .long   0x00000000  /* Ending linear address of command line (unused) */
> +SYM_DATA_END(mle_header)
> +#endif
> diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S
> index 083ec6d7722a..f82184801462 100644
> --- a/arch/x86/boot/compressed/vmlinux.lds.S
> +++ b/arch/x86/boot/compressed/vmlinux.lds.S
> @@ -118,3 +118,10 @@ SECTIONS
>         }
>         ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
>  }
> +
> +#ifdef CONFIG_SECURE_LAUNCH
> +PROVIDE(kernel_info_offset      = ABSOLUTE(kernel_info - startup_32));
> +PROVIDE(mle_header_offset       = kernel_info_offset + ABSOLUTE(mle_header - startup_32));
> +PROVIDE(sl_stub_entry_offset    = kernel_info_offset + ABSOLUTE(sl_stub_entry - startup_32));
> +PROVIDE(_edata_offset           = kernel_info_offset + ABSOLUTE(_edata - startup_32));
> +#endif
> --
> 2.39.3
>


From will at kernel.org  Tue Aug 27 05:24:59 2024
From: will at kernel.org (Will Deacon)
Date: Tue, 27 Aug 2024 13:24:59 +0100
Subject: [PATCH] arm64/vmcore: Add pgtable_l5_enabled information in
 vmcoreinfo
In-Reply-To: <20240826065219.305963-1-kuan-ying.lee@canonical.com>
References: <20240826065219.305963-1-kuan-ying.lee@canonical.com>
Message-ID: <20240827122459.GA4679@willie-the-truck>

On Mon, Aug 26, 2024 at 02:52:02PM +0800, Kuan-Ying Lee wrote:
> Since arm64 supports 5-level page tables, we need to add this
> information to vmcoreinfo to make debug tools know if 5-level
> page table is enabled or not.
> 
> Missing this information will break the debug tool like crash [1].
> 
> [1] https://github.com/crash-utility/crash
> 
> Signed-off-by: Kuan-Ying Lee <kuan-ying.lee at canonical.com>
> ---
>  Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 ++++++
>  arch/arm64/kernel/vmcore_info.c                | 3 +++
>  2 files changed, 9 insertions(+)

In which case, wouldn't you also want to know about pgtable_l4_enabled()?

Will


From thomas.lendacky at amd.com  Tue Aug 27 06:52:20 2024
From: thomas.lendacky at amd.com (Tom Lendacky)
Date: Tue, 27 Aug 2024 08:52:20 -0500
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <Zs1FrZVuZK14Je7z@MiWiFi-R3L-srv>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1FrZVuZK14Je7z@MiWiFi-R3L-srv>
Message-ID: <be6e5ab6-8b43-1a3f-39a6-b4aa5e0523ac@amd.com>

On 8/26/24 22:19, Baoquan He wrote:
> On 08/26/24 at 09:24am, Tom Lendacky wrote:
>> On 8/25/24 21:44, Baoquan He wrote:
>>> Recently, it's reported that kdump kernel is broken during bootup on
>>> SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
>>> can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
>>> IMA measurement log on kexec"). Just nobody ever tested it on SME
>>> system when enabling CONFIG_IMA_KEXEC.
>>>
>>>
>>> Here fix the code bug to make kexec/kdump kernel boot up successfully.
>>>
>>> Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
>>
>> The check that was modified was added by:
>> 	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
>>
>> The SETUP_INDIRECT patches seem to be the issue here.
> 
> Hmm, I didn't check it carefully, thanks for addding this info. While
> after checking commit b3c72fc9a78e, I feel the adding code was trying to
> fix your original early_memremap_is_setup_data(). Even though
> SETUP_INDIRECT type of setup_data has been added, the original
> early_memremap_is_setup_data() only check the starting address and
> the content of struct setup_data, that's obviously wrong.

IIRC, when this function was created, the value of "len" in setup_data
included the length of "data", so the calculation was correct. Everything
was contiguous in a setup_data element.

> 
> arch/x86/include/uapi/asm/setup_data.h:
> /* extensible setup data list node */
> struct setup_data {
>         __u64 next;
>         __u32 type;
>         __u32 len;
>         __u8 data[];
> };
> 
> As you can see, the zero-length will embed the carried data which is
> actually expected and adjacent to its carrier, the struct setup_data.

Right, and "len" is the length of that data. So paddr + len goes to the
end of the overall setup_data.

Thanks,
Tom

> 
>>


From thomas.lendacky at amd.com  Tue Aug 27 06:57:23 2024
From: thomas.lendacky at amd.com (Tom Lendacky)
Date: Tue, 27 Aug 2024 08:57:23 -0500
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <CALu+AoTNtzVGFyG=GLAtT=VEWJG7FNbx6jD_Ye+4ORYXOiMekw@mail.gmail.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1j31JGB/5EJatz@MiWiFi-R3L-srv>
 <CALu+AoTNtzVGFyG=GLAtT=VEWJG7FNbx6jD_Ye+4ORYXOiMekw@mail.gmail.com>
Message-ID: <b66bc23a-56d8-7115-4641-5869501ab114@amd.com>

On 8/27/24 00:41, Dave Young wrote:
> On Tue, 27 Aug 2024 at 13:28, Baoquan He <bhe at redhat.com> wrote:
>>
>> On 08/26/24 at 09:24am, Tom Lendacky wrote:
>>> On 8/25/24 21:44, Baoquan He wrote:
>>>> Recently, it's reported that kdump kernel is broken during bootup on
>>>> SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
>>>> can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
>>>> IMA measurement log on kexec"). Just nobody ever tested it on SME
>>>> system when enabling CONFIG_IMA_KEXEC.
>>>>

>>
>> I talked to Dave, he reminded me that people could mix the passed in
>> parameter 'size' and the local variable 'size' defined inside the while
>> loop, not sure which 'size' you are referring to.
>>
> Baoquan, you are right, but I think I mistakenly read the code in
> memremap_is_setup_data instead of early_memremap_is_setup_data.  You

Ditto.

> can check the memremap_is_setup_data, no "size = sizeof (*data)",  so
> these two functions could both need fixes.
> 
> Otherwise it would be better to change the function internal variable
> name, it could cause confusion even if the actual result is correct.

Yes, the use of size as a local variable while being passed in as a
parameter is very confusing.

Thanks,
Tom

> 
> Thanks
> Dave
> 


From thomas.lendacky at amd.com  Tue Aug 27 07:00:51 2024
From: thomas.lendacky at amd.com (Tom Lendacky)
Date: Tue, 27 Aug 2024 09:00:51 -0500
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <be6e5ab6-8b43-1a3f-39a6-b4aa5e0523ac@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1FrZVuZK14Je7z@MiWiFi-R3L-srv>
 <be6e5ab6-8b43-1a3f-39a6-b4aa5e0523ac@amd.com>
Message-ID: <ac929075-27a3-8cbd-5ffd-966ea3e82697@amd.com>

On 8/27/24 08:52, Tom Lendacky wrote:
> On 8/26/24 22:19, Baoquan He wrote:
>> On 08/26/24 at 09:24am, Tom Lendacky wrote:
>>> On 8/25/24 21:44, Baoquan He wrote:
>>>> Recently, it's reported that kdump kernel is broken during bootup on
>>>> SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
>>>> can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
>>>> IMA measurement log on kexec"). Just nobody ever tested it on SME
>>>> system when enabling CONFIG_IMA_KEXEC.
>>>>
>>>>
>>>> Here fix the code bug to make kexec/kdump kernel boot up successfully.
>>>>
>>>> Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
>>>
>>> The check that was modified was added by:
>>> 	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
>>>
>>> The SETUP_INDIRECT patches seem to be the issue here.
>>
>> Hmm, I didn't check it carefully, thanks for addding this info. While
>> after checking commit b3c72fc9a78e, I feel the adding code was trying to
>> fix your original early_memremap_is_setup_data(). Even though
>> SETUP_INDIRECT type of setup_data has been added, the original
>> early_memremap_is_setup_data() only check the starting address and
>> the content of struct setup_data, that's obviously wrong.
> 
> IIRC, when this function was created, the value of "len" in setup_data
> included the length of "data", so the calculation was correct. Everything
> was contiguous in a setup_data element.
> 
>>
>> arch/x86/include/uapi/asm/setup_data.h:
>> /* extensible setup data list node */
>> struct setup_data {
>>         __u64 next;
>>         __u32 type;
>>         __u32 len;
>>         __u8 data[];
>> };
>>
>> As you can see, the zero-length will embed the carried data which is
>> actually expected and adjacent to its carrier, the struct setup_data.
> 
> Right, and "len" is the length of that data. So paddr + len goes to the
> end of the overall setup_data.

Ah, I see what you're saying. "len" doesn't include the size of the
setup_data structure, only the data. If so, then, yes, adding a sizeof()
to the calculation in the if statement is correct.

Thanks,
Tom

> 
> Thanks,
> Tom
> 
>>
>>>


From ross.philipson at oracle.com  Tue Aug 27 10:19:13 2024
From: ross.philipson at oracle.com (ross.philipson at oracle.com)
Date: Tue, 27 Aug 2024 10:19:13 -0700
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <CAMj1kXEyStoqmvvQirxt_GXTnO2qQjOxtQGzHzQeCdRCYzT7uA@mail.gmail.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
 <20240826223835.3928819-21-ross.philipson@oracle.com>
 <CAMj1kXEyStoqmvvQirxt_GXTnO2qQjOxtQGzHzQeCdRCYzT7uA@mail.gmail.com>
Message-ID: <833c9b45-b11d-4253-afab-6c4e92d650d2@oracle.com>

On 8/27/24 3:28 AM, Ard Biesheuvel wrote:
> On Tue, 27 Aug 2024 at 00:44, Ross Philipson <ross.philipson at oracle.com> wrote:
>>
>> This support allows the DRTM launch to be initiated after an EFI stub
>> launch of the Linux kernel is done. This is accomplished by providing
>> a handler to jump to when a Secure Launch is in progress. This has to be
>> called after the EFI stub does Exit Boot Services.
>>
>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
> 
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>

Thank you for the two reviews
Ross

> 
>> ---
>>   drivers/firmware/efi/libstub/efistub.h  |  8 ++
>>   drivers/firmware/efi/libstub/x86-stub.c | 98 +++++++++++++++++++++++++
>>   2 files changed, 106 insertions(+)
>>
>> diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
>> index d33ccbc4a2c6..baf42d6d0796 100644
>> --- a/drivers/firmware/efi/libstub/efistub.h
>> +++ b/drivers/firmware/efi/libstub/efistub.h
>> @@ -135,6 +135,14 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
>>          *hi = upper_32_bits(data);
>>   }
>>
>> +static inline
>> +void efi_set_u64_form(u32 lo, u32 hi, u64 *data)
>> +{
>> +       u64 upper = hi;
>> +
>> +       *data = lo | upper << 32;
>> +}
>> +
>>   /*
>>    * Allocation types for calls to boottime->allocate_pages.
>>    */
>> diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
>> index f8e465da344d..04786c1b3b5d 100644
>> --- a/drivers/firmware/efi/libstub/x86-stub.c
>> +++ b/drivers/firmware/efi/libstub/x86-stub.c
>> @@ -9,6 +9,8 @@
>>   #include <linux/efi.h>
>>   #include <linux/pci.h>
>>   #include <linux/stddef.h>
>> +#include <linux/slr_table.h>
>> +#include <linux/slaunch.h>
>>
>>   #include <asm/efi.h>
>>   #include <asm/e820/types.h>
>> @@ -923,6 +925,99 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
>>          return efi_adjust_memory_range_protection(addr, kernel_text_size);
>>   }
>>
>> +static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
>> +                                                struct boot_params *boot_params)
>> +{
>> +       struct slr_entry_intel_info *txt_info;
>> +       struct slr_entry_policy *policy;
>> +       struct txt_os_mle_data *os_mle;
>> +       bool updated = false;
>> +       int i;
>> +
>> +       txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
>> +       if (!txt_info)
>> +               return false;
>> +
>> +       os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
>> +       if (!os_mle)
>> +               return false;
>> +
>> +       os_mle->boot_params_addr = (u64)boot_params;
>> +
>> +       policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
>> +       if (!policy)
>> +               return false;
>> +
>> +       for (i = 0; i < policy->nr_entries; i++) {
>> +               if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
>> +                       policy->policy_entries[i].entity = (u64)boot_params;
>> +                       updated = true;
>> +                       break;
>> +               }
>> +       }
>> +
>> +       /*
>> +        * If this is a PE entry into EFI stub the mocked up boot params will
>> +        * be missing some of the setup header data needed for the second stage
>> +        * of the Secure Launch boot.
>> +        */
>> +       if (image) {
>> +               struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
>> +                                           offsetof(struct boot_params, hdr));
>> +               u64 cmdline_ptr;
>> +
>> +               boot_params->hdr.setup_sects = hdr->setup_sects;
>> +               boot_params->hdr.syssize = hdr->syssize;
>> +               boot_params->hdr.version = hdr->version;
>> +               boot_params->hdr.loadflags = hdr->loadflags;
>> +               boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
>> +               boot_params->hdr.min_alignment = hdr->min_alignment;
>> +               boot_params->hdr.xloadflags = hdr->xloadflags;
>> +               boot_params->hdr.init_size = hdr->init_size;
>> +               boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
>> +               efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
>> +                                &cmdline_ptr);
>> +               boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
>> +       }
>> +
>> +       return updated;
>> +}
>> +
>> +static void efi_secure_launch(struct boot_params *boot_params)
>> +{
>> +       struct slr_entry_dl_info *dlinfo;
>> +       efi_guid_t guid = SLR_TABLE_GUID;
>> +       dl_handler_func handler_callback;
>> +       struct slr_table *slrt;
>> +
>> +       if (!IS_ENABLED(CONFIG_SECURE_LAUNCH))
>> +               return;
>> +
>> +       /*
>> +        * The presence of this table indicated a Secure Launch
>> +        * is being requested.
>> +        */
>> +       slrt = (struct slr_table *)get_efi_config_table(guid);
>> +       if (!slrt || slrt->magic != SLR_TABLE_MAGIC)
>> +               return;
>> +
>> +       /*
>> +        * Since the EFI stub library creates its own boot_params on entry, the
>> +        * SLRT and TXT heap have to be updated with this version.
>> +        */
>> +       if (!efi_secure_launch_update_boot_params(slrt, boot_params))
>> +               return;
>> +
>> +       /* Jump through DL stub to initiate Secure Launch */
>> +       dlinfo = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO);
>> +
>> +       handler_callback = (dl_handler_func)dlinfo->dl_handler;
>> +
>> +       handler_callback(&dlinfo->bl_context);
>> +
>> +       unreachable();
>> +}
>> +
>>   static void __noreturn enter_kernel(unsigned long kernel_addr,
>>                                      struct boot_params *boot_params)
>>   {
>> @@ -1050,6 +1145,9 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
>>                  goto fail;
>>          }
>>
>> +       /* If a Secure Launch is in progress, this never returns */
>> +       efi_secure_launch(boot_params);
>> +
>>          /*
>>           * Call the SEV init code while still running with the firmware's
>>           * GDT/IDT, so #VC exceptions will be handled by EFI.
>> --
>> 2.39.3
>>



From ebiggers at kernel.org  Tue Aug 27 11:14:26 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Tue, 27 Aug 2024 11:14:26 -0700
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <20240531021656.GA1502@sol.localdomain>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
Message-ID: <20240827181426.GC2049@sol.localdomain>

On Thu, May 30, 2024 at 07:16:56PM -0700, Eric Biggers wrote:
> On Thu, May 30, 2024 at 06:03:18PM -0700, Ross Philipson wrote:
> > From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
> > 
> > For better or worse, Secure Launch needs SHA-1 and SHA-256. The
> > choice of hashes used lie with the platform firmware, not with
> > software, and is often outside of the users control.
> > 
> > Even if we'd prefer to use SHA-256-only, if firmware elected to start us
> > with the SHA-1 and SHA-256 backs active, we still need SHA-1 to parse
> > the TPM event log thus far, and deliberately cap the SHA-1 PCRs in order
> > to safely use SHA-256 for everything else.
> > 
> > The SHA-1 code here has its origins in the code from the main kernel:
> > 
> > commit c4d5b9ffa31f ("crypto: sha1 - implement base layer for SHA-1")
> > 
> > A modified version of this code was introduced to the lib/crypto/sha1.c
> > to bring it in line with the SHA-256 code and allow it to be pulled into the
> > setup kernel in the same manner as SHA-256 is.
> > 
> > Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
> > Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
> 
> Thanks.  This explanation doesn't seem to have made it into the actual code or
> documentation.  Can you please get it into a more permanent location?

I see that a new version of the patchset was sent out but this suggestion was
not taken.  Are you planning to address it?

- Eric


From lkp at intel.com  Tue Aug 27 13:09:17 2024
From: lkp at intel.com (kernel test robot)
Date: Wed, 28 Aug 2024 04:09:17 +0800
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <20240826223835.3928819-21-ross.philipson@oracle.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
Message-ID: <202408280656.66ZxoOOL-lkp@intel.com>

Hi Ross,

kernel test robot noticed the following build warnings:

[auto build test WARNING on tip/x86/core]
[also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
[cannot apply to herbert-crypto-2.6/master next-20240827]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225
base:   tip/x86/core
patch link:    https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson%40oracle.com
patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20240828/202408280656.66ZxoOOL-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240828/202408280656.66ZxoOOL-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408280656.66ZxoOOL-lkp at intel.com/

All warnings (new ones prefixed by >>):

   drivers/firmware/efi/libstub/x86-stub.c: In function 'efi_secure_launch_update_boot_params':
>> drivers/firmware/efi/libstub/x86-stub.c:941:40: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     941 |         os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
         |                                        ^
   drivers/firmware/efi/libstub/x86-stub.c:945:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     945 |         os_mle->boot_params_addr = (u64)boot_params;
         |                                    ^
   drivers/firmware/efi/libstub/x86-stub.c:953:60: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     953 |                         policy->policy_entries[i].entity = (u64)boot_params;
         |                                                            ^
   drivers/firmware/efi/libstub/x86-stub.c:980:56: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     980 |                 boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
         |                                                        ^
   drivers/firmware/efi/libstub/x86-stub.c: In function 'efi_secure_launch':
   drivers/firmware/efi/libstub/x86-stub.c:1014:28: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
    1014 |         handler_callback = (dl_handler_func)dlinfo->dl_handler;
         |                            ^


vim +941 drivers/firmware/efi/libstub/x86-stub.c

   927	
   928	static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
   929							 struct boot_params *boot_params)
   930	{
   931		struct slr_entry_intel_info *txt_info;
   932		struct slr_entry_policy *policy;
   933		struct txt_os_mle_data *os_mle;
   934		bool updated = false;
   935		int i;
   936	
   937		txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
   938		if (!txt_info)
   939			return false;
   940	
 > 941		os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
   942		if (!os_mle)
   943			return false;
   944	
   945		os_mle->boot_params_addr = (u64)boot_params;
   946	
   947		policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
   948		if (!policy)
   949			return false;
   950	
   951		for (i = 0; i < policy->nr_entries; i++) {
   952			if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
   953				policy->policy_entries[i].entity = (u64)boot_params;
   954				updated = true;
   955				break;
   956			}
   957		}
   958	
   959		/*
   960		 * If this is a PE entry into EFI stub the mocked up boot params will
   961		 * be missing some of the setup header data needed for the second stage
   962		 * of the Secure Launch boot.
   963		 */
   964		if (image) {
   965			struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
   966						    offsetof(struct boot_params, hdr));
   967			u64 cmdline_ptr;
   968	
   969			boot_params->hdr.setup_sects = hdr->setup_sects;
   970			boot_params->hdr.syssize = hdr->syssize;
   971			boot_params->hdr.version = hdr->version;
   972			boot_params->hdr.loadflags = hdr->loadflags;
   973			boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
   974			boot_params->hdr.min_alignment = hdr->min_alignment;
   975			boot_params->hdr.xloadflags = hdr->xloadflags;
   976			boot_params->hdr.init_size = hdr->init_size;
   977			boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
   978			efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
   979					 &cmdline_ptr);
   980			boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
   981		}
   982	
   983		return updated;
   984	}
   985	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From Ashish.Kalra at amd.com  Tue Aug 27 13:38:04 2024
From: Ashish.Kalra at amd.com (Ashish Kalra)
Date: Tue, 27 Aug 2024 20:38:04 +0000
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
Message-ID: <20240827203804.4989-1-Ashish.Kalra@amd.com>

From: Ashish Kalra <ashish.kalra at amd.com>

With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
crashkernel boot failure with the following signature:

[  563.497112] sysrq: Trigger a crash
[  563.508415] Kernel panic - not syncing: sysrq triggered crash
[  563.522002] CPU: 10 UID: 0 PID: 4661 Comm: bash Kdump: loaded Not tainted 6.11.0-rc3-next-20240813-snp-host-f2a41ff576cc-dirty #61
[  563.549762] Hardware name: AMD Corporation ETHANOL_X/ETHANOL_X, BIOS RXM100AB 10/17/2022
[  563.566266] Call Trace:
[  563.576430]  <TASK>
[  563.585932]  dump_stack_lvl+0x2b/0x90
[  563.597244]  dump_stack+0x14/0x20
[  563.608141]  panic+0x3b9/0x400
[  563.618801]  ? srso_alias_return_thunk+0x5/0xfbef5
[  563.631271]  sysrq_handle_crash+0x19/0x20
[  563.642696]  __handle_sysrq+0xf9/0x290
[  563.653691]  ? srso_alias_return_thunk+0x5/0xfbef5
[  563.666126]  write_sysrq_trigger+0x60/0x80
...
...
[  564.186804] in panic
[  564.194287] in panic_other_cpus_shutdown
[  564.203674] kexec: in crash_smp_send_stop
[  564.213205] kexec: in kdump_nmi_shootdown_cpus
[  564.224338] Kernel Offset: 0x35a00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  564.282209] in snp_shutdown_on_panic after decommision, wbinvd + df_flush required
[  564.462217] ccp 0000:23:00.1: SEV-SNP DF_FLUSH failed with error 14
[  564.676920] kexec: in native_machine_crash_shutdown
early console in extract_kernel
input_data: 0x000000007410d2cc
input_len: 0x0000000000ce98b2
output: 0x0000000071600000
output_len: 0x000000000379eb8c
kernel_total_size: 0x0000000002c30000
needed_size: 0x0000000003800000
trampoline_32bit: 0x0000000000000000

Invalid physical address chosen!

Physical KASLR disabled: no suitable memory region!

Virtual KASLR using RDRAND RDTSC...

Decompressing Linux... Parsing ELF... Performing relocations... done.
Booting the kernel (entry_offset: 0x0000000000000bda).
[    0.000000] Linux version 6.11.0-rc3-next-20240813-snp-host-f2a41ff576cc-dirty (amd at ethanolx7e2ehost) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils) 2.40) #61 SMP Mon Aug 19 19:59:02 UTC 2024
[    0.000000] Command line: BOOT_IMAGE=/vmlinuz-6.11.0-rc3-next-20240813-snp-host-f2a41ff576cc-dirty root=UUID=4b87a03b-0e78-42ca-a8ad-997e63bba4e0 ro console=tty0 console=ttyS0,115200n8 earlyprintk=ttyS0,115200n8 amd_iommu_dump=1 reset_devices systemd.unit=kdump-tools-dump.service nr_cpus=1 irqpoll nousb elfcorehdr=1916276K
[    0.000000] KERNEL supported cpus:
...
...
[    1.671804] AMD-Vi: Using global IVHD EFR:0x841f77e022094ace, EFR2:0x0
[    1.679835] AMD-Vi: Translation is already enabled - trying to copy translation structures
[    1.689363] AMD-Vi: Copied DEV table from previous kernel.
[    1.864369] AMD-Vi: Completion-Wait loop timed out
[    2.038289] AMD-Vi: Completion-Wait loop timed out
[    2.212215] AMD-Vi: Completion-Wait loop timed out
[    2.386141] AMD-Vi: Completion-Wait loop timed out
[    2.560068] AMD-Vi: Completion-Wait loop timed out
[    2.733997] AMD-Vi: Completion-Wait loop timed out
[    2.907927] AMD-Vi: Completion-Wait loop timed out
[    3.081855] AMD-Vi: Completion-Wait loop timed out
[    3.225500] AMD-Vi: Completion-Wait loop timed out
[    3.231083] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
d out
[    3.579592] AMD-Vi: Completion-Wait loop timed out
[    3.753164] AMD-Vi: Completion-Wait loop timed out
[    3.815762] Kernel panic - not syncing: timer doesn't work through Interrupt-remapped IO-APIC
[    3.825347] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.11.0-rc3-next-20240813-snp-host-f2a41ff576cc-dirty #61
[    3.837188] Hardware name: AMD Corporation ETHANOL_X/ETHANOL_X, BIOS RXM100AB 10/17/2022
[    3.846215] Call Trace:
[    3.848939]  <TASK>
[    3.851277]  dump_stack_lvl+0x2b/0x90
[    3.855354]  dump_stack+0x14/0x20
[    3.859050]  panic+0x3b9/0x400
[    3.862454]  panic_if_irq_remap+0x21/0x30
[    3.866925]  setup_IO_APIC+0x8aa/0xa50
[    3.871106]  ? __pfx_amd_iommu_enable_faulting+0x10/0x10
[    3.877032]  ? __cpuhp_setup_state+0x5e/0xd0
[    3.881793]  apic_intr_mode_init+0x6a/0xf0
[    3.886360]  x86_late_time_init+0x28/0x40
[    3.890832]  start_kernel+0x6a8/0xb50
[    3.894914]  x86_64_start_reservations+0x1c/0x30
[    3.900064]  x86_64_start_kernel+0xbf/0x110
[    3.904729]  ? setup_ghcb+0x12/0x130
[    3.908716]  common_startup_64+0x13e/0x141
[    3.913283]  </TASK>
[    3.915715] in panic
[    3.918149] in panic_other_cpus_shutdown
[    3.922523] ---[ end Kernel panic - not syncing: timer doesn't work through Interrupt-remapped IO-APIC ]---

This happens as SNP_SHUTDOWN_EX fails when SNP VMs are active as the
firmware checks every encryption-capable ASID to verify that it is
not in use by a guest and a DF_FLUSH is not required. If a DF_FLUSH
is required, the firmware returns DFFLUSH_REQUIRED.

To fix this, added support to do SNP_DECOMMISION of all active SNP VMs
in the panic notifier before doing SNP_SHUTDOWN_EX, but then
SNP_DECOMMISION tags all CPUs on which guest has been activated to do
a WBINVD. This causes SNP_DF_FLUSH command failure with the following
flow: SNP_DECOMMISION -> SNP_SHUTDOWN_EX -> SNP_DF_FLUSH ->
failure with WBINVD_REQUIRED.

When panic notifier is invoked all other CPUs have already been
shutdown, so it is not possible to do a wbinvd_on_all_cpus() after
SNP_DECOMMISION has been executed. This eventually causes SNP_SHUTDOWN_EX
to fail after SNP_DECOMMISION.

Adding fix to do SNP_DECOMMISION and subsequent WBINVD on all CPUs
during NMI shutdown of CPUs as part of disabling virtualization on
all CPUs via cpu_emergency_disable_virtualization ->
svm_emergency_disable().

This fixes and enables crashkernel/kdump on SNP host.

Fixes: c3b86e61b756 ("x86/cpufeatures: Enable/unmask SEV-SNP CPU feature")
Signed-off-by: Ashish Kalra <ashish.kalra at amd.com>
---
 arch/x86/kvm/svm/sev.c | 39 ++++++++++++++++++
 arch/x86/kvm/svm/svm.c | 91 ++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/svm/svm.h |  3 +-
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 0b851ef937f2..34ddea43c4e6 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -89,6 +89,7 @@ static unsigned int nr_asids;
 static unsigned long *sev_asid_bitmap;
 static unsigned long *sev_reclaim_asid_bitmap;
 
+static void **snp_asid_to_gctx_pages_map;
 static int snp_decommission_context(struct kvm *kvm);
 
 struct enc_region {
@@ -2248,6 +2249,9 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
 		goto e_free_context;
 	}
 
+	if (snp_asid_to_gctx_pages_map)
+		snp_asid_to_gctx_pages_map[sev_get_asid(kvm)] = sev->snp_context;
+
 	return 0;
 
 e_free_context:
@@ -2884,9 +2888,35 @@ static int snp_decommission_context(struct kvm *kvm)
 	snp_free_firmware_page(sev->snp_context);
 	sev->snp_context = NULL;
 
+	if (snp_asid_to_gctx_pages_map)
+		snp_asid_to_gctx_pages_map[sev_get_asid(kvm)] = NULL;
+
 	return 0;
 }
 
+/*
+ * NOTE: called in NMI context from sev_emergency_disable().
+ */
+void snp_decommision_all(void)
+{
+	struct sev_data_snp_addr data = {};
+	int ret, asid;
+
+	if (!snp_asid_to_gctx_pages_map)
+		return;
+
+	for (asid = 1; asid < min_sev_asid; asid++) {
+		if (snp_asid_to_gctx_pages_map[asid]) {
+			data.address = __sme_pa(snp_asid_to_gctx_pages_map[asid]);
+			ret = sev_do_cmd(SEV_CMD_SNP_DECOMMISSION, &data, NULL);
+			if (!ret) {
+				snp_free_firmware_page(snp_asid_to_gctx_pages_map[asid]);
+				snp_asid_to_gctx_pages_map[asid] = NULL;
+			}
+		}
+	}
+}
+
 void sev_vm_destroy(struct kvm *kvm)
 {
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
@@ -3052,6 +3082,13 @@ void __init sev_hardware_setup(void)
 	sev_es_supported = true;
 	sev_snp_supported = sev_snp_enabled && cc_platform_has(CC_ATTR_HOST_SEV_SNP);
 
+	if (sev_snp_supported) {
+		snp_asid_to_gctx_pages_map = kmalloc_array(min_sev_asid,
+							   sizeof(void *),
+							   GFP_KERNEL | __GFP_ZERO);
+		if (!snp_asid_to_gctx_pages_map)
+			pr_warn("Could not allocate SNP asid to guest context map\n");
+	}
 out:
 	if (boot_cpu_has(X86_FEATURE_SEV))
 		pr_info("SEV %s (ASIDs %u - %u)\n",
@@ -3094,6 +3131,8 @@ void sev_hardware_unsetup(void)
 
 	misc_cg_set_capacity(MISC_CG_RES_SEV, 0);
 	misc_cg_set_capacity(MISC_CG_RES_SEV_ES, 0);
+
+	kfree(snp_asid_to_gctx_pages_map);
 }
 
 int sev_cpu_init(struct svm_cpu_data *sd)
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index e13c54d93964..a8f64a1710c2 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -17,6 +17,7 @@
 #include <linux/highmem.h>
 #include <linux/amd-iommu.h>
 #include <linux/sched.h>
+#include <linux/delay.h>
 #include <linux/trace_events.h>
 #include <linux/slab.h>
 #include <linux/hashtable.h>
@@ -248,6 +249,8 @@ static unsigned long iopm_base;
 
 DEFINE_PER_CPU(struct svm_cpu_data, svm_data);
 
+static DEFINE_SPINLOCK(snp_decommision_lock);
+
 /*
  * Only MSR_TSC_AUX is switched via the user return hook.  EFER is switched via
  * the VMCB, and the SYSCALL/SYSENTER MSRs are handled by VMLOAD/VMSAVE.
@@ -594,9 +597,97 @@ static inline void kvm_cpu_svm_disable(void)
 
 static void svm_emergency_disable(void)
 {
+	static atomic_t waiting_for_cpus_synchronized;
+	static bool synchronize_cpus_initiated;
+	static bool snp_decommision_handled;
+	static atomic_t cpus_synchronized;
+
 	kvm_rebooting = true;
 
 	kvm_cpu_svm_disable();
+
+	if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+		return;
+
+	/*
+	 * SNP_SHUTDOWN_EX fails when SNP VMs are active as the firmware checks
+	 * every encryption-capable ASID to verify that it is not in use by a
+	 * guest and a DF_FLUSH is not required. If a DF_FLUSH is required,
+	 * the firmware returns DFFLUSH_REQUIRED. To address this, SNP_DECOMMISION
+	 * is required to shutdown all active SNP VMs, but SNP_DECOMMISION tags all
+	 * CPUs that guest was activated on to do a WBINVD. When panic notifier
+	 * is invoked all other CPUs have already been shutdown, so it is not
+	 * possible to do a wbinvd_on_all_cpus() after SNP_DECOMMISION has been
+	 * executed. This eventually causes SNP_SHUTDOWN_EX to fail after
+	 * SNP_DECOMMISION. To fix this, do SNP_DECOMMISION and subsequent WBINVD
+	 * on all CPUs during NMI shutdown of CPUs as part of disabling
+	 * virtualization on all CPUs via cpu_emergency_disable_virtualization().
+	 */
+
+	spin_lock(&snp_decommision_lock);
+
+	/*
+	 * exit early for call from native_machine_crash_shutdown()
+	 * as SNP_DECOMMISSION has already been done as part of
+	 * NMI shutdown of the CPUs.
+	 */
+	if (snp_decommision_handled) {
+		spin_unlock(&snp_decommision_lock);
+		return;
+	}
+
+	/*
+	 * Synchronize all CPUs handling NMI before issuing
+	 * SNP_DECOMMISSION.
+	 */
+	if (!synchronize_cpus_initiated) {
+		/*
+		 * one CPU handling panic, the other CPU is initiator for
+		 * CPU synchronization.
+		 */
+		atomic_set(&waiting_for_cpus_synchronized, num_online_cpus() - 2);
+		synchronize_cpus_initiated = true;
+		/*
+		 * Ensure CPU synchronization parameters are setup before dropping
+		 * the lock to let other CPUs continue to reach synchronization.
+		 */
+		wmb();
+
+		spin_unlock(&snp_decommision_lock);
+
+		/*
+		 * This will not cause system to hang forever as the CPU
+		 * handling panic waits for maximum one second for
+		 * other CPUs to stop in nmi_shootdown_cpus().
+		 */
+		while (atomic_read(&waiting_for_cpus_synchronized) > 0)
+		       mdelay(1);
+
+		/* Reacquire the lock once CPUs are synchronized */
+		spin_lock(&snp_decommision_lock);
+
+		atomic_set(&cpus_synchronized, 1);
+	} else {
+		atomic_dec(&waiting_for_cpus_synchronized);
+		/*
+		 * drop the lock to let other CPUs contiune to reach
+		 * synchronization.
+		 */
+		spin_unlock(&snp_decommision_lock);
+
+		while (atomic_read(&cpus_synchronized) == 0)
+		       mdelay(1);
+
+		/* Try to re-acquire lock after CPUs are synchronized */
+		spin_lock(&snp_decommision_lock);
+	}
+
+	if (!snp_decommision_handled) {
+		snp_decommision_all();
+		snp_decommision_handled = true;
+	}
+	spin_unlock(&snp_decommision_lock);
+	wbinvd();
 }
 
 static void svm_hardware_disable(void)
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 76107c7d0595..2f933b941b8d 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -749,6 +749,7 @@ void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu);
 int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
 void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
 int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn);
+void snp_decommision_all(void);
 #else
 static inline struct page *snp_safe_alloc_page_node(int node, gfp_t gfp)
 {
@@ -779,7 +780,7 @@ static inline int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
 {
 	return 0;
 }
-
+static void snp_decommision_all(void);
 #endif
 
 /* vmenter.S */
-- 
2.34.1



From bhe at redhat.com  Tue Aug 27 15:40:02 2024
From: bhe at redhat.com (Baoquan He)
Date: Wed, 28 Aug 2024 06:40:02 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <ac929075-27a3-8cbd-5ffd-966ea3e82697@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com>
 <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
 <Zs1FrZVuZK14Je7z@MiWiFi-R3L-srv>
 <be6e5ab6-8b43-1a3f-39a6-b4aa5e0523ac@amd.com>
 <ac929075-27a3-8cbd-5ffd-966ea3e82697@amd.com>
Message-ID: <Zs5VwrKVetWFkYmR@MiWiFi-R3L-srv>

On 08/27/24 at 09:00am, Tom Lendacky wrote:
> On 8/27/24 08:52, Tom Lendacky wrote:
> > On 8/26/24 22:19, Baoquan He wrote:
> >> On 08/26/24 at 09:24am, Tom Lendacky wrote:
> >>> On 8/25/24 21:44, Baoquan He wrote:
> >>>> Recently, it's reported that kdump kernel is broken during bootup on
> >>>> SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> >>>> can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> >>>> IMA measurement log on kexec"). Just nobody ever tested it on SME
> >>>> system when enabling CONFIG_IMA_KEXEC.
> >>>>
> >>>>
> >>>> Here fix the code bug to make kexec/kdump kernel boot up successfully.
> >>>>
> >>>> Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
> >>>
> >>> The check that was modified was added by:
> >>> 	b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
> >>>
> >>> The SETUP_INDIRECT patches seem to be the issue here.
> >>
> >> Hmm, I didn't check it carefully, thanks for addding this info. While
> >> after checking commit b3c72fc9a78e, I feel the adding code was trying to
> >> fix your original early_memremap_is_setup_data(). Even though
> >> SETUP_INDIRECT type of setup_data has been added, the original
> >> early_memremap_is_setup_data() only check the starting address and
> >> the content of struct setup_data, that's obviously wrong.
> > 
> > IIRC, when this function was created, the value of "len" in setup_data
> > included the length of "data", so the calculation was correct. Everything
> > was contiguous in a setup_data element.
> > 
> >>
> >> arch/x86/include/uapi/asm/setup_data.h:
> >> /* extensible setup data list node */
> >> struct setup_data {
> >>         __u64 next;
> >>         __u32 type;
> >>         __u32 len;
> >>         __u8 data[];
> >> };
> >>
> >> As you can see, the zero-length will embed the carried data which is
> >> actually expected and adjacent to its carrier, the struct setup_data.
> > 
> > Right, and "len" is the length of that data. So paddr + len goes to the
> > end of the overall setup_data.
> 
> Ah, I see what you're saying. "len" doesn't include the size of the
> setup_data structure, only the data. If so, then, yes, adding a sizeof()
> to the calculation in the if statement is correct.

Exactly. That could confuse people sometime.



From bhe at redhat.com  Tue Aug 27 15:48:03 2024
From: bhe at redhat.com (Baoquan He)
Date: Wed, 28 Aug 2024 06:48:03 +0800
Subject: [PATCH] arm64/vmcore: Add pgtable_l5_enabled information in
 vmcoreinfo
In-Reply-To: <20240827122459.GA4679@willie-the-truck>
References: <20240826065219.305963-1-kuan-ying.lee@canonical.com>
 <20240827122459.GA4679@willie-the-truck>
Message-ID: <Zs5Xo5eVUvGMbtSv@MiWiFi-R3L-srv>

On 08/27/24 at 01:24pm, Will Deacon wrote:
> On Mon, Aug 26, 2024 at 02:52:02PM +0800, Kuan-Ying Lee wrote:
> > Since arm64 supports 5-level page tables, we need to add this
> > information to vmcoreinfo to make debug tools know if 5-level
> > page table is enabled or not.
> > 
> > Missing this information will break the debug tool like crash [1].
> > 
> > [1] https://github.com/crash-utility/crash
> > 
> > Signed-off-by: Kuan-Ying Lee <kuan-ying.lee at canonical.com>
> > ---
> >  Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 ++++++
> >  arch/arm64/kernel/vmcore_info.c                | 3 +++
> >  2 files changed, 9 insertions(+)
> 
> In which case, wouldn't you also want to know about pgtable_l4_enabled()?

That is a good question. I guess it's deduced in code, mostly needed for
different PAGE_OFFSET, how to transfer virtual addr to physical addr,
etc.

Add Crash utility experts here.



From inf at lab.noncloud.ch  Mon Aug 26 19:41:21 2024
From: inf at lab.noncloud.ch (Malcolm D Amos)
Date: Mon, 26 Aug 2024 19:41:21 -0700
Subject: Good Day...
Message-ID: <mailman.3.1724816983.1276.kexec@lists.infradead.org>

Hello.

Sorry for my direct email even though you do not know me We are interested in Partnering with you in any Business Project you need funds injected into and wish to remain and maintain a silent Financial position.We can provide capital injection for the advancement of any viable capital project which you require funding for We intend to be a silent partner with the sole aim of providing the necessary capital injection into your business, as long as it?s viable and this Could be an Equity/JV/loan term basis?

Please contact me if you are interested

Warms regards
Malcolm D Amos.
mathers.david at yandex.com


From ardb at kernel.org  Wed Aug 28 06:28:01 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 28 Aug 2024 15:28:01 +0200
Subject: [RFCv2 1/9] efi/libstub: Ask efi_random_alloc() to skip unusable memory
In-Reply-To: <20240819145417.23367-2-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com> <20240819145417.23367-2-piliu@redhat.com>
Message-ID: <CAMj1kXG_TynaQni6mzXYg6sCybSMba7cuwnyb4qi5LNZ=53pKQ@mail.gmail.com>

On Mon, 19 Aug 2024 at 16:55, Pingfan Liu <piliu at redhat.com> wrote:
>
> efi_random_alloc() demands EFI_ALLOCATE_ADDRESS when allocate_pages(),
> but the current implement can not ensure the selected target locates
> inside free area, that is to exclude EFI_BOOT_SERVICES_*,
> EFI_RUNTIME_SERVICES_* etc.
>
> Fix the issue by checking md->type.
>
> Signed-off-by: Pingfan Liu <piliu at redhat.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> To: linux-efi at vger.kernel.org
> ---
>  drivers/firmware/efi/libstub/randomalloc.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c
> index c41e7b2091cdd..7304e767688f2 100644
> --- a/drivers/firmware/efi/libstub/randomalloc.c
> +++ b/drivers/firmware/efi/libstub/randomalloc.c
> @@ -79,6 +79,8 @@ efi_status_t efi_random_alloc(unsigned long size,
>                 efi_memory_desc_t *md = (void *)map->map + map_offset;
>                 unsigned long slots;
>
> +               if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> +                       continue;

This is wrong in 3 different ways:
- md->type is not a bitmask
- || is not bitwise but boolean
- get_entry_num_slots() ignores all memory types except
EFI_CONVENTIONAL_MEMORY anyway.

So what exactly are you trying to fix here?


>                 slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
>                                             alloc_max);
>                 MD_NUM_SLOTS(md) = slots;
> @@ -111,6 +113,9 @@ efi_status_t efi_random_alloc(unsigned long size,
>                 efi_physical_addr_t target;
>                 unsigned long pages;
>
> +               if (!(md->type & (EFI_CONVENTIONAL_MEMORY || EFI_PERSISTENT_MEMORY)))
> +                       continue;
> +
>                 if (total_mirrored_slots > 0 &&
>                     !(md->attribute & EFI_MEMORY_MORE_RELIABLE))
>                         continue;
> --
> 2.41.0
>


From ardb at kernel.org  Wed Aug 28 10:08:14 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 28 Aug 2024 19:08:14 +0200
Subject: [RFCv2 0/9] UEFI emulator for kexec
In-Reply-To: <20240819145417.23367-1-piliu@redhat.com>
References: <20240819145417.23367-1-piliu@redhat.com>
Message-ID: <CAMj1kXGB3VF=NAQBADkdmodSVaZyf8h2n0FXwi5fXLUE2WgXag@mail.gmail.com>

On Mon, 19 Aug 2024 at 16:55, Pingfan Liu <piliu at redhat.com> wrote:
>
> *** Background ***
>
> As more PE format kernel images are introduced, it post challenge to kexec to
> cope with the new format.
>
> In my attempt to add support for arm64 zboot image in the kernel [1],
> Ard suggested using an emulator to tackle this issue.  Last year, when
> Jan tried to introduce UKI support in the kernel [2], Ard mentioned the
> emulator approach again [3]
>
> After discussion, Ard's approach seems to be a more promising solution
> to handle PE format kernels once and for all.  This series follows that
> approach and implements an emulator to emulate EFI boot time services,
> allowing the efistub kernel to self-extract and boot.
>
> Another year has passed, and UKI kernel is more and more frequently used
> in product. I think it is time to pay effort to resolve this issue.
>
>
> *** Overview of implement ***
> The whole model consits of three parts:
>
> -1. The emulator
> It is a self-relocatable PIC code, which is finally linked into kernel, but not
> export any internal symbol to kernel.  It mainly contains: a PE file parser,
> which loads PE format kernel, a group of functions to emulate efi boot service.
>
> -2. inside kernel, PE-format loader
> Its main task is to set up two extra kexec_segment, one for emulator, the other
> for passing information from the first kernel to emulator.
>
> -3. set up identity mapping only for the memory used by the emulator.
> Here it relies on kimage_alloc_control_pages() to get pages, which will not
> stamped during the process of kexec relocate (cp from src to dst). And since the
> mapping only covers a small range of memory, it cost small amount memory.
>
>
> *** To do ***
>
> Currently, it only works on arm64 virt machine. For x86, it needs some slightly
> changes. (I plan to do it in the next version)
>
> Also, this series does not implement a memory allocator, which I plan to
> implement with the help of bitmap.
>
> About console, currently it hard code for arm64 virt machine, later it should
> extract the information through ACPI table.
>
> For kdump code, it is not implmented yet. But it should share the majority of
> this series.
>
>
> *** Test of this series ***
> I have tested this series on arm64 virt machine. There I booted the vmlinuz.efi
> and kexec_file_load a UKI image, then switch to the second kernel.
>
> I used a modified kexec-tools [4], which just skips the check of the file format and passes the file directly to kernel.
>
> [1]: https://lore.kernel.org/linux-arm-kernel/ZBvKSis+dfnqa+Vz at piliu.users.ipa.redhat.com/T/#m42abb0ad3c10126b8b3bfae8a596deb707d6f76e
> [2]: https://lore.kernel.org/lkml/20230918173607.421d2616 at rotkaeppchen/T/
> [3]: https://lore.kernel.org/lkml/20230918173607.421d2616 at rotkaeppchen/T/#mc60aa591cb7616ceb39e1c98f352383f9ba6e985
> [4]: https://github.com/pfliu/kexec-tools.git branch: kexec_uefi_emulator
>
>
> RFCv1 -> RFCv2:
> -1.Support to run UKI kernel by: add LoadImage() and StartImage(), add
>    PE file relocation support, add InstallMultiProtocol()
> -2.Also set up idmap for EFI runtime memory descriptor since UKI's
>    systemd-stub calls runtime service
> -3.Move kexec_pe_image.c from arch/arm64/kernel to kernel/, since it
>    aims to provide a more general architecture support.
>
> RFCv1: https://lore.kernel.org/linux-efi/20240718085759.13247-1-piliu at redhat.com/
> RFCv2: https://github.com/pfliu/linux.git  branch kexec_uefi_emulator_RFCv2
>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Jan Hendrik Farr <kernel at jfarr.cc>
> Cc: Philipp Rudo <prudo at redhat.com>
> Cc: Lennart Poettering <mzxreary at 0pointer.de>
> Cc: Jarkko Sakkinen <jarkko at kernel.org>
> Cc: Eric Biederman <ebiederm at xmission.com>
> Cc: Baoquan He <bhe at redhat.com>
> Cc: Dave Young <dyoung at redhat.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: kexec at lists.infradead.org
> Cc: linux-efi at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
>
>
>
> Pingfan Liu (9):
>   efi/libstub: Ask efi_random_alloc() to skip unusable memory
>   efi/libstub: Complete efi_simple_text_output_protocol
>   efi/emulator: Initial rountines to emulate EFI boot time service
>   efi/emulator: Turn on mmu for arm64
>   kexec: Introduce kexec_pe_image to parse and load PE file
>   arm64: kexec: Introduce a new member param_mem to kimage_arch
>   arm64: mm: Change to prototype of
>   arm64: kexec: Prepare page table for emulator
>   arm64: kexec: Enable kexec_pe_image
>

Thanks for putting this RFC together. This is useful work, and gives
us food for thought and discussion.

There are a few problems that become apparent when going through these changes.

1. Implementing UEFI entirely is intractable, and unnecessary.
Implementing the subset of UEFI that is actually needed to boot Linux
*is* tractable, though, but we need to work together to write this
down somewhere.
  - the EFI stub needs the boot services for the EFI memory map and
the allocation routines
  - GRUB needs block I/O
  - systemd-stub/UKI needs file I/O to look for sidecars
  - etc etc

I implemented a Rust 'efiloader' crate a while ago that encapsulates
most of this (it can boot Linux/arm64 on QEMU and boot x86 via GRUB in
user space **). Adding file I/O to this should be straight-forward -
as Lennart points out, we only need the protocol, it doesn't need to
be backed by an actual file system, it just needs to be able to expose
other files in the right way.

2. Running the UEFI emulator on bare metal is not going to scale.
Cloning UART driver code and MMU code etc is a can of worms that you
want to leave closed. And as Lennart points out, there is other
hardware (TPM) that needs to be accessible as well. Providing a
separate set of drivers for all hardware that the EFI emulator may
need to access is not a tractable problem either.

The fix for this, as I see it, is to run the EFI emulator in user
space, to the point where the payload calls ExitBootServices(). This
will allow all I/O and memory protocol to be implemented trivially,
using C library routines. I have a crude prototype** of this running
to the point where ExitBootServices() is called (and then it crashes).
The tricky yet interesting bit here is how we migrate a chunk of user
space memory to the bare metal context that will be created by the
kexec syscall later (in which the call to ExitBootServices() would
return and proceed with the boot). But the principle is rather
straight-forward, and would permit us, e.g., to kexec an OS installer
too.

3. We need to figure out how to support TPM and PCRs in the context of
kexec. This is a fundamental issue with verified boot, given that the
kexec PCR state is necessarily different from the boot state, and so
we cannot reuse the TPM directly if we want to pretend that we are
doing an ordinary boot in kexec. The alternative is to leave the TPM
in a state where the kexec kernel can access its sealed secrets, and
mock up the TCG2 EFI protocols using a shim that sits between the TPM
hardware (as the real TCG2 protocols will be long gone) and the EFI
payload. But as I said, this is a fundamental issue, as the ability to
pretend that a kexec boot is a pristine boot would mean that verified
boot is broken.


As future work, I'd like to propose to collaborate on some alignment
regarding a UEFI baseline for Linux, i.e., the parts that we actually
need to boot Linux.

For this series in particular, I don't see a way forward where we
adopt this approach, and carry all this code inside the kernel.

Thanks.
Ard.


From lkp at intel.com  Wed Aug 28 10:09:15 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 29 Aug 2024 01:09:15 +0800
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <20240826223835.3928819-21-ross.philipson@oracle.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
Message-ID: <202408290030.FEbUhHbr-lkp@intel.com>

Hi Ross,

kernel test robot noticed the following build warnings:

[auto build test WARNING on tip/x86/core]
[also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
[cannot apply to herbert-crypto-2.6/master next-20240828]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225
base:   tip/x86/core
patch link:    https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson%40oracle.com
patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
config: i386-randconfig-062-20240828 (https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408290030.FEbUhHbr-lkp at intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/firmware/efi/libstub/x86-stub.c:945:41: sparse: sparse: non size-preserving pointer to integer cast
   drivers/firmware/efi/libstub/x86-stub.c:953:65: sparse: sparse: non size-preserving pointer to integer cast
>> drivers/firmware/efi/libstub/x86-stub.c:980:70: sparse: sparse: non size-preserving integer to pointer cast
   drivers/firmware/efi/libstub/x86-stub.c:1014:45: sparse: sparse: non size-preserving integer to pointer cast

vim +945 drivers/firmware/efi/libstub/x86-stub.c

   927	
   928	static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
   929							 struct boot_params *boot_params)
   930	{
   931		struct slr_entry_intel_info *txt_info;
   932		struct slr_entry_policy *policy;
   933		struct txt_os_mle_data *os_mle;
   934		bool updated = false;
   935		int i;
   936	
   937		txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
   938		if (!txt_info)
   939			return false;
   940	
   941		os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
   942		if (!os_mle)
   943			return false;
   944	
 > 945		os_mle->boot_params_addr = (u64)boot_params;
   946	
   947		policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
   948		if (!policy)
   949			return false;
   950	
   951		for (i = 0; i < policy->nr_entries; i++) {
   952			if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
   953				policy->policy_entries[i].entity = (u64)boot_params;
   954				updated = true;
   955				break;
   956			}
   957		}
   958	
   959		/*
   960		 * If this is a PE entry into EFI stub the mocked up boot params will
   961		 * be missing some of the setup header data needed for the second stage
   962		 * of the Secure Launch boot.
   963		 */
   964		if (image) {
   965			struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
   966						    offsetof(struct boot_params, hdr));
   967			u64 cmdline_ptr;
   968	
   969			boot_params->hdr.setup_sects = hdr->setup_sects;
   970			boot_params->hdr.syssize = hdr->syssize;
   971			boot_params->hdr.version = hdr->version;
   972			boot_params->hdr.loadflags = hdr->loadflags;
   973			boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
   974			boot_params->hdr.min_alignment = hdr->min_alignment;
   975			boot_params->hdr.xloadflags = hdr->xloadflags;
   976			boot_params->hdr.init_size = hdr->init_size;
   977			boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
   978			efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
   979					 &cmdline_ptr);
 > 980			boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
   981		}
   982	
   983		return updated;
   984	}
   985	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From ardb at kernel.org  Wed Aug 28 10:14:06 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 28 Aug 2024 19:14:06 +0200
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <202408290030.FEbUhHbr-lkp@intel.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com> <202408290030.FEbUhHbr-lkp@intel.com>
Message-ID: <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>

On Wed, 28 Aug 2024 at 19:09, kernel test robot <lkp at intel.com> wrote:
>
> Hi Ross,
>
> kernel test robot noticed the following build warnings:
>
> [auto build test WARNING on tip/x86/core]
> [also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
> [cannot apply to herbert-crypto-2.6/master next-20240828]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225
> base:   tip/x86/core
> patch link:    https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson%40oracle.com
> patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
> config: i386-randconfig-062-20240828 (https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config)


This is a i386 32-bit build, which makes no sense: this stuff should
just declare 'depends on 64BIT'


> compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp at intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202408290030.FEbUhHbr-lkp at intel.com/
>
> sparse warnings: (new ones prefixed by >>)
> >> drivers/firmware/efi/libstub/x86-stub.c:945:41: sparse: sparse: non size-preserving pointer to integer cast
>    drivers/firmware/efi/libstub/x86-stub.c:953:65: sparse: sparse: non size-preserving pointer to integer cast
> >> drivers/firmware/efi/libstub/x86-stub.c:980:70: sparse: sparse: non size-preserving integer to pointer cast
>    drivers/firmware/efi/libstub/x86-stub.c:1014:45: sparse: sparse: non size-preserving integer to pointer cast
>
> vim +945 drivers/firmware/efi/libstub/x86-stub.c
>
>    927
>    928  static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
>    929                                                   struct boot_params *boot_params)
>    930  {
>    931          struct slr_entry_intel_info *txt_info;
>    932          struct slr_entry_policy *policy;
>    933          struct txt_os_mle_data *os_mle;
>    934          bool updated = false;
>    935          int i;
>    936
>    937          txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
>    938          if (!txt_info)
>    939                  return false;
>    940
>    941          os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
>    942          if (!os_mle)
>    943                  return false;
>    944
>  > 945          os_mle->boot_params_addr = (u64)boot_params;
>    946
>    947          policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
>    948          if (!policy)
>    949                  return false;
>    950
>    951          for (i = 0; i < policy->nr_entries; i++) {
>    952                  if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
>    953                          policy->policy_entries[i].entity = (u64)boot_params;
>    954                          updated = true;
>    955                          break;
>    956                  }
>    957          }
>    958
>    959          /*
>    960           * If this is a PE entry into EFI stub the mocked up boot params will
>    961           * be missing some of the setup header data needed for the second stage
>    962           * of the Secure Launch boot.
>    963           */
>    964          if (image) {
>    965                  struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
>    966                                              offsetof(struct boot_params, hdr));
>    967                  u64 cmdline_ptr;
>    968
>    969                  boot_params->hdr.setup_sects = hdr->setup_sects;
>    970                  boot_params->hdr.syssize = hdr->syssize;
>    971                  boot_params->hdr.version = hdr->version;
>    972                  boot_params->hdr.loadflags = hdr->loadflags;
>    973                  boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
>    974                  boot_params->hdr.min_alignment = hdr->min_alignment;
>    975                  boot_params->hdr.xloadflags = hdr->xloadflags;
>    976                  boot_params->hdr.init_size = hdr->init_size;
>    977                  boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
>    978                  efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
>    979                                   &cmdline_ptr);
>  > 980                  boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
>    981          }
>    982
>    983          return updated;
>    984  }
>    985
>
> --
> 0-DAY CI Kernel Test Service
> https://github.com/intel/lkp-tests/wiki
>


From ardb at kernel.org  Wed Aug 28 10:45:09 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 28 Aug 2024 19:45:09 +0200
Subject: [PATCH v8 01/15] x86/boot: Place kernel_info at a fixed offset
In-Reply-To: <9d01a6d2-4dd9-4331-8fc9-b01c07cfdbb5@apertussolutions.com>
References: <20240214221847.2066632-1-ross.philipson@oracle.com>
 <20240214221847.2066632-2-ross.philipson@oracle.com> <CAMj1kXH3Gvr3vDRLDdXuc0s7ZAQYE6+D7tmCRBjJWwWt2fn4-w@mail.gmail.com>
 <9d01a6d2-4dd9-4331-8fc9-b01c07cfdbb5@apertussolutions.com>
Message-ID: <CAMj1kXHn6xeAskWiDLvvA4oG3j9_tqx+iMYJXMqmgvyX4pMzgg@mail.gmail.com>

(cc Stuart)

On Thu, 21 Mar 2024 at 15:46, Daniel P. Smith
<dpsmith at apertussolutions.com> wrote:
>
> Hi Ard!
>
> On 2/15/24 02:56, Ard Biesheuvel wrote:
> > On Wed, 14 Feb 2024 at 23:31, Ross Philipson <ross.philipson at oracle.com> wrote:
> >>
> >> From: Arvind Sankar <nivedita at alum.mit.edu>
> >>
> >> There are use cases for storing the offset of a symbol in kernel_info.
> >> For example, the trenchboot series [0] needs to store the offset of the
> >> Measured Launch Environment header in kernel_info.
> >>
> >
> > Why? Is this information consumed by the bootloader?
>
> Yes, the bootloader needs a standardized means to find the offset of the
> MLE header, which communicates a set of meta-data needed by the DCE in
> order to set up for and start the loaded kernel. Arm will also need to
> provide a similar metadata structure and alternative entry point (or a
> complete rewrite of the existing entry point), as the current Arm entry
> point is in direct conflict with Arm DRTM specification.
>

Digging up an old thread here: could you elaborate on this? What do
you mean by 'Arm entry point' and how does it conflict directly with
the Arm DRTM specification? The Linux/arm64 port predates that spec by
about 10 years, so I would expect the latter to take the former into
account. If that failed to happen, we should fix the spec while we
still can.

Thanks,
Ard.


From ross.philipson at oracle.com  Wed Aug 28 13:14:45 2024
From: ross.philipson at oracle.com (ross.philipson at oracle.com)
Date: Wed, 28 Aug 2024 13:14:45 -0700
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <20240827181426.GC2049@sol.localdomain>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <20240827181426.GC2049@sol.localdomain>
Message-ID: <601646a2-46ac-47a0-a8b7-1d45a09172ab@oracle.com>

On 8/27/24 11:14 AM, 'Eric Biggers' via trenchboot-devel wrote:
> On Thu, May 30, 2024 at 07:16:56PM -0700, Eric Biggers wrote:
>> On Thu, May 30, 2024 at 06:03:18PM -0700, Ross Philipson wrote:
>>> From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
>>>
>>> For better or worse, Secure Launch needs SHA-1 and SHA-256. The
>>> choice of hashes used lie with the platform firmware, not with
>>> software, and is often outside of the users control.
>>>
>>> Even if we'd prefer to use SHA-256-only, if firmware elected to start us
>>> with the SHA-1 and SHA-256 backs active, we still need SHA-1 to parse
>>> the TPM event log thus far, and deliberately cap the SHA-1 PCRs in order
>>> to safely use SHA-256 for everything else.
>>>
>>> The SHA-1 code here has its origins in the code from the main kernel:
>>>
>>> commit c4d5b9ffa31f ("crypto: sha1 - implement base layer for SHA-1")
>>>
>>> A modified version of this code was introduced to the lib/crypto/sha1.c
>>> to bring it in line with the SHA-256 code and allow it to be pulled into the
>>> setup kernel in the same manner as SHA-256 is.
>>>
>>> Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
>>> Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
>>
>> Thanks.  This explanation doesn't seem to have made it into the actual code or
>> documentation.  Can you please get it into a more permanent location?
> 
> I see that a new version of the patchset was sent out but this suggestion was
> not taken.  Are you planning to address it?

Sorry we sort of overlooked that part of the request. We will take the 
latest commit message, clean it up a little and put it in 
boot/compressed/sha1.c file as a comment. I believe that is what you 
would like us to do.

Thanks
Ross

> 
> - Eric
> 



From ross.philipson at oracle.com  Wed Aug 28 13:19:16 2024
From: ross.philipson at oracle.com (ross.philipson at oracle.com)
Date: Wed, 28 Aug 2024 13:19:16 -0700
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
 <202408290030.FEbUhHbr-lkp@intel.com>
 <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>
Message-ID: <6b214ad2-d448-4f5f-85e9-93cd38e0e035@oracle.com>

On 8/28/24 10:14 AM, Ard Biesheuvel wrote:
> On Wed, 28 Aug 2024 at 19:09, kernel test robot <lkp at intel.com> wrote:
>>
>> Hi Ross,
>>
>> kernel test robot noticed the following build warnings:
>>
>> [auto build test WARNING on tip/x86/core]
>> [also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
>> [cannot apply to herbert-crypto-2.6/master next-20240828]
>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>> And when submitting patch, we suggest to use '--base' as documented in
>> https://urldefense.com/v3/__https://git-scm.com/docs/git-format-patch*_base_tree_information__;Iw!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIxuz-LAC$ ]
>>
>> url:    https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI7Z6SQKy$
>> base:   tip/x86/core
>> patch link:    https://urldefense.com/v3/__https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson*40oracle.com__;JQ!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIzWfs1XZ$
>> patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
>> config: i386-randconfig-062-20240828 (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIwkYG0TY$ )
> 
> 
> This is a i386 32-bit build, which makes no sense: this stuff should
> just declare 'depends on 64BIT'

Our config entry already has 'depends on X86_64' which in turn depends 
on 64BIT. I would think that would be enough. Do you think it needs an 
explicit 'depends on 64BIT' in our entry as well?

Thanks
Ross

> 
> 
>> compiler: clang version 18.1.5 (https://urldefense.com/v3/__https://github.com/llvm/llvm-project__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI2SDLdTN$  617a15a9eac96088ae5e9134248d8236e34b91b1)
>> reproduce (this is a W=1 build): (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/reproduce__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI5MJDdIG$ )
>>
>> If you fix the issue in a separate patch/commit (i.e. not just a new version of
>> the same patch/commit), kindly add following tags
>> | Reported-by: kernel test robot <lkp at intel.com>
>> | Closes: https://urldefense.com/v3/__https://lore.kernel.org/oe-kbuild-all/202408290030.FEbUhHbr-lkp at intel.com/__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI-MitiqR$
>>
>> sparse warnings: (new ones prefixed by >>)
>>>> drivers/firmware/efi/libstub/x86-stub.c:945:41: sparse: sparse: non size-preserving pointer to integer cast
>>     drivers/firmware/efi/libstub/x86-stub.c:953:65: sparse: sparse: non size-preserving pointer to integer cast
>>>> drivers/firmware/efi/libstub/x86-stub.c:980:70: sparse: sparse: non size-preserving integer to pointer cast
>>     drivers/firmware/efi/libstub/x86-stub.c:1014:45: sparse: sparse: non size-preserving integer to pointer cast
>>
>> vim +945 drivers/firmware/efi/libstub/x86-stub.c
>>
>>     927
>>     928  static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
>>     929                                                   struct boot_params *boot_params)
>>     930  {
>>     931          struct slr_entry_intel_info *txt_info;
>>     932          struct slr_entry_policy *policy;
>>     933          struct txt_os_mle_data *os_mle;
>>     934          bool updated = false;
>>     935          int i;
>>     936
>>     937          txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
>>     938          if (!txt_info)
>>     939                  return false;
>>     940
>>     941          os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
>>     942          if (!os_mle)
>>     943                  return false;
>>     944
>>   > 945          os_mle->boot_params_addr = (u64)boot_params;
>>     946
>>     947          policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
>>     948          if (!policy)
>>     949                  return false;
>>     950
>>     951          for (i = 0; i < policy->nr_entries; i++) {
>>     952                  if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
>>     953                          policy->policy_entries[i].entity = (u64)boot_params;
>>     954                          updated = true;
>>     955                          break;
>>     956                  }
>>     957          }
>>     958
>>     959          /*
>>     960           * If this is a PE entry into EFI stub the mocked up boot params will
>>     961           * be missing some of the setup header data needed for the second stage
>>     962           * of the Secure Launch boot.
>>     963           */
>>     964          if (image) {
>>     965                  struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
>>     966                                              offsetof(struct boot_params, hdr));
>>     967                  u64 cmdline_ptr;
>>     968
>>     969                  boot_params->hdr.setup_sects = hdr->setup_sects;
>>     970                  boot_params->hdr.syssize = hdr->syssize;
>>     971                  boot_params->hdr.version = hdr->version;
>>     972                  boot_params->hdr.loadflags = hdr->loadflags;
>>     973                  boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
>>     974                  boot_params->hdr.min_alignment = hdr->min_alignment;
>>     975                  boot_params->hdr.xloadflags = hdr->xloadflags;
>>     976                  boot_params->hdr.init_size = hdr->init_size;
>>     977                  boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
>>     978                  efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
>>     979                                   &cmdline_ptr);
>>   > 980                  boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
>>     981          }
>>     982
>>     983          return updated;
>>     984  }
>>     985
>>
>> --
>> 0-DAY CI Kernel Test Service
>> https://urldefense.com/v3/__https://github.com/intel/lkp-tests/wiki__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIy5kGTJf$
>>



From ebiggers at kernel.org  Wed Aug 28 16:13:50 2024
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 28 Aug 2024 23:13:50 +0000
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <601646a2-46ac-47a0-a8b7-1d45a09172ab@oracle.com>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <20240827181426.GC2049@sol.localdomain>
 <601646a2-46ac-47a0-a8b7-1d45a09172ab@oracle.com>
Message-ID: <20240828231350.GA558903@google.com>

On Wed, Aug 28, 2024 at 01:14:45PM -0700, ross.philipson at oracle.com wrote:
> On 8/27/24 11:14 AM, 'Eric Biggers' via trenchboot-devel wrote:
> > On Thu, May 30, 2024 at 07:16:56PM -0700, Eric Biggers wrote:
> > > On Thu, May 30, 2024 at 06:03:18PM -0700, Ross Philipson wrote:
> > > > From: "Daniel P. Smith" <dpsmith at apertussolutions.com>
> > > > 
> > > > For better or worse, Secure Launch needs SHA-1 and SHA-256. The
> > > > choice of hashes used lie with the platform firmware, not with
> > > > software, and is often outside of the users control.
> > > > 
> > > > Even if we'd prefer to use SHA-256-only, if firmware elected to start us
> > > > with the SHA-1 and SHA-256 backs active, we still need SHA-1 to parse
> > > > the TPM event log thus far, and deliberately cap the SHA-1 PCRs in order
> > > > to safely use SHA-256 for everything else.
> > > > 
> > > > The SHA-1 code here has its origins in the code from the main kernel:
> > > > 
> > > > commit c4d5b9ffa31f ("crypto: sha1 - implement base layer for SHA-1")
> > > > 
> > > > A modified version of this code was introduced to the lib/crypto/sha1.c
> > > > to bring it in line with the SHA-256 code and allow it to be pulled into the
> > > > setup kernel in the same manner as SHA-256 is.
> > > > 
> > > > Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
> > > > Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
> > > 
> > > Thanks.  This explanation doesn't seem to have made it into the actual code or
> > > documentation.  Can you please get it into a more permanent location?
> > 
> > I see that a new version of the patchset was sent out but this suggestion was
> > not taken.  Are you planning to address it?
> 
> Sorry we sort of overlooked that part of the request. We will take the
> latest commit message, clean it up a little and put it in
> boot/compressed/sha1.c file as a comment. I believe that is what you would
> like us to do.
> 

Do users of this feature need to make a decision about SHA-1?  If so there needs
to be guidance in Documentation/.  A comment in a .c file is not user facing.

- Eric


From luto at amacapital.net  Wed Aug 28 20:17:05 2024
From: luto at amacapital.net (Andy Lutomirski)
Date: Wed, 28 Aug 2024 20:17:05 -0700
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <87ttflli09.ffs@tglx>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com> <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org> <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
Message-ID: <CALCETrXQ7rChWLDqTG0+KY7rsfajSPguMnHO1G4VJi_mgwN9Zw@mail.gmail.com>

On Thu, Aug 15, 2024 at 12:10?PM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> On Thu, Aug 15 2024 at 13:38, Daniel P. Smith wrote:
> > On 5/31/24 09:54, Eric W. Biederman wrote:
> >> Eric Biggers <ebiggers at kernel.org> writes:
> >>> That paragraph is also phrased as a hypothetical, "Even if we'd prefer to use
> >>> SHA-256-only".  That implies that you do not, in fact, prefer SHA-256 only.  Is
> >>> that the case?  Sure, maybe there are situations where you *have* to use SHA-1,
> >>> but why would you not at least *prefer* SHA-256?
> >>
> >> Yes.  Please prefer to use SHA-256.
> >>
> >> Have you considered implementing I think it is SHA1-DC (as git has) that
> >> is compatible with SHA1 but blocks the known class of attacks where
> >> sha1 is actively broken at this point?
> >
> > We are using the kernel's implementation, addressing what the kernel
> > provides is beyond our efforts. Perhaps someone who is interested in
> > improving the kernel's SHA1 could submit a patch implementing/replacing
> > it with SHA1-DC, as I am sure the maintainers would welcome the help.
>
> Well, someone who is interested to get his "secure" code merged should
> have a vested interested to have a non-broken SHA1 implementation if
> there is a sensible requirement to use SHA1 in that new "secure" code,
> no?
>
> Just for the record. The related maintainers can rightfully decide to
> reject known broken "secure" code on a purely technical argument.
>

Wait, hold on a second.

SHA1-DC isn't SHA1.  It's a different hash function that is mostly
compatible with SHA1, is different on some inputs, and is maybe more
secure.  But the _whole point_ of using SHA1 in the TPM code (well,
this really should be the whole point for new applications) is to
correctly cap the SHA1 PCRs so we can correctly _turn them off_ in the
best way without breaking compatibility with everything that might
read the event log.  I think that anyone suggesting using SHA1-DC for
this purpose should give some actual analysis as to why they think
it's an improvement, let alone even valid.

Ross et al, can you confirm that your code actually, at least by
default and with a monstrous warning to anyone who tries to change the
default, caps SHA1 PCRs if SHA256 is available?  And then can we maybe
all stop hassling the people trying to develop this series about the
fact that they're doing their best with the obnoxious system that the
TPM designers gave them?

Thanks,
Andy


From mjg59 at srcf.ucam.org  Wed Aug 28 20:25:26 2024
From: mjg59 at srcf.ucam.org (Matthew Garrett)
Date: Thu, 29 Aug 2024 04:25:26 +0100
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <CALCETrXQ7rChWLDqTG0+KY7rsfajSPguMnHO1G4VJi_mgwN9Zw@mail.gmail.com>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com>
 <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org>
 <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx>
 <CALCETrXQ7rChWLDqTG0+KY7rsfajSPguMnHO1G4VJi_mgwN9Zw@mail.gmail.com>
Message-ID: <Zs/qJsKu3StL3Wzt@srcf.ucam.org>

On Wed, Aug 28, 2024 at 08:17:05PM -0700, Andy Lutomirski wrote:

> Ross et al, can you confirm that your code actually, at least by
> default and with a monstrous warning to anyone who tries to change the
> default, caps SHA1 PCRs if SHA256 is available?  And then can we maybe
> all stop hassling the people trying to develop this series about the
> fact that they're doing their best with the obnoxious system that the
> TPM designers gave them?

Presumably this would be dependent upon non-SHA1 banks being enabled?


From bp at alien8.de  Thu Aug 29 01:34:49 2024
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 29 Aug 2024 10:34:49 +0200
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <20240827203804.4989-1-Ashish.Kalra@amd.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
Message-ID: <87475131-856C-44DC-A27A-84648294F094@alien8.de>

On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
>From: Ashish Kalra <ashish.kalra at amd.com>
>
>With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
>crashkernel boot failure with the following signature:

Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and there's potential to lose guest data in the process?!

I don't think you want to be on the receiving end of those customer support calls at your cloud provider...

-- 
Sent from a small device: formatting sucks and brevity is inevitable. 


From bhe at redhat.com  Thu Aug 29 03:40:14 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 29 Aug 2024 18:40:14 +0800
Subject: [PATCH v2 0/2] x86/mm/sme: fix the kdump kernel breakage on SME system when CONFIG_IMA_KEXEC=y
Message-ID: <20240829104016.84139-1-bhe@redhat.com>

In this v2 posting,
- patch 2 is to fix the kdump kernel breakage;
- patch 1 is added to clean up the confusing local varibale naming because
people may mix up the local variable 'size' with the passed in parameter
in function early_memremap_is_setup_data(). This cleanup is suggested by
Dave and Tom during v1 patch reviewing.

V1 post can be found here:
===
[PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system when CONFIG_IMA_KEXEC=y
https://lore.kernel.org/all/20240826024457.22423-1-bhe at redhat.com/T/#u

Baoquan He (2):
  x86/mm: rename the confusing local variable in
    early_memremap_is_setup_data()
  x86/mm/sme: fix the kdump kernel breakage on SME system when
    CONFIG_IMA_KEXEC=y

 arch/x86/mm/ioremap.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

-- 
2.41.0



From bhe at redhat.com  Thu Aug 29 03:40:15 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 29 Aug 2024 18:40:15 +0800
Subject: [PATCH v2 1/2] x86/mm: rename the confusing local variable in early_memremap_is_setup_data()
In-Reply-To: <20240829104016.84139-1-bhe@redhat.com>
References: <20240829104016.84139-1-bhe@redhat.com>
Message-ID: <20240829104016.84139-2-bhe@redhat.com>

In function early_memremap_is_setup_data(), parameter 'size' passed has
the same name as the local variable inside the while loop. That
confuses people who sometime mix up them when reading code.

Here rename the local variable 'size' inside while loop to 'sd_size'.

And also add one local variable 'sd_size' likewise in function
memremap_is_setup_data() to simplify code. In later patch, this can also
be used.

Signed-off-by: Baoquan He <bhe at redhat.com>
---
 arch/x86/mm/ioremap.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index aa7d279321ea..f1ee8822ddf1 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -640,7 +640,7 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 
 	paddr = boot_params.hdr.setup_data;
 	while (paddr) {
-		unsigned int len;
+		unsigned int len, sd_size;
 
 		if (phys_addr == paddr)
 			return true;
@@ -652,6 +652,8 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 			return false;
 		}
 
+		sd_size = sizeof(*data);
+
 		paddr_next = data->next;
 		len = data->len;
 
@@ -662,7 +664,9 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 
 		if (data->type == SETUP_INDIRECT) {
 			memunmap(data);
-			data = memremap(paddr, sizeof(*data) + len,
+
+			sd_size += len;
+			data = memremap(paddr, sd_size,
 					MEMREMAP_WB | MEMREMAP_DEC);
 			if (!data) {
 				pr_warn("failed to memremap indirect setup_data\n");
@@ -701,7 +705,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 
 	paddr = boot_params.hdr.setup_data;
 	while (paddr) {
-		unsigned int len, size;
+		unsigned int len, sd_size;
 
 		if (phys_addr == paddr)
 			return true;
@@ -712,7 +716,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 			return false;
 		}
 
-		size = sizeof(*data);
+		sd_size = sizeof(*data);
 
 		paddr_next = data->next;
 		len = data->len;
@@ -723,9 +727,9 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 		}
 
 		if (data->type == SETUP_INDIRECT) {
-			size += len;
+			sd_size += len;
 			early_memunmap(data, sizeof(*data));
-			data = early_memremap_decrypted(paddr, size);
+			data = early_memremap_decrypted(paddr, sd_size);
 			if (!data) {
 				pr_warn("failed to early memremap indirect setup_data\n");
 				return false;
@@ -739,7 +743,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 			}
 		}
 
-		early_memunmap(data, size);
+		early_memunmap(data, sd_size);
 
 		if ((phys_addr > paddr) && (phys_addr < (paddr + len)))
 			return true;
-- 
2.41.0



From bhe at redhat.com  Thu Aug 29 03:40:16 2024
From: bhe at redhat.com (Baoquan He)
Date: Thu, 29 Aug 2024 18:40:16 +0800
Subject: [PATCH v2 2/2] x86/mm/sme: fix the kdump kernel breakage on SME system when CONFIG_IMA_KEXEC=y
In-Reply-To: <20240829104016.84139-1-bhe@redhat.com>
References: <20240829104016.84139-1-bhe@redhat.com>
Message-ID: <20240829104016.84139-3-bhe@redhat.com>

Recently, it's reported that kdump kernel is broken during bootup on
SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
IMA measurement log on kexec"). Just nobody ever tested it on SME
system when enabling CONFIG_IMA_KEXEC.

--------------------------------------------------
 ima: No TPM chip found, activating TPM-bypass!
 Loading compiled-in module X.509 certificates
 Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
 ima: Allocated hash algorithm: sha256
 Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
 CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
 Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
 RIP: 0010:ima_restore_measurement_list+0xdc/0x420
 Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
 RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
 RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
 RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
 RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
 R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
 R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
 FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
 Call Trace:
  <TASK>
  ? show_trace_log_lvl+0x1b0/0x2f0
  ? show_trace_log_lvl+0x1b0/0x2f0
  ? ima_load_kexec_buffer+0x6e/0xf0
  ? __die_body.cold+0x8/0x12
  ? die_addr+0x3c/0x60
  ? exc_general_protection+0x178/0x410
  ? asm_exc_general_protection+0x26/0x30
  ? ima_restore_measurement_list+0xdc/0x420
  ? vprintk_emit+0x1f0/0x270
  ? ima_load_kexec_buffer+0x6e/0xf0
  ima_load_kexec_buffer+0x6e/0xf0
  ima_init+0x52/0xb0
  ? __pfx_init_ima+0x10/0x10
  init_ima+0x26/0xc0
  ? __pfx_init_ima+0x10/0x10
  do_one_initcall+0x5b/0x300
  do_initcalls+0xdf/0x100
  ? __pfx_kernel_init+0x10/0x10
  kernel_init_freeable+0x147/0x1a0
  kernel_init+0x1a/0x140
  ret_from_fork+0x34/0x50
  ? __pfx_kernel_init+0x10/0x10
  ret_from_fork_asm+0x1a/0x30
  </TASK>
 Modules linked in:
 ---[ end trace 0000000000000000 ]---
 RIP: 0010:ima_restore_measurement_list+0xdc/0x420
 Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
 RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
 RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
 RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
 RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
 R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
 R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
 FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
 Kernel panic - not syncing: Fatal exception
 Kernel Offset: disabled
 Rebooting in 10 seconds..

>From debugging printing, the stored addr and size of ima_kexec buffer
are not decrypted correctly like:
 ------
 ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
 ------

There are three pieces of setup_data info passed to kexec/kdump kernel:
SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
ima_kexec buffer suffered from the incorrect decryption. After
debugging, it's because of the code bug in early_memremap_is_setup_data()
where checking the embedded content inside setup_data takes wrong range
calculation.

The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
and the length of setup_data is 0x10. When checking if data is inside
the embedded conent of setup_data, the starting address of efi data and
rng_seed happened to land in the wrong calculated range. While the
ima_kexec's starting address unluckily doesn't pass the checking, then
error occurred.

Here fix the code bug to make kexec/kdump kernel boot up successfully.

And also fix the similar buggy code in memremap_is_setup_data() which
are found out during code reviewing.

Fixes: b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
Signed-off-by: Baoquan He <bhe at redhat.com>
---
 arch/x86/mm/ioremap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index f1ee8822ddf1..4cadc7ef1cb4 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -657,7 +657,7 @@ static bool memremap_is_setup_data(resource_size_t phys_addr,
 		paddr_next = data->next;
 		len = data->len;
 
-		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+		if ((phys_addr > paddr) && (phys_addr < (paddr + sd_size + len))) {
 			memunmap(data);
 			return true;
 		}
@@ -721,7 +721,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
 		paddr_next = data->next;
 		len = data->len;
 
-		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+		if ((phys_addr > paddr) && (phys_addr < (paddr + sd_size + len))) {
 			early_memunmap(data, sizeof(*data));
 			return true;
 		}
-- 
2.41.0



From noodles at earth.li  Thu Aug 29 06:23:56 2024
From: noodles at earth.li (Jonathan McDowell)
Date: Thu, 29 Aug 2024 14:23:56 +0100
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <6b214ad2-d448-4f5f-85e9-93cd38e0e035@oracle.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
 <202408290030.FEbUhHbr-lkp@intel.com>
 <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>
 <6b214ad2-d448-4f5f-85e9-93cd38e0e035@oracle.com>
Message-ID: <ZtB2bP1Mx3zTr9e5@earth.li>

On Wed, Aug 28, 2024 at 01:19:16PM -0700, ross.philipson at oracle.com wrote:
> On 8/28/24 10:14 AM, Ard Biesheuvel wrote:
> > On Wed, 28 Aug 2024 at 19:09, kernel test robot <lkp at intel.com> wrote:
> > > 
> > > Hi Ross,
> > > 
> > > kernel test robot noticed the following build warnings:
> > > 
> > > [auto build test WARNING on tip/x86/core]
> > > [also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
> > > [cannot apply to herbert-crypto-2.6/master next-20240828]
> > > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > > And when submitting patch, we suggest to use '--base' as documented in
> > > https://urldefense.com/v3/__https://git-scm.com/docs/git-format-patch*_base_tree_information__;Iw!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIxuz-LAC$ ]
> > > 
> > > url:    https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI7Z6SQKy$
> > > base:   tip/x86/core
> > > patch link:    https://urldefense.com/v3/__https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson*40oracle.com__;JQ!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIzWfs1XZ$
> > > patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
> > > config: i386-randconfig-062-20240828 (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIwkYG0TY$ )
> > 
> > 
> > This is a i386 32-bit build, which makes no sense: this stuff should
> > just declare 'depends on 64BIT'
> 
> Our config entry already has 'depends on X86_64' which in turn depends on
> 64BIT. I would think that would be enough. Do you think it needs an explicit
> 'depends on 64BIT' in our entry as well?

The error is in x86-stub.c, which is pre-existing and compiled for 32
bit as well, so you need more than a "depends" here.

> > > compiler: clang version 18.1.5 (https://urldefense.com/v3/__https://github.com/llvm/llvm-project__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI2SDLdTN$  617a15a9eac96088ae5e9134248d8236e34b91b1)
> > > reproduce (this is a W=1 build): (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/reproduce__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI5MJDdIG$ )
> > > 
> > > If you fix the issue in a separate patch/commit (i.e. not just a new version of
> > > the same patch/commit), kindly add following tags
> > > | Reported-by: kernel test robot <lkp at intel.com>
> > > | Closes: https://urldefense.com/v3/__https://lore.kernel.org/oe-kbuild-all/202408290030.FEbUhHbr-lkp at intel.com/__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI-MitiqR$
> > > 
> > > sparse warnings: (new ones prefixed by >>)
> > > > > drivers/firmware/efi/libstub/x86-stub.c:945:41: sparse: sparse: non size-preserving pointer to integer cast
> > >     drivers/firmware/efi/libstub/x86-stub.c:953:65: sparse: sparse: non size-preserving pointer to integer cast
> > > > > drivers/firmware/efi/libstub/x86-stub.c:980:70: sparse: sparse: non size-preserving integer to pointer cast
> > >     drivers/firmware/efi/libstub/x86-stub.c:1014:45: sparse: sparse: non size-preserving integer to pointer cast
> > > 
> > > vim +945 drivers/firmware/efi/libstub/x86-stub.c
> > > 
> > >     927
> > >     928  static bool efi_secure_launch_update_boot_params(struct slr_table *slrt,
> > >     929                                                   struct boot_params *boot_params)
> > >     930  {
> > >     931          struct slr_entry_intel_info *txt_info;
> > >     932          struct slr_entry_policy *policy;
> > >     933          struct txt_os_mle_data *os_mle;
> > >     934          bool updated = false;
> > >     935          int i;
> > >     936
> > >     937          txt_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
> > >     938          if (!txt_info)
> > >     939                  return false;
> > >     940
> > >     941          os_mle = txt_os_mle_data_start((void *)txt_info->txt_heap);
> > >     942          if (!os_mle)
> > >     943                  return false;
> > >     944
> > >   > 945          os_mle->boot_params_addr = (u64)boot_params;
> > >     946
> > >     947          policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
> > >     948          if (!policy)
> > >     949                  return false;
> > >     950
> > >     951          for (i = 0; i < policy->nr_entries; i++) {
> > >     952                  if (policy->policy_entries[i].entity_type == SLR_ET_BOOT_PARAMS) {
> > >     953                          policy->policy_entries[i].entity = (u64)boot_params;
> > >     954                          updated = true;
> > >     955                          break;
> > >     956                  }
> > >     957          }
> > >     958
> > >     959          /*
> > >     960           * If this is a PE entry into EFI stub the mocked up boot params will
> > >     961           * be missing some of the setup header data needed for the second stage
> > >     962           * of the Secure Launch boot.
> > >     963           */
> > >     964          if (image) {
> > >     965                  struct setup_header *hdr = (struct setup_header *)((u8 *)image->image_base +
> > >     966                                              offsetof(struct boot_params, hdr));
> > >     967                  u64 cmdline_ptr;
> > >     968
> > >     969                  boot_params->hdr.setup_sects = hdr->setup_sects;
> > >     970                  boot_params->hdr.syssize = hdr->syssize;
> > >     971                  boot_params->hdr.version = hdr->version;
> > >     972                  boot_params->hdr.loadflags = hdr->loadflags;
> > >     973                  boot_params->hdr.kernel_alignment = hdr->kernel_alignment;
> > >     974                  boot_params->hdr.min_alignment = hdr->min_alignment;
> > >     975                  boot_params->hdr.xloadflags = hdr->xloadflags;
> > >     976                  boot_params->hdr.init_size = hdr->init_size;
> > >     977                  boot_params->hdr.kernel_info_offset = hdr->kernel_info_offset;
> > >     978                  efi_set_u64_form(boot_params->hdr.cmd_line_ptr, boot_params->ext_cmd_line_ptr,
> > >     979                                   &cmdline_ptr);
> > >   > 980                  boot_params->hdr.cmdline_size = strlen((const char *)cmdline_ptr);
> > >     981          }
> > >     982
> > >     983          return updated;
> > >     984  }
> > >     985
> > > 
> > > --
> > > 0-DAY CI Kernel Test Service
> > > https://urldefense.com/v3/__https://github.com/intel/lkp-tests/wiki__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIy5kGTJf$
> > > 
> 
> 

J.

-- 
   101 things you can't have too   |  .''`.  Debian GNU/Linux Developer
     much of : 23 - Red Dwarf.     | : :' :  Happy to accept PGP signed
                                   | `. `'   or encrypted mail - RSA
                                   |   `-    key on the keyservers.


From ardb at kernel.org  Thu Aug 29 06:28:47 2024
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 29 Aug 2024 15:28:47 +0200
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <ZtB2bP1Mx3zTr9e5@earth.li>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
 <202408290030.FEbUhHbr-lkp@intel.com> <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>
 <6b214ad2-d448-4f5f-85e9-93cd38e0e035@oracle.com> <ZtB2bP1Mx3zTr9e5@earth.li>
Message-ID: <CAMj1kXHvTjC1ALgHnu-_Tad4Ur9RqJR_d9h8bQDvXcx2p5H2AA@mail.gmail.com>

On Thu, 29 Aug 2024 at 15:24, Jonathan McDowell <noodles at earth.li> wrote:
>
> On Wed, Aug 28, 2024 at 01:19:16PM -0700, ross.philipson at oracle.com wrote:
> > On 8/28/24 10:14 AM, Ard Biesheuvel wrote:
> > > On Wed, 28 Aug 2024 at 19:09, kernel test robot <lkp at intel.com> wrote:
> > > >
> > > > Hi Ross,
> > > >
> > > > kernel test robot noticed the following build warnings:
> > > >
> > > > [auto build test WARNING on tip/x86/core]
> > > > [also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
> > > > [cannot apply to herbert-crypto-2.6/master next-20240828]
> > > > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > > > And when submitting patch, we suggest to use '--base' as documented in
> > > > https://urldefense.com/v3/__https://git-scm.com/docs/git-format-patch*_base_tree_information__;Iw!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIxuz-LAC$ ]
> > > >
> > > > url:    https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI7Z6SQKy$
> > > > base:   tip/x86/core
> > > > patch link:    https://urldefense.com/v3/__https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson*40oracle.com__;JQ!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIzWfs1XZ$
> > > > patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
> > > > config: i386-randconfig-062-20240828 (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIwkYG0TY$ )
> > >
> > >
> > > This is a i386 32-bit build, which makes no sense: this stuff should
> > > just declare 'depends on 64BIT'
> >
> > Our config entry already has 'depends on X86_64' which in turn depends on
> > 64BIT. I would think that would be enough. Do you think it needs an explicit
> > 'depends on 64BIT' in our entry as well?
>
> The error is in x86-stub.c, which is pre-existing and compiled for 32
> bit as well, so you need more than a "depends" here.
>

Ugh, that means this is my fault - apologies. Replacing the #ifdef
with IS_ENABLED() makes the code visible to the 32-bit compiler, even
though the code is disregarded.

I'd still prefer IS_ENABLED(), but this would require the code in
question to live in a separate compilation unit (which depends on
CONFIG_SECURE_LAUNCH). If that is too fiddly, feel free to bring back
the #ifdef CONFIG_SECURE_LAUNCH here (and retain my R-b)


From dpsmith at apertussolutions.com  Thu Aug 29 07:11:11 2024
From: dpsmith at apertussolutions.com (Daniel P. Smith)
Date: Thu, 29 Aug 2024 10:11:11 -0400
Subject: [PATCH v8 01/15] x86/boot: Place kernel_info at a fixed offset
In-Reply-To: <CAMj1kXHn6xeAskWiDLvvA4oG3j9_tqx+iMYJXMqmgvyX4pMzgg@mail.gmail.com>
References: <20240214221847.2066632-1-ross.philipson@oracle.com>
 <20240214221847.2066632-2-ross.philipson@oracle.com>
 <CAMj1kXH3Gvr3vDRLDdXuc0s7ZAQYE6+D7tmCRBjJWwWt2fn4-w@mail.gmail.com>
 <9d01a6d2-4dd9-4331-8fc9-b01c07cfdbb5@apertussolutions.com>
 <CAMj1kXHn6xeAskWiDLvvA4oG3j9_tqx+iMYJXMqmgvyX4pMzgg@mail.gmail.com>
Message-ID: <e3194ad1-e976-40a6-a8f3-98081b0b07ea@apertussolutions.com>

On 8/28/24 13:45, Ard Biesheuvel wrote:
> (cc Stuart)
> 
> On Thu, 21 Mar 2024 at 15:46, Daniel P. Smith
> <dpsmith at apertussolutions.com> wrote:
>>
>> Hi Ard!
>>
>> On 2/15/24 02:56, Ard Biesheuvel wrote:
>>> On Wed, 14 Feb 2024 at 23:31, Ross Philipson <ross.philipson at oracle.com> wrote:
>>>>
>>>> From: Arvind Sankar <nivedita at alum.mit.edu>
>>>>
>>>> There are use cases for storing the offset of a symbol in kernel_info.
>>>> For example, the trenchboot series [0] needs to store the offset of the
>>>> Measured Launch Environment header in kernel_info.
>>>>
>>>
>>> Why? Is this information consumed by the bootloader?
>>
>> Yes, the bootloader needs a standardized means to find the offset of the
>> MLE header, which communicates a set of meta-data needed by the DCE in
>> order to set up for and start the loaded kernel. Arm will also need to
>> provide a similar metadata structure and alternative entry point (or a
>> complete rewrite of the existing entry point), as the current Arm entry
>> point is in direct conflict with Arm DRTM specification.
>>
> 
> Digging up an old thread here: could you elaborate on this? What do
> you mean by 'Arm entry point' and how does it conflict directly with
> the Arm DRTM specification? The Linux/arm64 port predates that spec by
> about 10 years, so I would expect the latter to take the former into
> account. If that failed to happen, we should fix the spec while we
> still can.

Yes, we have been working with Stuart regarding the specification and 
crafting a compliant implementation approach. It is still very early 
days, we are attempting to draft a plan around the specification with no 
physical implementation to validate against. After some discussion, the 
concern that a separate entry point may be needed has faded and in fact 
it likely will not be needed. As always, the devil is in the details, 
and until we have a hardware that has implemented the specification, and 
we attempt to light it up, we won't know what will be needed for the 
implementation.

In short, at this point it was determined no update to the DRTM spec is 
needed. As hardware becomes available, and we do battle with it, Stuart 
will be kept up to date. We will work with him to ensure any changes are 
captured that will help reduce chances that vendors and developers do 
not misinterpret the spec.

V/r,
Daniel P. Smith


From ashish.kalra at amd.com  Thu Aug 29 07:30:54 2024
From: ashish.kalra at amd.com (Kalra, Ashish)
Date: Thu, 29 Aug 2024 09:30:54 -0500
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <87475131-856C-44DC-A27A-84648294F094@alien8.de>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
 <87475131-856C-44DC-A27A-84648294F094@alien8.de>
Message-ID: <3f887fb7-e30e-41f4-8ac1-bd245e707ccc@amd.com>

Hello Boris,

On 8/29/2024 3:34 AM, Borislav Petkov wrote:
> On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
>> From: Ashish Kalra <ashish.kalra at amd.com>
>>
>> With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
>> crashkernel boot failure with the following signature:
> Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and there's potential to lose guest data in the process?!

If SNP_SHUTDOWN is not done, then crashkernel panics during boot as the crashdump attached to the fix/patch here shows, so essentially if SNP_DECOMMISSION followed by SNP_SHUTDOWN is not done then we can't boot crashkernel in case of any active SNP guests (which i will believe is an important requirement for cloud providers).

Additionally, in case of SNP_DECOMMISSION, the firmware marks the ASID of the guest as not runnable and then transitions the SNP guest context page into a Firmware page (so that is one RMP table change) and for SNP_SHUTDOWN_EX, the firmware transitions all pages associated with the IOMMU to the Reclaim state (which then the HV marks as hypervisor pages), these IOMMU pages are the event log, PPR log, and completion wait buffers of the IOMMU.

Aside from the IOMMU pages mentioned above, the firmware will not automatically reclaim or modify any other pages in the RMP table and also does not reset the RMP table.

So essentially all host memory (and guest data) will still be available and saved by crashkernel.

Thanks, Ashish



From bp at alien8.de  Thu Aug 29 07:40:03 2024
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 29 Aug 2024 16:40:03 +0200
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <3f887fb7-e30e-41f4-8ac1-bd245e707ccc@amd.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
 <87475131-856C-44DC-A27A-84648294F094@alien8.de>
 <3f887fb7-e30e-41f4-8ac1-bd245e707ccc@amd.com>
Message-ID: <20240829144003.GFZtCIQzK6SCrZsgyE@fat_crate.local>

On Thu, Aug 29, 2024 at 09:30:54AM -0500, Kalra, Ashish wrote:
> Hello Boris,
> 
> On 8/29/2024 3:34 AM, Borislav Petkov wrote:
> > On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
> >> From: Ashish Kalra <ashish.kalra at amd.com>
> >>
> >> With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
> >> crashkernel boot failure with the following signature:
> > Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and there's potential to lose guest data in the process?!
> 
> If SNP_SHUTDOWN is not done,

Read my question again pls.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From seanjc at google.com  Thu Aug 29 07:50:16 2024
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 29 Aug 2024 07:50:16 -0700
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <87475131-856C-44DC-A27A-84648294F094@alien8.de>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com> <87475131-856C-44DC-A27A-84648294F094@alien8.de>
Message-ID: <ZtCKqD_gc6wnqu-P@google.com>

On Thu, Aug 29, 2024, Borislav Petkov wrote:
> On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
> >From: Ashish Kalra <ashish.kalra at amd.com>
> >
> >With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
> >crashkernel boot failure with the following signature:
> 
> Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and
> there's potential to lose guest data in the process?!

Because if the host is panicking, guests are hosed regardless.  Unless I'm
misreading things, the goal here is to ensure the crashkernel can actually capture
a kdump.


From bp at alien8.de  Thu Aug 29 08:04:01 2024
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 29 Aug 2024 17:04:01 +0200
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <ZtCKqD_gc6wnqu-P@google.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
 <87475131-856C-44DC-A27A-84648294F094@alien8.de>
 <ZtCKqD_gc6wnqu-P@google.com>
Message-ID: <20240829150401.GGZtCN4ZtVyqjYHbpD@fat_crate.local>

On Thu, Aug 29, 2024 at 07:50:16AM -0700, Sean Christopherson wrote:
> Because if the host is panicking, guests are hosed regardless.

Are they?

I read "active SNP VMs"...

I guess if it reaches svm_emergency_disable() we're hosed anyway and that's
what you mean but I'm not sure...

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From ashish.kalra at amd.com  Thu Aug 29 08:16:39 2024
From: ashish.kalra at amd.com (Kalra, Ashish)
Date: Thu, 29 Aug 2024 10:16:39 -0500
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <ZtCKqD_gc6wnqu-P@google.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
 <87475131-856C-44DC-A27A-84648294F094@alien8.de>
 <ZtCKqD_gc6wnqu-P@google.com>
Message-ID: <155cb321-a169-4a56-b0ac-940676c1e9ee@amd.com>

On 8/29/2024 9:50 AM, Sean Christopherson wrote:

> On Thu, Aug 29, 2024, Borislav Petkov wrote:
>> On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
>>> From: Ashish Kalra <ashish.kalra at amd.com>
>>>
>>> With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
>>> crashkernel boot failure with the following signature:
>> Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and
>> there's potential to lose guest data in the process?!
> Because if the host is panicking, guests are hosed regardless.  Unless I'm
> misreading things, the goal here is to ensure the crashkernel can actually capture
> a kdump.

Yes, that is the main goal here to ensure that crashkernel can boot and capture a kdump on a SNP enabled host regardless of SNP VMs running.

Thanks, Ashish



From ross.philipson at oracle.com  Thu Aug 29 08:13:34 2024
From: ross.philipson at oracle.com (ross.philipson at oracle.com)
Date: Thu, 29 Aug 2024 08:13:34 -0700
Subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for
 Secure Launch
In-Reply-To: <CAMj1kXHvTjC1ALgHnu-_Tad4Ur9RqJR_d9h8bQDvXcx2p5H2AA@mail.gmail.com>
References: <20240826223835.3928819-21-ross.philipson@oracle.com>
 <202408290030.FEbUhHbr-lkp@intel.com>
 <CAMj1kXGVn85ht_srwhYXDnKffPFX=B2+Cnv-8EAocwoHi__OoQ@mail.gmail.com>
 <6b214ad2-d448-4f5f-85e9-93cd38e0e035@oracle.com> <ZtB2bP1Mx3zTr9e5@earth.li>
 <CAMj1kXHvTjC1ALgHnu-_Tad4Ur9RqJR_d9h8bQDvXcx2p5H2AA@mail.gmail.com>
Message-ID: <98330007-d07e-4124-a26a-0ffb3d50a773@oracle.com>

On 8/29/24 6:28 AM, Ard Biesheuvel wrote:
> On Thu, 29 Aug 2024 at 15:24, Jonathan McDowell <noodles at earth.li> wrote:
>>
>> On Wed, Aug 28, 2024 at 01:19:16PM -0700, ross.philipson at oracle.com wrote:
>>> On 8/28/24 10:14 AM, Ard Biesheuvel wrote:
>>>> On Wed, 28 Aug 2024 at 19:09, kernel test robot <lkp at intel.com> wrote:
>>>>>
>>>>> Hi Ross,
>>>>>
>>>>> kernel test robot noticed the following build warnings:
>>>>>
>>>>> [auto build test WARNING on tip/x86/core]
>>>>> [also build test WARNING on char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus herbert-cryptodev-2.6/master efi/next linus/master v6.11-rc5]
>>>>> [cannot apply to herbert-crypto-2.6/master next-20240828]
>>>>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>>>>> And when submitting patch, we suggest to use '--base' as documented in
>>>>> https://urldefense.com/v3/__https://git-scm.com/docs/git-format-patch*_base_tree_information__;Iw!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIxuz-LAC$ ]
>>>>>
>>>>> url:    https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commits/Ross-Philipson/Documentation-x86-Secure-Launch-kernel-documentation/20240827-065225__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmI7Z6SQKy$
>>>>> base:   tip/x86/core
>>>>> patch link:    https://urldefense.com/v3/__https://lore.kernel.org/r/20240826223835.3928819-21-ross.philipson*40oracle.com__;JQ!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIzWfs1XZ$
>>>>> patch subject: [PATCH v10 20/20] x86/efi: EFI stub DRTM launch support for Secure Launch
>>>>> config: i386-randconfig-062-20240828 (https://urldefense.com/v3/__https://download.01.org/0day-ci/archive/20240829/202408290030.FEbUhHbr-lkp at intel.com/config__;!!ACWV5N9M2RV99hQ!KhkZK77BXRIR4F24tKkUeIlIrdqXtUW2vcnDV74c_5BmrQBQaQ4FqcDKKv9LB3HQUocTGkrmIwkYG0TY$ )
>>>>
>>>>
>>>> This is a i386 32-bit build, which makes no sense: this stuff should
>>>> just declare 'depends on 64BIT'
>>>
>>> Our config entry already has 'depends on X86_64' which in turn depends on
>>> 64BIT. I would think that would be enough. Do you think it needs an explicit
>>> 'depends on 64BIT' in our entry as well?
>>
>> The error is in x86-stub.c, which is pre-existing and compiled for 32
>> bit as well, so you need more than a "depends" here.
>>
> 
> Ugh, that means this is my fault - apologies. Replacing the #ifdef
> with IS_ENABLED() makes the code visible to the 32-bit compiler, even
> though the code is disregarded.
> 
> I'd still prefer IS_ENABLED(), but this would require the code in
> question to live in a separate compilation unit (which depends on
> CONFIG_SECURE_LAUNCH). If that is too fiddly, feel free to bring back
> the #ifdef CONFIG_SECURE_LAUNCH here (and retain my R-b)

Thanks to both of you for the followup.

If there was a very large amount of new code here, I would consider 
making a separate compilation unit. I can't really say if this is a 
wider issue with the the EFI libstub code but if it ware broken up 
later, it would make sense to move our bits to where 64bit only code lives.

Given that it is a small block of code though, I am inclined to just go 
back to #ifdef's for now.

Thanks
Ross


From lkp at intel.com  Thu Aug 29 08:50:07 2024
From: lkp at intel.com (kernel test robot)
Date: Thu, 29 Aug 2024 23:50:07 +0800
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <20240827203804.4989-1-Ashish.Kalra@amd.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
Message-ID: <202408292344.yuQ5sYEz-lkp@intel.com>

Hi Ashish,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kvm/queue]
[also build test WARNING on linus/master v6.11-rc5 next-20240829]
[cannot apply to kvm/linux-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ashish-Kalra/x86-sev-Fix-host-kdump-support-for-SNP/20240828-044035
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue
patch link:    https://lore.kernel.org/r/20240827203804.4989-1-Ashish.Kalra%40amd.com
patch subject: [PATCH] x86/sev: Fix host kdump support for SNP
config: x86_64-buildonly-randconfig-002-20240829 (https://download.01.org/0day-ci/archive/20240829/202408292344.yuQ5sYEz-lkp at intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240829/202408292344.yuQ5sYEz-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408292344.yuQ5sYEz-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from arch/x86/kvm/svm/avic.c:28:
>> arch/x86/kvm/svm/svm.h:783:13: warning: 'snp_decommision_all' declared 'static' but never defined [-Wunused-function]
     783 | static void snp_decommision_all(void);
         |             ^~~~~~~~~~~~~~~~~~~
--
   In file included from arch/x86/kvm/svm/svm.c:50:
>> arch/x86/kvm/svm/svm.h:783:13: warning: 'snp_decommision_all' used but never defined
     783 | static void snp_decommision_all(void);
         |             ^~~~~~~~~~~~~~~~~~~


vim +783 arch/x86/kvm/svm/svm.h

   763	
   764	static inline void sev_free_vcpu(struct kvm_vcpu *vcpu) {}
   765	static inline void sev_vm_destroy(struct kvm *kvm) {}
   766	static inline void __init sev_set_cpu_caps(void) {}
   767	static inline void __init sev_hardware_setup(void) {}
   768	static inline void sev_hardware_unsetup(void) {}
   769	static inline int sev_cpu_init(struct svm_cpu_data *sd) { return 0; }
   770	static inline int sev_dev_get_attr(u32 group, u64 attr, u64 *val) { return -ENXIO; }
   771	#define max_sev_asid 0
   772	static inline void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code) {}
   773	static inline void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu) {}
   774	static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order)
   775	{
   776		return 0;
   777	}
   778	static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {}
   779	static inline int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
   780	{
   781		return 0;
   782	}
 > 783	static void snp_decommision_all(void);
   784	#endif
   785	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From luto at amacapital.net  Thu Aug 29 10:26:18 2024
From: luto at amacapital.net (Andy Lutomirski)
Date: Thu, 29 Aug 2024 10:26:18 -0700
Subject: [PATCH v9 06/19] x86: Add early SHA-1 support for Secure Launch
 early measurements
In-Reply-To: <Zs/qJsKu3StL3Wzt@srcf.ucam.org>
References: <20240531010331.134441-1-ross.philipson@oracle.com>
 <20240531010331.134441-7-ross.philipson@oracle.com> <20240531021656.GA1502@sol.localdomain>
 <874jaegk8i.fsf@email.froward.int.ebiederm.org> <5b1ce8d3-516d-4dfd-a976-38e5cee1ef4e@apertussolutions.com>
 <87ttflli09.ffs@tglx> <CALCETrXQ7rChWLDqTG0+KY7rsfajSPguMnHO1G4VJi_mgwN9Zw@mail.gmail.com>
 <Zs/qJsKu3StL3Wzt@srcf.ucam.org>
Message-ID: <CALCETrW8jfkvMc2rwCoyiVON25YFVQZWrb4ZFFoUs3zhRV4YEQ@mail.gmail.com>

On Wed, Aug 28, 2024 at 8:25?PM Matthew Garrett <mjg59 at srcf.ucam.org> wrote:
>
> On Wed, Aug 28, 2024 at 08:17:05PM -0700, Andy Lutomirski wrote:
>
> > Ross et al, can you confirm that your code actually, at least by
> > default and with a monstrous warning to anyone who tries to change the
> > default, caps SHA1 PCRs if SHA256 is available?  And then can we maybe
> > all stop hassling the people trying to develop this series about the
> > fact that they're doing their best with the obnoxious system that the
> > TPM designers gave them?
>
> Presumably this would be dependent upon non-SHA1 banks being enabled?

Of course.  It's also not immediately obvious to me what layer of the
stack should be responsible for capping SHA1 PCRs.  Should it be the
kernel?  Userspace?

It seems like a whole lot of people, for better or for worse, want to
minimize the amount of code that even knows how to compute SHA1
hashes.  I'm not personally convinced I agree with this strategy, but
it is what it is.  And maybe people would be happier if the default
behavior of the kernel is to notice that SHA256 is available and then
cap SHA1 before even asking user code's permission.

--Andy


From jonathan.capeluto at neteris.com  Thu Aug 29 15:13:05 2024
From: jonathan.capeluto at neteris.com (Roy Kessier)
Date: 29 Aug 2024 15:13:05 -0700
Subject: =?UTF-8?B?SW50ZXJuYXRpb25hbGUgV8OkaHJ1bmdzZm9uZHMgKElXRik=?=
Message-ID: <20240829151305.22AA9C6EDCC37996@neteris.com>

Sehr geehrter Empf?nger:

Die Europ?ische Investitionsbank in Luxemburg und der 
Internationale W?hrungsfonds (IWF) haben uns beauftragt, die 
Ursache f?r die Verz?gerung bei der Auszahlung ihrer gesetzlich 
genehmigten Mittel zu untersuchen.

Unsere Untersuchung ergab, dass seine Zahlung aufgrund korrupter 
Bankangestellte verz?gert wurde, die versuchten, sein Geld auf 
seine Privatkonten bei ABANCA umzuleiten. Um diese Art von 
betr?gerischen Aktivit?ten zu verhindern, haben wir eine 
Vereinbarung mit der Europ?ischen Investitionsbank und dem IWF 
zur Verwaltung und ?berwachung Ihrer Zahlung. F?r Ihre Zahlung 
haben wir daher von MFY eine unwiderrufliche Zahlungsgarantie 
erhalten.

Wir freuen uns, Ihnen mitteilen zu k?nnen, dass die Europ?ische 
Investitionsbank beschlossen hat, Ihnen den Betrag von 
3.500.000,00 EUR zur?ckzuerstatten und ihn per Bank?berweisung 
direkt auf Ihr Bankkonto zu ?berweisen.

Um einen reibungslosen und problemlosen Zahlungsvorgang zu 
gew?hrleisten, kontaktieren Sie bitte unseren Vertreter, Herrn 
Roy Kessier, unter der folgenden E-Mail-Adresse:
E-Mail: info at elibertytrust.us

Bitte teilen Sie uns auch Ihre WhatsApp-Nummer mit, um die 
Kommunikation zu erleichtern.

Vielen Dank f?r Ihre Aufmerksamkeit in dieser Angelegenheit.

Aufrichtig,
Herr Roy Kessier
info at elibertytrust.us


From bhe at redhat.com  Thu Aug 29 20:15:51 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 30 Aug 2024 11:15:51 +0800
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <20240823125156.104775-1-dave@vasilevsky.ca>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
Message-ID: <ZtE5Z/gDR1WixG9S@MiWiFi-R3L-srv>

Hi Dave,

On 08/23/24 at 08:51am, Dave Vasilevsky wrote:
......snip..
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 1aa3c4a0c5b2..b04cfa23378c 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool BROKEN_ON_SMP
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool n

If we don't add ARCH_DEFAULT_CRASH_DUMP at all in sh arch, the
CRASH_DUMP will be off by default according to the below new definition
of CRASH_DUMP?

Thanks
Baoquan

> +
>  config ARCH_SUPPORTS_KEXEC_JUMP
>  	def_bool y
>  
......  
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 6c34e63c88ff..4d111f871951 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>  
>  config CRASH_DUMP
>  	bool "kernel crash dumps"
> -	default y
> +	default ARCH_DEFAULT_CRASH_DUMP
>  	depends on ARCH_SUPPORTS_CRASH_DUMP
>  	depends on KEXEC_CORE
>  	select VMCORE_INFO
> -- 
> 2.34.1
> 



From dave at vasilevsky.ca  Thu Aug 29 20:37:29 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Thu, 29 Aug 2024 23:37:29 -0400
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <ZtE5Z/gDR1WixG9S@MiWiFi-R3L-srv>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <ZtE5Z/gDR1WixG9S@MiWiFi-R3L-srv>
Message-ID: <1568b378-5592-4d23-a572-4e09f3996331@vasilevsky.ca>

On 2024-08-29 23:15, Baoquan He wrote:
>> +config ARCH_DEFAULT_CRASH_DUMP
>> +	def_bool n
> 
> If we don't add ARCH_DEFAULT_CRASH_DUMP at all in sh arch, the
> CRASH_DUMP will be off by default according to the below new definition
> of CRASH_DUMP?

Yes, that's true. But if we don't add it at all in sh arch, it looks confusing
in the search feature of menuconfig:

> Symbol: ARCH_DEFAULT_CRASH_DUMP [=ARCH_DEFAULT_CRASH_DUMP]
> Type  : unknown

So I thought it was better to explicitly set it to 'n'. What do you think?

-Dave


From bhe at redhat.com  Thu Aug 29 23:30:45 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 30 Aug 2024 14:30:45 +0800
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <1568b378-5592-4d23-a572-4e09f3996331@vasilevsky.ca>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <ZtE5Z/gDR1WixG9S@MiWiFi-R3L-srv>
 <1568b378-5592-4d23-a572-4e09f3996331@vasilevsky.ca>
Message-ID: <ZtFnFaHfh09wOw6o@MiWiFi-R3L-srv>

On 08/29/24 at 11:37pm, Dave Vasilevsky wrote:
> On 2024-08-29 23:15, Baoquan He wrote:
> >> +config ARCH_DEFAULT_CRASH_DUMP
> >> +	def_bool n
> > 
> > If we don't add ARCH_DEFAULT_CRASH_DUMP at all in sh arch, the
> > CRASH_DUMP will be off by default according to the below new definition
> > of CRASH_DUMP?
> 
> Yes, that's true. But if we don't add it at all in sh arch, it looks confusing
> in the search feature of menuconfig:
> 
> > Symbol: ARCH_DEFAULT_CRASH_DUMP [=ARCH_DEFAULT_CRASH_DUMP]
> > Type  : unknown
> 
> So I thought it was better to explicitly set it to 'n'. What do you think?

If so, better adding it. Thanks.



From bhe at redhat.com  Thu Aug 29 23:35:28 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 30 Aug 2024 14:35:28 +0800
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <20240823125156.104775-1-dave@vasilevsky.ca>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
Message-ID: <ZtFoMMsS5PuFw3LF@MiWiFi-R3L-srv>

On 08/23/24 at 08:51am, Dave Vasilevsky wrote:
> Fixes boot failures on 6.9 on PPC_BOOK3S_32 machines using
> Open Firmware. On these machines, the kernel refuses to boot
> from non-zero PHYSICAL_START, which occurs when CRASH_DUMP is on.
> 
> Since most PPC_BOOK3S_32 machines boot via Open Firmware, it should
> default to off for them. Users booting via some other mechanism
> can still turn it on explicitly.
> 
> Also defaults to CRASH_DUMP=n on sh.

The overrall looks good to me except of the CRASH_DUMP=n on sh, do you
have a comment about the reasoning since you have discussed with John?
Is it because of below config items?

arch/sh/Kconfig:
config ARCH_SUPPORTS_CRASH_DUMP
        def_bool BROKEN_ON_SMP
...
config PHYSICAL_START
        hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP)
        default MEMORY_START
	...

> 
> Signed-off-by: Dave Vasilevsky <dave at vasilevsky.ca>
> Reported-by: Reimar D?ffinger <Reimar.Doeffinger at gmx.de>
> Closes: https://lists.debian.org/debian-powerpc/2024/07/msg00001.html
> Fixes: 75bc255a7444 ("crash: clean up kdump related config items")
> ---
>  arch/arm/Kconfig       | 3 +++
>  arch/arm64/Kconfig     | 3 +++
>  arch/loongarch/Kconfig | 3 +++
>  arch/mips/Kconfig      | 3 +++
>  arch/powerpc/Kconfig   | 4 ++++
>  arch/riscv/Kconfig     | 3 +++
>  arch/s390/Kconfig      | 3 +++
>  arch/sh/Kconfig        | 3 +++
>  arch/x86/Kconfig       | 3 +++
>  kernel/Kconfig.kexec   | 2 +-
>  10 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 54b2bb817a7f..200995052690 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1597,6 +1597,9 @@ config ATAGS_PROC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config AUTO_ZRELADDR
>  	bool "Auto calculation of the decompressed kernel image address" if !ARCH_MULTIPLATFORM
>  	default !(ARCH_FOOTBRIDGE || ARCH_RPC || ARCH_SA1100)
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index a2f8ff354ca6..43e08cc8204f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1558,6 +1558,9 @@ config ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
> index 70f169210b52..ce232ddcd27d 100644
> --- a/arch/loongarch/Kconfig
> +++ b/arch/loongarch/Kconfig
> @@ -599,6 +599,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 60077e576935..b547f4304d0c 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -2881,6 +2881,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config PHYSICAL_START
>  	hex "Physical address where the kernel is loaded"
>  	default "0xffffffff84000000"
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index d7b09b064a8a..0f3c1f958eac 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -682,6 +682,10 @@ config RELOCATABLE_TEST
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool PPC64 || PPC_BOOK3S_32 || PPC_85xx || (44x && !SMP)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	bool
> +	default y if !PPC_BOOK3S_32
> +
>  config ARCH_SELECTS_CRASH_DUMP
>  	def_bool y
>  	depends on CRASH_DUMP
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 0f3cd7c3a436..eb247b5ee569 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -880,6 +880,9 @@ config ARCH_SUPPORTS_KEXEC_PURGATORY
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool y
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
>  	def_bool CRASH_RESERVE
>  
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index a822f952f64a..05a1fb408471 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -275,6 +275,9 @@ config ARCH_SUPPORTS_CRASH_DUMP
>  	  This option also enables s390 zfcpdump.
>  	  See also <file:Documentation/arch/s390/zfcpdump.rst>
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  menu "Processor type and features"
>  
>  config HAVE_MARCH_Z10_FEATURES
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index 1aa3c4a0c5b2..b04cfa23378c 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -549,6 +549,9 @@ config ARCH_SUPPORTS_KEXEC
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool BROKEN_ON_SMP
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool n
> +
>  config ARCH_SUPPORTS_KEXEC_JUMP
>  	def_bool y
>  
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 007bab9f2a0e..aa4666bb9e9c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2087,6 +2087,9 @@ config ARCH_SUPPORTS_KEXEC_JUMP
>  config ARCH_SUPPORTS_CRASH_DUMP
>  	def_bool X86_64 || (X86_32 && HIGHMEM)
>  
> +config ARCH_DEFAULT_CRASH_DUMP
> +	def_bool y
> +
>  config ARCH_SUPPORTS_CRASH_HOTPLUG
>  	def_bool y
>  
> diff --git a/kernel/Kconfig.kexec b/kernel/Kconfig.kexec
> index 6c34e63c88ff..4d111f871951 100644
> --- a/kernel/Kconfig.kexec
> +++ b/kernel/Kconfig.kexec
> @@ -97,7 +97,7 @@ config KEXEC_JUMP
>  
>  config CRASH_DUMP
>  	bool "kernel crash dumps"
> -	default y
> +	default ARCH_DEFAULT_CRASH_DUMP
>  	depends on ARCH_SUPPORTS_CRASH_DUMP
>  	depends on KEXEC_CORE
>  	select VMCORE_INFO
> -- 
> 2.34.1
> 



From kuan-ying.lee at canonical.com  Thu Aug 29 23:41:49 2024
From: kuan-ying.lee at canonical.com (Kuan-Ying Lee)
Date: Fri, 30 Aug 2024 14:41:49 +0800
Subject: [PATCH] arm64/vmcore: Add pgtable_l5_enabled information in
 vmcoreinfo
In-Reply-To: <CANU+ZydbFPiSnCRr3qQ52GjUQQmU3ZO62c6hRkoLM147+u5u8w@mail.gmail.com>
References: <20240826065219.305963-1-kuan-ying.lee@canonical.com>
 <20240827122459.GA4679@willie-the-truck>
 <Zs5Xo5eVUvGMbtSv@MiWiFi-R3L-srv>
 <CANU+ZydbFPiSnCRr3qQ52GjUQQmU3ZO62c6hRkoLM147+u5u8w@mail.gmail.com>
Message-ID: <ZtFprQX-UzyqnKTH@kylee-ThinkPad-E16-Gen-1>

On Wed, Aug 28, 2024 at 05:37:07PM +0800, lijiang wrote:
> On Wed, Aug 28, 2024 at 6:48?AM Baoquan He <bhe at redhat.com> wrote:
> 
> > On 08/27/24 at 01:24pm, Will Deacon wrote:
> > > On Mon, Aug 26, 2024 at 02:52:02PM +0800, Kuan-Ying Lee wrote:
> > > > Since arm64 supports 5-level page tables, we need to add this
> > > > information to vmcoreinfo to make debug tools know if 5-level
> > > > page table is enabled or not.
> > > >
> > > > Missing this information will break the debug tool like crash [1].

Sorry, the above line was mistakenly expressed.

Currently, the crash tool doesn't support 4K page with 5-level
page tables (LPA2), so I initially planned to add this
information to implement support for 4K page with 5-level page
table in the crash tool.

> > > >
> > > > [1] https://github.com/crash-utility/crash
> > > >
> > > > Signed-off-by: Kuan-Ying Lee <kuan-ying.lee at canonical.com>
> > > > ---
> > > >  Documentation/admin-guide/kdump/vmcoreinfo.rst | 6 ++++++
> > > >  arch/arm64/kernel/vmcore_info.c                | 3 +++
> > > >  2 files changed, 9 insertions(+)
> > >
> > > In which case, wouldn't you also want to know about pgtable_l4_enabled()?
> >
> > That is a good question. I guess it's deduced in code, mostly needed for
> > different PAGE_OFFSET, how to transfer virtual addr to physical addr,
> > etc.
> >
> >
> Thanks for the information, Baoquan.
> 
> If I understand correctly, for arm64, currently, the crash tool determines
> the levels of the page table based on page size and va_bits, and then
> decides how to translate the address, such as calculating it in conjunction
> with other values, e.g: kernel pgd, offset, etc.

Thanks for the information. I will then try to use VA_BITS to determine
if it is a 5-level page table.
Let me investigate further.

Thanks,
Kuan-Ying Lee

> 
> For more details, please refer to this one:
> https://github.com/crash-utility/crash/blob/master/arm64.c
> 
> 
> Thanks
> Lianbo
> 
> 
> > Add Crash utility experts here.
> >
> >


From dave at vasilevsky.ca  Fri Aug 30 00:24:17 2024
From: dave at vasilevsky.ca (Dave Vasilevsky)
Date: Fri, 30 Aug 2024 03:24:17 -0400
Subject: [PATCH] crash: Default to CRASH_DUMP=n when support for it is
 unlikely
In-Reply-To: <ZtFoMMsS5PuFw3LF@MiWiFi-R3L-srv>
References: <20240823125156.104775-1-dave@vasilevsky.ca>
 <ZtFoMMsS5PuFw3LF@MiWiFi-R3L-srv>
Message-ID: <e12e89e5-9617-4515-a3a5-19cf9a6db624@vasilevsky.ca>

On 2024-08-30 02:35, Baoquan He wrote:
> The overrall looks good to me except of the CRASH_DUMP=n on sh, do you
> have a comment about the reasoning since you have discussed with John?
> Is it because of below config items?

I don't yet know why John asked to turn this off by default on sh, though
I'm sure there's a good reason! John, I'd appreciate if you could chime in.

Otherwise, I could split the patch, and we can discuss the default
on sh separately from powerpc.

-Dave


From dyoung at redhat.com  Fri Aug 30 01:49:07 2024
From: dyoung at redhat.com (Dave Young)
Date: Fri, 30 Aug 2024 16:49:07 +0800
Subject: [PATCH] x86/mm/sme: fix the kdump kernel breakage on SME system
 when CONFIG_IMA_KEXEC=y
In-Reply-To: <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
References: <20240826024457.22423-1-bhe@redhat.com> <35e40987-1541-cbbe-6b16-1ddadc2c4c35@amd.com>
Message-ID: <CALu+AoRSQpi7M9CFOS9BFmiszrRcvNucEicti_NuX2oSnObS0w@mail.gmail.com>

On Mon, 26 Aug 2024 at 22:24, Tom Lendacky <thomas.lendacky at amd.com> wrote:
>
> On 8/25/24 21:44, Baoquan He wrote:
> > Recently, it's reported that kdump kernel is broken during bootup on
> > SME system when CONFIG_IMA_KEXEC=y. When debugging, I noticed this
> > can be traced back to commit ("b69a2afd5afc x86/kexec: Carry forward
> > IMA measurement log on kexec"). Just nobody ever tested it on SME
> > system when enabling CONFIG_IMA_KEXEC.
> >
> > --------------------------------------------------
> >  ima: No TPM chip found, activating TPM-bypass!
> >  Loading compiled-in module X.509 certificates
> >  Loaded X.509 cert 'Build time autogenerated kernel key: 18ae0bc7e79b64700122bb1d6a904b070fef2656'
> >  ima: Allocated hash algorithm: sha256
> >  Oops: general protection fault, probably for non-canonical address 0xcfacfdfe6660003e: 0000 [#1] PREEMPT SMP NOPTI
> >  CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.11.0-rc2+ #14
> >  Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.20.0 05/03/2023
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Call Trace:
> >   <TASK>
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? show_trace_log_lvl+0x1b0/0x2f0
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ? __die_body.cold+0x8/0x12
> >   ? die_addr+0x3c/0x60
> >   ? exc_general_protection+0x178/0x410
> >   ? asm_exc_general_protection+0x26/0x30
> >   ? ima_restore_measurement_list+0xdc/0x420
> >   ? vprintk_emit+0x1f0/0x270
> >   ? ima_load_kexec_buffer+0x6e/0xf0
> >   ima_load_kexec_buffer+0x6e/0xf0
> >   ima_init+0x52/0xb0
> >   ? __pfx_init_ima+0x10/0x10
> >   init_ima+0x26/0xc0
> >   ? __pfx_init_ima+0x10/0x10
> >   do_one_initcall+0x5b/0x300
> >   do_initcalls+0xdf/0x100
> >   ? __pfx_kernel_init+0x10/0x10
> >   kernel_init_freeable+0x147/0x1a0
> >   kernel_init+0x1a/0x140
> >   ret_from_fork+0x34/0x50
> >   ? __pfx_kernel_init+0x10/0x10
> >   ret_from_fork_asm+0x1a/0x30
> >   </TASK>
> >  Modules linked in:
> >  ---[ end trace 0000000000000000 ]---
> >  RIP: 0010:ima_restore_measurement_list+0xdc/0x420
> >  Code: ff 48 c7 85 10 ff ff ff 00 00 00 00 48 c7 85 18 ff ff ff 00 00 00 00 48 85 f6 0f 84 09 03 00 00 48 83 fa 17 0f 86 ff 02 00 00 <66> 83 3e 01 49 89 f4 0f 85 90 94 7d 00 48 83 7e 10 ff 0f 84 74 94
> >  RSP: 0018:ffffc90000053c80 EFLAGS: 00010286
> >  RAX: 0000000000000000 RBX: ffffc90000053d03 RCX: 0000000000000000
> >  RDX: e48066052d5df359 RSI: cfacfdfe6660003e RDI: cfacfdfe66600056
> >  RBP: ffffc90000053d80 R08: 0000000000000000 R09: ffffffff82de1a88
> >  R10: ffffc90000053da0 R11: 0000000000000003 R12: 00000000000001a4
> >  R13: ffffc90000053df0 R14: 0000000000000000 R15: 0000000000000000
> >  FS:  0000000000000000(0000) GS:ffff888040200000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 00007f2c744050e8 CR3: 000080004110e000 CR4: 00000000003506b0
> >  Kernel panic - not syncing: Fatal exception
> >  Kernel Offset: disabled
> >  Rebooting in 10 seconds..
> >
> > From debugging printing, the stored addr and size of ima_kexec buffer
> > are not decrypted correctly like:
> >  ------
> >  ima: ima_load_kexec_buffer, buffer:0xcfacfdfe6660003e, size:0xe48066052d5df359
> >  ------
> >
> > There are three pieces of setup_data info passed to kexec/kdump kernel:
> > SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED. However, among them, only
> > ima_kexec buffer suffered from the incorrect decryption. After
> > debugging, it's because of the code bug in early_memremap_is_setup_data()
> > where checking the embedded content inside setup_data takes wrong range
> > calculation.
> >
> > The length of efi data, rng_seed and ima_kexec are 0x70, 0x20, 0x10,
> > and the length of setup_data is 0x10. When checking if data is inside
> > the embedded conent of setup_data, the starting address of efi data and
> > rng_seed happened to land in the wrong calculated range. While the
> > ima_kexec's starting address unluckily doesn't pass the checking, then
> > error occurred.
> >
> > Here fix the code bug to make kexec/kdump kernel boot up successfully.
> >
> > Fixes: 8f716c9b5feb ("x86/mm: Add support to access boot related data in the clear")
>
> The check that was modified was added by:
>         b3c72fc9a78e ("x86/boot: Introduce setup_indirect")
>
> The SETUP_INDIRECT patches seem to be the issue here.
>
> > Signed-off-by: Baoquan He <bhe at redhat.com>
> > ---
> >  arch/x86/mm/ioremap.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> > index aa7d279321ea..7953c4a1d28d 100644
> > --- a/arch/x86/mm/ioremap.c
> > +++ b/arch/x86/mm/ioremap.c
> > @@ -717,7 +717,7 @@ static bool __init early_memremap_is_setup_data(resource_size_t phys_addr,
> >               paddr_next = data->next;
> >               len = data->len;
> >
> > -             if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
> > +             if ((phys_addr > paddr) && (phys_addr < (paddr + size + len))) {
>

Tom,    I have an old laptop with AMD cpu,  according to dmesg below I
assume SME is enabled:
[    0.082438] Memory Encryption Features active: AMD SME

I tried kexec with mem_encrypt=on, but I can not reproduce Baoquan's
problem,  it seems either ENC or NOENC works, it is weird to me.  Any
idea about this?

Otherwise I tried earlycon=efi,  early printk does not work.  It works
with "NOENC" mapping though:
@@ -59,7 +62,8 @@ static __ref void *efi_earlycon_map(unsigned long
start, unsigned long len)
        if (efi_fb)
                return efi_fb + start;

-       fb_prot = fb_wb ? PAGE_KERNEL : pgprot_writecombine(PAGE_KERNEL);
+       //fb_prot = fb_wb ? PAGE_KERNEL : pgprot_writecombine(PAGE_KERNEL);
+       fb_prot = fb_wb ? PAGE_KERNEL_NOENC :
pgprot_writecombine(PAGE_KERNEL_NOENC);
        return early_memremap_prot(fb_base + start, len, pgprot_val(fb_prot));
 }



From bhe at redhat.com  Fri Aug 30 04:17:33 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 30 Aug 2024 19:17:33 +0800
Subject: [PATCH] kexec/crash: no crash update when kexec in progress
In-Reply-To: <1e4a8e18-cda9-45f5-a842-8ffcd725efc9@linux.ibm.com>
References: <20240731152738.194893-1-sourabhjain@linux.ibm.com>
 <87v80lnf8d.fsf@mail.lhotse>
 <10c666ae-d528-4f49-82e9-8e0fee7099e0@linux.ibm.com>
 <355b58b1-6c51-4c42-b6ea-dcd6b1617a18@linux.ibm.com>
 <ZsLjGJvAUIaxrG6x@MiWiFi-R3L-srv>
 <1e4a8e18-cda9-45f5-a842-8ffcd725efc9@linux.ibm.com>
Message-ID: <ZtGqTSMvx6Ljf5Xi@MiWiFi-R3L-srv>

On 08/20/24 at 12:10pm, Sourabh Jain wrote:
> Hello Baoquan,
> 
> On 19/08/24 11:45, Baoquan He wrote:
> > On 08/19/24 at 09:45am, Sourabh Jain wrote:
> > > Hello Michael and Boaquan
> > > 
> > > On 01/08/24 12:21, Sourabh Jain wrote:
> > > > Hello Michael,
> > > > 
> > > > On 01/08/24 08:04, Michael Ellerman wrote:
> > > > > Sourabh Jain <sourabhjain at linux.ibm.com> writes:
> > > > > > The following errors are observed when kexec is done with SMT=off on
> > > > > > powerpc.
> > > > > > 
> > > > > > [? 358.458385] Removing IBM Power 842 compression device
> > > > > > [? 374.795734] kexec_core: Starting new kernel
> > > > > > [? 374.795748] kexec: Waking offline cpu 1.
> > > > > > [? 374.875695] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > > > be inaccurate
> > > > > > [? 374.935833] kexec: Waking offline cpu 2.
> > > > > > [? 375.015664] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > > > be inaccurate
> > > > > > snip..
> > > > > > [? 375.515823] kexec: Waking offline cpu 6.
> > > > > > [? 375.635667] crash hp: kexec_trylock() failed, elfcorehdr may
> > > > > > be inaccurate
> > > > > > [? 375.695836] kexec: Waking offline cpu 7.
> > > > > Are they actually errors though? Do they block the actual kexec from
> > > > > happening? Or are they just warnings in dmesg?
> > > > The kexec kernel boots fine.
> > > > 
> > > > This warning appears regardless of whether the kdump kernel is loaded.
> > > > 
> > > > However, when the kdump kernel is loaded, we will not be able to update
> > > > the kdump image (FDT).
> > > > I think this should be fine given that kexec is in progress.
> > > > 
> > > > Please let me know your opinion.
> > > > 
> > > > > Because the fix looks like it could be racy.
> > > > It seems like it is racy, but given that kexec takes the lock first and
> > > > then
> > > > brings the CPU up, which triggers the kdump image, which always fails to
> > > > update the kdump image because it could not take the same lock.
> > > > 
> > > > Note: the kexec lock is not released unless kexec boot fails.
> > > Any comments or suggestions on this fix?
> > Is this a little better?
> > 
> > diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> > index 63cf89393c6e..0355ffb712f4 100644
> > --- a/kernel/crash_core.c
> > +++ b/kernel/crash_core.c
> > @@ -504,7 +504,7 @@ int crash_check_hotplug_support(void)
> >   	crash_hotplug_lock();
> >   	/* Obtain lock while reading crash information */
> > -	if (!kexec_trylock()) {
> > +	if (!kexec_trylock() && kexec_in_progress) {
> >   		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> >   		crash_hotplug_unlock();
> >   		return 0;
> > @@ -539,7 +539,7 @@ static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu,
> >   	crash_hotplug_lock();
> >   	/* Obtain lock while changing crash information */
> > -	if (!kexec_trylock()) {
> > +	if (!kexec_trylock() && kexec_in_progress) {
> >   		pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n");
> >   		crash_hotplug_unlock();
> >   		return;
> 
> Ideally, when `kexec_in_progress` is True, there should be no way to acquire
> the kexec lock.
> Therefore, calling `kexec_trylock()` before checking `kexec_in_progress` is
> not helpful.
> The kernel will print the error message "kexec_trylock() failed, elfcorehdr
> may be inaccurate."
> So, with the above changes, the original problem remains unsolved.
> 
> However, after closely inspecting the `kernel/kexec_core.c:kernel_kexec()`
> function, I discovered
> an exceptional case where my patch needs an update. The issue arises when
> the system returns
> from the `machine_kexec()` function, which indicates that kexec has failed.
> 
> In this scenario, the kexec lock is released, but `kexec_in_progress`
> remains True.
> 
> I am unsure why `kexec_in_progress` is NOT set to False when kexec fails.
> Was this by design,
> or was it an oversight because returning from the `machine_kexec()` function
> is highly unlikely?
> 
> Here is my proposal to address the original problem along with the
> exceptional case I described
> above.
> 
> Let's implement two patches:
> 
> 1. A patch that sets `kexec_in_progress` to False if the system returns from
> `machine_kexec()` before

I don't think we have chance to return from machine_kexec() after
triggering kexec/kdump jumping. The KEXEC_JUMP could return, but I'v
never heard people using it.

> ?? unlocking the kexec lock in the `kernel_kexec()` function.
> 
> ?? ```
> ?? diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> ?? index c0caa14880c3..b41277183455 100644
> ?? --- a/kernel/kexec_core.c
> ?? +++ b/kernel/kexec_core.c
> ?? @@ -1069,6 +1069,7 @@ int kernel_kexec(void)
> ?? #endif
> 
> ??? Unlock:
> ?? +????? kexec_in_progress = false;
> ?????????? kexec_unlock();
> ?????????? return error;
> ??? ```
> 
> 2. A patch to return early from the `crash_handle_hotplug_event()` function
> if `kexec_in_progress` is
> ?? set to True. This is essentially my original patch.

There's a race gap between the kexec_in_progress checking and the
setting it to true which Michael has mentioned. That's why I think
maybe checking kexec_in_progress after failing to retriving
__kexec_lock is a little better, not very sure.

> 
> Please share your comments on the new approach.
> 
> Thank you for review.
> 
> - Sourabh Jain
> 



From gpiccoli at igalia.com  Fri Aug 30 07:03:22 2024
From: gpiccoli at igalia.com (Guilherme G. Piccoli)
Date: Fri, 30 Aug 2024 11:03:22 -0300
Subject: [PATCH] Documentation: Improve crash_kexec_post_notifiers description
Message-ID: <20240830140401.458542-1-gpiccoli@igalia.com>

Be more clear about the downsides, the upsides (yes, there are some!)
and about code that unconditionally sets that.

Signed-off-by: Guilherme G. Piccoli <gpiccoli at igalia.com>
---
 Documentation/admin-guide/kernel-parameters.txt | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index efc52ddc6864..cb25dc5cbe9a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -913,12 +913,16 @@
 			the parameter has no effect.
 
 	crash_kexec_post_notifiers
-			Run kdump after running panic-notifiers and dumping
-			kmsg. This only for the users who doubt kdump always
-			succeeds in any situation.
-			Note that this also increases risks of kdump failure,
-			because some panic notifiers can make the crashed
-			kernel more unstable.
+			Only jump to kdump kernel after running the panic
+			notifiers and dumping kmsg. This option increases the
+			risks of a kdump failure, since some panic notifiers
+			can make the crashed kernel more unstable. As a bright
+			side, it might allow to collect more data on dmesg like
+			stack traces from other CPUs or extra data dumped by
+			panic_print. This is usually only for users who doubt
+			kdump will succeed every time. Notice that some code
+			enables this option unconditionally, like Hyper-V,
+			PowerPC (fadump) and AMD SEV.
 
 	crashkernel=size[KMG][@offset[KMG]]
 			[KNL,EARLY] Using kexec, Linux can switch to a 'crash kernel'
-- 
2.46.0



From gpiccoli at igalia.com  Fri Aug 30 07:17:15 2024
From: gpiccoli at igalia.com (Guilherme G. Piccoli)
Date: Fri, 30 Aug 2024 11:17:15 -0300
Subject: [PATCH] powerpc/fadump, x86/sev: Inform about unconditionally enabling crash_kexec_post_notifiers
Message-ID: <20240830141752.460173-1-gpiccoli@igalia.com>

Inspired by commit d57d6fe5bf34 ("drivers: hv: log when enabling crash_kexec_post_notifiers"),
a good idea is to signal on dmesg about unconditionally enabling the kernel
parameter crash_kexec_post_notifiers, which affects how kdump works.

By checking the source code, found 2 more cases besides Hyper-V, so let's
print that on dmesg for them as well.

Signed-off-by: Guilherme G. Piccoli <gpiccoli at igalia.com>
---
 arch/powerpc/kernel/fadump.c | 1 +
 arch/x86/virt/svm/sev.c      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index a612e7513a4f..37dee89a0bf2 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -1819,6 +1819,7 @@ int __init setup_fadump(void)
 	 * notifiers are invoked.
 	 */
 	crash_kexec_post_notifiers = true;
+	pr_info("PPC/fadump: enabling crash_kexec_post_notifiers\n");
 
 	return 1;
 }
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index 0ce17766c0e5..ac445ad2fcc8 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -257,6 +257,7 @@ static int __init snp_rmptable_init(void)
 	 * notifier is invoked to do SNP IOMMU shutdown before kdump.
 	 */
 	crash_kexec_post_notifiers = true;
+	pr_info("AMD/SEV: enabling crash_kexec_post_notifiers\n");
 
 	return 0;
 
-- 
2.46.0



From bhe at redhat.com  Fri Aug 30 07:45:44 2024
From: bhe at redhat.com (Baoquan He)
Date: Fri, 30 Aug 2024 22:45:44 +0800
Subject: [PATCH] Add support for soft reserved memory range
In-Reply-To: <20240814053313.35251-1-jacekt@dugeo.com>
References: <20240814052024.25731-1-jacekt@dugeo.com>
 <20240814053313.35251-1-jacekt@dugeo.com>
Message-ID: <ZtHbGIuXOAT59IBJ@MiWiFi-R3L-srv>

Hi,

On 08/14/24 at 01:33pm, Jacek Tomaka wrote:
> Essentially catch up with e820 related changes in the kernel.
> Intel Sapphire Rappids MAX has high bandwidth memory which is
> precious resource that is better not allocated by the kernel.

Wondering what use cases you have encountered and want to use this patch
to resolve. Could you say more about it?

> 
> Userspace later can enable soft reserved range using daxctl.
> 
> Signed-off-by: Jacek Tomaka <jacek.tomaka at poczta.fm>
> ---
>  include/x86/x86-linux.h               | 2 ++
>  kexec/arch/i386/crashdump-x86.c       | 7 +++++++
>  kexec/arch/i386/kexec-multiboot-x86.c | 1 +
>  kexec/arch/i386/kexec-x86-common.c    | 5 +++++
>  kexec/arch/i386/x86-linux-setup.c     | 3 +++
>  kexec/firmware_memmap.c               | 2 ++
>  kexec/kexec.h                         | 1 +
>  7 files changed, 21 insertions(+)
> 
> diff --git a/include/x86/x86-linux.h b/include/x86/x86-linux.h
> index 9646102835..fbde93df94 100644
> --- a/include/x86/x86-linux.h
> +++ b/include/x86/x86-linux.h
> @@ -23,6 +23,8 @@ struct e820entry {
>  #define E820_NVS	4
>  #define E820_PMEM       7
>  #define E820_PRAM       12
> +#define E820_SOFT_RESERVED 0xefffffff
> +
>  } __attribute__((packed));
>  #endif
>  
> diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
> index a01031e570..49108b2032 100644
> --- a/kexec/arch/i386/crashdump-x86.c
> +++ b/kexec/arch/i386/crashdump-x86.c
> @@ -288,6 +288,10 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
>  			type = RANGE_RESERVED;
>  		} else if (memcmp(str, "Reserved\n", 9) == 0) {
>  			type = RANGE_RESERVED;
> +		} else if (memcmp(str, "soft reserved\n", 14) == 0 ) {
> +			type = RANGE_SOFT_RESERVED;
> +		} else if (memcmp(str, "Soft Reserved\n", 14) == 0 ) {
> +			type = RANGE_SOFT_RESERVED;
>  		} else if (memcmp(str, "GART\n", 5) == 0) {
>  			gart_start = start;
>  			gart_end = end;
> @@ -615,6 +619,8 @@ static void cmdline_add_memmap_internal(char *cmdline, unsigned long startk,
>  		strcat (str_mmap, "K@");
>  	else if (type == RANGE_RESERVED)
>  		strcat (str_mmap, "K$");
> +	else if (type == RANGE_SOFT_RESERVED)
> +		strcat (str_mmap, "K*");
>  	else if (type == RANGE_ACPI || type == RANGE_ACPI_NVS)
>  		strcat (str_mmap, "K#");
>  	else if (type == RANGE_PRAM)
> @@ -985,6 +991,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
>  		if ( !( mem_range[i].type == RANGE_ACPI
>  			|| mem_range[i].type == RANGE_ACPI_NVS
>  			|| mem_range[i].type == RANGE_RESERVED
> +			|| mem_range[i].type == RANGE_SOFT_RESERVED
>  			|| mem_range[i].type == RANGE_PMEM
>  			|| mem_range[i].type == RANGE_PRAM))
>  			continue;
> diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c
> index 33c885a2fa..49d57cb5ae 100644
> --- a/kexec/arch/i386/kexec-multiboot-x86.c
> +++ b/kexec/arch/i386/kexec-multiboot-x86.c
> @@ -379,6 +379,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
>  			mmap[i].Type = 4;
>  			break;
>  		case RANGE_RESERVED:
> +		case RANGE_SOFT_RESERVED:
>  		default:
>  			mmap[i].Type = 2;  /* Not RAM (reserved) */
>  		}
> diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
> index ffc95a9e43..116c4f4fd3 100644
> --- a/kexec/arch/i386/kexec-x86-common.c
> +++ b/kexec/arch/i386/kexec-x86-common.c
> @@ -99,6 +99,9 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges
>  		else if (strncasecmp(str, "reserved\n", 9) == 0) {
>  			type = RANGE_RESERVED;
>  		}
> +		else if (strncasecmp(str, "soft reserved\n", 9) == 0) {
> +			type = RANGE_SOFT_RESERVED;
> +		}
>  		else if (memcmp(str, "ACPI Tables\n", 12) == 0) {
>  			type = RANGE_ACPI;
>  		}
> @@ -170,6 +173,8 @@ unsigned xen_e820_to_kexec_type(uint32_t type)
>  			return RANGE_PMEM;
>  		case E820_PRAM:
>  			return RANGE_PRAM;
> +		case E820_SOFT_RESERVED;
> +			return RANGE_SOFT_RESERVED;
>  		case E820_RESERVED:
>  		default:
>  			return RANGE_RESERVED;
> diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
> index 73251b9339..afc83fe729 100644
> --- a/kexec/arch/i386/x86-linux-setup.c
> +++ b/kexec/arch/i386/x86-linux-setup.c
> @@ -755,6 +755,9 @@ static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode,
>  			case RANGE_PRAM:
>  				e820[i].type = E820_PRAM;
>  				break;
> +			case RANGE_SOFT_RESERVED:
> +				e820[i].type = E820_SOFT_RESERVED;
> +				break;
>  			default:
>  			case RANGE_RESERVED:
>  				e820[i].type = E820_RESERVED;
> diff --git a/kexec/firmware_memmap.c b/kexec/firmware_memmap.c
> index 457c3dc9a6..fa0c22140a 100644
> --- a/kexec/firmware_memmap.c
> +++ b/kexec/firmware_memmap.c
> @@ -182,6 +182,8 @@ static int parse_memmap_entry(const char *entry, struct memory_range *range)
>  		range->type = RANGE_RESERVED;
>  	else if (strcmp(type, "Reserved") == 0)
>  		range->type = RANGE_RESERVED;
> +        else if (strcmp(type, "Soft Reserved") == 0)
> +                range->type = RANGE_SOFT_RESERVED;
>  	else if (strcmp(type, "Unknown E820 type") == 0)
>  		range->type = RANGE_RESERVED;
>  	else if (strcmp(type, "ACPI Non-volatile Storage") == 0)
> diff --git a/kexec/kexec.h b/kexec/kexec.h
> index 31c323f674..dbb27a7607 100644
> --- a/kexec/kexec.h
> +++ b/kexec/kexec.h
> @@ -139,6 +139,7 @@ struct memory_range {
>  #define RANGE_UNCACHED	4
>  #define RANGE_PMEM		6
>  #define RANGE_PRAM		11
> +#define RANGE_SOFT_RESERVED 0xefffffff
>  };
>  
>  struct memory_ranges {
> -- 
> 2.17.0
> 
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 



From stephen.s.brennan at oracle.com  Fri Aug 30 10:15:50 2024
From: stephen.s.brennan at oracle.com (Stephen Brennan)
Date: Fri, 30 Aug 2024 10:15:50 -0700
Subject: [PATCH] Documentation: Improve crash_kexec_post_notifiers
 description
In-Reply-To: <20240830140401.458542-1-gpiccoli@igalia.com>
References: <20240830140401.458542-1-gpiccoli@igalia.com>
Message-ID: <87ed66q6d5.fsf@oracle.com>

"Guilherme G. Piccoli" <gpiccoli at igalia.com> writes:
> Be more clear about the downsides, the upsides (yes, there are some!)
> and about code that unconditionally sets that.
>
> Signed-off-by: Guilherme G. Piccoli <gpiccoli at igalia.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index efc52ddc6864..cb25dc5cbe9a 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -913,12 +913,16 @@
>  			the parameter has no effect.
>  
>  	crash_kexec_post_notifiers
> -			Run kdump after running panic-notifiers and dumping
> -			kmsg. This only for the users who doubt kdump always
> -			succeeds in any situation.
> -			Note that this also increases risks of kdump failure,
> -			because some panic notifiers can make the crashed
> -			kernel more unstable.
> +			Only jump to kdump kernel after running the panic
> +			notifiers and dumping kmsg. This option increases the
> +			risks of a kdump failure, since some panic notifiers
> +			can make the crashed kernel more unstable. As a bright
> +			side, it might allow to collect more data on dmesg like
> +			stack traces from other CPUs or extra data dumped by
> +			panic_print. This is usually only for users who doubt
> +			kdump will succeed every time.

This is definitely clearer and an improvement! But I didn't (and still
don't) love the phrase "users who doubt kdump will succeed" because I
think that implies user error or silly beliefs.

What if these two sentences read something like:

In configurations where kdump may not be reliable, running the panic
notifiers can allow collecting more data on dmesg, like stack traces
from other CPUS or extra data dumped by panic_print.

> Notice that some code
> +			enables this option unconditionally, like Hyper-V,
> +			PowerPC (fadump) and AMD SEV.

Yes, great addition.

With or without my suggestions it's an improvement, so:

Reviewed-by: Stephen Brennan <stephen.s.brennan at oracle.com>


From stephen.s.brennan at oracle.com  Fri Aug 30 10:54:05 2024
From: stephen.s.brennan at oracle.com (Stephen Brennan)
Date: Fri, 30 Aug 2024 10:54:05 -0700
Subject: [PATCH] powerpc/fadump, x86/sev: Inform about unconditionally
 enabling crash_kexec_post_notifiers
In-Reply-To: <20240830141752.460173-1-gpiccoli@igalia.com>
References: <20240830141752.460173-1-gpiccoli@igalia.com>
Message-ID: <87bk19rj5u.fsf@oracle.com>

"Guilherme G. Piccoli" <gpiccoli at igalia.com> writes:
> Inspired by commit d57d6fe5bf34 ("drivers: hv: log when enabling crash_kexec_post_notifiers"),
> a good idea is to signal on dmesg about unconditionally enabling the kernel
> parameter crash_kexec_post_notifiers, which affects how kdump works.
>
> By checking the source code, found 2 more cases besides Hyper-V, so let's
> print that on dmesg for them as well.

This is a great catch! One of those was already there when I sent the
original patch, but the other is new.

Could we maybe go further than this, and delete the public declarations
of crash_kexec_post_notifiers in "include/linux"? (I see two). We could
replace the users that set it to true with a function that logs the
change so that it's impossible for new code to set it directly without
notifying the user. Something like this? Compile tested only for x86.

commit da8691a25d7b0c2f914720bc054dd1d9dbe4b373
Author: Stephen Brennan <stephen.s.brennan at oracle.com>
Date:   Fri Aug 30 10:49:24 2024 -0700

    panic: make crash_kexec_post_notifiers private
    
    This requires that any in-kernel user setting it directly must log the
    reason so that users are aware their panic behavior may be different
    from their configuration.
    
    Signed-off-by: Stephen Brennan <stephen.s.brennan at oracle.com>

diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index a612e7513a4f8..9966f29409599 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -1818,7 +1818,7 @@ int __init setup_fadump(void)
 	 * lets panic() function take crash friendly path before panic
 	 * notifiers are invoked.
 	 */
-	crash_kexec_post_notifiers = true;
+	enable_crash_kexec_post_notifiers("PPC/fadump");
 
 	return 1;
 }
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
index 0ce17766c0e52..6e9f5f8d13cc5 100644
--- a/arch/x86/virt/svm/sev.c
+++ b/arch/x86/virt/svm/sev.c
@@ -256,7 +256,7 @@ static int __init snp_rmptable_init(void)
 	 * Setting crash_kexec_post_notifiers to 'true' to ensure that SNP panic
 	 * notifier is invoked to do SNP IOMMU shutdown before kdump.
 	 */
-	crash_kexec_post_notifiers = true;
+	enable_crash_kexec_post_notifiers("AMD/SEV");
 
 	return 0;
 
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index 9c452bfbd5719..fa3bbb66235de 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -303,8 +303,7 @@ int __init hv_common_init(void)
 	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
 		u64 hyperv_crash_ctl;
 
-		crash_kexec_post_notifiers = true;
-		pr_info("Hyper-V: enabling crash_kexec_post_notifiers\n");
+		enable_crash_kexec_post_notifiers("Hyper-V");
 
 		/*
 		 * Panic message recording (sysctl_record_panic_msg)
diff --git a/include/linux/panic.h b/include/linux/panic.h
index 54d90b6c5f47b..697184664c6f4 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -31,8 +31,6 @@ extern int sysctl_panic_on_rcu_stall;
 extern int sysctl_max_rcu_stall_to_panic;
 extern int sysctl_panic_on_stackoverflow;
 
-extern bool crash_kexec_post_notifiers;
-
 extern void __stack_chk_fail(void);
 void abort(void);
 
diff --git a/include/linux/panic_notifier.h b/include/linux/panic_notifier.h
index 41e32483d7a7b..97c31cf5c2fdb 100644
--- a/include/linux/panic_notifier.h
+++ b/include/linux/panic_notifier.h
@@ -7,6 +7,6 @@
 
 extern struct atomic_notifier_head panic_notifier_list;
 
-extern bool crash_kexec_post_notifiers;
+void enable_crash_kexec_post_notifiers(const char *reason);
 
 #endif	/* _LINUX_PANIC_NOTIFIERS_H */
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 63cf89393c6eb..634c6b99717c5 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -33,6 +33,9 @@
 /* Per cpu memory for storing cpu states in case of system crash. */
 note_buf_t __percpu *crash_notes;
 
+/* Defined in kernel/panic.c and needed here, but not intended to be public. */
+extern bool crash_kexec_post_notifiers;
+
 #ifdef CONFIG_CRASH_DUMP
 
 int kimage_crash_copy_vmcoreinfo(struct kimage *image)
diff --git a/kernel/panic.c b/kernel/panic.c
index 2a0449144f82e..f4ae3abbea7ed 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -137,6 +137,12 @@ static long no_blink(int state)
 	return 0;
 }
 
+void enable_crash_kexec_post_notifiers(const char *reason)
+{
+	crash_kexec_post_notifiers = true;
+	pr_info("%s: enabling crash_kexec_post_notifiers\n", reason);
+}
+
 /* Returns how long it waited in ms */
 long (*panic_blink)(int state);
 EXPORT_SYMBOL(panic_blink);


From gpiccoli at igalia.com  Fri Aug 30 11:11:13 2024
From: gpiccoli at igalia.com (Guilherme G. Piccoli)
Date: Fri, 30 Aug 2024 15:11:13 -0300
Subject: [PATCH] powerpc/fadump, x86/sev: Inform about unconditionally
 enabling crash_kexec_post_notifiers
In-Reply-To: <87bk19rj5u.fsf@oracle.com>
References: <20240830141752.460173-1-gpiccoli@igalia.com>
 <87bk19rj5u.fsf@oracle.com>
Message-ID: <d1e65436-b49b-76b1-01d4-2be2a0eb0f3a@igalia.com>

On 30/08/2024 14:54, Stephen Brennan wrote:
> [...]
> Could we maybe go further than this, and delete the public declarations
> of crash_kexec_post_notifiers in "include/linux"? (I see two). We could
> replace the users that set it to true with a function that logs the
> change so that it's impossible for new code to set it directly without
> notifying the user. Something like this? Compile tested only for x86.
> 
> commit da8691a25d7b0c2f914720bc054dd1d9dbe4b373
> Author: Stephen Brennan <stephen.s.brennan at oracle.com>
> Date:   Fri Aug 30 10:49:24 2024 -0700
> 
>     panic: make crash_kexec_post_notifiers private
>     
>     This requires that any in-kernel user setting it directly must log the
>     reason so that users are aware their panic behavior may be different
>     from their configuration.
>     
>     Signed-off-by: Stephen Brennan <stephen.s.brennan at oracle.com>
> 

Thanks Stephen! I'm totally into that, your approach is very good.
Cheers,


Guilherme


> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index a612e7513a4f8..9966f29409599 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -1818,7 +1818,7 @@ int __init setup_fadump(void)
>  	 * lets panic() function take crash friendly path before panic
>  	 * notifiers are invoked.
>  	 */
> -	crash_kexec_post_notifiers = true;
> +	enable_crash_kexec_post_notifiers("PPC/fadump");
>  
>  	return 1;
>  }
> diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
> index 0ce17766c0e52..6e9f5f8d13cc5 100644
> --- a/arch/x86/virt/svm/sev.c
> +++ b/arch/x86/virt/svm/sev.c
> @@ -256,7 +256,7 @@ static int __init snp_rmptable_init(void)
>  	 * Setting crash_kexec_post_notifiers to 'true' to ensure that SNP panic
>  	 * notifier is invoked to do SNP IOMMU shutdown before kdump.
>  	 */
> -	crash_kexec_post_notifiers = true;
> +	enable_crash_kexec_post_notifiers("AMD/SEV");
>  
>  	return 0;
>  
> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> index 9c452bfbd5719..fa3bbb66235de 100644
> --- a/drivers/hv/hv_common.c
> +++ b/drivers/hv/hv_common.c
> @@ -303,8 +303,7 @@ int __init hv_common_init(void)
>  	if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
>  		u64 hyperv_crash_ctl;
>  
> -		crash_kexec_post_notifiers = true;
> -		pr_info("Hyper-V: enabling crash_kexec_post_notifiers\n");
> +		enable_crash_kexec_post_notifiers("Hyper-V");
>  
>  		/*
>  		 * Panic message recording (sysctl_record_panic_msg)
> diff --git a/include/linux/panic.h b/include/linux/panic.h
> index 54d90b6c5f47b..697184664c6f4 100644
> --- a/include/linux/panic.h
> +++ b/include/linux/panic.h
> @@ -31,8 +31,6 @@ extern int sysctl_panic_on_rcu_stall;
>  extern int sysctl_max_rcu_stall_to_panic;
>  extern int sysctl_panic_on_stackoverflow;
>  
> -extern bool crash_kexec_post_notifiers;
> -
>  extern void __stack_chk_fail(void);
>  void abort(void);
>  
> diff --git a/include/linux/panic_notifier.h b/include/linux/panic_notifier.h
> index 41e32483d7a7b..97c31cf5c2fdb 100644
> --- a/include/linux/panic_notifier.h
> +++ b/include/linux/panic_notifier.h
> @@ -7,6 +7,6 @@
>  
>  extern struct atomic_notifier_head panic_notifier_list;
>  
> -extern bool crash_kexec_post_notifiers;
> +void enable_crash_kexec_post_notifiers(const char *reason);
>  
>  #endif	/* _LINUX_PANIC_NOTIFIERS_H */
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 63cf89393c6eb..634c6b99717c5 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -33,6 +33,9 @@
>  /* Per cpu memory for storing cpu states in case of system crash. */
>  note_buf_t __percpu *crash_notes;
>  
> +/* Defined in kernel/panic.c and needed here, but not intended to be public. */
> +extern bool crash_kexec_post_notifiers;
> +
>  #ifdef CONFIG_CRASH_DUMP
>  
>  int kimage_crash_copy_vmcoreinfo(struct kimage *image)
> diff --git a/kernel/panic.c b/kernel/panic.c
> index 2a0449144f82e..f4ae3abbea7ed 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -137,6 +137,12 @@ static long no_blink(int state)
>  	return 0;
>  }
>  
> +void enable_crash_kexec_post_notifiers(const char *reason)
> +{
> +	crash_kexec_post_notifiers = true;
> +	pr_info("%s: enabling crash_kexec_post_notifiers\n", reason);
> +}
> +
>  /* Returns how long it waited in ms */
>  long (*panic_blink)(int state);
>  EXPORT_SYMBOL(panic_blink);
> 


From gpiccoli at igalia.com  Fri Aug 30 11:21:00 2024
From: gpiccoli at igalia.com (Guilherme G. Piccoli)
Date: Fri, 30 Aug 2024 15:21:00 -0300
Subject: [PATCH V2] Documentation: Improve crash_kexec_post_notifiers description
Message-ID: <20240830182219.485065-1-gpiccoli@igalia.com>

Be more clear about the downsides, the upsides (yes, there are some!)
and about code that unconditionally sets that.

Reviewed-by: Stephen Brennan <stephen.s.brennan at oracle.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli at igalia.com>

---

V2: Some wording improvements from Stephen, thanks!
Also added his review tag.

V1 link: https://lore.kernel.org/r/20240830140401.458542-1-gpiccoli at igalia.com/


 Documentation/admin-guide/kernel-parameters.txt | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index efc52ddc6864..351730108c58 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -913,12 +913,16 @@
 			the parameter has no effect.
 
 	crash_kexec_post_notifiers
-			Run kdump after running panic-notifiers and dumping
-			kmsg. This only for the users who doubt kdump always
-			succeeds in any situation.
-			Note that this also increases risks of kdump failure,
-			because some panic notifiers can make the crashed
-			kernel more unstable.
+			Only jump to kdump kernel after running the panic
+			notifiers and dumping kmsg. This option increases the
+			risks of a kdump failure, since some panic notifiers
+			can make the crashed kernel more unstable. In the
+			configurations where kdump may not be reliable,
+			running the panic notifiers can allow collecting more
+			data on dmesg, like stack traces from other CPUS or
+			extra data dumped by panic_print. Notice that some
+			code enables this option unconditionally, like
+			Hyper-V, PowerPC (fadump) and AMD SEV.
 
 	crashkernel=size[KMG][@offset[KMG]]
 			[KNL,EARLY] Using kexec, Linux can switch to a 'crash kernel'
-- 
2.46.0



From gpiccoli at igalia.com  Fri Aug 30 11:23:45 2024
From: gpiccoli at igalia.com (Guilherme G. Piccoli)
Date: Fri, 30 Aug 2024 15:23:45 -0300
Subject: [PATCH] Documentation: Improve crash_kexec_post_notifiers
 description
In-Reply-To: <87ed66q6d5.fsf@oracle.com>
References: <20240830140401.458542-1-gpiccoli@igalia.com>
 <87ed66q6d5.fsf@oracle.com>
Message-ID: <ffe4b1ac-926e-7f99-900b-707384f09462@igalia.com>

On 30/08/2024 14:15, Stephen Brennan wrote:
> [...]
> 
> This is definitely clearer and an improvement! But I didn't (and still
> don't) love the phrase "users who doubt kdump will succeed" because I
> think that implies user error or silly beliefs.
> 
> What if these two sentences read something like:
> 
> In configurations where kdump may not be reliable, running the panic
> notifiers can allow collecting more data on dmesg, like stack traces
> from other CPUS or extra data dumped by panic_print.
> 
>> Notice that some code
>> +			enables this option unconditionally, like Hyper-V,
>> +			PowerPC (fadump) and AMD SEV.
> 
> Yes, great addition.
> 
> With or without my suggestions it's an improvement, so:
> 
> Reviewed-by: Stephen Brennan <stephen.s.brennan at oracle.com>
> 

Thanks Stephen, I agree - your wording sounds better.
I've incorporated that in the just sent V2.
Cheers,


Guilherme


P.S. I'll be OOO some days, so expect a bit of delay in case there are
more reviews/interactions.


From ashish.kalra at amd.com  Fri Aug 30 14:08:35 2024
From: ashish.kalra at amd.com (Kalra, Ashish)
Date: Fri, 30 Aug 2024 16:08:35 -0500
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <155cb321-a169-4a56-b0ac-940676c1e9ee@amd.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
 <87475131-856C-44DC-A27A-84648294F094@alien8.de>
 <ZtCKqD_gc6wnqu-P@google.com> <155cb321-a169-4a56-b0ac-940676c1e9ee@amd.com>
Message-ID: <26da9c1f-3cb6-45a5-b4df-1e4838057ea4@amd.com>

Hello Boris,

On 8/29/2024 10:16 AM, Kalra, Ashish wrote:
> On 8/29/2024 9:50 AM, Sean Christopherson wrote:
>
>> On Thu, Aug 29, 2024, Borislav Petkov wrote:
>>> On August 27, 2024 10:38:04 PM GMT+02:00, Ashish Kalra <Ashish.Kalra at amd.com> wrote:
>>>> From: Ashish Kalra <ashish.kalra at amd.com>
>>>>
>>>> With active SNP VMs, SNP_SHUTDOWN_EX invoked during panic notifiers causes
>>>> crashkernel boot failure with the following signature:
>>> Why would SNP_SHUTDOWN be allowed *at all* if there are active SNP guests and
>>> there's potential to lose guest data in the process?!
>> Because if the host is panicking, guests are hosed regardless.  Unless I'm
>> misreading things, the goal here is to ensure the crashkernel can actually capture
>> a kdump.
> Yes, that is the main goal here to ensure that crashkernel can boot and capture a kdump on a SNP enabled host regardless of SNP VMs running.

Are you convinced with Sean's feedback here that this is a required feature to fix ?

And it is important to reiterate this again:

SNP_DECOMMISSION mainly unbinds the ASID from SNP context and marks the ASID as unusable and then transitions the SNP guest context page to a FW page and SNP_SHUTDOWN_EX transitions all pages associated with the IOMMU to reclaim state which the HV then transitions to hypervisor state, all these page state changes are in the RMP table, so there is no loss of guest data as such and the complete host memory is captured with the crashkernel boot. There are no processes which are being killed and host/guest memory is not being altered or modified in any way.

Additionally, i believe that the support staff will absolutely need this kind of support which enables crashkernel/kdump for SNP hosts.

Thanks, Ashish



From lkp at intel.com  Sat Aug 31 00:35:11 2024
From: lkp at intel.com (kernel test robot)
Date: Sat, 31 Aug 2024 15:35:11 +0800
Subject: [PATCH] x86/sev: Fix host kdump support for SNP
In-Reply-To: <20240827203804.4989-1-Ashish.Kalra@amd.com>
References: <20240827203804.4989-1-Ashish.Kalra@amd.com>
Message-ID: <202408311530.cYa27OX8-lkp@intel.com>

Hi Ashish,

kernel test robot noticed the following build warnings:

[auto build test WARNING on kvm/queue]
[also build test WARNING on linus/master v6.11-rc5 next-20240830]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ashish-Kalra/x86-sev-Fix-host-kdump-support-for-SNP/20240828-044035
base:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue
patch link:    https://lore.kernel.org/r/20240827203804.4989-1-Ashish.Kalra%40amd.com
patch subject: [PATCH] x86/sev: Fix host kdump support for SNP
config: i386-buildonly-randconfig-006-20240831 (https://download.01.org/0day-ci/archive/20240831/202408311530.cYa27OX8-lkp at intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240831/202408311530.cYa27OX8-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202408311530.cYa27OX8-lkp at intel.com/

All warnings (new ones prefixed by >>):

   In file included from arch/x86/kvm/svm/svm.c:50:
>> arch/x86/kvm/svm/svm.h:783:13: warning: function 'snp_decommision_all' has internal linkage but is not defined [-Wundefined-internal]
     783 | static void snp_decommision_all(void);
         |             ^
   arch/x86/kvm/svm/svm.c:686:3: note: used here
     686 |                 snp_decommision_all();
         |                 ^
   1 warning generated.


vim +/snp_decommision_all +783 arch/x86/kvm/svm/svm.h

   763	
   764	static inline void sev_free_vcpu(struct kvm_vcpu *vcpu) {}
   765	static inline void sev_vm_destroy(struct kvm *kvm) {}
   766	static inline void __init sev_set_cpu_caps(void) {}
   767	static inline void __init sev_hardware_setup(void) {}
   768	static inline void sev_hardware_unsetup(void) {}
   769	static inline int sev_cpu_init(struct svm_cpu_data *sd) { return 0; }
   770	static inline int sev_dev_get_attr(u32 group, u64 attr, u64 *val) { return -ENXIO; }
   771	#define max_sev_asid 0
   772	static inline void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code) {}
   773	static inline void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu) {}
   774	static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order)
   775	{
   776		return 0;
   777	}
   778	static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {}
   779	static inline int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn)
   780	{
   781		return 0;
   782	}
 > 783	static void snp_decommision_all(void);
   784	#endif
   785	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From ross.philipson at oracle.com  Mon Aug 26 15:42:22 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 22:42:22 -0000
Subject: [PATCH v10 01/20] Documentation/x86: Secure Launch kernel documentation
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-2-ross.philipson@oracle.com>

From: "Daniel P. Smith" <dpsmith at apertussolutions.com>

Introduce background, overview and configuration/ABI information
for the Secure Launch kernel feature.

Signed-off-by: Daniel P. Smith <dpsmith at apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson at oracle.com>
Reviewed-by: Bagas Sanjaya <bagasdotme at gmail.com>
---
 Documentation/security/index.rst              |   1 +
 .../security/launch-integrity/index.rst       |  11 +
 .../security/launch-integrity/principles.rst  | 320 ++++++++++
 .../secure_launch_details.rst                 | 587 ++++++++++++++++++
 .../secure_launch_overview.rst                | 227 +++++++
 5 files changed, 1146 insertions(+)
 create mode 100644 Documentation/security/launch-integrity/index.rst
 create mode 100644 Documentation/security/launch-integrity/principles.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_details.rst
 create mode 100644 Documentation/security/launch-integrity/secure_launch_overview.rst

diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst
index 59f8fc106cb0..56e31fb3d91f 100644
--- a/Documentation/security/index.rst
+++ b/Documentation/security/index.rst
@@ -19,3 +19,4 @@ Security Documentation
    digsig
    landlock
    secrets/index
+   launch-integrity/index
diff --git a/Documentation/security/launch-integrity/index.rst b/Documentation/security/launch-integrity/index.rst
new file mode 100644
index 000000000000..838328186dd2
--- /dev/null
+++ b/Documentation/security/launch-integrity/index.rst
@@ -0,0 +1,11 @@
+=====================================
+System Launch Integrity documentation
+=====================================
+
+.. toctree::
+   :maxdepth: 1
+
+   principles
+   secure_launch_overview
+   secure_launch_details
+
diff --git a/Documentation/security/launch-integrity/principles.rst b/Documentation/security/launch-integrity/principles.rst
new file mode 100644
index 000000000000..d6d95099dfad
--- /dev/null
+++ b/Documentation/security/launch-integrity/principles.rst
@@ -0,0 +1,320 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. Copyright ? 2019-2024 Daniel P. Smith <dpsmith at apertussolutions.com>
+
+=======================
+System Launch Integrity
+=======================
+
+:Author: Daniel P. Smith
+:Date: August 2024
+
+This document serves to establish a common understanding of what is system
+launch, the integrity concern for system launch, and why using a Root of Trust
+(RoT) from a Dynamic Launch may be desired. Throughout this document
+terminology from the Trusted Computing Group (TCG) and National Institute for
+Science and Technology (NIST) is used to ensure a vendor natural language is
+used to describe and reference security-related concepts.
+
+System Launch
+=============
+
+There is a tendency to only consider the classical power-on boot as the only
+means to launch an Operating System (OS) on a computer system, but in fact most
+modern processors support two methods to launch the system. To provide clarity
+a common definition of a system launch should be established. This definition
+is that a during a single power life cycle of a system, a System Launch
+consists of an initialization event, typically in hardware, that is followed by
+an executing software payload that takes the system from the initialized state
+to a running state. Driven by the Trusted Computing Group (TCG) architecture,
+modern processors are able to support two methods to launch a system, these two
+types of system launch are known as Static Launch and Dynamic Launch.
+
+Static Launch
+-------------
+
+Static launch is the system launch associated with the power cycle of the CPU.
+Thus, static launch refers to the classical power-on boot where the
+initialization event is the release of the CPU from reset and the system
+firmware is the software payload that brings the system up to a running state.
+Since static launch is the system launch associated with the beginning of the
+power lifecycle of a system, it is therefore a fixed, one-time system launch.
+It is because of this that static launch is referred to and thought of as being
+"static".
+
+Dynamic Launch
+--------------
+
+Modern CPUs architectures provides a mechanism to re-initialize the system to a
+"known good" state without requiring a power event. This re-initialization
+event is the event for a dynamic launch and is referred to as the Dynamic
+Launch Event (DLE). The DLE functions by accepting a software payload, referred
+to as the Dynamic Configuration Environment (DCE), that execution is handed to
+after the DLE is invoked. The DCE is responsible for bringing the system back
+to a running state. Since the dynamic launch is not tied to a power event like
+the static launch, this enables a dynamic launch to be initiated at any time
+and multiple times during a single power life cycle. This dynamism is the
+reasoning behind referring to this system launch as being dynamic.
+
+Because a dynamic launch can be conducted at any time during a single power
+life cycle, they are classified into one of two types, an early launch or a
+late launch.
+
+:Early Launch: When a dynamic launch is used as a transition from a static
+   launch chain to the final Operating System.
+
+:Late Launch: The usage of a dynamic launch by an executing Operating System to
+   transition to a ?known good? state to perform one or more operations, e.g. to
+   launch into a new Operating System.
+
+System Integrity
+================
+
+A computer system can be considered a collection of mechanisms that work
+together to produce a result. The assurance that the mechanisms are functioning
+correctly and producing the expected result is the integrity of the system. To
+ensure a system's integrity there are a subset of these mechanisms, commonly
+referred to as security mechanisms, that are present to help ensure the system
+produces the expected result or at least detect the potential of an unexpected
+result may have happened. Since the security mechanisms are relied upon to
+ensue the integrity of the system, these mechanisms are trusted. Upon
+inspection these security mechanisms each have a set of properties and these
+properties can be evaluated to determine how susceptible a mechanism might be
+to failure. This assessment is referred to as the Strength of Mechanism and for
+trusted mechanism enables for the trustworthiness of that mechanism to be
+quantified.
+
+For software systems, there are two system states for which the integrity is
+critical, when the software is loaded into memory and when the software is
+executing on the hardware. Ensuring that the expected software is load into
+memory is referred to as load-time integrity while ensuring that the software
+executing is the expected software is the runtime integrity of that software.
+
+Load-time Integrity
+-------------------
+
+It is critical to understand what load-time integrity establishes about a
+system and what is assumed, i.e. what is being trusted. Load-time integrity is
+when a trusted entity, i.e. an entity with an assumed integrity, takes an
+action to assess an entity being loaded into memory before it is used. A
+variety of mechanisms may be used to conduct the assessment, each with
+different properties. A particular property is whether the mechanism creates an
+evidence of the assessment. Often either cryptographic signature checking or
+hashing are the common assessment operations used.
+
+A signature checking assessment functions by requiring a representation of the
+accepted authorities and uses those representations to assess if the entity has
+been signed by an accepted authority. The benefit to this process is that
+assessment process includes an adjudication of the assessment. The drawbacks
+are that 1) the adjudication is susceptible to tampering by the Trusted
+Computing Base (TCB), 2) there is no evidence to assert that an untampered
+adjudication was completed, and 3) the system must be an active participant in
+the key management infrastructure.
+
+A cryptographic hashing assessment does not adjudicate the assessment but
+instead, generates evidence of the assessment to be adjudicated independently.
+The benefits to this approach is that the assessment may be simple such that it
+may be implemented in an immutable mechanism, e.g. in hardware.  Additionally,
+it is possible for the adjudication to be conducted where it cannot be tampered
+with by the TCB. The drawback is that a compromised environment will be allowed
+to execute until an adjudication can be completed.
+
+Ultimately, load-time integrity provides confidence that the correct entity was
+loaded and in the absence of a run-time integrity mechanism assumes, i.e.
+trusts, that the entity will never become corrupted.
+
+Runtime Integrity
+-----------------
+
+Runtime integrity in the general sense is when a trusted entity makes an
+assessment of an entity at any point in time during the assessed entity's
+execution. A more concrete explanation is the taking of an integrity assessment
+of an active process executing on the system at any point during the process'
+execution. Often the load-time integrity of an operating system's user-space,
+i.e. the operating environment, is confused to be the runtime integrity of the
+system, since it is an integrity assessment of the "runtime" software. The
+reality is that actual runtime integrity is a very difficult problem and thus
+not very many solutions are public and/or available. One example of a runtime
+integrity solution would be Johns Hopkins Advanced Physics Laboratory's (APL)
+Linux Kernel Integrity Module (LKIM).
+
+Trust Chains
+============
+
+Building upon the understanding of security mechanisms to establish load-time
+integrity of an entity, it is possible to chain together load-time integrity
+assessments to establish the integrity of the whole system. This process is
+known as transitive trust and provides the concept of building a chain of
+load-time integrity assessments, commonly referred to as a trust chain. These
+assessments may be used to adjudicate the load-time integrity of the whole
+system. This trust chain is started by a trusted entity that does the first
+assessment. This first entity is referred to as the Root of Trust(RoT) with the
+entities name being derived from the mechanism used for the assessment, i.e.
+RoT for Verification (RTV) and RoT for Measurement (RTM).
+
+A trust chain is itself a mechanism, specifically a mechanism of mechanisms,
+and therefore it too has a Strength of Mechanism. The factors that contribute
+to the strength of a trust chain are,
+
+  - The strength of the chain's RoT
+  - The strength of each member of the trust chain
+  - The length, i.e. the number of members, of the chain
+
+Therefore, to provide the strongest trust chains, they should start with a
+strong RoT and should consist of members being of low complexity and minimizing
+the number of members participating as possible. In a more colloquial sense, a
+trust chain is only as strong as its weakest link, thus more links increase the
+probability of a weak link.
+
+Dynamic Launch Components
+=========================
+
+The TCG architecture for dynamic launch is composed of a component series that
+are used to set up and then carry out the launch. These components work
+together to construct an RTM trust chain that is rooted in the dynamic launch
+and thus commonly referred to as the Dynamic Root of Trust for Measurement
+(DRTM) chain.
+
+What follows is a brief explanation of each component in execution order. A
+subset of these components are what establishes the dynamic launch's trust
+chain.
+
+Dynamic Configuration Environment Preamble
+------------------------------------------
+
+The Dynamic Configuration Environment (DCE) Preamble is responsible for setting
+up the system environment in preparation for a dynamic launch. The DCE Preamble
+is not a part of the DRTM trust chain.
+
+Dynamic Launch Event
+--------------------
+
+The dynamic launch event is the event, typically a CPU instruction, that
+triggers the system's dynamic launch mechanism to begin the launch. The dynamic
+launch mechanism is also the RoT for the DRTM trust chain.
+
+Dynamic Configuration Environment
+---------------------------------
+
+The dynamic launch mechanism may have resulted in a reset of a portion of the
+system. To bring the system back to an adequate state for system software, the
+dynamic launch will hand over control to the DCE. Prior to handing over this
+control, the dynamic launch, will measure the DCE. Once the DCE is complete it
+will proceed to measure and then execute the Dynamic Launch Measured
+Environment (DLME).
+
+Dynamic Launch Measured Environment
+-----------------------------------
+
+The DLME is the first system kernel to have control of the system, but may not
+be the last. Depending on the usage and configuration, the DLME may be the
+final/target operating system, or it may be a bootloader that will load the
+final/target operating system.
+
+Why DRTM
+========
+
+It is a fact that DRTM increases the load-time integrity of the system by
+providing a trust chain that has an immutable hardware RoT, uses a limited
+number of small, special purpose code to establish the trust chain that starts
+the target operating system. As mentioned in the Trust Chain section, these are
+the main three factors in driving up the strength of a trust chain. As has been
+seen with the BootHole exploit, which in fact did not affect the integrity of
+DRTM solutions, the sophistication of attacks targeting system launch is at an
+all-time high. There is no reason a system should not employ every integrity
+measure hardware makes available. This is the crux of a defense-in-depth
+approach to system security. In the past, the now closed SMI gap was often
+pointed to as invalidating DRTM, which in fact was nothing but a straw man
+argument. As has continued to be demonstrated, if/when SMM is corrupted it can
+always circumvent all load-time integrity, SRTM and DRTM, because it is a
+run-time integrity problem. Regardless, Intel and AMD have both deployed
+runtime integrity for SMI and SMM which is tied directly to DRTM such that this
+perceived deficiency is now non-existent, and the world is moving forward with
+an expectation that DRTM must be present.
+
+Glossary
+========
+
+.. glossary::
+  integrity
+    Guarding against improper information modification or destruction, and
+    includes ensuring information non-repudiation and authenticity.
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
+
+  mechanism
+    A process or system that is used to produce a particular result.
+
+    - NIST Special Publication 800-160 (VOLUME 1 ) - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-160v1.pdf
+
+  risk
+    A measure of the extent to which an entity is threatened by a potential
+    circumstance or event, and typically a function of: (i) the adverse impacts
+    that would arise if the circumstance or event occurs; and (ii) the
+    likelihood of occurrence.
+
+    - NIST SP 800-30 Rev. 1 - https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-30r1.pdf
+
+  security mechanism
+    A device or function designed to provide one or more security services
+    usually rated in terms of strength of service and assurance of the design.
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
+
+  Strength of Mechanism
+    A scale for measuring the relative strength of a security mechanism
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
+
+  transitive trust
+    Also known as "Inductive Trust", in this process a Root of Trust gives a
+    trustworthy description of a second group of functions. Based on this
+    description, an interested entity can determine the trust it is to place in
+    this second group of functions. If the interested entity determines that
+    the trust level of the second group of functions is acceptable, the trust
+    boundary is extended from the Root of Trust to include the second group of
+    functions. In this case, the process can be iterated. The second group of
+    functions can give a trustworthy description of the third group of
+    functions, etc. Transitive trust is used to provide a trustworthy
+    description of platform characteristics, and also to prove that
+    non-migratable keys are in fact non-migratable.
+
+    - TCG Glossary - https://trustedcomputinggroup.org/wp-content/uploads/TCG-Glossary-V1.1-Rev-1.0.pdf
+
+  trust
+    The confidence one element has in another that the second element will
+    behave as expected`
+
+    - NISTIR 8320A - https://nvlpubs.nist.gov/nistpubs/ir/2021/NIST.IR.8320A.pdf
+
+  trust anchor
+    An authoritative entity for which trust is assumed.
+
+    - NIST SP 800-57 Part 1 Rev. 5 - https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf
+
+  trusted
+    An element that another element relies upon to fulfill critical
+    requirements on its behalf.
+
+    - NISTIR 8320A - https://nvlpubs.nist.gov/nistpubs/ir/2021/NIST.IR.8320A.pdf
+
+  trusted computing base (TCB)
+    Totality of protection mechanisms within a computer system, including
+    hardware, firmware, and software, the combination responsible for enforcing
+    a security policy.
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
+
+  trusted computer system
+    A system that has the necessary security functions and assurance that the
+    security policy will be enforced and that can process a range of
+    information sensitivities (i.e. classified, controlled unclassified
+    information (CUI), or unclassified public information) simultaneously.
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
+
+  trustworthiness
+    The attribute of a person or enterprise that provides confidence to others
+    of the qualifications, capabilities, and reliability of that entity to
+    perform specific tasks and fulfill assigned responsibilities.
+
+    - NIST CNSSI No. 4009 - https://www.cnss.gov/CNSS/issuances/Instructions.cfm
diff --git a/Documentation/security/launch-integrity/secure_launch_details.rst b/Documentation/security/launch-integrity/secure_launch_details.rst
new file mode 100644
index 000000000000..7ea4cd1bdac9
--- /dev/null
+++ b/Documentation/security/launch-integrity/secure_launch_details.rst
@@ -0,0 +1,587 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. Copyright ? 2019-2024 Daniel P. Smith <dpsmith at apertussolutions.com>
+
+===================================
+Secure Launch Config and Interfaces
+===================================
+
+:Author: Daniel P. Smith
+:Date: August 2024
+
+Configuration
+=============
+
+The settings to enable Secure Launch using Kconfig are under::
+
+  "Processor type and features" --> "Secure Launch support"
+
+A kernel with this option enabled can still be booted using other supported
+methods.
+
+To reduce the Trusted Computing Base (TCB) of the MLE [1]_, the build
+configuration should be pared down as narrowly as one's use case allows. The
+fewer drivers (less active hardware) and features reduces the attack surface.
+As an example in the extreme, the MLE could only have local disk access with no
+other hardware supports, except optional network access for remote attestation.
+
+It is also desirable, if possible, to embed the initrd used with the MLE kernel
+image to reduce complexity.
+
+The following are a few important configuration necessities to always consider:
+
+KASLR Configuration
+-------------------
+
+Due to Secure Launch hardware implementation details and how KASLR functions,
+Secure Launch is not able to interoperate with KASLR at this time. Attempts to
+enable KASLR in a kernel started using Secure Launch may result in crashes and
+other instabilities at boot. Even in cases where Secure Launch and KASLR work
+together, it is still recommended that KASLR be disabled to avoid introducing
+security concerns with unprotected kernel memory.
+
+If possible, a kernel being used as an MLE should be built with KASLR disabled::
+
+  "Processor type and features" -->
+      "Build a relocatable kernel" -->
+          "Randomize the address of the kernel image (KASLR) [ ]"
+
+This action unsets the Kconfig value CONFIG_RANDOMIZE_BASE.
+
+If it is not possible to disable at build time, then it is recommended to force
+KASLR to be disabled using the kernel command line when doing a Secure Launch.
+The kernel parameter is as follows::
+
+  nokaslr
+
+.. note::
+    Should KASLR be made capable of reading/using only the protected page
+    regions set up by the memory protection mechanisms used by the hardware
+    DRTM capability, then it would become possible to use KASLR with Secure
+    Launch.
+
+IOMMU Configuration
+-------------------
+
+When doing a Secure Launch, the IOMMU should always be enabled and the drivers
+loaded. However, IOMMU passthrough mode should never be used. This leaves the
+MLE completely exposed to DMA after the PMR's [2]_ are disabled. The current
+default mode is to use IOMMU in lazy translated mode, but strict translated
+mode is the preferred IOMMU mode and this should be selected in the build
+configuration::
+
+  "Device Drivers" -->
+      "IOMMU Hardware Support" -->
+          "IOMMU default domain type" -->
+              "(X) Translated - Strict"
+
+In addition, the Intel IOMMU should be on by default. The following sets this as the
+default in the build configuration::
+
+  "Device Drivers" -->
+      "IOMMU Hardware Support" -->
+          "Support for Intel IOMMU using DMA Remapping Devices [*]"
+
+and::
+
+  "Device Drivers" -->
+      "IOMMU Hardware Support" -->
+          "Support for Intel IOMMU using DMA Remapping Devices [*]" -->
+              "Enable Intel DMA Remapping Devices by default  [*]"
+
+It is recommended that no other command line options should be set to override
+the defaults above. If there is a desire to run an alternate configuration,
+then that configuration should be evaluated for what benefits are attempting to
+be gained against the risks for DMA attacks for which the kernel is likely
+going to be exposed.
+
+Secure Launch Resource Table
+============================
+
+The Secure Launch Resource Table (SLRT) is a platform-agnostic, standard format
+for providing information for the pre-launch environment and to pass
+information to the post-launch environment. The table is populated by one or
+more bootloaders in the boot chain and used by Secure Launch on how to set up
+the environment during post-launch. The details for the SLRT are documented
+in the TrenchBoot Secure Launch Specification [3]_.
+
+Intel TXT Interface
+===================
+
+The primary interfaces between the various components in TXT are the TXT MMIO
+registers and the TXT heap. The MMIO register banks are described in Appendix B
+of the TXT MLE [1]_ Development Guide.
+
+The TXT heap is described in Appendix C of the TXT MLE [1]_ Development
+Guide. Most of the TXT heap is predefined in the specification. The heap is
+initialized by firmware and the pre-launch environment and is subsequently used
+by the SINIT ACM. One section, called the OS to MLE Data Table, is reserved for
+software to define. This table is set up per the recommendation detailed in
+Appendix B of the TrenchBoot Secure Launch Specification::
+
+        /*
+         * Secure Launch defined OS/MLE TXT Heap table
+         */
+        struct txt_os_mle_data {
+                u32 version;
+                u32 boot_params_addr;
+                u64 slrt;
+                u64 txt_info;
+                u32 ap_wake_block;
+                u32 ap_wake_block_size;
+                u8 mle_scratch[64];
+        } __packed;
+
+Description of structure:
+
+=====================  ========================================================================
+Field                  Use
+=====================  ========================================================================
+version                Structure version, current value 1
+boot_params_addr       Physical base address of the Linux boot parameters
+slrt                   Physical address of the Secure Launch Resource Table
+txt_info               Pointer into the SLRT for easily locating TXT specific table
+ap_wake_block          Physical address of the block of memory for parking APs after a launch
+ap_wake_block_size     Size of the AP wake block
+mle_scratch            Scratch area used post-launch by the MLE kernel. Fields:
+ 
+                        - SL_SCRATCH_AP_EBX area to share %ebx base pointer among CPUs
+                        - SL_SCRATCH_AP_JMP_OFFSET offset to abs. ljmp fixup location for APs
+=====================  ========================================================================
+
+Error Codes
+-----------
+
+The TXT specification defines the layout for TXT 32 bit error code values.
+The bit encodings indicate where the error originated (e.g. with the CPU,
+in the SINIT ACM, in software). The error is written to a sticky TXT
+register that persists across resets called TXT.ERRORCODE (see the TXT
+MLE Development Guide). The errors defined by the Secure Launch feature are
+those generated in the MLE software. They have the format::
+
+  0xc0008XXX
+
+The low 12 bits are free for defining the following Secure Launch specific
+error codes.
+
+======  ================
+Name:   SL_ERROR_GENERIC
+Value:  0xc0008001
+======  ================
+
+Description:
+
+Generic catch all error. Currently unused.
+
+======  =================
+Name:   SL_ERROR_TPM_INIT
+Value:  0xc0008002
+======  =================
+
+Description:
+
+The Secure Launch code failed to get access to the TPM hardware interface.
+This is most likely due to misconfigured hardware or kernel. Ensure the TPM
+chip is enabled, and the kernel TPM support is built in (it should not be built
+as a module).
+
+======  ==========================
+Name:   SL_ERROR_TPM_INVALID_LOG20
+Value:  0xc0008003
+======  ==========================
+
+Description:
+
+The Secure Launch code failed to find a valid event log descriptor for a
+version 2.0 TPM or the event log descriptor is malformed. Usually this
+indicates there are incompatible versions of the pre-launch environment and the
+MLE kernel. The pre-launch environment and the kernel share a structure in the
+TXT heap and if this structure (the OS-MLE table) is mismatched, this error is
+often seen. This TXT heap area is set up by the pre-launch environment, so the
+issue may originate there. It could also be the sign of an attempted attack.
+
+======  ===========================
+Name:   SL_ERROR_TPM_LOGGING_FAILED
+Value:  0xc0008004
+======  ===========================
+
+Description:
+
+There was a failed attempt to write a TPM event to the event log early in the
+Secure Launch process. This is likely the result of a malformed TPM event log
+buffer. Formatting of the event log buffer information is done by the
+pre-launch environment, so the issue most likely originates there.
+
+======  ============================
+Name:   SL_ERROR_REGION_STRADDLE_4GB
+Value:  0xc0008005
+======  ============================
+
+Description:
+
+During early validation, a buffer or region was found to straddle the 4GB
+boundary. Because of the way TXT does DMA memory protection, this is an unsafe
+configuration and is flagged as an error. This is most likely a configuration
+issue in the pre-launch environment. It could also be the sign of an attempted
+attack.
+
+======  ===================
+Name:   SL_ERROR_TPM_EXTEND
+Value:  0xc0008006
+======  ===================
+
+Description:
+
+There was a failed attempt to extend a TPM PCR in the Secure Launch platform
+module. This is most likely to due to misconfigured hardware or kernel. Ensure
+the TPM chip is enabled, and the kernel TPM support is built in (it should not
+be built as a module).
+
+======  ======================
+Name:   SL_ERROR_MTRR_INV_VCNT
+Value:  0xc0008007
+======  ======================
+
+Description:
+
+During early Secure Launch validation, an invalid variable MTRR count was
+found. The pre-launch environment passes a number of MSR values to the MLE to
+restore including the MTRRs. The values are restored by the Secure Launch early
+entry point code. After measuring the values supplied by the pre-launch
+environment, a discrepancy was found, validating the values. It could be the
+sign of an attempted attack.
+
+======  ==========================
+Name:   SL_ERROR_MTRR_INV_DEF_TYPE
+Value:  0xc0008008
+======  ==========================
+
+Description:
+
+During early Secure Launch validation, an invalid default MTRR type was found.
+See SL_ERROR_MTRR_INV_VCNT for more details.
+
+======  ======================
+Name:   SL_ERROR_MTRR_INV_BASE
+Value:  0xc0008009
+======  ======================
+
+Description:
+
+During early Secure Launch validation, an invalid variable MTRR base value was
+found. See SL_ERROR_MTRR_INV_VCNT for more details.
+
+======  ======================
+Name:   SL_ERROR_MTRR_INV_MASK
+Value:  0xc000800a
+======  ======================
+
+Description:
+
+During early Secure Launch validation, an invalid variable MTRR mask value was
+found. See SL_ERROR_MTRR_INV_VCNT for more details.
+
+======  ========================
+Name:   SL_ERROR_MSR_INV_MISC_EN
+Value:  0xc000800b
+======  ========================
+
+Description:
+
+During early Secure Launch validation, an invalid miscellaneous enable MSR
+value was found. See SL_ERROR_MTRR_INV_VCNT for more details.
+
+======  =========================
+Name:   SL_ERROR_INV_AP_INTERRUPT
+Value:  0xc000800c
+======  =========================
+
+Description:
+
+The application processors (APs) wait to be woken up by the SMP initialization
+code. The only interrupt that they expect is an NMI; all other interrupts
+should be masked. If an AP gets some other interrupt other than an NMI, it will
+cause this error. This error is very unlikely to occur.
+
+======  =========================
+Name:   SL_ERROR_INTEGER_OVERFLOW
+Value:  0xc000800d
+======  =========================
+
+Description:
+
+A buffer base and size passed to the MLE caused an integer overflow when
+added together. This is most likely a configuration issue in the pre-launch
+environment. It could also be the sign of an attempted attack.
+
+======  ==================
+Name:   SL_ERROR_HEAP_WALK
+Value:  0xc000800e
+======  ==================
+
+Description:
+
+An error occurred in TXT heap walking code. The underlying issue is a failure to
+early_memremap() portions of the heap, most likely due to a resource shortage.
+
+======  =================
+Name:   SL_ERROR_HEAP_MAP
+Value:  0xc000800f
+======  =================
+
+Description:
+
+This error is essentially the same as SL_ERROR_HEAP_WALK but occurred during the
+actual early_memremap() operation.
+
+======  =========================
+Name:   SL_ERROR_REGION_ABOVE_4GB
+Value:  0xc0008010
+======  =========================
+
+Description:
+
+A memory region used by the MLE is above 4GB. In general this is not a problem
+because memory > 4Gb can be protected from DMA. There are certain buffers that
+should never be above 4Gb, and one of these caused the violation. This is most
+likely a configuration issue in the pre-launch environment. It could also be
+the sign of an attempted attack.
+
+======  ==========================
+Name:   SL_ERROR_HEAP_INVALID_DMAR
+Value:  0xc0008011
+======  ==========================
+
+Description:
+
+The backup copy of the ACPI DMAR table which is supposed to be located in the
+TXT heap could not be found. This is due to a bug in the platform's ACM module
+or in firmware.
+
+======  =======================
+Name:   SL_ERROR_HEAP_DMAR_SIZE
+Value:  0xc0008012
+======  =======================
+
+Description:
+
+The backup copy of the ACPI DMAR table in the TXT heap is to large to be stored
+for later usage. This error is very unlikely to occur since the area reserved
+for the copy is far larger than the DMAR should be.
+
+======  ======================
+Name:   SL_ERROR_HEAP_DMAR_MAP
+Value:  0xc0008013
+======  ======================
+
+Description:
+
+The backup copy of the ACPI DMAR table in the TXT heap could not be mapped. The
+underlying issue is a failure to early_memremap() the DMAR table, most likely
+due to a resource shortage.
+
+======  ====================
+Name:   SL_ERROR_HI_PMR_BASE
+Value:  0xc0008014
+======  ====================
+
+Description:
+
+On a system with more than 4G of RAM, the high PMR [2]_ base address should be
+set to 4G. This error is due to that not being the case. This PMR value is set
+by the pre-launch environment, so the issue most likely originates there. It
+could also be the sign of an attempted attack.
+
+======  ====================
+Name:   SL_ERROR_HI_PMR_SIZE
+Value:  0xc0008015
+======  ====================
+
+Description:
+
+On a system with more than 4G of RAM, the high PMR [2]_ size should be set to
+cover all RAM > 4G. This error is due to that not being the case. This PMR
+value is set by the pre-launch environment, so the issue most likely originates
+there. It could also be the sign of an attempted attack.
+
+======  ====================
+Name:   SL_ERROR_LO_PMR_BASE
+Value:  0xc0008016
+======  ====================
+
+Description:
+
+The low PMR [2]_ base should always be set to address zero. This error is due
+to that not being the case. This PMR value is set by the pre-launch environment
+so the issue most likely originates there. It could also be the sign of an
+attempted attack.
+
+======  ====================
+Name:   SL_ERROR_LO_PMR_MLE
+Value:  0xc0008017
+======  ====================
+
+Description:
+
+This error indicates the MLE image is not covered by the low PMR [2]_ range.
+The PMR values are set by the pre-launch environment, so the issue most likely
+originates there. It could also be the sign of an attempted attack.
+
+======  =======================
+Name:   SL_ERROR_INITRD_TOO_BIG
+Value:  0xc0008018
+======  =======================
+
+Description:
+
+The external initrd provided is larger than 4Gb. This is not a valid
+configuration for a Secure Launch due to managing DMA protection.
+
+======  =========================
+Name:   SL_ERROR_HEAP_ZERO_OFFSET
+Value:  0xc0008019
+======  =========================
+
+Description:
+
+During a TXT heap walk, an invalid/zero next table offset value was found. This
+indicates the TXT heap is malformed. The TXT heap is initialized by the
+pre-launch environment, so the issue most likely originates there. It could
+also be a sign of an attempted attack. In addition, ACM is also responsible for
+manipulating parts of the TXT heap, so the issue could be due to a bug in the
+platform's ACM module.
+
+======  =============================
+Name:   SL_ERROR_WAKE_BLOCK_TOO_SMALL
+Value:  0xc000801a
+======  =============================
+
+Description:
+
+The AP wake block buffer passed to the MLE via the OS-MLE TXT heap table is not
+large enough. This value is set by the pre-launch environment, so the issue
+most likely originates there. It also could be the sign of an attempted attack.
+
+======  ===========================
+Name:   SL_ERROR_MLE_BUFFER_OVERLAP
+Value:  0xc000801b
+======  ===========================
+
+Description:
+
+One of the buffers passed to the MLE via the OS-MLE TXT heap table overlaps
+with the MLE image in memory. This value is set by the pre-launch environment
+so the issue most likely originates there. It could also be the sign of an
+attempted attack.
+
+======  ==========================
+Name:   SL_ERROR_BUFFER_BEYOND_PMR
+Value:  0xc000801c
+======  ==========================
+
+Description:
+
+One of the buffers passed to the MLE via the OS-MLE TXT heap table is not
+protected by a PMR. This value is set by the pre-launch environment, so the
+issue most likely originates there. It could also be the sign of an attempted
+attack.
+
+======  =============================
+Name:   SL_ERROR_OS_SINIT_BAD_VERSION
+Value:  0xc000801d
+======  =============================
+
+Description:
+
+The version of the OS-SINIT TXT heap table is bad. It must be 6 or greater.
+This value is set by the pre-launch environment, so the issue most likely
+originates there. It could also be the sign of an attempted attack. It is also
+possible though very unlikely that the platform is so old that the ACM being
+used requires an unsupported version.
+
+======  =====================
+Name:   SL_ERROR_EVENTLOG_MAP
+Value:  0xc000801e
+======  =====================
+
+Description:
+
+An error occurred in the Secure Launch module while mapping the TPM event log.
+The underlying issue is memremap() failure, most likely due to a resource
+shortage.
+
+======  ========================
+Name:   SL_ERROR_TPM_NUMBER_ALGS
+Value:  0xc000801f
+======  ========================
+
+Description:
+
+The TPM 2.0 event log reports an unsupported number of hashing algorithms.
+Secure launch currently only supports a maximum of two: SHA1 and SHA256.
+
+======  ===========================
+Name:   SL_ERROR_TPM_UNKNOWN_DIGEST
+Value:  0xc0008020
+======  ===========================
+
+Description:
+
+The TPM 2.0 event log reports an unsupported hashing algorithm. Secure launch
+currently only supports two algorithms: SHA1 and SHA256.
+
+======  ==========================
+Name:   SL_ERROR_TPM_INVALID_EVENT
+Value:  0xc0008021
+======  ==========================
+
+Description:
+
+An invalid/malformed event was found in the TPM event log while reading it.
+Since only trusted entities are supposed to be writing the event log, this
+would indicate either a bug or a possible attack.
+
+======  =====================
+Name:   SL_ERROR_INVALID_SLRT
+Value:  0xc0008022
+======  =====================
+
+Description:
+
+The Secure Launch Resource Table is invalid or malformed and is unusable. This
+implies the pre-launch code did not properly set up the SLRT.
+
+======  ===========================
+Name:   SL_ERROR_SLRT_MISSING_ENTRY
+Value:  0xc0008023
+======  ===========================
+
+Description:
+
+The Secure Launch Resource Table is missing a required entry within it. This
+implies the pre-launch code did not properly set up the SLRT.
+
+======  =================
+Name:   SL_ERROR_SLRT_MAP
+Value:  0xc0008024
+======  =================
+
+Description:
+
+An error occurred in the Secure Launch module while mapping the Secure Launch
+Resource table. The underlying issue is memremap() failure, most likely due to
+a resource shortage.
+
+.. [1]
+    MLE: Measured Launch Environment is the binary runtime that is measured and
+    then run by the TXT SINIT ACM. The TXT MLE Development Guide describes the
+    requirements for the MLE in detail.
+
+.. [2]
+    PMR: Intel VTd has a feature in the IOMMU called Protected Memory Registers.
+    There are two of these registers and they allow all DMA to be blocked
+    to large areas of memory. The low PMR can cover all memory below 4Gb on 2Mb
+    boundaries. The high PMR can cover all RAM on the system, again on 2Mb
+    boundaries. This feature is used during a Secure Launch by TXT.
+
+.. [3]
+    Secure Launch Specification: https://trenchboot.org/specifications/Secure_Launch/
diff --git a/Documentation/security/launch-integrity/secure_launch_overview.rst b/Documentation/security/launch-integrity/secure_launch_overview.rst
new file mode 100644
index 000000000000..47e2e8ede88d
--- /dev/null
+++ b/Documentation/security/launch-integrity/secure_launch_overview.rst
@@ -0,0 +1,227 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. Copyright ? 2019-2024 Daniel P. Smith <dpsmith at apertussolutions.com>
+
+======================
+Secure Launch Overview
+======================
+
+:Author: Daniel P. Smith
+:Date: August 2024
+
+Overview
+========
+
+Prior to the start of the TrenchBoot project, the only active Open Source
+project supporting dynamic launch was Intel's tboot project to support their
+implementation of dynamic launch known as Intel Trusted eXecution Technology
+(TXT). The approach taken by tboot was to provide an exokernel that could
+handle the launch protocol implemented by Intel's special loader, the SINIT
+Authenticated Code Module (ACM [2]_) and remained in memory to manage the SMX
+CPU mode that a dynamic launch would put a system. While it is not precluded
+from being used for doing a late launch, tboot's primary use case was to be
+used as an early launch solution. As a result, the TrenchBoot project started
+the development of Secure Launch kernel feature to provide a more generalized
+approach. The focus of the effort is twofold, the first is to make the Linux
+kernel directly aware of the launch protocol used by Intel, AMD/Hygon, Arm, and
+potentially OpenPOWER. The second is to make the Linux kernel be able to
+initiate a dynamic launch. It is through this approach that the Secure Launch
+kernel feature creates a basis for the Linux kernel to be used in a variety of
+dynamic launch use cases.
+
+.. note::
+    A quick note on terminology. The larger open source project itself is
+    called TrenchBoot, which is hosted on GitHub (links below). The kernel
+    feature enabling the use of the x86 technology is referred to as "Secure
+    Launch" within the kernel code.
+
+Goals
+=====
+
+The first use case that the TrenchBoot project focused on was the ability for
+the Linux kernel to be started by a dynamic launch, in particular as part of an
+early launch sequence. In this case, the dynamic launch will be initiated by
+any bootloader with associated support added to it, for example the first
+targeted bootloader in this case was GRUB2. An integral part of establishing a
+measurement-based launch integrity involves measuring everything that is
+intended to be executed (kernel image, initrd, etc.) and everything that will
+configure that kernel to execute (command line, boot params, etc.). Then
+storing those measurements in a protected manner. Both the Intel and AMD
+dynamic launch implementations leverage the Trusted Platform Module (TPM) to
+store those measurements. The TPM itself has been designed such that a dynamic
+launch unlocks a specific set of Platform Configuration Registers (PCR) for
+holding measurement taken during the dynamic launch.  These are referred to as
+the DRTM PCRs, PCRs 17-22. Further details on this process can be found in the
+documentation for the GETSEC instruction provided by Intel's TXT and the SKINIT
+instruction provided by AMD's AMD-V. The documentation on these technologies
+can be readily found online; see the `Resources`_ section below for references.
+
+.. note::
+    Currently, only Intel TXT is supported in this first release of the Secure
+    Launch feature. AMD/Hygon SKINIT and Arm support will be added in a
+    subsequent release.
+
+To enable the kernel to be launched by GETSEC a stub, the Secure Launch stub,
+must be built into the setup section of the compressed kernel to handle the
+specific state that the dynamic launch process leaves the BSP. Also, the Secure
+Launch stub must measure everything that is going to be used as early as
+possible. This stub code and subsequent code must also deal with the specific
+state that the dynamic launch leaves the APs as well.
+
+Design Decisions
+================
+
+A number of design decisions were made during the development of the Secure
+Launch feature. The two primary guiding decisions were:
+
+ - Keeping the Secure Launch code as separate from the rest of the kernel
+   as possible.
+ - Modifying the existing boot path of the kernel as little as possible.
+
+The following illustrate how the implementation followed these design
+decisions:
+
+ - All the entry point code necessary to properly configure the system post
+   launch is found in st_stub.S in the compressed kernel image. This code
+   validates the state of the system, restores necessary system operating
+   configurations and properly handles post launch CPU states.
+ - After the sl_stub.S is complete, it jumps directly to the unmodified
+   startup_32 kernel entry point.
+ - A single call is made to a function sl_main() prior to the main kernel
+   decompression step. This code performs further validation and takes the
+   needed DRTM measurements.
+ - After the call to sl_main(), the main kernel is decompressed and boots as
+   it normally would.
+ - Final setup for the Secure Launch kernel is done in a separate Secure
+   Launch module that is loaded via a late initcall. This code is responsible
+   for extending the measurements taken earlier into the TPM DRTM PCRs and
+   setting up the securityfs interface to allow access to the TPM event log and
+   public TXT registers.
+ - On the reboot and kexec paths, calls are made to a function to finalize the
+   state of the Secure Launch kernel.
+
+The one place where Secure Launch code is mixed directly in with kernel code is
+in the SMP boot code. This is due to the unique state that the dynamic launch
+leaves the APs in. On Intel, this involves using a method other than the
+standard INIT-SIPI sequence.
+
+A final note is that originally the extending of the PCRs was completed in the
+Secure Launch stub when the measurements were taken. An alternative solution
+had to be implemented due to the TPM maintainers objecting to the PCR
+extensions being done with a minimal interface to the TPM that was an
+independent implementation of the mainline kernel driver. Since the mainline
+driver relies heavily on kernel interfaces not available in the compressed
+kernel, it was not possible to reuse the mainline TPM driver. This resulted in
+the decision to move the extension operations to the Secure Launch module in
+the mainline kernel, where the TPM driver would be available.
+
+Basic Boot Flow
+===============
+
+Outlined here is a summary of the boot flow for Secure Launch. A more detailed
+review of Secure Launch process can be found in the Secure Launch
+Specification, a link is located in the `Resources`_ section.
+
+Pre-launch: *Phase where the environment is prepared and configured to initiate
+the secure launch by the boot chain.*
+
+ - The SLRT is initialized and dl_stub is placed in memory.
+ - Load the kernel, initrd and ACM [2]_ into memory.
+ - Set up the TXT heap and page tables describing the MLE [1]_ per the
+   specification.
+ - If non-UEFI platform, dl_stub is called.
+ - If UEFI platforms, SLRT registered with UEFI and efi-stub called.
+ - Upon completion, efi-stub will call EBS followed by dl_stub.
+ - The dl_stub will prepare the CPU and the TPM for the launch.
+ - The secure launch is then initiated with the GETSET[SENTER] instruction.
+
+Post-launch: *Phase where control is passed from the ACM to the MLE and the secure
+kernel begins execution.*
+
+ - Entry from the dynamic launch jumps to the SL stub.
+ - SL stub fixes up the world on the BSP.
+ - For TXT, SL stub wakes the APs, fixes up their worlds.
+ - For TXT, APs are left halted using MONITOR/MWAIT intructions.
+ - SL stub jumps to startup_32.
+ - SL main does validation of buffers and memory locations. It sets
+   the boot parameter loadflag value SLAUNCH_FLAG to inform the main
+   kernel that a Secure Launch was done.
+ - SL main locates the TPM event log and writes the measurements of
+   configuration and module information into it.
+ - Kernel boot proceeds normally from this point.
+ - During early setup, slaunch_setup() runs to finish some validation
+   and setup tasks.
+ - The SMP bring up code is modified to wake the waiting APs via the monitor
+   address.
+ - APs vector to rmpiggy and start up normally from that point.
+ - SL platform module is registered as a late initcall module. It reads
+   the TPM event log and extends the measurements taken into the TPM PCRs.
+ - SL platform module initializes the securityfs interface to allow
+   access to the TPM event log and TXT public registers.
+ - Kernel boot finishes booting normally
+ - SEXIT support to leave SMX mode is present on the kexec path and
+   the various reboot paths (poweroff, reset, halt).
+
+PCR Usage
+=========
+
+The TCG DRTM architecture there are three PCRs defined for usage, PCR.Details
+(PCR17), PCR.Authorities (PCR18), and PCR.DLME_Authority (PCR19). For a deeper
+understanding of Detail and Authorities it is recommended to review the TCG
+DRTM architecture.
+
+To determine PCR usage, Linux Secure Launch follows the TrenchBoot Secure
+Launch Specification of using a measurement policy stored in the SLRT. The
+policy details what should be measured and the PCR in which to store the
+measurement. The measurement policy provides the ability to select the
+PCR.DLME_Detail (PCR20) PCR as the location for the DRTM components measured by
+the kernel, e.g. external initrd image. This can then be combined with storing
+the user authority in the PCR.DLME_Authority PCR to seal/attest to different
+variations of platform details/authorities and user details/authorities. An
+example of how this can be achieved was presented in the FOSDEM - 2021 talk
+"Secure Upgrades with DRTM".
+
+Resources
+=========
+
+The TrenchBoot project:
+
+https://trenchboot.org
+
+Secure Launch Specification:
+
+https://trenchboot.org/specifications/Secure_Launch/
+
+Trusted Computing Group's D-RTM Architecture:
+
+https://trustedcomputinggroup.org/wp-content/uploads/TCG_D-RTM_Architecture_v1-0_Published_06172013.pdf
+
+TXT documentation in the Intel TXT MLE Development Guide:
+
+https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf
+
+TXT instructions documentation in the Intel SDM Instruction Set volume:
+
+https://software.intel.com/en-us/articles/intel-sdm
+
+AMD SKINIT documentation in the System Programming manual:
+
+https://www.amd.com/system/files/TechDocs/24593.pdf
+
+GRUB Secure Launch support:
+
+https://github.com/TrenchBoot/grub/tree/grub-sl-fc-38-dlstub
+
+FOSDEM 2021: Secure Upgrades with DRTM
+
+https://archive.fosdem.org/2021/schedule/event/firmware_suwd/
+
+.. [1]
+    MLE: Measured Launch Environment is the binary runtime that is measured and
+    then run by the TXT SINIT ACM. The TXT MLE Development Guide describes the
+    requirements for the MLE in detail.
+
+.. [2]
+    ACM: Intel's Authenticated Code Module. This is the 32b bit binary blob that
+    is run securely by the GETSEC[SENTER] during a measured launch. It is described
+    in the Intel documentation on TXT and versions for various chipsets are
+    signed and distributed by Intel.
-- 
2.39.3



From ross.philipson at oracle.com  Mon Aug 26 15:42:57 2024
From: ross.philipson at oracle.com (Ross Philipson)
Date: Mon, 26 Aug 2024 22:42:57 -0000
Subject: [PATCH v10 09/20] x86: Secure Launch kernel early boot stub
In-Reply-To: <20240826223835.3928819-1-ross.philipson@oracle.com>
References: <20240826223835.3928819-1-ross.philipson@oracle.com>
Message-ID: <20240826223835.3928819-10-ross.philipson@oracle.com>

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 <ross.philipson at oracle.com>
---
 Documentation/arch/x86/boot.rst       |  21 +
 arch/x86/boot/compressed/Makefile     |   3 +-
 arch/x86/boot/compressed/head_64.S    |  29 +
 arch/x86/boot/compressed/sl_main.c    | 588 +++++++++++++++++++++
 arch/x86/boot/compressed/sl_stub.S    | 726 ++++++++++++++++++++++++++
 arch/x86/include/uapi/asm/bootparam.h |   1 +
 arch/x86/kernel/asm-offsets.c         |  20 +
 7 files changed, 1387 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 4fd492cb4970..295cdf9bcbdb 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 setup 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.
@@ -1028,6 +1036,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 40dc0b9babd5..ce651eaa68dd 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -107,7 +107,8 @@ vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
 vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
 vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
-vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/sha1.o $(obj)/sha256.o
+vmlinux-objs-$(CONFIG_SECURE_LAUNCH) += $(obj)/sha1.o $(obj)/sha256.o \
+	$(obj)/sl_main.o $(obj)/sl_stub.o
 
 $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-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 1dcb794c5479..545329c97377 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -420,6 +420,13 @@ SYM_CODE_START(startup_64)
 	pushq	$0
 	popfq
 
+#ifdef CONFIG_SECURE_LAUNCH
+	/* Ensure the relocation region is covered by a PMR */
+	movq	%rbx, %rdi
+	movl	$(_bss - startup_32), %esi
+	callq	sl_check_region
+#endif
+
 /*
  * Copy the compressed kernel to the end of our buffer
  * where decompression in place becomes safe.
@@ -462,6 +469,28 @@ 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
+	 * checks in place.
+	 */
+	movq	%r15, %rdi
+	callq	sl_main
+
+	/* Ensure the decompression location is covered by a PMR */
+	movq	%rbp, %rdi
+	movq	output_len(%rip), %rsi
+	callq	sl_check_region
+#endif
+
 	call	load_stage2_idt
 
 	/* Pass boot_params to initialize_identity_maps() */
diff --git a/arch/x86/boot/compressed/sl_main.c b/arch/x86/boot/compressed/sl_main.c
new file mode 100644
index 000000000000..0fc8c2d9fc94
--- /dev/null
+++ b/arch/x86/boot/compressed/sl_main.c
@@ -0,0 +1,588 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Secure Launch early measurement and validation routines.
+ *
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/boot.h>
+#include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/processor-flags.h>
+#include <asm/asm-offsets.h>
+#include <asm/bootparam.h>
+#include <asm/bootparam_utils.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+
+#define CAPS_VARIABLE_MTRR_COUNT_MASK	0xff
+
+#define SL_TPM_LOG		1
+#define SL_TPM2_LOG		2
+
+#define SL_TPM2_MAX_ALGS	2
+
+#define SL_MAX_EVENT_DATA	64
+#define SL_TPM_LOG_SIZE		(sizeof(struct tcg_pcr_event) + \
+				SL_MAX_EVENT_DATA)
+#define SL_TPM2_LOG_SIZE	(sizeof(struct tcg_pcr_event2_head) + \
+				SHA1_DIGEST_SIZE + SHA256_DIGEST_SIZE + \
+				sizeof(struct tcg_event_field) + \
+				SL_MAX_EVENT_DATA)
+
+static void *evtlog_base;
+static u32 evtlog_size;
+static struct txt_heap_event_log_pointer2_1_element *log21_elem;
+static u32 tpm_log_ver = SL_TPM_LOG;
+static struct tcg_efi_specid_event_algs tpm_algs[SL_TPM2_MAX_ALGS] = {0};
+
+extern u32 sl_cpu_type;
+extern u32 sl_mle_start;
+
+void __cold __noreturn __fortify_panic(const u8 reason, const size_t avail, const size_t size)
+{
+	asm volatile ("ud2");
+
+	unreachable();
+}
+
+static u64 sl_txt_read(u32 reg)
+{
+	return readq((void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
+}
+
+static void sl_txt_write(u32 reg, u64 val)
+{
+	writeq(val, (void *)(u64)(TXT_PRIV_CONFIG_REGS_BASE + reg));
+}
+
+static void __noreturn sl_txt_reset(u64 error)
+{
+	/* Reading the E2STS register acts as a barrier for TXT registers */
+	sl_txt_write(TXT_CR_ERRORCODE, error);
+	sl_txt_read(TXT_CR_E2STS);
+	sl_txt_write(TXT_CR_CMD_UNLOCK_MEM_CONFIG, 1);
+	sl_txt_read(TXT_CR_E2STS);
+	sl_txt_write(TXT_CR_CMD_RESET, 1);
+
+	for ( ; ; )
+		asm volatile ("hlt");
+
+	unreachable();
+}
+
+static u64 sl_rdmsr(u32 reg)
+{
+	u64 lo, hi;
+
+	asm volatile ("rdmsr" : "=a" (lo), "=d" (hi) : "c" (reg));
+
+	return (hi << 32) | lo;
+}
+
+static struct slr_table *sl_locate_and_validate_slrt(void)
+{
+	struct txt_os_mle_data *os_mle_data;
+	struct slr_table *slrt;
+	void *txt_heap;
+
+	txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+	os_mle_data = txt_os_mle_data_start(txt_heap);
+
+	if (!os_mle_data->slrt)
+		sl_txt_reset(SL_ERROR_INVALID_SLRT);
+
+	slrt = (struct slr_table *)os_mle_data->slrt;
+
+	if (slrt->magic != SLR_TABLE_MAGIC)
+		sl_txt_reset(SL_ERROR_INVALID_SLRT);
+
+	if (slrt->architecture != SLR_INTEL_TXT)
+		sl_txt_reset(SL_ERROR_INVALID_SLRT);
+
+	return slrt;
+}
+
+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 ((u64)end >= SZ_4G && (u64)base < SZ_4G)
+		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 ((u64)end > SZ_4G && (u64)base >= SZ_4G) {
+		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);
+		}
+	}
+
+	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;
+
+	mtrr_caps = sl_rdmsr(MSR_MTRRcap);
+	vcnt = (u32)(mtrr_caps & CAPS_VARIABLE_MTRR_COUNT_MASK);
+
+	if (saved_bsp_mtrrs->mtrr_vcnt > vcnt)
+		sl_txt_reset(SL_ERROR_MTRR_INV_VCNT);
+	if (saved_bsp_mtrrs->mtrr_vcnt > TXT_OS_MLE_MAX_VARIABLE_MTRRS)
+		sl_txt_reset(SL_ERROR_MTRR_INV_VCNT);
+
+	mtrr_def_type = sl_rdmsr(MSR_MTRRdefType);
+	if (saved_bsp_mtrrs->default_mem_type != mtrr_def_type)
+		sl_txt_reset(SL_ERROR_MTRR_INV_DEF_TYPE);
+
+	for (i = 0; i < saved_bsp_mtrrs->mtrr_vcnt; i++) {
+		mtrr_var = sl_rdmsr(MTRRphysBase_MSR(i));
+		if (saved_bsp_mtrrs->mtrr_pair[i].mtrr_physbase != mtrr_var)
+			sl_txt_reset(SL_ERROR_MTRR_INV_BASE);
+		mtrr_var = sl_rdmsr(MTRRphysMask_MSR(i));
+		if (saved_bsp_mtrrs->mtrr_pair[i].mtrr_physmask != mtrr_var)
+			sl_txt_reset(SL_ERROR_MTRR_INV_MASK);
+	}
+
+	misc_en_msr = sl_rdmsr(MSR_IA32_MISC_ENABLE);
+	if (txt_info->saved_misc_enable_msr != misc_en_msr)
+		sl_txt_reset(SL_ERROR_MSR_INV_MISC_EN);
+}
+
+static void sl_find_drtm_event_log(struct slr_table *slrt)
+{
+	struct txt_os_sinit_data *os_sinit_data;
+	struct slr_entry_log_info *log_info;
+	void *txt_heap;
+
+	log_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO);
+	if (!log_info)
+		sl_txt_reset(SL_ERROR_SLRT_MISSING_ENTRY);
+
+	evtlog_base = (void *)log_info->addr;
+	evtlog_size = log_info->size;
+
+	txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+
+	/*
+	 * For TPM 2.0, the event log 2.1 extended data structure has to also
+	 * be located and fixed up.
+	 */
+	os_sinit_data = txt_os_sinit_data_start(txt_heap);
+
+	/*
+	 * Only support version 6 and later that properly handle the
+	 * list of ExtDataElements in the OS-SINIT structure.
+	 */
+	if (os_sinit_data->version < 6)
+		sl_txt_reset(SL_ERROR_OS_SINIT_BAD_VERSION);
+
+	/* Find the TPM2.0 logging extended heap element */
+	log21_elem = tpm2_find_log2_1_element(os_sinit_data);
+
+	/* If found, this implies TPM2 log and family */
+	if (log21_elem)
+		tpm_log_ver = SL_TPM2_LOG;
+}
+
+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 */
+
+	if (evtlog_end <= mle_base && evtlog_base < mle_base)
+		goto pmr_check; /* below */
+
+	sl_txt_reset(SL_ERROR_MLE_BUFFER_OVERLAP);
+
+pmr_check:
+	/*
+	 * The TXT heap is protected by the DPR. If the TPM event log is
+	 * inside the TXT heap, there is no need for a PMR check.
+	 */
+	if (evtlog_base > txt_heap && evtlog_end < txt_end)
+		return;
+
+	sl_check_pmr_coverage(evtlog_base, evtlog_size, true);
+}
+
+static void sl_find_event_log_algorithms(void)
+{
+	struct tcg_efi_specid_event_head *efi_head =
+		(struct tcg_efi_specid_event_head *)(evtlog_base +
+					log21_elem->first_record_offset +
+					sizeof(struct tcg_pcr_event));
+
+	if (efi_head->num_algs == 0 || efi_head->num_algs > 2)
+		sl_txt_reset(SL_ERROR_TPM_NUMBER_ALGS);
+
+	memcpy(&tpm_algs[0], &efi_head->digest_sizes[0],
+	       sizeof(struct tcg_efi_specid_event_algs) * efi_head->num_algs);
+}
+
+static void sl_tpm_log_event(u32 pcr, u32 event_type,
+			     const u8 *data, u32 length,
+			     const u8 *event_data, u32 event_size)
+{
+	u8 sha1_hash[SHA1_DIGEST_SIZE] = {0};
+	u8 log_buf[SL_TPM_LOG_SIZE] = {0};
+	struct tcg_pcr_event *pcr_event;
+	u32 total_size;
+
+	pcr_event = (struct tcg_pcr_event *)log_buf;
+	pcr_event->pcr_idx = pcr;
+	pcr_event->event_type = event_type;
+	if (length > 0) {
+		sha1(data, length, &sha1_hash[0]);
+		memcpy(&pcr_event->digest[0], &sha1_hash[0], SHA1_DIGEST_SIZE);
+	}
+	pcr_event->event_size = event_size;
+	if (event_size > 0)
+		memcpy((u8 *)pcr_event + sizeof(struct tcg_pcr_event),
+		       event_data, event_size);
+
+	total_size = sizeof(struct tcg_pcr_event) + event_size;
+
+	if (tpm_log_event(evtlog_base, evtlog_size, total_size, pcr_event))
+		sl_txt_reset(SL_ERROR_TPM_LOGGING_FAILED);
+}
+
+static void sl_tpm2_log_event(u32 pcr, u32 event_type,
+			      const u8 *data, u32 length,
+			      const u8 *event_data, u32 event_size)
+{
+	u8 sha256_hash[SHA256_DIGEST_SIZE] = {0};
+	u8 sha1_hash[SHA1_DIGEST_SIZE] = {0};
+	u8 log_buf[SL_TPM2_LOG_SIZE] = {0};
+	struct sha256_state sctx256 = {0};
+	struct tcg_pcr_event2_head *head;
+	struct tcg_event_field *event;
+	u32 total_size;
+	u16 *alg_ptr;
+	u8 *dgst_ptr;
+
+	head = (struct tcg_pcr_event2_head *)log_buf;
+	head->pcr_idx = pcr;
+	head->event_type = event_type;
+	total_size = sizeof(struct tcg_pcr_event2_head);
+	alg_ptr = (u16 *)(log_buf + sizeof(struct tcg_pcr_event2_head));
+
+	for ( ; head->count < 2; head->count++) {
+		if (!tpm_algs[head->count].alg_id)
+			break;
+
+		*alg_ptr = tpm_algs[head->count].alg_id;
+		dgst_ptr = (u8 *)alg_ptr + sizeof(u16);
+
+		if (tpm_algs[head->count].alg_id == TPM_ALG_SHA256 &&
+		    length) {
+			sha256_init(&sctx256);
+			sha256_update(&sctx256, data, length);
+			sha256_final(&sctx256, &sha256_hash[0]);
+		} else if (tpm_algs[head->count].alg_id == TPM_ALG_SHA1 &&
+			   length) {
+			sha1(data, length, &sha1_hash[0]);
+		}
+
+		if (tpm_algs[head->count].alg_id == TPM_ALG_SHA256) {
+			memcpy(dgst_ptr, &sha256_hash[0], SHA256_DIGEST_SIZE);
+			total_size += SHA256_DIGEST_SIZE + sizeof(u16);
+			alg_ptr = (u16 *)((u8 *)alg_ptr + SHA256_DIGEST_SIZE + sizeof(u16));
+		} else if (tpm_algs[head->count].alg_id == TPM_ALG_SHA1) {
+			memcpy(dgst_ptr, &sha1_hash[0], SHA1_DIGEST_SIZE);
+			total_size += SHA1_DIGEST_SIZE + sizeof(u16);
+			alg_ptr = (u16 *)((u8 *)alg_ptr + SHA1_DIGEST_SIZE + sizeof(u16));
+		} else {
+			sl_txt_reset(SL_ERROR_TPM_UNKNOWN_DIGEST);
+		}
+	}
+
+	event = (struct tcg_event_field *)(log_buf + total_size);
+	event->event_size = event_size;
+	if (event_size > 0)
+		memcpy((u8 *)event + sizeof(struct tcg_event_field), event_data, event_size);
+	total_size += sizeof(struct tcg_event_field) + event_size;
+
+	if (tpm2_log_event(log21_elem, evtlog_base, evtlog_size, total_size, &log_buf[0]))
+		sl_txt_reset(SL_ERROR_TPM_LOGGING_FAILED);
+}
+
+static void sl_tpm_extend_evtlog(u32 pcr, u32 type,
+				 const u8 *data, u32 length, const char *desc)
+{
+	if (tpm_log_ver == SL_TPM2_LOG)
+		sl_tpm2_log_event(pcr, type, data, length,
+				  (const u8 *)desc, strlen(desc));
+	else
+		sl_tpm_log_event(pcr, type, data, length,
+				 (const u8 *)desc, strlen(desc));
+}
+
+static struct setup_data *sl_handle_setup_data(struct setup_data *curr,
+					       struct slr_policy_entry *entry)
+{
+	struct setup_indirect *ind;
+	struct setup_data *next;
+
+	if (!curr)
+		return NULL;
+
+	next = (struct setup_data *)(unsigned long)curr->next;
+
+	/* SETUP_INDIRECT instances have to be handled differently */
+	if (curr->type == SETUP_INDIRECT) {
+		ind = (struct setup_indirect *)((u8 *)curr + offsetof(struct setup_data, data));
+
+		sl_check_pmr_coverage((void *)ind->addr, ind->len, true);
+
+		sl_tpm_extend_evtlog(entry->pcr, TXT_EVTYPE_SLAUNCH,
+				     (void *)ind->addr, ind->len,
+				     entry->evt_info);
+
+		return next;
+	}
+
+	sl_check_pmr_coverage(((u8 *)curr) + sizeof(struct setup_data),
+			      curr->len, true);
+
+	sl_tpm_extend_evtlog(entry->pcr, TXT_EVTYPE_SLAUNCH,
+			     ((u8 *)curr) + sizeof(struct setup_data),
+			     curr->len,
+			     entry->evt_info);
+
+	return next;
+}
+
+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);
+}
+
+static void sl_extend_slrt(struct slr_policy_entry *entry)
+{
+	struct slr_table *slrt = (struct slr_table *)entry->entity;
+	struct slr_entry_intel_info *intel_info;
+
+	/*
+	 * In revision one of the SLRT, the only table that needs to be
+	 * measured is the Intel info table. Everything else is meta-data,
+	 * addresses and sizes. Note the size of what to measure is not set.
+	 * The flag SLR_POLICY_IMPLICIT_SIZE leaves it to the measuring code
+	 * to sort out.
+	 */
+	if (slrt->revision == 1) {
+		intel_info = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO);
+		if (!intel_info)
+			sl_txt_reset(SL_ERROR_SLRT_MISSING_ENTRY);
+
+		sl_tpm_extend_evtlog(entry->pcr, TXT_EVTYPE_SLAUNCH,
+				     (void *)entry->entity, sizeof(struct slr_entry_intel_info),
+				     entry->evt_info);
+	}
+}
+
+static void sl_extend_txt_os2mle(struct slr_policy_entry *entry)
+{
+	struct txt_os_mle_data *os_mle_data;
+	void *txt_heap;
+
+	txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+	os_mle_data = txt_os_mle_data_start(txt_heap);
+
+	/*
+	 * Version 1 of the OS-MLE heap structure has no fields to measure. It just
+	 * has addresses and sizes and a scratch buffer.
+	 */
+	if (os_mle_data->version == 1)
+		return;
+}
+
+/*
+ * Process all policy entries and extend the measurements to the evtlog
+ */
+static void sl_process_extend_policy(struct slr_table *slrt)
+{
+	struct slr_entry_policy *policy;
+	u16 i;
+
+	policy = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_ENTRY_POLICY);
+	if (!policy)
+		sl_txt_reset(SL_ERROR_SLRT_MISSING_ENTRY);
+
+	for (i = 0; i < policy->nr_entries; i++) {
+		switch (policy->policy_entries[i].entity_type) {
+		case SLR_ET_SETUP_DATA:
+			sl_extend_setup_data(&policy->policy_entries[i]);
+			break;
+		case SLR_ET_SLRT:
+			sl_extend_slrt(&policy->policy_entries[i]);
+			break;
+		case SLR_ET_TXT_OS2MLE:
+			sl_extend_txt_os2mle(&policy->policy_entries[i]);
+			break;
+		case SLR_ET_UNUSED:
+			continue;
+		default:
+			sl_tpm_extend_evtlog(policy->policy_entries[i].pcr, TXT_EVTYPE_SLAUNCH,
+					     (void *)policy->policy_entries[i].entity,
+					     policy->policy_entries[i].size,
+					     policy->policy_entries[i].evt_info);
+		}
+	}
+}
+
+/*
+ * Process all EFI config entries and extend the measurements to the evtlog
+ */
+static void sl_process_extend_uefi_config(struct slr_table *slrt)
+{
+	struct slr_entry_uefi_config *uefi_config;
+	u16 i;
+
+	uefi_config = slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_UEFI_CONFIG);
+
+	/* Optionally here depending on how SL kernel was booted */
+	if (!uefi_config)
+		return;
+
+	for (i = 0; i < uefi_config->nr_entries; i++) {
+		sl_tpm_extend_evtlog(uefi_config->uefi_cfg_entries[i].pcr, TXT_EVTYPE_SLAUNCH,
+				     (void *)uefi_config->uefi_cfg_entries[i].cfg,
+				     uefi_config->uefi_cfg_entries[i].size,
+				     uefi_config->uefi_cfg_entries[i].evt_info);
+	}
+}
+
+asmlinkage __visible void sl_check_region(void *base, u32 size)
+{
+	sl_check_pmr_coverage(base, size, false);
+}
+
+asmlinkage __visible void sl_main(void *bootparams)
+{
+	struct boot_params *bp  = (struct boot_params *)bootparams;
+	struct txt_os_mle_data *os_mle_data;
+	struct slr_table *slrt;
+	void *txt_heap;
+
+	/*
+	 * Ensure loadflags do not indicate a secure launch was done
+	 * unless it really was.
+	 */
+	bp->hdr.loadflags &= ~SLAUNCH_FLAG;
+
+	/*
+	 * Currently only Intel TXT is supported for Secure Launch. Testing
+	 * this value also indicates that the kernel was booted successfully
+	 * through the Secure Launch entry point and is in SMX mode.
+	 */
+	if (!(sl_cpu_type & SL_CPU_INTEL))
+		return;
+
+	slrt = sl_locate_and_validate_slrt();
+
+	/* Locate the TPM event log. */
+	sl_find_drtm_event_log(slrt);
+
+	/* Validate the location of the event log buffer before using it */
+	sl_validate_event_log_buffer();
+
+	/*
+	 * Find the TPM hash algorithms used by the ACM and recorded in the
+	 * event log.
+	 */
+	if (tpm_log_ver == SL_TPM2_LOG)
+		sl_find_event_log_algorithms();
+
+	/*
+	 * Sanitize them before measuring. Set the SLAUNCH_FLAG early since if
+	 * anything fails, the system will reset anyway.
+	 */
+	sanitize_boot_params(bp);
+	bp->hdr.loadflags |= SLAUNCH_FLAG;
+
+	sl_check_pmr_coverage(bootparams, PAGE_SIZE, false);
+
+	/* Place event log SL specific tags before and after measurements */
+	sl_tpm_extend_evtlog(17, TXT_EVTYPE_SLAUNCH_START, NULL, 0, "");
+
+	sl_process_extend_policy(slrt);
+
+	sl_process_extend_uefi_config(slrt);
+
+	sl_tpm_extend_evtlog(17, TXT_EVTYPE_SLAUNCH_END, NULL, 0, "");
+
+	/* No PMR check is needed, the TXT heap is covered by the DPR */
+	txt_heap = (void *)sl_txt_read(TXT_CR_HEAP_BASE);
+	os_mle_data = txt_os_mle_data_start(txt_heap);
+
+	/*
+	 * Now that the OS-MLE data is measured, ensure the MTRR and
+	 * misc enable MSRs are what we expect.
+	 */
+	sl_txt_validate_msrs(os_mle_data);
+}
diff --git a/arch/x86/boot/compressed/sl_stub.S b/arch/x86/boot/compressed/sl_stub.S
new file mode 100644
index 000000000000..92ca1f03c619
--- /dev/null
+++ b/arch/x86/boot/compressed/sl_stub.S
@@ -0,0 +1,726 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Secure Launch protected mode entry point.
+ *
+ * Copyright (c) 2024, Oracle and/or its affiliates.
+ */
+	.code32
+	.text
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/msr.h>
+#include <asm/apicdef.h>
+#include <asm/trapnr.h>
+#include <asm/processor-flags.h>
+#include <asm/asm-offsets.h>
+#include <asm/bootparam.h>
+#include <asm/page_types.h>
+#include <asm/irq_vectors.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
+
+/* CPUID: leaf 1, ECX, SMX feature bit */
+#define X86_FEATURE_BIT_SMX	(1 << 6)
+
+#define IDT_VECTOR_LO_BITS	0
+#define IDT_VECTOR_HI_BITS	6
+
+/*
+ * See the comment in head_64.S for detailed information on what this macro
+ * and others like it are used for. The comment appears right at the top of
+ * the file.
+ */
+#define rva(X) ((X) - sl_stub_entry)
+
+/*
+ * The GETSEC op code is open coded because older versions of
+ * GCC do not support the getsec mnemonic.
+ */
+.macro GETSEC leaf
+	pushl	%ebx
+	xorl	%ebx, %ebx	/* Must be zero for SMCTRL */
+	movl	\leaf, %eax	/* Leaf function */
+	.byte 	0x0f, 0x37	/* GETSEC opcode */
+	popl	%ebx
+.endm
+
+.macro TXT_RESET error
+	/*
+	 * Set a sticky error value and reset. Note the movs to %eax act as
+	 * TXT register barriers.
+	 */
+	movl	\error, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_ERRORCODE)
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_E2STS), %eax
+	movl	$1, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_CMD_NO_SECRETS)
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_E2STS), %eax
+	movl	$1, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_CMD_UNLOCK_MEM_CONFIG)
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_E2STS), %eax
+	movl	$1, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_CMD_RESET)
+1:
+	hlt
+	jmp	1b
+.endm
+
+	.code32
+SYM_FUNC_START(sl_stub_entry)
+	cli
+	cld
+
+	/*
+	 * On entry, %ebx has the entry abs offset to sl_stub_entry. The rva()
+	 * macro is used to generate relative references using %ebx as a base, as
+	 * to avoid absolute relocations, which would require fixups at runtime.
+	 * Only %cs and %ds segments are known good.
+	 */
+
+	/* Load GDT, set segment regs and lret to __SL32_CS */
+	leal	rva(sl_gdt_desc)(%ebx), %eax
+	addl	%eax, 2(%eax)
+	lgdt	(%eax)
+
+	movl	$(__SL32_DS), %eax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/*
+	 * Now that %ss is known good, take the first stack for the BSP. The
+	 * AP stacks are only used on Intel.
+	 */
+	leal	rva(sl_stacks_end)(%ebx), %esp
+
+	leal	rva(.Lsl_cs)(%ebx), %eax
+	pushl	$(__SL32_CS)
+	pushl	%eax
+	lret
+
+.Lsl_cs:
+	/* Save our base pointer reg and page table for MLE */
+	pushl	%ebx
+	pushl	%ecx
+
+	/* See if SMX feature is supported. */
+	movl	$1, %eax
+	cpuid
+	testl	$(X86_FEATURE_BIT_SMX), %ecx
+	jz	.Ldo_unknown_cpu
+
+	popl	%ecx
+	popl	%ebx
+
+	/* Know it is Intel */
+	movl	$(SL_CPU_INTEL), rva(sl_cpu_type)(%ebx)
+
+	/* Locate the base of the MLE using the page tables in %ecx */
+	call	sl_find_mle_base
+
+	/* Increment CPU count for BSP */
+	incl	rva(sl_txt_cpu_count)(%ebx)
+
+	/*
+	 * Enable SMI with GETSEC[SMCTRL] which were disabled by SENTER.
+	 * NMIs were also disabled by SENTER. Since there is no IDT for the BSP,
+	 * allow the mainline kernel re-enable them in the normal course of
+	 * booting.
+	 */
+	GETSEC	$(SMX_X86_GETSEC_SMCTRL)
+
+	/* Clear the TXT error registers for a clean start of day */
+	movl	$0, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_ERRORCODE)
+	movl	$0xffffffff, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_ESTS)
+
+	/* On Intel, the zero page address is passed in the TXT heap */
+	/* Read physical base of heap into EAX */
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_HEAP_BASE), %eax
+	/* Read the size of the BIOS data into ECX (first 8 bytes) */
+	movl	(%eax), %ecx
+	/* Skip over BIOS data and size of OS to MLE data section */
+	leal	8(%eax, %ecx), %eax
+
+	/* Need to verify the values in the OS-MLE struct passed in */
+	call	sl_txt_verify_os_mle_struct
+
+	/*
+	 * Get the boot params address from the heap. Note %esi and %ebx MUST
+	 * be preserved across calls and operations.
+	 */
+	movl	SL_boot_params_addr(%eax), %esi
+
+	/* Save %ebx so the APs can find their way home */
+	movl	%ebx, (SL_mle_scratch + SL_SCRATCH_AP_EBX)(%eax)
+
+	/* Fetch the AP wake code block address from the heap */
+	movl	SL_ap_wake_block(%eax), %edi
+	movl	%edi, rva(sl_txt_ap_wake_block)(%ebx)
+
+	/* Store the offset in the AP wake block to the jmp address */
+	movl	$(sl_ap_jmp_offset - sl_txt_ap_wake_begin), \
+		(SL_mle_scratch + SL_SCRATCH_AP_JMP_OFFSET)(%eax)
+
+	/* Store the offset in the AP wake block to the AP stacks block */
+	movl	$(sl_stacks - sl_txt_ap_wake_begin), \
+		(SL_mle_scratch + SL_SCRATCH_AP_STACKS_OFFSET)(%eax)
+
+	/* %eax still is the base of the OS-MLE block, save it */
+	pushl	%eax
+
+	/* Relocate the AP wake code to the safe block */
+	call	sl_txt_reloc_ap_wake
+
+	/*
+	 * Wake up all APs that are blocked in the ACM and wait for them to
+	 * halt. This should be done before restoring the MTRRs so the ACM is
+	 * still properly in WB memory.
+	 */
+	call	sl_txt_wake_aps
+
+	/* Restore OS-MLE in %eax */
+	popl	%eax
+
+	/*
+	 * %edi is used by this routine to find the MTRRs which are in the SLRT
+	 * in the Intel info.
+	 */
+	movl	SL_txt_info(%eax), %edi
+	call	sl_txt_load_regs
+
+	jmp	.Lcpu_setup_done
+
+.Ldo_unknown_cpu:
+	/* Non-Intel CPUs are not yet supported */
+	ud2
+
+.Lcpu_setup_done:
+	/*
+	 * Don't enable MCE at this point. The kernel will enable
+	 * it on the BSP later when it is ready.
+	 */
+
+	/* Done, jump to normal 32b pm entry */
+	jmp	startup_32
+SYM_FUNC_END(sl_stub_entry)
+
+SYM_FUNC_START(sl_find_mle_base)
+	/* %ecx has PDPT, get first PD */
+	movl	(%ecx), %eax
+	andl	$(PAGE_MASK), %eax
+	/* Get first PT from first PDE */
+	movl	(%eax), %eax
+	andl	$(PAGE_MASK), %eax
+	/* Get MLE base from first PTE */
+	movl	(%eax), %eax
+	andl	$(PAGE_MASK), %eax
+
+	movl	%eax, rva(sl_mle_start)(%ebx)
+	ret
+SYM_FUNC_END(sl_find_mle_base)
+
+SYM_FUNC_START(sl_check_buffer_mle_overlap)
+	/* %ecx: buffer begin %edx: buffer end */
+	/* %ebx: MLE begin %edi: MLE end */
+	/* %eax: region may be inside MLE */
+
+	cmpl	%edi, %ecx
+	jb	.Lnext_check
+	cmpl	%edi, %edx
+	jbe	.Lnext_check
+	jmp	.Lvalid /* Buffer above MLE */
+
+.Lnext_check:
+	cmpl	%ebx, %edx
+	ja	.Linside_check
+	cmpl	%ebx, %ecx
+	jae	.Linside_check
+	jmp	.Lvalid /* Buffer below MLE */
+
+.Linside_check:
+	cmpl	$0, %eax
+	jz	.Linvalid
+	cmpl	%ebx, %ecx
+	jb	.Linvalid
+	cmpl	%edi, %edx
+	ja	.Linvalid
+	jmp	.Lvalid /* Buffer in MLE */
+
+.Linvalid:
+	TXT_RESET $(SL_ERROR_MLE_BUFFER_OVERLAP)
+
+.Lvalid:
+	ret
+SYM_FUNC_END(sl_check_buffer_mle_overlap)
+
+SYM_FUNC_START(sl_txt_verify_os_mle_struct)
+	pushl	%ebx
+	/*
+	 * %eax points to the base of the OS-MLE struct. Need to also
+	 * read some values from the OS-SINIT struct too.
+	 */
+	movl	-8(%eax), %ecx
+	/* Skip over OS to MLE data section and size of OS-SINIT structure */
+	leal	(%eax, %ecx), %edx
+
+	/* Load MLE image base absolute offset */
+	movl	rva(sl_mle_start)(%ebx), %ebx
+
+	/* Verify the value of the low PMR base. It should always be 0. */
+	movl	SL_vtd_pmr_lo_base(%edx), %esi
+	cmpl	$0, %esi
+	jz	.Lvalid_pmr_base
+	TXT_RESET $(SL_ERROR_LO_PMR_BASE)
+
+.Lvalid_pmr_base:
+	/* Grab some values from OS-SINIT structure */
+	movl	SL_mle_size(%edx), %edi
+	addl	%ebx, %edi
+	jc	.Loverflow_detected
+	movl	SL_vtd_pmr_lo_size(%edx), %esi
+
+	/* Check the AP wake block */
+	movl	SL_ap_wake_block(%eax), %ecx
+	movl	SL_ap_wake_block_size(%eax), %edx
+	addl	%ecx, %edx
+	jc	.Loverflow_detected
+	pushl	%eax
+	xorl	%eax, %eax
+	call	sl_check_buffer_mle_overlap
+	popl	%eax
+	cmpl	%esi, %edx
+	ja	.Lbuffer_beyond_pmr
+
+	/*
+	 * Check the boot params. Note during a UEFI boot, the boot
+	 * params will be inside the MLE image. Test for this case
+	 * in the overlap case.
+	 */
+	movl	SL_boot_params_addr(%eax), %ecx
+	movl	$(PAGE_SIZE), %edx
+	addl	%ecx, %edx
+	jc	.Loverflow_detected
+	pushl	%eax
+	movl	$1, %eax
+	call	sl_check_buffer_mle_overlap
+	popl	%eax
+	cmpl	%esi, %edx
+	ja	.Lbuffer_beyond_pmr
+
+	/* Check that the AP wake block is big enough */
+	cmpl	$(sl_txt_ap_wake_end - sl_txt_ap_wake_begin), \
+		SL_ap_wake_block_size(%eax)
+	jae	.Lwake_block_ok
+	TXT_RESET $(SL_ERROR_WAKE_BLOCK_TOO_SMALL)
+
+.Lwake_block_ok:
+	popl	%ebx
+	ret
+
+.Loverflow_detected:
+	TXT_RESET $(SL_ERROR_INTEGER_OVERFLOW)
+
+.Lbuffer_beyond_pmr:
+	TXT_RESET $(SL_ERROR_BUFFER_BEYOND_PMR)
+SYM_FUNC_END(sl_txt_verify_os_mle_struct)
+
+SYM_FUNC_START(sl_txt_ap_entry)
+	cli
+	cld
+	/*
+	 * The %cs and %ds segments are known good after waking the AP.
+	 * First order of business is to find where we are and
+	 * save it in %ebx.
+	 */
+
+	/* Read physical base of heap into EAX */
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_HEAP_BASE), %eax
+	/* Read the size of the BIOS data into ECX (first 8 bytes) */
+	movl	(%eax), %ecx
+	/* Skip over BIOS data and size of OS to MLE data section */
+	leal	8(%eax, %ecx), %eax
+
+	/* Saved %ebx from the BSP and stash OS-MLE pointer */
+	movl	(SL_mle_scratch + SL_SCRATCH_AP_EBX)(%eax), %ebx
+
+	/* Save TXT info ptr in %edi for call to sl_txt_load_regs */
+	movl	SL_txt_info(%eax), %edi
+
+	/* Lock and get our stack index */
+	movl	$1, %ecx
+.Lspin:
+	xorl	%eax, %eax
+	lock cmpxchgl	%ecx, rva(sl_txt_spin_lock)(%ebx)
+	pause
+	jnz	.Lspin
+
+	/* Increment the stack index and use the next value inside lock */
+	incl	rva(sl_txt_stack_index)(%ebx)
+	movl	rva(sl_txt_stack_index)(%ebx), %eax
+
+	/* Unlock */
+	movl	$0, rva(sl_txt_spin_lock)(%ebx)
+
+	/* Location of the relocated AP wake block */
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %ecx
+
+	/* Load reloc GDT, set segment regs and lret to __SL32_CS */
+	lgdt	(sl_ap_gdt_desc - sl_txt_ap_wake_begin)(%ecx)
+
+	movl	$(__SL32_DS), %edx
+	movw	%dx, %ds
+	movw	%dx, %es
+	movw	%dx, %fs
+	movw	%dx, %gs
+	movw	%dx, %ss
+
+	/* Load our reloc AP stack */
+	movl	$(TXT_BOOT_STACK_SIZE), %edx
+	mull	%edx
+	leal	(sl_stacks_end - sl_txt_ap_wake_begin)(%ecx), %esp
+	subl	%eax, %esp
+
+	/* Switch to AP code segment */
+	leal	rva(.Lsl_ap_cs)(%ebx), %eax
+	pushl	$(__SL32_CS)
+	pushl	%eax
+	lret
+
+.Lsl_ap_cs:
+	/* Load the relocated AP IDT */
+	lidt	(sl_ap_idt_desc - sl_txt_ap_wake_begin)(%ecx)
+
+	/* Fixup MTRRs and misc enable MSR on APs too */
+	call	sl_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 */
+	leal	rva(.Lnmi_enabled_ap)(%ebx), %eax
+	pushfl
+	pushl	$(__SL32_CS)
+	pushl	%eax
+	iret
+
+.Lnmi_enabled_ap:
+	/* Put APs in X2APIC mode like the BSP */
+	movl	$(MSR_IA32_APICBASE), %ecx
+	rdmsr
+	orl	$(XAPIC_ENABLE | X2APIC_ENABLE), %eax
+	wrmsr
+
+	/*
+	 * Basically done, increment the CPU count and jump off to the AP
+	 * wake block to wait.
+	 */
+	lock incl	rva(sl_txt_cpu_count)(%ebx)
+
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %eax
+	jmp	*%eax
+SYM_FUNC_END(sl_txt_ap_entry)
+
+SYM_FUNC_START(sl_txt_reloc_ap_wake)
+	/* Save boot params register */
+	pushl	%esi
+
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %edi
+
+	/* Fixup AP IDT and GDT descriptor before relocating */
+	leal	rva(sl_ap_idt_desc)(%ebx), %eax
+	addl	%edi, 2(%eax)
+	leal	rva(sl_ap_gdt_desc)(%ebx), %eax
+	addl	%edi, 2(%eax)
+
+	/*
+	 * Copy the AP wake code and AP GDT/IDT to the protected wake block
+	 * provided by the loader. Destination already in %edi.
+	 */
+	movl	$(sl_txt_ap_wake_end - sl_txt_ap_wake_begin), %ecx
+	leal	rva(sl_txt_ap_wake_begin)(%ebx), %esi
+	rep movsb
+
+	/* Setup the IDT for the APs to use in the relocation block */
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %ecx
+	addl	$(sl_ap_idt - sl_txt_ap_wake_begin), %ecx
+	xorl	%edx, %edx
+
+	/* Form the default reset vector relocation address */
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %esi
+	addl	$(sl_txt_int_reset - sl_txt_ap_wake_begin), %esi
+
+1:
+	cmpw	$(NR_VECTORS), %dx
+	jz	.Lap_idt_done
+
+	cmpw	$(X86_TRAP_NMI), %dx
+	jz	2f
+
+	/* Load all other fixed vectors with reset handler */
+	movl	%esi, %eax
+	movw	%ax, (IDT_VECTOR_LO_BITS)(%ecx)
+	shrl	$16, %eax
+	movw	%ax, (IDT_VECTOR_HI_BITS)(%ecx)
+	jmp	3f
+
+2:
+	/* Load single wake NMI IPI vector at the relocation address */
+	movl	rva(sl_txt_ap_wake_block)(%ebx), %eax
+	addl	$(sl_txt_int_nmi - sl_txt_ap_wake_begin), %eax
+	movw	%ax, (IDT_VECTOR_LO_BITS)(%ecx)
+	shrl	$16, %eax
+	movw	%ax, (IDT_VECTOR_HI_BITS)(%ecx)
+
+3:
+	incw	%dx
+	addl	$8, %ecx
+	jmp	1b
+
+.Lap_idt_done:
+	popl	%esi
+	ret
+SYM_FUNC_END(sl_txt_reloc_ap_wake)
+
+SYM_FUNC_START(sl_txt_load_regs)
+	/* Save base pointer register */
+	pushl	%ebx
+
+	/*
+	 * On Intel, the original variable MTRRs and Misc Enable MSR are
+	 * restored on the BSP at early boot. Each AP will also restore
+	 * its MTRRs and Misc Enable MSR.
+	 */
+	pushl	%edi
+	addl	$(SL_saved_bsp_mtrrs), %edi
+	movl	(%edi), %ebx
+	pushl	%ebx /* default_mem_type lo */
+	addl	$4, %edi
+	movl	(%edi), %ebx
+	pushl	%ebx /* default_mem_type hi */
+	addl	$4, %edi
+	movl	(%edi), %ebx /* mtrr_vcnt lo, don't care about hi part */
+	addl	$8, %edi /* now at MTRR pair array */
+	/* Write the variable MTRRs */
+	movl	$(MSR_MTRRphysBase0), %ecx
+1:
+	cmpl	$0, %ebx
+	jz	2f
+
+	movl	(%edi), %eax /* MTRRphysBaseX lo */
+	addl	$4, %edi
+	movl	(%edi), %edx /* MTRRphysBaseX hi */
+	wrmsr
+	addl	$4, %edi
+	incl	%ecx
+	movl	(%edi), %eax /* MTRRphysMaskX lo */
+	addl	$4, %edi
+	movl	(%edi), %edx /* MTRRphysMaskX hi */
+	wrmsr
+	addl	$4, %edi
+	incl	%ecx
+
+	decl	%ebx
+	jmp	1b
+2:
+	/* Write the default MTRR register */
+	popl	%edx
+	popl	%eax
+	movl	$(MSR_MTRRdefType), %ecx
+	wrmsr
+
+	/* Return to beginning and write the misc enable msr */
+	popl	%edi
+	addl	$(SL_saved_misc_enable_msr), %edi
+	movl	(%edi), %eax /* saved_misc_enable_msr lo */
+	addl	$4, %edi
+	movl	(%edi), %edx /* saved_misc_enable_msr hi */
+	movl	$(MSR_IA32_MISC_ENABLE), %ecx
+	wrmsr
+
+	popl	%ebx
+	ret
+SYM_FUNC_END(sl_txt_load_regs)
+
+SYM_FUNC_START(sl_txt_wake_aps)
+	/* Save boot params register */
+	pushl	%esi
+
+	/* First setup the MLE join structure and load it into TXT reg */
+	leal	rva(sl_gdt)(%ebx), %eax
+	leal	rva(sl_txt_ap_entry)(%ebx), %ecx
+	leal	rva(sl_smx_rlp_mle_join)(%ebx), %edx
+	movl	%eax, SL_rlp_gdt_base(%edx)
+	movl	%ecx, SL_rlp_entry_point(%edx)
+	movl	%edx, (TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_MLE_JOIN)
+
+	/* Another TXT heap walk to find various values needed to wake APs */
+	movl	(TXT_PRIV_CONFIG_REGS_BASE + TXT_CR_HEAP_BASE), %eax
+	/* At BIOS data size, find the number of logical processors */
+	movl	(SL_num_logical_procs + 8)(%eax), %edx
+	/* Skip over BIOS data */
+	movl	(%eax), %ecx
+	addl	%ecx, %eax
+	/* Skip over OS to MLE */
+	movl	(%eax), %ecx
+	addl	%ecx, %eax
+	/* At OS-SNIT size, get capabilities to know how to wake up the APs */
+	movl	(SL_capabilities + 8)(%eax), %esi
+	/* Skip over OS to SNIT */
+	movl	(%eax), %ecx
+	addl	%ecx, %eax
+	/* At SINIT-MLE size, get the AP wake MONITOR address */
+	movl	(SL_rlp_wakeup_addr + 8)(%eax), %edi
+
+	/* Determine how to wake up the APs */
+	testl	$(1 << TXT_SINIT_MLE_CAP_WAKE_MONITOR), %esi
+	jz	.Lwake_getsec
+
+	/* Wake using MWAIT MONITOR */
+	movl	$1, (%edi)
+	jmp	.Laps_awake
+
+.Lwake_getsec:
+	/* Wake using GETSEC(WAKEUP) */
+	GETSEC	$(SMX_X86_GETSEC_WAKEUP)
+
+.Laps_awake:
+	/*
+	 * All of the APs are woken up and rendesvous in the relocated wake
+	 * block starting at sl_txt_ap_wake_begin. Wait for all of them to
+	 * halt.
+	 */
+	pause
+	cmpl	rva(sl_txt_cpu_count)(%ebx), %edx
+	jne	.Laps_awake
+
+	popl	%esi
+	ret
+SYM_FUNC_END(sl_txt_wake_aps)
+
+/* This is the beginning of the relocated AP wake code block */
+	.global sl_txt_ap_wake_begin
+sl_txt_ap_wake_begin:
+
+	/* Get the LAPIC ID for each AP and stash it on the stack */
+	movl	$(MSR_IA32_X2APIC_APICID), %ecx
+	rdmsr
+	pushl	%eax
+
+	/*
+	 * Get a pointer to the monitor location on this APs stack to test below
+	 * after mwait returns. Currently %esp points to just past the pushed APIC
+	 * ID value.
+	 */
+	movl	%esp, %eax
+	subl	$(TXT_BOOT_STACK_SIZE - 4), %eax
+	movl	$0, (%eax)
+
+	/* Clear ecx/edx so no invalid extensions or hints are passed to monitor */
+	xorl	%ecx, %ecx
+	xorl	%edx, %edx
+
+	/*
+	 * Arm the monitor and wait for it to be poked by he SMP bringup code. The mwait
+	 * instruction can return for a number of reasons. Test to see if it returned
+	 * because the monitor was written to.
+	 */
+	monitor
+
+1:
+	mfence
+	mwait
+	movl	(%eax), %edx
+	testl	%edx, %edx
+	jz	1b
+
+	/*
+	 * This is the long absolute jump to the 32b Secure Launch protected mode stub
+	 * code in sl_trampoline_start32() in the rmpiggy. The jump address will be
+	 * fixed in 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.
+	 */
+	.byte	0xea
+sl_ap_jmp_offset:
+	.long	0x00000000
+	.word	__SL32_CS
+
+SYM_FUNC_START(sl_txt_int_nmi)
+	/* NMI context, just IRET */
+	iret
+SYM_FUNC_END(sl_txt_int_nmi)
+
+SYM_FUNC_START(sl_txt_int_reset)
+	TXT_RESET $(SL_ERROR_INV_AP_INTERRUPT)
+SYM_FUNC_END(sl_txt_int_reset)
+
+	.balign 8
+SYM_DATA_START_LOCAL(sl_ap_idt_desc)
+	.word	sl_ap_idt_end - sl_ap_idt - 1		/* Limit */
+	.long	sl_ap_idt - sl_txt_ap_wake_begin	/* Base */
+SYM_DATA_END_LABEL(sl_ap_idt_desc, SYM_L_LOCAL, sl_ap_idt_desc_end)
+
+	.balign 8
+SYM_DATA_START_LOCAL(sl_ap_idt)
+	.rept	NR_VECTORS
+	.word	0x0000		/* Offset 15 to 0 */
+	.word	__SL32_CS	/* Segment selector */
+	.word	0x8e00		/* Present, DPL=0, 32b Vector, Interrupt */
+	.word	0x0000		/* Offset 31 to 16 */
+	.endr
+SYM_DATA_END_LABEL(sl_ap_idt, SYM_L_LOCAL, sl_ap_idt_end)
+
+	.balign 8
+SYM_DATA_START_LOCAL(sl_ap_gdt_desc)
+	.word	sl_ap_gdt_end - sl_ap_gdt - 1
+	.long	sl_ap_gdt - sl_txt_ap_wake_begin
+SYM_DATA_END_LABEL(sl_ap_gdt_desc, SYM_L_LOCAL, sl_ap_gdt_desc_end)
+
+	.balign	8
+SYM_DATA_START_LOCAL(sl_ap_gdt)
+	.quad	0x0000000000000000	/* NULL */
+	.quad	0x00cf9a000000ffff	/* __SL32_CS */
+	.quad	0x00cf92000000ffff	/* __SL32_DS */
+SYM_DATA_END_LABEL(sl_ap_gdt, SYM_L_LOCAL, sl_ap_gdt_end)
+
+	/* Small stacks for BSP and APs to work with */
+	.balign 64
+SYM_DATA_START_LOCAL(sl_stacks)
+	.fill (TXT_MAX_CPUS * TXT_BOOT_STACK_SIZE), 1, 0
+SYM_DATA_END_LABEL(sl_stacks, SYM_L_LOCAL, sl_stacks_end)
+
+/* This is the end of the relocated AP wake code block */
+	.global sl_txt_ap_wake_end
+sl_txt_ap_wake_end:
+
+	.data
+	.balign 8
+SYM_DATA_START_LOCAL(sl_gdt_desc)
+	.word	sl_gdt_end - sl_gdt - 1
+	.long	sl_gdt - sl_gdt_desc
+SYM_DATA_END_LABEL(sl_gdt_desc, SYM_L_LOCAL, sl_gdt_desc_end)
+
+	.balign	8
+SYM_DATA_START_LOCAL(sl_gdt)
+	.quad	0x0000000000000000	/* NULL */
+	.quad	0x00cf9a000000ffff	/* __SL32_CS */
+	.quad	0x00cf92000000ffff	/* __SL32_DS */
+SYM_DATA_END_LABEL(sl_gdt, SYM_L_LOCAL, sl_gdt_end)
+
+	.balign 8
+SYM_DATA_START_LOCAL(sl_smx_rlp_mle_join)
+	.long	sl_gdt_end - sl_gdt - 1	/* GDT limit */
+	.long	0x00000000		/* GDT base */
+	.long	__SL32_CS	/* Seg Sel - CS (DS, ES, SS = seg_sel+8) */
+	.long	0x00000000	/* Entry point physical address */
+SYM_DATA_END(sl_smx_rlp_mle_join)
+
+SYM_DATA(sl_cpu_type, .long 0x00000000)
+
+SYM_DATA(sl_mle_start, .long 0x00000000)
+
+SYM_DATA_LOCAL(sl_txt_spin_lock, .long 0x00000000)
+
+SYM_DATA_LOCAL(sl_txt_stack_index, .long 0x00000000)
+
+SYM_DATA_LOCAL(sl_txt_cpu_count, .long 0x00000000)
+
+SYM_DATA_LOCAL(sl_txt_ap_wake_block, .long 0x00000000)
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 9b82eebd7add..7ce283a22d6b 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -12,6 +12,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)
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index a98020bf31bb..925adce6e2c7 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -13,6 +13,8 @@
 #include <linux/hardirq.h>
 #include <linux/suspend.h>
 #include <linux/kbuild.h>
+#include <linux/slr_table.h>
+#include <linux/slaunch.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
 #include <asm/sigframe.h>
@@ -120,4 +122,22 @@ static void __used common(void)
 	OFFSET(ARIA_CTX_rounds, aria_ctx, rounds);
 #endif
 
+#ifdef CONFIG_SECURE_LAUNCH
+	BLANK();
+	OFFSET(SL_txt_info, txt_os_mle_data, txt_info);
+	OFFSET(SL_mle_scratch, txt_os_mle_data, mle_scratch);
+	OFFSET(SL_boot_params_addr, txt_os_mle_data, boot_params_addr);
+	OFFSET(SL_ap_wake_block, txt_os_mle_data, ap_wake_block);
+	OFFSET(SL_ap_wake_block_size, txt_os_mle_data, ap_wake_block_size);
+	OFFSET(SL_saved_misc_enable_msr, slr_entry_intel_info, saved_misc_enable_msr);
+	OFFSET(SL_saved_bsp_mtrrs, slr_entry_intel_info, saved_bsp_mtrrs);
+	OFFSET(SL_num_logical_procs, txt_bios_data, num_logical_procs);
+	OFFSET(SL_capabilities, txt_os_sinit_data, capabilities);
+	OFFSET(SL_mle_size, txt_os_sinit_data, mle_size);
+	OFFSET(SL_vtd_pmr_lo_base, txt_os_sinit_data, vtd_pmr_lo_base);
+	OFFSET(SL_vtd_pmr_lo_size, txt_os_sinit_data, vtd_pmr_lo_size);
+	OFFSET(SL_rlp_wakeup_addr, txt_sinit_mle_data, rlp_wakeup_addr);
+	OFFSET(SL_rlp_gdt_base, smx_rlp_mle_join, rlp_gdt_base);
+	OFFSET(SL_rlp_entry_point, smx_rlp_mle_join, rlp_entry_point);
+#endif
 }
-- 
2.39.3



