On Tue, Feb 27, 2024 at 02:27:26PM +0100, Greg Kroah-Hartman wrote:
5.10-stable review patch. If anyone has any objections, please let me know.
From: Peter Zijlstra peterz@infradead.org
Upstream commit: ba27d1a80871eb8dbeddf34ec7d396c149cbb8d7
Less duplication is more better.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Josh Poimboeuf jpoimboe@redhat.com Link: https://lore.kernel.org/r/20220308154317.697253958@infradead.org [ Keep struct branch. ] Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
arch/x86/include/asm/text-patching.h | 20 ++++++++++++++------ arch/x86/kernel/paravirt.c | 22 +++++----------------- 2 files changed, 19 insertions(+), 23 deletions(-)
--- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -96,32 +96,40 @@ union text_poke_insn { }; static __always_inline -void *text_gen_insn(u8 opcode, const void *addr, const void *dest) +void __text_gen_insn(void *buf, u8 opcode, const void *addr, const void *dest, int size) {
- static union text_poke_insn insn; /* per instance */
- int size = text_opcode_size(opcode);
- union text_poke_insn *insn = buf;
- BUG_ON(size < text_opcode_size(opcode));
/* * Hide the addresses to avoid the compiler folding in constants when * referencing code, these can mess up annotations like * ANNOTATE_NOENDBR. */
- OPTIMIZER_HIDE_VAR(insn); OPTIMIZER_HIDE_VAR(addr); OPTIMIZER_HIDE_VAR(dest);
- insn.opcode = opcode;
- insn->opcode = opcode;
if (size > 1) {
insn.disp = (long)dest - (long)(addr + size);
if (size == 2) { /* * Ensure that for JMP8 the displacement * actually fits the signed byte. */insn->disp = (long)dest - (long)(addr + size);
BUG_ON((insn.disp >> 31) != (insn.disp >> 7));
} }BUG_ON((insn->disp >> 31) != (insn->disp >> 7));
+} +static __always_inline +void *text_gen_insn(u8 opcode, const void *addr, const void *dest) +{
- static union text_poke_insn insn; /* per instance */
- __text_gen_insn(&insn, opcode, addr, dest, text_opcode_size(opcode)); return &insn.text;
} --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -55,28 +55,16 @@ void __init default_banner(void) static const unsigned char ud2a[] = { 0x0f, 0x0b }; struct branch {
- unsigned char opcode;
- u32 delta;
unsigned char opcode;
u32 delta;
} __attribute__((packed)); static unsigned paravirt_patch_call(void *insn_buff, const void *target, unsigned long addr, unsigned len) {
- const int call_len = 5;
- struct branch *b = insn_buff;
- unsigned long delta = (unsigned long)target - (addr+call_len);
- if (len < call_len) {
pr_warn("paravirt: Failed to patch indirect CALL at %ps\n", (void *)addr);
/* Kernel might not be viable if patching fails, bail out: */
BUG_ON(1);
- }
- b->opcode = 0xe8; /* call */
- b->delta = delta;
- BUILD_BUG_ON(sizeof(*b) != call_len);
- return call_len;
- __text_gen_insn(insn_buff, CALL_INSN_OPCODE,
(void *)addr, target, CALL_INSN_SIZE);
- return CALL_INSN_SIZE;
v5.10.211 is failing to build with the attached .config with the following error:
/home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c: In function 'paravirt_patch_call': /home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c:65:9: error: implicit declaration of function '__text_gen_insn' [-Werror=implicit-function-declaration] 65 | __text_gen_insn(insn_buff, CALL_INSN_OPCODE, | ^~~~~~~~~~~~~~~ /home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c:65:36: error: 'CALL_INSN_OPCODE' undeclared (first use in this function) 65 | __text_gen_insn(insn_buff, CALL_INSN_OPCODE, | ^~~~~~~~~~~~~~~~ /home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c:65:36: note: each undeclared identifier is reported only once for each function it appears in /home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c:66:47: error: 'CALL_INSN_SIZE' undeclared (first use in this function) 66 | (void *)addr, target, CALL_INSN_SIZE); | ^~~~~~~~~~~~~~ /home/runner/work/drgn/drgn/build/vmtest/linux.git/arch/x86/kernel/paravirt.c:68:1: error: control reaches end of non-void function [-Werror=return-type] 68 | } | ^
Newer versions include asm/text-patching.h through the include of linux/static-call.h added by a0e2bf7cb700 ("x86/paravirt: Switch time pvops functions to use static_call()"). This code is gone in mainline as of commit f7af6977621a ("x86/paravirt: Remove no longer needed paravirt patching code"). What's the preferred way to resolve this?
Thanks, Omar