[PATCHv6 03/16] x86/alternatives: Disable LASS when patching kernel alternatives

Kirill A. Shutemov posted 16 patches 3 months, 2 weeks ago
There is a newer version of this series
[PATCHv6 03/16] x86/alternatives: Disable LASS when patching kernel alternatives
Posted by Kirill A. Shutemov 3 months, 2 weeks ago
From: Sohil Mehta <sohil.mehta@intel.com>

For patching, the kernel initializes a temporary mm area in the lower
half of the address range. See commit 4fc19708b165 ("x86/alternatives:
Initialize temporary mm for patching").

Disable LASS enforcement during patching using the stac()/clac()
instructions to avoid triggering a #GP fault.

The objtool warns due to a call to a non-allowed function that exists
outside of the stac/clac guard, or references to any function with a
dynamic function pointer inside the guard. See the Objtool warnings
section #9 in the document tools/objtool/Documentation/objtool.txt.

Considering that patching is usually small, replace the memcpy and
memset functions in the text poking functions with their inline versions
respectively.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 arch/x86/kernel/alternative.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 9ae80fa904a2..0b9f41ed6af7 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2447,16 +2447,24 @@ void __init_or_module text_poke_early(void *addr, const void *opcode,
 __ro_after_init struct mm_struct *text_poke_mm;
 __ro_after_init unsigned long text_poke_mm_addr;
 
+/*
+ * poking_init() initializes the text poking address from the lower half of the
+ * address space. Relax LASS enforcement when accessing the poking address.
+ */
 static void text_poke_memcpy(void *dst, const void *src, size_t len)
 {
-	memcpy(dst, src, len);
+	lass_stac();
+	__inline_memcpy(dst, src, len);
+	lass_clac();
 }
 
 static void text_poke_memset(void *dst, const void *src, size_t len)
 {
 	int c = *(const int *)src;
 
-	memset(dst, c, len);
+	lass_stac();
+	__inline_memset(dst, c, len);
+	lass_clac();
 }
 
 typedef void text_poke_f(void *dst, const void *src, size_t len);
-- 
2.47.2
Re: [PATCHv6 03/16] x86/alternatives: Disable LASS when patching kernel alternatives
Posted by Dave Hansen 3 months, 2 weeks ago
On 6/20/25 06:53, Kirill A. Shutemov wrote:
> +/*
> + * poking_init() initializes the text poking address from the lower half of the
> + * address space. Relax LASS enforcement when accessing the poking address.
> + */

This does not read quite right. I think there's some unnecessary
confusiuon about initializing the address versus the contents. But
either way, how about:

/*
 * Text poking creates and uses a mapping in the lower half of the
 * address space. Relax LASS enforcement when accessing the poking
 * address.
 */

>  static void text_poke_memset(void *dst, const void *src, size_t len)
>  {
>  	int c = *(const int *)src;
>  
> -	memset(dst, c, len);
> +	lass_stac();
> +	__inline_memset(dst, c, len);
> +	lass_clac();
>  }

Yeah, this patch small enough that lass_{stac,clac}() are definitely
misplaced in this series. Just move them into this patch.
Re: [PATCHv6 03/16] x86/alternatives: Disable LASS when patching kernel alternatives
Posted by Kirill A. Shutemov 3 months, 2 weeks ago
On Fri, Jun 20, 2025 at 08:33:57AM -0700, Dave Hansen wrote:
> On 6/20/25 06:53, Kirill A. Shutemov wrote:
> > +/*
> > + * poking_init() initializes the text poking address from the lower half of the
> > + * address space. Relax LASS enforcement when accessing the poking address.
> > + */
> 
> This does not read quite right. I think there's some unnecessary
> confusiuon about initializing the address versus the contents. But
> either way, how about:
> 
> /*
>  * Text poking creates and uses a mapping in the lower half of the
>  * address space. Relax LASS enforcement when accessing the poking
>  * address.
>  */

Looks good. Will update, thanks!
> 
> >  static void text_poke_memset(void *dst, const void *src, size_t len)
> >  {
> >  	int c = *(const int *)src;
> >  
> > -	memset(dst, c, len);
> > +	lass_stac();
> > +	__inline_memset(dst, c, len);
> > +	lass_clac();
> >  }
> 
> Yeah, this patch small enough that lass_{stac,clac}() are definitely
> misplaced in this series. Just move them into this patch.

Okay, makes sense.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov