[PATCH] x86/tdx: Fix crash on kexec

Kirill A. Shutemov posted 1 patch 1 year, 5 months ago
arch/x86/coco/tdx/tdx.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
[PATCH] x86/tdx: Fix crash on kexec
Posted by Kirill A. Shutemov 1 year, 5 months ago
The function tdx_enc_status_changed() was modified to handle vmalloc()
mappings. It now utilizes slow_virt_to_phys() to determine the physical
address of the page by walking page tables and looking for the physical
address in the page table entry.

However, this adjustment conflicted with the enabling of kexec. The
function tdx_kexec_finish() clears the page table entry before calling
tdx_enc_status_changed(), causing a BUG_ON() error in
slow_virt_to_phys().

To address this issue, tdx_enc_status_change() should use __pa() to
obtain physical addresses whenever possible. The virt_addr_valid() check
will handle such cases, while any other scenarios, including vmalloc()
mappings, will resort to slow_virt_to_phys().

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Fixes: e1b8ac3aae58 ("x86/tdx: Support vmalloc() for tdx_enc_status_changed()")
---
 arch/x86/coco/tdx/tdx.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
index ef8ec2425998..8f471260924f 100644
--- a/arch/x86/coco/tdx/tdx.c
+++ b/arch/x86/coco/tdx/tdx.c
@@ -813,8 +813,16 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
 		step = PAGE_SIZE;
 
 	for (addr = start; addr < end; addr += step) {
-		phys_addr_t start_pa = slow_virt_to_phys((void *)addr);
-		phys_addr_t end_pa   = start_pa + step;
+		phys_addr_t start_pa;
+		phys_addr_t end_pa;
+
+		/* The check fails on vmalloc() mappings */
+		if (virt_addr_valid(addr))
+			start_pa = __pa(addr);
+		else
+			start_pa = slow_virt_to_phys((void *)addr);
+
+		end_pa = start_pa + step;
 
 		if (!tdx_enc_status_changed_phys(start_pa, end_pa, enc))
 			return false;
-- 
2.43.0
Re: [PATCH] x86/tdx: Fix crash on kexec
Posted by Borislav Petkov 1 year, 5 months ago
On Sat, Jun 29, 2024 at 04:06:20PM +0300, Kirill A. Shutemov wrote:
> The function tdx_enc_status_changed() was modified to handle vmalloc()
> mappings. It now utilizes slow_virt_to_phys() to determine the physical
> address of the page by walking page tables and looking for the physical
> address in the page table entry.
> 
> However, this adjustment conflicted with the enabling of kexec. The
> function tdx_kexec_finish() clears the page table entry before calling
> tdx_enc_status_changed(), causing a BUG_ON() error in
> slow_virt_to_phys().
> 
> To address this issue, tdx_enc_status_change() should use __pa() to
> obtain physical addresses whenever possible. The virt_addr_valid() check
> will handle such cases, while any other scenarios, including vmalloc()
> mappings, will resort to slow_virt_to_phys().
> 
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Fixes: e1b8ac3aae58 ("x86/tdx: Support vmalloc() for tdx_enc_status_changed()")

I'm going to zap this one from x86/urgent and give you guys ample time to test
thus stuff better and longer.

Also, what is this e1b8ac3aae58 fixing and why is it urgent?

AFAICT, it can go through the normal merge window...

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: [PATCH] x86/tdx: Fix crash on kexec
Posted by Kirill A. Shutemov 1 year, 5 months ago
On Sat, Jun 29, 2024 at 03:59:33PM +0200, Borislav Petkov wrote:
> On Sat, Jun 29, 2024 at 04:06:20PM +0300, Kirill A. Shutemov wrote:
> > The function tdx_enc_status_changed() was modified to handle vmalloc()
> > mappings. It now utilizes slow_virt_to_phys() to determine the physical
> > address of the page by walking page tables and looking for the physical
> > address in the page table entry.
> > 
> > However, this adjustment conflicted with the enabling of kexec. The
> > function tdx_kexec_finish() clears the page table entry before calling
> > tdx_enc_status_changed(), causing a BUG_ON() error in
> > slow_virt_to_phys().
> > 
> > To address this issue, tdx_enc_status_change() should use __pa() to
> > obtain physical addresses whenever possible. The virt_addr_valid() check
> > will handle such cases, while any other scenarios, including vmalloc()
> > mappings, will resort to slow_virt_to_phys().
> > 
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> > Fixes: e1b8ac3aae58 ("x86/tdx: Support vmalloc() for tdx_enc_status_changed()")
> 
> I'm going to zap this one from x86/urgent and give you guys ample time to test
> thus stuff better and longer.
> 
> Also, what is this e1b8ac3aae58 fixing and why is it urgent?

Daxuan, how urgent is this fix for you?

-- 
  Kiryl Shutsemau / Kirill A. Shutemov