objtool/x86: noinstr vs PARAVIRT
Subsystems (14)
Peter Zijlstra
maintainerv2 cover objtool/x86: noinstr vs PARAVIRT
Hi,
Per long standing request from Thomas, this makes the noinstr validation work with PARAVIRT=y.
It isn't exactly pretty, but it does work.
With all this on top of tip/master (which includes some of the previous round), all (*) the robots seem to get is endless garbage like:
vmlinux.o: warning: objtool: __rdgsbase_inactive()+0x24: call to ftrace_likely_update() leaves .noinstr.text section
And my secret plan is to pull the KPTI CR3 swizzling into C such that all that will insta explode and become unfixable.
Steve, can I please delete TRACE_BRANCH_PROFILING and PROFILE_ALL_BRANCHES already?
(*) there were also a few reports from 0day running out of memory.
Peter Zijlstra
maintainerPATCH v2 1/24 x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
The asm_cpu_bringup_and_idle() function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.
The thing is that asm_cpu_bringup_and_idle() doesn't return, so validate_branch() never terminates and falls through to the next function, which in the normal case is the hypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Make asm_cpu_bringup_and_idle() terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -177,6 +177,7 @@ static bool __dead_end_function(struct o"rewind_stack_do_exit" ,"kunit_try_catch_throw" ,"xen_start_kernel" , + "cpu_bringup_and_idle", };if (!func)
Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
In reply to Peter ZijlstraQuoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>
M
Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
In reply to Peter ZijlstraQuoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Looks right. Only problem is, with my assembler I get this:
arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instruction
Because gas insists on jumping over the page of nops...
0000000000000000 <asm_cpu_bringup_and_idle>:
0: e8 00 00 00 00 callq 5 <asm_cpu_bringup_and_idle+0x5>
1: R_X86_64_PLT32 cpu_bringup_and_idle-0x4
5: e9 f6 0f 00 00 jmpq 1000 <xen_hypercall_set_trap_table>
a: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
11: 00 00 00 00
15: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
1c: 00 00 00 00
20: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
27: 00 00 00 00
2b: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
32: 00 00 00 00
36: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
3d: 00 00 00 00 Signature · 1 line
Josh
Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 24 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>Looks right. Only problem is, with my assembler I get this:
arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instructionBecause gas insists on jumping over the page of nops...
0000000000000000 <
asm_cpu_bringup_and_idle>:
Quoted 13 lines
0: e8 00 00 00 00 callq 5 <asm_cpu_bringup_and_idle+0x5>
1: R_X86_64_PLT32 cpu_bringup_and_idle-0x4
5: e9 f6 0f 00 00 jmpq 1000 <xen_hypercall_set_trap_table>
a: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
11: 00 00 00 00
15: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
1c: 00 00 00 00
20: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
27: 00 00 00 00
2b: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
32: 00 00 00 00
36: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1)
3d: 00 00 00 00 Here's a fix:
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] x86/xen: Move hypercall_page to top of the file
Because hypercall_page is page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning of hypercall_page.
That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move hypercall_page to the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.
$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.o
--- arch/x86/xen/xen-head.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
arch/x86/xen/xen-head.S +17 -17
@@ -20,6 +20,23 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> +.pushsection .text + .balign PAGE_SIZE +SYM_CODE_START(hypercall_page) + .rept (PAGE_SIZE / 32) + UNWIND_HINT_FUNC + .skip 31, 0x90 + ret + .endr + +#define HYPERCALL(n) \ + .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ + .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 +#include <asm/xen-hypercalls.h> +#undef HYPERCALL +SYM_CODE_END(hypercall_page) +.popsection + #ifdef CONFIG_XEN_PV __INIT SYM_CODE_START(startup_xen)
@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) #endif #endif -.pushsection .text - .balign PAGE_SIZE -SYM_CODE_START(hypercall_page) - .rept (PAGE_SIZE / 32) - UNWIND_HINT_FUNC - .skip 31, 0x90 - ret - .endr - -#define HYPERCALL(n) \ - .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ - .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 -#include <asm/xen-hypercalls.h> -#undef HYPERCALL -SYM_CODE_END(hypercall_page) -.popsection - ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
Signature · 1 line
2.31.1
Re: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 55 lines · Josh Poimboeuf
Quoted 24 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>Looks right. Only problem is, with my assembler I get this:
arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instructionBecause gas insists on jumping over the page of nops...
0000000000000000 <
asm_cpu_bringup_and_idle>:Quoted 13 lines
0: e8 00 00 00 00 callq 5 <asm_cpu_bringup_and_idle+0x5> 1: R_X86_64_PLT32 cpu_bringup_and_idle-0x4 5: e9 f6 0f 00 00 jmpq 1000 <xen_hypercall_set_trap_table> a: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 11: 00 00 00 00 15: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 1c: 00 00 00 00 20: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 27: 00 00 00 00 2b: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 32: 00 00 00 00 36: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 3d: 00 00 00 00Here's a fix:
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] x86/xen: Movehypercall_pageto top of the fileBecause
hypercall_pageis page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning ofhypercall_page.That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move
hypercall_pageto the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.
Quoted 6 lines
$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.oSigned-off-by Josh Poimboeuf <[email protected]
Juergen
Quoted 57 lines
--- arch/x86/xen/xen-head.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)arch/x86/xen/xen-head.S +17
-17@@ -20,6 +20,23 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> +.pushsection .text + .balign PAGE_SIZE +SYM_CODE_START(hypercall_page) + .rept (PAGE_SIZE / 32) + UNWIND_HINT_FUNC + .skip 31, 0x90 + ret + .endr + +#define HYPERCALL(n) \ + .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ + .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 +#include <asm/xen-hypercalls.h> +#undef HYPERCALL +SYM_CODE_END(hypercall_page) +.popsection + #ifdef CONFIG_XEN_PV __INIT SYM_CODE_START(startup_xen)@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) #endif #endif -.pushsection .text - .balign PAGE_SIZE -SYM_CODE_START(hypercall_page) - .rept (PAGE_SIZE / 32) - UNWIND_HINT_FUNC - .skip 31, 0x90 - ret - .endr - -#define HYPERCALL(n) \ - .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ - .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 -#include <asm/xen-hypercalls.h> -#undef HYPERCALL -SYM_CODE_END(hypercall_page) -.popsection - ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
Juergen Gross
maintainerRe: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 56 lines · Juergen Gross
Quoted 55 lines · Josh Poimboeuf
Quoted 23 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
The
asm_cpu_bringup_and_idle()function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.The thing is that
asm_cpu_bringup_and_idle()doesn't return, sovalidate_branch()never terminates and falls through to the next function, which in the normal case is thehypercall_page. And that, as it happens, is 4095 NOPs and a RET.Quoted 6 lines
Make
asm_cpu_bringup_and_idle()terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.Fixes c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable")Signed-off-by Peter Zijlstra (Intel) <[email protected]>Looks right. Only problem is, with my assembler I get this:
arch/x86/kernel/head_64.o: warning: objtool: .text+0x5: unreachable instructionBecause gas insists on jumping over the page of nops...
Quoted 14 lines
0000000000000000 <
asm_cpu_bringup_and_idle>:
0: e8 00 00 00 00 callq 5 <asm_cpu_bringup_and_idle+0x5> 1: R_X86_64_PLT32 cpu_bringup_and_idle-0x4
5: e9 f6 0f 00 00 jmpq 1000 <xen_hypercall_set_trap_table> a: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 11: 00 00 00 00
15: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 1c: 00 00 00 00
20: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 27: 00 00 00 00
2b: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 32: 00 00 00 00
36: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 3d: 00 00 00 00Here's a fix:
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] x86/xen: Movehypercall_pageto top of the fileBecause
hypercall_pageis page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning ofhypercall_page.That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move
hypercall_pageto the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.
Quoted 8 lines
Quoted 6 lines
$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.oSigned-off-by Josh Poimboeuf <[email protected]Reviewed-by Juergen Gross <[email protected]>
Umm, will this be carried through the tip tree, or shall I take it in the xen tree?
Juergen
Quoted 60 lines
Juergen
Quoted 55 lines
---
arch/x86/xen/xen-head.S| 34 +++++++++++++++++-----------------1 file changed, 17 insertions(+), 17 deletions(-)arch/x86/xen/xen-head.S +17
-0@@ -20,6 +20,23 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> +.pushsection .text + .balign PAGE_SIZE +SYM_CODE_START(hypercall_page) + .rept (PAGE_SIZE / 32) + UNWIND_HINT_FUNC + .skip 31, 0x90 + ret + .endr + +#define HYPERCALL(n) \ + .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ + .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 +#include <asm/xen-hypercalls.h> +#undef HYPERCALL +SYM_CODE_END(hypercall_page) +.popsection + #ifdef CONFIG_XEN_PV
__INIT
SYM_CODE_START(startup_xen)arch/x86/xen/xen-head.S +0
-17@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) #endif #endif -.pushsection .text - .balign PAGE_SIZE -SYM_CODE_START(hypercall_page) - .rept (PAGE_SIZE / 32) - UNWIND_HINT_FUNC - .skip 31, 0x90 - ret - .endr - -#define HYPERCALL(n) \ - .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ - .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 -#include <asm/xen-hypercalls.h> -#undef HYPERCALL -SYM_CODE_END(hypercall_page) -.popsection - ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
Peter Zijlstra
maintainerRe: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 21 lines · Juergen Gross
Quoted 21 lines
Quoted 21 lines
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] x86/xen: Movehypercall_pageto top of the fileBecause
hypercall_pageis page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning ofhypercall_page.That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move
hypercall_pageto the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.o
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Josh Poimboeuf <[email protected]Reviewed-by Juergen Gross <[email protected]>Umm, will this be carried through the tip tree, or shall I take it in the xen tree?
I have it in the whole x86/objtool/paravirt series. I you want it in the Xen tree, I'll be happy to drop it from there, although I hope to get all that merged this cycles somewhere.
Juergen Gross
maintainerRe: [PATCH v2 01/24] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Quoted 24 lines · Peter Zijlstra
Quoted 23 lines · Juergen Gross
Quoted 23 lines
Quoted 22 lines
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] x86/xen: Movehypercall_pageto top of the fileBecause
hypercall_pageis page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning ofhypercall_page.That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move
hypercall_pageto the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.oSigned-off-by Josh Poimboeuf <[email protected]
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
Reviewed-by Juergen Gross <[email protected]>Umm, will this be carried through the tip tree, or shall I take it in the xen tree?
I have it in the whole x86/objtool/paravirt series. I you want it in the Xen tree, I'll be happy to drop it from there, although I hope to get all that merged this cycles somewhere.
Okay, I think it is better kept in your series then.
Juergen
[tip: objtool/core] x86/xen: Move hypercall_page to top of the file
In reply to Josh PoimboeufThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: b7b205c3a0bc2b51f83cb793178ccbc12addf275 Gitweb: https://git.kernel.org/tip/b7b205c3a0bc2b51f83cb793178ccbc12addf275 Author: Josh Poimboeuf <[email protected]> AuthorDate: Fri, 20 Aug 2021 12:31:07 -07:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:44 +02:00
x86/xen: Move hypercall_page to top of the file
Because hypercall_page is page-aligned, the assembler inexplicably adds an unreachable jump from after the end of the previous code to the beginning of hypercall_page.
That confuses objtool, understandably. It also creates significant text fragmentation. As a result, much of the object file is wasted text (nops).
Move hypercall_page to the beginning of the file to both prevent the text fragmentation and avoid the dead jump instruction.
$ size /tmp/head_64.before.o /tmp/head_64.after.o text data bss dec hex filename 10924 307252 4096 322272 4eae0 /tmp/head_64.before.o 6823 307252 4096 318171 4dadb /tmp/head_64.after.o
--- arch/x86/xen/xen-head.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
arch/x86/xen/xen-head.S +17 -17
@@ -20,6 +20,23 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> +.pushsection .text + .balign PAGE_SIZE +SYM_CODE_START(hypercall_page) + .rept (PAGE_SIZE / 32) + UNWIND_HINT_FUNC + .skip 31, 0x90 + ret + .endr + +#define HYPERCALL(n) \ + .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ + .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 +#include <asm/xen-hypercalls.h> +#undef HYPERCALL +SYM_CODE_END(hypercall_page) +.popsection + #ifdef CONFIG_XEN_PV __INIT SYM_CODE_START(startup_xen)
@@ -64,23 +81,6 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) #endif #endif -.pushsection .text - .balign PAGE_SIZE -SYM_CODE_START(hypercall_page) - .rept (PAGE_SIZE / 32) - UNWIND_HINT_FUNC - .skip 31, 0x90 - ret - .endr - -#define HYPERCALL(n) \ - .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \ - .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32 -#include <asm/xen-hypercalls.h> -#undef HYPERCALL -SYM_CODE_END(hypercall_page) -.popsection - ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
[tip: objtool/core] x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 9af9dcf11bda3e2c0e24c1acaacb8685ad974e93 Gitweb: https://git.kernel.org/tip/9af9dcf11bda3e2c0e24c1acaacb8685ad974e93 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:00 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:44 +02:00
x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
The asm_cpu_bringup_and_idle() function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.
The thing is that asm_cpu_bringup_and_idle() doesn't return, so validate_branch() never terminates and falls through to the next function, which in the normal case is the hypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Make asm_cpu_bringup_and_idle() terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -173,6 +173,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,"rewind_stack_do_exit" ,"kunit_try_catch_throw" ,"xen_start_kernel" , + "cpu_bringup_and_idle", };if (!func)
Peter Zijlstra
maintainerPATCH v2 2/24 objtool: Introduce CFI hash
In reply to Peter ZijlstraAndi reported that objtool on vmlinux.o consumes more memory than his system has, leading to horrific performance.
This is in part because we keep a struct instruction for every instruction in the file in-memory. Shrink struct instruction by removing the CFI state (which includes full register state) from it and demand allocating it.
Given most instructions don't actually change CFI state, there's lots of repetition there, so add a hash table to find previous CFI instances.
Reduces memory consumption (and runtime) for processing an x86_64-allyesconfig:
pre: 4:40.84 real, 143.99 user, 44.18 sys, 30624988 mem post: 2:14.61 real, 108.58 user, 25.04 sys, 16396184 mem
--- tools/objtool/arch/x86/decode.c | 2 tools/objtool/check.c | 155 ++++++++++++++++++++++++++++++---- tools/objtool/include/objtool/cfi.h | 2 tools/objtool/include/objtool/check.h | 4 tools/objtool/orc_gen.c | 15 ++- 5 files changed, 154 insertions(+), 24 deletions(-)
tools/objtool/arch/x86/decode.c +1 -1
@@ -781,7 +781,7 @@ int arch_rewrite_retpolines(struct objtoint arch_decode_hint_reg (struct instruction *insn,u8 sp_reg) { -struct cfi_reg *cfa = &insn->cfi.cfa; +struct cfi_reg *cfa = &insn->cfip->cfa;switch (sp_reg) {case ORC_REG_UNDEFINED :
tools/objtool/check.c +137 -18
273 lines not on this page · raw message
tools/objtool/include/objtool/cfi.h +2 -0
@@ -7,6 +7,7 @@#define _OBJTOOL_CFI_H#include <arch/cfi_regs.h> +#include <linux/list.h> #define CFI_UNDEFINED -1#define CFI_CFA -2
@@ -24,6 +25,7 @@ struct cfi_init_state { };struct cfi_state { +struct hlist_node hash;/* must be first, cficmp() */ struct cfi_reg regs[CFI_NUM_REGS ];struct cfi_reg vals[CFI_NUM_REGS ];struct cfi_reg cfa;
tools/objtool/include/objtool/check.h +3 -1
@@ -60,9 +60,11 @@ struct instruction {struct list_head alts;struct symbol *func;struct list_head stack_ops; -struct cfi_state cfi; +struct cfi_state *cfip; }; +extern struct cfi_state *insn_get_cfi (struct instruction *); +static inline bool is_static_jump (struct instruction *insn) { return insn->type == INSN_JUMP_CONDITIONAL ||
tools/objtool/orc_gen.c +11 -4
@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc)); +if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } + orc->end = cfi->end;if (cfi->cfa.base ==CFI_UNDEFINED ) {
@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *fileint i;if (!alt_group) { -if (init_orc_entry (&orc, &insn->cfi)) +if (init_orc_entry (&orc, insn->cfip, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *filestruct cfi_state *cfi = alt_group->cfi[i];if (!cfi)continue ; -if (init_orc_entry (&orc, cfi)) +/* errors are reported on the original insn */ +if (init_orc_entry (&orc, cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
Re: [PATCH v2 02/24] objtool: Introduce CFI hash
tools/objtool/check.c static int validate_branch(struct objtoo · line 2824
Quoted 7 lines
tools/objtool/check.c +2
-1@@ -2725,15 +2820,24 @@ static int validate_branch(struct objtooif (insn->visited & visited)return 0 ; - } + }else + nr_visited++;
just a coding style
} else {
nr_visited++;
}tools/objtool/check.c int check(struct objtool_file *file) · line 3308
Quoted 6 lines
tools/objtool/check.c +2
-0@@ -3192,6 +3304,13 @@ int check(struct objtool_file *file) warnings += ret; } +if (stats) { +printf ("nr_visited: %ld\n" , nr_visited);
Could we make this nr_insns_visited?
Quoted 15 lines
tools/objtool/check.c +8
-2+printf ("nr_cfi: %ld\n" , nr_cfi); +printf ("nr_cfi_reused: %ld\n" , nr_cfi_reused); +printf ("nr_cfi_cache: %ld\n" , nr_cfi_cache); + } + +++ b/tools/objtool/orc_gen.c@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);
tools/objtool/check.c line 28
Quoted 10 lines
tools/objtool/check.c +6
-0struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc)); +if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } +
This looks strange. You access cfi a couple of lines earlier (bp cfi_reg initialization).
Is it even possible to have cfi == NULL here? The second call site below has a check and the first one should not happen (insn->cfip should be always set if I am not missing something).
Quoted 13 lines
tools/objtool/orc_gen.c +1
-1orc->end = cfi->end;if (cfi->cfa.base ==CFI_UNDEFINED ) {@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *fileint i;if (!alt_group) { -if (init_orc_entry (&orc, &insn->cfi)) +if (init_orc_entry (&orc, insn->cfip, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
tools/objtool/orc_gen.c int orc_create(struct objtool_file *file · line 199
Quoted 9 lines
tools/objtool/orc_gen.c +2
-1@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *filestruct cfi_state *cfi = alt_group->cfi[i];if (!cfi)continue ; -if (init_orc_entry (&orc, cfi)) +/* errors are reported on the original insn */ +if (init_orc_entry (&orc, cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
Anyway, this is a nice improvement.
Miroslav
Peter Zijlstra
maintainerRe: [PATCH v2 02/24] objtool: Introduce CFI hash
Quoted 14 lines · Miroslav Benes
tools/objtool/check.c static int validate_branch(struct objtoo · line 2824
Quoted 7 lines
tools/objtool/check.c +2
-1@@ -2725,15 +2820,24 @@ static int validate_branch(struct objtooif (insn->visited & visited)return 0 ; - } + }else + nr_visited++;just a coding style
} else { nr_visited++; }
Quoted 8 lines
tools/objtool/check.c int check(struct objtool_file *file) · line 3308
Quoted 6 lines
tools/objtool/check.c +2
-0@@ -3192,6 +3304,13 @@ int check(struct objtool_file *file) warnings += ret; } +if (stats) { +printf ("nr_visited: %ld\n" , nr_visited);Could we make this
nr_insns_visited?
Both done.
Quoted 19 lines
Quoted 19 lines
tools/objtool/check.c +8
-2+printf ("nr_cfi: %ld\n" , nr_cfi); +printf ("nr_cfi_reused: %ld\n" , nr_cfi_reused); +printf ("nr_cfi_cache: %ld\n" , nr_cfi_cache); + } + +++ b/tools/objtool/orc_gen.c@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc));
Quoted 9 lines
tools/objtool/orc_gen.c line 28
Quoted 6 lines
tools/objtool/orc_gen.c +6
-0+if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } +This looks strange. You access cfi a couple of lines earlier (bp
cfi_reginitialization).
That's a relative address compute, it doesn't actually dereference the pointer.
Quoted 3 lines
Is it even possible to have cfi == NULL here? The second call site below has a check and the first one should not happen (
insn->cfipshould be always set if I am not missing something).
I can happen for instructions that are not visited, like NOP fillers between functions. Remove the check and try to build a file :-)
Re: [PATCH v2 02/24] objtool: Introduce CFI hash
Quoted 24 lines
Quoted 14 lines
Quoted 14 lines
+++
b/tools/objtool/orc_gen.ctools/objtool/orc_gen.c +2
-2@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc));Quoted 9 lines
tools/objtool/orc_gen.c line 28
Quoted 6 lines
tools/objtool/orc_gen.c +6
-0+if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } +This looks strange. You access cfi a couple of lines earlier (bp
cfi_reginitialization).
Quoted 2 lines
That's a relative address compute, it doesn't actually dereference the pointer.
Right, I misread the line.
Quoted 6 lines
Quoted 3 lines
Is it even possible to have cfi == NULL here? The second call site below has a check and the first one should not happen (
insn->cfipshould be always set if I am not missing something).I can happen for instructions that are not visited, like NOP fillers between functions. Remove the check and try to build a file :-)
Doh, I should have done that. Of course there must be unvisited instructions. Sorry for the noise.
Miroslav
Re: [PATCH v2 02/24] objtool: Introduce CFI hash
In reply to Peter ZijlstraQuoted 12 lines · Peter Zijlstra
Andi reported that objtool on vmlinux.o consumes more memory than his system has, leading to horrific performance.
This is in part because we keep a struct instruction for every instruction in the file in-memory. Shrink struct instruction by removing the CFI state (which includes full register state) from it and demand allocating it.
Given most instructions don't actually change CFI state, there's lots of repetition there, so add a hash table to find previous CFI instances.
Quoted 5 lines
Reduces memory consumption (and runtime) for processing an x86_64-allyesconfig:
pre: 4:40.84 real, 143.99 user, 44.18 sys, 30624988 mem post: 2:14.61 real, 108.58 user, 25.04 sys, 16396184 mem
Excellent.
tools/objtool/check.c static void init_insn_state(struct insn_ · line 282
Quoted 11 lines
tools/objtool/check.c +11
-0+static struct cfi_state *cfi_alloc (void ) +{ +struct cfi_state *cfi =calloc (sizeof (struct cfi_state ),1 ); +if (!cfi) { +WARN ("calloc failed" ); +exit (1 ); + } + nr_cfi++; +init_cfi_state (cfi); +return cfi; +}
I'm thinking this should also add it to the hash. i.e. I don't think there's a scenario where you'd alloc a cfi and not want to add it to the hash. The more sharing the better.
tools/objtool/check.c static void init_insn_state(struct insn_ · line 290
Quoted 8 lines
tools/objtool/check.c +8
-0+ +struct cfi_state *insn_get_cfi (struct instruction *insn) +{ +if (!insn->cfip) + insn->cfip =cfi_alloc (); + +return insn->cfip; +}
Call it something like insn_get_or_alloc_cfi()?
Also, the function can be static.
Quoted 7 lines
tools/objtool/check.c +7
-0+static struct cfi_state *cfi_hash_find (struct cfi_state *cfi) +{ +struct hlist_head *head = &cfi_hash[hash_min (cfi_key (cfi), cfi_bits)]; +struct cfi_state *obj; + +hlist_for_each_entry (obj, head, hash) { +if (!cficmp (cfi, obj)) {
tools/objtool/check.c static void init_insn_state(struct insn_ · line 324
Quoted 10 lines
tools/objtool/check.c +10
-0+ nr_cfi_cache++; +return obj; + } + } + + obj =cfi_alloc (); + *obj = *cfi; +hlist_add_head (&obj->hash, head); + +return obj;
cfi_hash_find_or_alloc_cfi()?
Quoted 9 lines
tools/objtool/check.c +2
-1@@ -2725,15 +2820,24 @@ static int validate_branch(struct objtooif (insn->visited & visited)return 0 ; - } + }else + nr_visited++;if (state.noinstr)
tools/objtool/check.c static int validate_branch(struct objtoo · line 2832
Quoted 10 lines
tools/objtool/check.c +4
-4state.instr += insn->instr; -if (insn->hint) - state.cfi = insn->cfi; -else - insn->cfi = state.cfi; +if (insn->hint) { + state.cfi = *insn->cfip; + }else { +/* XXX track if we actually changed state.cfi */
Why would we do that?
tools/objtool/include/objtool/check.h struct instruction { · line 63
Quoted 7 lines
tools/objtool/include/objtool/check.h +2
-1+++ b/tools/objtool/include/objtool/check.h@@ -60,9 +60,11 @@ struct instruction {struct list_head alts;struct symbol *func;struct list_head stack_ops; -struct cfi_state cfi; +struct cfi_state *cfip;
Not sure about this rename. Pointers generally don't need a 'p' postfix.
Signature · 1 line
Josh
Peter Zijlstra
maintainerRe: [PATCH v2 02/24] objtool: Introduce CFI hash
Quoted 7 lines · Josh Poimboeuf
Quoted 7 lines
(quoted diff) +7
-0+static struct cfi_state *cfi_alloc(void) +{ + struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1); + if (!cfi) { + WARN("calloc failed"); + exit(1); + }
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+ nr_cfi++; + init_cfi_state(cfi); + return cfi; +}I'm thinking this should also add it to the hash. i.e. I don't think there's a scenario where you'd alloc a cfi and not want to add it to the hash. The more sharing the better.
Right, changed it like below.
Quoted 11 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ +struct cfi_state *insn_get_cfi(struct instruction *insn) +{ + if (!insn->cfip) + insn->cfip = cfi_alloc(); + + return insn->cfip; +}Call it something like
insn_get_or_alloc_cfi()?
Quoted 1 line
Also, the function can be static.
It's gone now.
Quoted 11 lines
Quoted 11 lines
(quoted diff) +11
-0+static struct cfi_state *cfi_hash_find(struct cfi_state *cfi) +{ + struct hlist_head *head = &cfi_hash[hash_min(cfi_key(cfi), cfi_bits)]; + struct cfi_state *obj; + + hlist_for_each_entry(obj, head, hash) { + if (!cficmp(cfi, obj)) { + nr_cfi_cache++; + return obj; + } + }
Quoted 8 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ + obj = cfi_alloc(); + *obj = *cfi; + hlist_add_head(&obj->hash, head); + + return obj;
cfi_hash_find_or_alloc_cfi()?
Made that cfi_hash_find_or_add()
tools/objtool/check.c +10 -7
@@ -30,6 +30,7 @@ struct alternative {static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache;static struct cfi_init_state initial_func_cfi; +static struct cfi_state init_cfi;static struct cfi_state func_cfi; struct instruction *find_insn(struct objtool_file *file,
@@ -278,7 +279,6 @@ static struct cfi_state *cfi_alloc(void)exit (1 ); } nr_cfi++; -init_cfi_state (cfi);return cfi; }
@@ -298,7 +298,7 @@ static inline u32 cfi_key(struct cfi_sta sizeof(*cfi) - sizeof(cfi->hash), 0); } -static struct cfi_state *cfi_hash_find (struct cfi_state *cfi) +static struct cfi_state *cfi_hash_find_or_add (struct cfi_state *cfi) {struct hlist_head *head = &cfi_hash[hash_min (cfi_key (cfi), cfi_bits)];struct cfi_state *obj;
@@ -1620,10 +1620,10 @@ static void set_func_state(struct cfi_ststatic int read_unwind_hints (struct objtool_file *file) { +struct cfi_state cfi = init_cfi;struct section *sec, *relocsec;struct unwind_hint *hint;struct instruction *insn; -struct cfi_state *cfi;struct reloc *reloc;int i;
@@ -1666,9 +1666,8 @@ static int read_unwind_hints(struct objtcontinue ; } - cfi = insn->cfip; -if (!cfi) - cfi = insn->cfip =cfi_alloc (); +if (insn->cfip) + cfi = *(insn->cfip);if (arch_decode_hint_reg (insn, hint->sp_reg)) { WARN_FUNC("unsupported unwind_hint sp base reg %d",
@@ -1679,6 +1678,8 @@ static int read_unwind_hints(struct objt cfi->cfa.offset =bswap_if_needed (hint->sp_offset); cfi->type = hint->type; cfi->end = hint->end; + + insn->cfip =cfi_hash_find_or_add (&cfi); }return 0 ;
@@ -2831,7 +2832,7 @@ static int validate_branch(struct objtoo insn->cfip = prev_insn->cfip; nr_cfi_reused++; }else { - insn->cfip =cfi_hash_find (&state.cfi); + insn->cfip =cfi_hash_find_or_add (&state.cfi); } }
@@ -3239,6 +3240,7 @@ int check(struct objtool_file *file)int ret, warnings =0 ;arch_initial_func_cfi_state (&initial_func_cfi); +init_cfi_state (&init_cfi);init_cfi_state (&func_cfi);set_func_state (&func_cfi);
@@ -3250,6 +3252,7 @@ int check(struct objtool_file *file)if (!cfi_hash_alloc (1UL << (file->elf->symbol_bits -3 ))) goto out; +cfi_hash_add (&init_cfi);cfi_hash_add (&func_cfi);if (list_empty (&file->insn_list))
Peter Zijlstra
maintainerRe: [PATCH v2 02/24] objtool: Introduce CFI hash
Quoted 19 lines · Peter Zijlstra
Quoted 15 lines · Josh Poimboeuf
Review
Quoted 11 lines
(quoted diff) +11
-0+static struct cfi_state *cfi_alloc(void) +{ + struct cfi_state *cfi = calloc(sizeof(struct cfi_state), 1); + if (!cfi) { + WARN("calloc failed"); + exit(1); + } + nr_cfi++; + init_cfi_state(cfi); + return cfi; +}I'm thinking this should also add it to the hash. i.e. I don't think there's a scenario where you'd alloc a cfi and not want to add it to the hash. The more sharing the better.
tools/objtool/check.c static int read_unwind_hints(struct objt · line 1671
Quoted 6 lines
tools/objtool/check.c +0
-3@@ -1666,9 +1666,8 @@ static int read_unwind_hints(struct objtcontinue ; } - cfi = insn->cfip; -if (!cfi) - cfi = insn->cfip =cfi_alloc ();
Urgh, the problem is that this runs before we allocate the hash-table! Lemme try and re-order thing.
Peter Zijlstra
maintainerRe: [PATCH v2 02/24] objtool: Introduce CFI hash
In reply to Josh PoimboeufQuoted 11 lines · Josh Poimboeuf
Quoted 11 lines
tools/objtool/check.c +2
-1@@ -2725,15 +2820,24 @@ static int validate_branch(struct objtooif (insn->visited & visited)return 0 ; - } + }else + nr_visited++;if (state.noinstr) state.instr += insn->instr;
Quoted 10 lines
tools/objtool/check.c static int validate_branch(struct objtoo · line 2832
Quoted 8 lines
tools/objtool/check.c +4
-4-if (insn->hint) - state.cfi = insn->cfi; -else - insn->cfi = state.cfi; +if (insn->hint) { + state.cfi = *insn->cfip; + }else { +/* XXX track if we actually changed state.cfi */ Why would we do that?
Saves on the memcmp()..
Quoted 9 lines
tools/objtool/include/objtool/check.h struct instruction { · line 63
Quoted 7 lines
tools/objtool/include/objtool/check.h +2
-1+++ b/tools/objtool/include/objtool/check.h@@ -60,9 +60,11 @@ struct instruction {struct list_head alts;struct symbol *func;struct list_head stack_ops; -struct cfi_state cfi; +struct cfi_state *cfip;Not sure about this rename. Pointers generally don't need a 'p' postfix.
It was a dev thing, meant I typically rename a member when I change type; easy for compiler and grep.
I can s/cfip/cfi/ on the patch, no biggie.
[tip: objtool/core] objtool: Introduce CFI hash
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 8b946cc38e063f0f7bb67789478c38f6d7d457c9 Gitweb: https://git.kernel.org/tip/8b946cc38e063f0f7bb67789478c38f6d7d457c9 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:01 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00
objtool: Introduce CFI hash
Andi reported that objtool on vmlinux.o consumes more memory than his system has, leading to horrific performance.
This is in part because we keep a struct instruction for every instruction in the file in-memory. Shrink struct instruction by removing the CFI state (which includes full register state) from it and demand allocating it.
Given most instructions don't actually change CFI state, there's lots of repetition there, so add a hash table to find previous CFI instances.
Reduces memory consumption (and runtime) for processing an x86_64-allyesconfig:
pre: 4:40.84 real, 143.99 user, 44.18 sys, 30624988 mem post: 2:14.61 real, 108.58 user, 25.04 sys, 16396184 mem
--- tools/objtool/arch/x86/decode.c | 20 +-- tools/objtool/check.c | 154 ++++++++++++++++++++++--- tools/objtool/include/objtool/arch.h | 2 +- tools/objtool/include/objtool/cfi.h | 2 +- tools/objtool/include/objtool/check.h | 2 +- tools/objtool/orc_gen.c | 15 +- 6 files changed, 160 insertions(+), 35 deletions(-)
tools/objtool/arch/x86/decode.c +9 -11
@@ -779,34 +779,32 @@ int arch_rewrite_retpolines(struct objtool_file *file)return 0 ; } -int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg) +int arch_decode_hint_reg (u8 sp_reg,int *base) { -struct cfi_reg *cfa = &insn->cfi.cfa; -switch (sp_reg) {case ORC_REG_UNDEFINED : - cfa->base =CFI_UNDEFINED ; + *base =CFI_UNDEFINED ;break ;case ORC_REG_SP : - cfa->base =CFI_SP ; + *base =CFI_SP ;break ;case ORC_REG_BP : - cfa->base =CFI_BP ; + *base =CFI_BP ;break ;case ORC_REG_SP_INDIRECT : - cfa->base =CFI_SP_INDIRECT ; + *base =CFI_SP_INDIRECT ;break ;case ORC_REG_R10 : - cfa->base =CFI_R10 ; + *base =CFI_R10 ;break ;case ORC_REG_R13 : - cfa->base =CFI_R13 ; + *base =CFI_R13 ;break ;case ORC_REG_DI : - cfa->base =CFI_DI ; + *base =CFI_DI ;break ;case ORC_REG_DX : - cfa->base =CFI_DX ; + *base =CFI_DX ;break ;default :return -1 ;
tools/objtool/check.c +136 -18
271 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -1
@@ -83,7 +83,7 @@ unsigned long arch_dest_reloc_offset(int addend);const char *arch_nop_insn (int len); -int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg); +int arch_decode_hint_reg (u8 sp_reg,int *base);bool arch_is_retpoline (struct symbol *sym);
tools/objtool/include/objtool/cfi.h +2 -0
@@ -7,6 +7,7 @@#define _OBJTOOL_CFI_H#include <arch/cfi_regs.h> +#include <linux/list.h> #define CFI_UNDEFINED -1#define CFI_CFA -2
@@ -24,6 +25,7 @@ struct cfi_init_state { };struct cfi_state { +struct hlist_node hash;/* must be first, cficmp() */ struct cfi_reg regs[CFI_NUM_REGS ];struct cfi_reg vals[CFI_NUM_REGS ];struct cfi_reg cfa;
tools/objtool/include/objtool/check.h +1 -1
@@ -60,7 +60,7 @@ struct instruction {struct list_head alts;struct symbol *func;struct list_head stack_ops; -struct cfi_state cfi; +struct cfi_state *cfi; };static inline bool is_static_jump (struct instruction *insn)
tools/objtool/orc_gen.c +11 -4
@@ -13,13 +13,19 @@#include <objtool/warn.h> #include <objtool/endianness.h> -static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi) +static int init_orc_entry (struct orc_entry *orc,struct cfi_state *cfi, +struct instruction *insn) { - struct instruction *insn = container_of(cfi, struct instruction, cfi);struct cfi_reg *bp = &cfi->regs[CFI_BP ];memset (orc,0 ,sizeof (*orc)); +if (!cfi) { + orc->end =0 ; + orc->sp_reg =ORC_REG_UNDEFINED ; +return 0 ; + } + orc->end = cfi->end;if (cfi->cfa.base ==CFI_UNDEFINED ) {
@@ -162,7 +168,7 @@ int orc_create(struct objtool_file *file)int i;if (!alt_group) { -if (init_orc_entry (&orc, &insn->cfi)) +if (init_orc_entry (&orc, insn->cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
@@ -186,7 +192,8 @@ int orc_create(struct objtool_file *file)struct cfi_state *cfi = alt_group->cfi[i];if (!cfi)continue ; -if (init_orc_entry (&orc, cfi)) +/* errors are reported on the original insn */ +if (init_orc_entry (&orc, cfi, insn))return -1 ;if (!memcmp (&prev_orc, &orc,sizeof (orc)))continue ;
Peter Zijlstra
maintainerPATCH v2 3/24 objtool: Handle __sanitize_cov*() tail calls
In reply to Peter ZijlstraTurns out the compilers also generate tail calls to __sanitize_cov*(), make sure to also patch those out in noinstr code.
--- tools/objtool/arch/x86/decode.c | 20 ++++ tools/objtool/check.c | 153 ++++++++++++++++++----------------- tools/objtool/include/objtool/arch.h | 1 3 files changed, 100 insertions(+), 74 deletions(-)
tools/objtool/arch/x86/decode.c +20 -0
@@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)return nops[len-1 ]; } +#define BYTE_RET 0xC3 + +const char *arch_ret_insn (int len) +{ +static const char ret[5 ][5 ] = { + {BYTE_RET }, + {BYTE_RET ,BYTES_NOP1 }, + {BYTE_RET ,BYTES_NOP2 }, + {BYTE_RET ,BYTES_NOP3 }, + {BYTE_RET ,BYTES_NOP4 }, + }; + +if (len <1 || len >5 ) { +WARN ("invalid RET size: %d\n" , len); +return NULL ; + } + +return ret[len-1 ]; +} +/* asm/alternative.h ? */ #define ALTINSTR_FLAG_INV (1 << 15)
tools/objtool/check.c +79 -74
208 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -0
@@ -82,6 +82,7 @@ unsigned long arch_jump_destination(struunsigned long arch_dest_reloc_offset (int addend);const char *arch_nop_insn (int len); +const char *arch_ret_insn (int len);int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg);
Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
Quoted 5 lines · Peter Zijlstra
Turns out the compilers also generate tail calls to __sanitize_cov*(), make sure to also patch those out in noinstr code.
Fixes 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Thanks! More reason to not even try to do the same for other architectures, and the compiler needing the attribute...
Quoted 266 lines
--- tools/objtool/arch/x86/decode.c | 20 ++++ tools/objtool/check.c | 153 ++++++++++++++++++----------------- tools/objtool/include/objtool/arch.h | 1 3 files changed, 100 insertions(+), 74 deletions(-)tools/objtool/arch/x86/decode.c +20
-0@@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)return nops[len-1 ]; } +#define BYTE_RET 0xC3 + +const char *arch_ret_insn (int len) +{ +static const char ret[5 ][5 ] = { + {BYTE_RET }, + {BYTE_RET ,BYTES_NOP1 }, + {BYTE_RET ,BYTES_NOP2 }, + {BYTE_RET ,BYTES_NOP3 }, + {BYTE_RET ,BYTES_NOP4 }, + }; + +if (len <1 || len >5 ) { +WARN ("invalid RET size: %d\n" , len); +return NULL ; + } + +return ret[len-1 ]; +} +/* asm/alternative.h ? */ #define ALTINSTR_FLAG_INV (1 << 15)tools/objtool/check.c +79
-74@@ -828,6 +828,74 @@ static struct reloc *insn_reloc(struct oreturn insn->reloc; } +static void remove_insn_ops (struct instruction *insn) +{ +struct stack_op *op, *tmp; + +list_for_each_entry_safe (op, tmp, &insn->stack_ops, list) { +list_del (&op->list); +free (op); + } +} + +static void add_call_dest (struct objtool_file *file,struct instruction *insn, +struct symbol *dest,bool sibling) +{ +struct reloc *reloc =insn_reloc (file, insn); + + insn->call_dest = dest; +if (!dest) +return ; + +if (insn->call_dest->static_call_tramp) { +list_add_tail (&insn->call_node, + &file->static_call_list); + } + +if (insn->sec->noinstr && + !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } + +elf_write_insn (file->elf, insn->sec, + insn->offset, insn->len, + sibling ?arch_ret_insn (insn->len) + :arch_nop_insn (insn->len)); + + insn->type = sibling ?INSN_RETURN :INSN_NOP ; + } + +if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { +if (sibling) +WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset); + +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } + +elf_write_insn (file->elf, insn->sec, + insn->offset, insn->len, +arch_nop_insn (insn->len)); + + insn->type =INSN_NOP ; + +list_add_tail (&insn->mcount_loc_node, + &file->mcount_loc_list); + } + +/* +* Whatever stack impact regular CALLs have, should be undone +* by the RETURN of the called function. +* +* Annotated intra-function calls retain the stack_ops but +* are converted to JUMP, see read_intra_function_calls(). +*/ +remove_insn_ops (insn); +} +/* * Find the destination instructions for all jumps. */ @@ -866,11 +934,7 @@ static int add_jump_destinations(structcontinue ; }else if (insn->func) {/* internal or external sibling call (with reloc) */ - insn->call_dest = reloc->sym; -if (insn->call_dest->static_call_tramp) { -list_add_tail (&insn->call_node, - &file->static_call_list); - } +add_call_dest (file, insn, reloc->sym, true);continue ; }else if (reloc->sym->sec->idx) { dest_sec = reloc->sym->sec;@@ -926,13 +990,8 @@ static int add_jump_destinations(struct }else if (insn->jump_dest->func->pfunc != insn->func->pfunc && insn->jump_dest->offset == insn->jump_dest->func->offset) { -/* internal sibling call (without reloc) */ - insn->call_dest = insn->jump_dest->func; -if (insn->call_dest->static_call_tramp) { -list_add_tail (&insn->call_node, - &file->static_call_list); - } +add_call_dest (file, insn, insn->jump_dest->func, true); } } }@@ -940,16 +999,6 @@ static int add_jump_destinations(structreturn 0 ; } -static void remove_insn_ops (struct instruction *insn) -{ -struct stack_op *op, *tmp; - -list_for_each_entry_safe (op, tmp, &insn->stack_ops, list) { -list_del (&op->list); -free (op); - } -} -static struct symbol *find_call_destination (struct section *sec,unsigned long offset) {struct symbol *call_dest;@@ -968,6 +1017,7 @@ static int add_call_destinations(struct {struct instruction *insn;unsigned long dest_off; +struct symbol *dest;struct reloc *reloc;for_each_insn (file, insn) {@@ -977,7 +1027,9 @@ static int add_call_destinations(struct reloc =insn_reloc (file, insn);if (!reloc) { dest_off =arch_jump_destination (insn); - insn->call_dest =find_call_destination (insn->sec, dest_off); + dest =find_call_destination (insn->sec, dest_off); + +add_call_dest (file, insn, dest, false);if (insn->ignore)continue ;@@ -995,9 +1047,8 @@ static int add_call_destinations(struct }else if (reloc->sym->type ==STT_SECTION ) { dest_off =arch_dest_reloc_offset (reloc->addend); - insn->call_dest =find_call_destination (reloc->sym->sec, - dest_off); -if (!insn->call_dest) { + dest =find_call_destination (reloc->sym->sec, dest_off); +if (!dest) { WARN_FUNC("can't find call dest symbol at %s+0x%lx", insn->sec, insn->offset, reloc->sym->sec->name,@@ -1005,6 +1056,8 @@ static int add_call_destinations(structreturn -1 ; } +add_call_dest (file, insn, dest, false); + }else if (arch_is_retpoline (reloc->sym)) {/* * Retpoline calls are really dynamic calls in @@ -1020,55 +1073,7 @@ static int add_call_destinations(structcontinue ; }else - insn->call_dest = reloc->sym; - -if (insn->call_dest && insn->call_dest->static_call_tramp) { -list_add_tail (&insn->call_node, - &file->static_call_list); - } - -/* -* Many compilers cannot disable KCOV with a function attribute -* so they need a little help, NOP out any KCOV calls from noinstr -* text. -*/ -if (insn->sec->noinstr && - !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { -if (reloc) { - reloc->type =R_NONE ; -elf_write_reloc (file->elf, reloc); - } - -elf_write_insn (file->elf, insn->sec, - insn->offset, insn->len, -arch_nop_insn (insn->len)); - insn->type =INSN_NOP ; - } - -if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { -if (reloc) { - reloc->type =R_NONE ; -elf_write_reloc (file->elf, reloc); - } - -elf_write_insn (file->elf, insn->sec, - insn->offset, insn->len, -arch_nop_insn (insn->len)); - - insn->type =INSN_NOP ; - -list_add_tail (&insn->mcount_loc_node, - &file->mcount_loc_list); - } - -/* -* Whatever stack impact regular CALLs have, should be undone -* by the RETURN of the called function. -* -* Annotated intra-function calls retain the stack_ops but -* are converted to JUMP, see read_intra_function_calls(). -*/ -remove_insn_ops (insn); +add_call_dest (file, insn, reloc->sym, false); }return 0 ;tools/objtool/include/objtool/arch.h +1
-0@@ -82,6 +82,7 @@ unsigned long arch_jump_destination(struunsigned long arch_dest_reloc_offset (int addend);const char *arch_nop_insn (int len); +const char *arch_ret_insn (int len);int arch_decode_hint_reg (struct instruction *insn,u8 sp_reg);
Peter Zijlstra
maintainerRe: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
Quoted 11 lines · Marco Elver
Quoted 5 lines · Peter Zijlstra
Turns out the compilers also generate tail calls to __sanitize_cov*(), make sure to also patch those out in noinstr code.
Fixes 0f1441b44e82 ("objtool: Fix noinstr vs KCOV")Signed-off-by Peter Zijlstra (Intel) <[email protected]>Acked-by Marco Elver <[email protected]>Thanks! More reason to not even try to do the same for other architectures, and the compiler needing the attribute...
Agreed!
Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
In reply to Peter ZijlstraQuoted 22 lines · On Thu, 24 Jun 2021 11:41:02 +0200 Peter Zijlstra <[email protected]> wrote:
tools/objtool/check.c +22
-0+static void add_call_dest (struct objtool_file *file,struct instruction *insn, +struct symbol *dest,bool sibling) +{ +struct reloc *reloc =insn_reloc (file, insn); + + insn->call_dest = dest; +if (!dest) +return ; + +if (insn->call_dest->static_call_tramp) { +list_add_tail (&insn->call_node, + &file->static_call_list); + } + +if (insn->sec->noinstr && + !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } + + elf_write_insn(file->elf, insn->sec,
tools/objtool/check.c static struct reloc *insn_reloc(struct o · line 872
Quoted 10 lines
tools/objtool/check.c +10
-0+ insn->offset, insn->len, + sibling ?arch_ret_insn (insn->len) + : arch_nop_insn(insn->len)); + + insn->type = sibling ?INSN_RETURN :INSN_NOP ; + } + +if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { +if (sibling) +WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset);
Have you ever triggered the above?
-- Steve
Quoted 6 lines
tools/objtool/check.c +6
-0+ +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } +
Peter Zijlstra
maintainerRe: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
Quoted 29 lines · Steven Rostedt
Quoted 26 lines · On Thu, 24 Jun 2021 11:41:02 +0200 Peter Zijlstra <[email protected]> wrote:
tools/objtool/check.c +26
-0+static void add_call_dest (struct objtool_file *file,struct instruction *insn, +struct symbol *dest,bool sibling) +{ +struct reloc *reloc =insn_reloc (file, insn); + + insn->call_dest = dest; +if (!dest) +return ; + +if (insn->call_dest->static_call_tramp) { +list_add_tail (&insn->call_node, + &file->static_call_list); + } + +if (insn->sec->noinstr && + !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } + +elf_write_insn (file->elf, insn->sec, + insn->offset, insn->len, + sibling ?arch_ret_insn (insn->len) + :arch_nop_insn (insn->len)); +
Quoted 8 lines
tools/objtool/check.c static struct reloc *insn_reloc(struct o · line 872
Quoted 6 lines
tools/objtool/check.c +6
-0+ insn->type = sibling ?INSN_RETURN :INSN_NOP ; + } + +if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { +if (sibling) +WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset);Have you ever triggered the above?
No, that would be really daft. But since this function is to be called for both regular and tail calls, I figured I'd at least pretend to handle the case.
Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
Quoted 9 lines · On Sat, 26 Jun 2021 10:18:12 +0200 Peter Zijlstra <[email protected]> wrote:
Quoted 5 lines
tools/objtool/check.c static struct reloc *insn_reloc(struct o · line 872
Quoted 3 lines
tools/objtool/check.c +3
-0+if (mcount && !strcmp (insn->call_dest->name,"__fentry__" )) { +if (sibling) +WARN_FUNC ("Tail call to __fentry__ !?!?" , insn->sec, insn->offset);Have you ever triggered the above?
No, that would be really daft. But since this function is to be called for both regular and tail calls, I figured I'd at least pretend to handle the case.
OK. I thought this was like one of those weird laws that were made because you know that someone did something really stupid once.
-- Steve
Re: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
In reply to Peter ZijlstraQuoted 4 lines · Peter Zijlstra
tools/objtool/check.c +4
-0+if (insn->sec->noinstr && + !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (reloc) { + reloc->type =R_NONE ;
tools/objtool/check.c static struct reloc *insn_reloc(struct o · line 868
Quoted 10 lines
tools/objtool/check.c +10
-0+elf_write_reloc (file->elf, reloc); + } + +elf_write_insn (file->elf, insn->sec, + insn->offset, insn->len, + sibling ?arch_ret_insn (insn->len) + :arch_nop_insn (insn->len)); + + insn->type = sibling ?INSN_RETURN :INSN_NOP ; + }
It'd be nice to keep the comment for this case that was in add_call_destinations().
Signature · 1 line
Josh
Peter Zijlstra
maintainerRe: [PATCH v2 03/24] objtool: Handle __sanitize_cov*() tail calls
Quoted 10 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
tools/objtool/check.c +9
-0+if (insn->sec->noinstr && + !strncmp (insn->call_dest->name,"__sanitizer_cov_" ,16 )) { +if (reloc) { + reloc->type =R_NONE ; +elf_write_reloc (file->elf, reloc); + } + + elf_write_insn(file->elf, insn->sec, + insn->offset, insn->len,
Quoted 8 lines
tools/objtool/check.c static struct reloc *insn_reloc(struct o · line 868
Quoted 5 lines
tools/objtool/check.c +5
-0+ sibling ?arch_ret_insn (insn->len) + : arch_nop_insn(insn->len)); + + insn->type = sibling ?INSN_RETURN :INSN_NOP ; + }It'd be nice to keep the comment for this case that was in
add_call_destinations().
Done!
[tip: objtool/core] objtool: Handle __sanitize_cov*() tail calls
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: f56dae88a81fded66adf2bea9922d1d98d1da14f Gitweb: https://git.kernel.org/tip/f56dae88a81fded66adf2bea9922d1d98d1da14f Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:02 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00
objtool: Handle __sanitize_cov*() tail calls
Turns out the compilers also generate tail calls to __sanitize_cov*(), make sure to also patch those out in noinstr code.
--- tools/objtool/arch/x86/decode.c | 20 +++- tools/objtool/check.c | 158 +++++++++++++------------- tools/objtool/include/objtool/arch.h | 1 +- 3 files changed, 105 insertions(+), 74 deletions(-)
tools/objtool/arch/x86/decode.c +20 -0
@@ -659,6 +659,26 @@ const char *arch_nop_insn(int len)return nops[len-1 ]; } +#define BYTE_RET 0xC3 + +const char *arch_ret_insn (int len) +{ +static const char ret[5 ][5 ] = { + {BYTE_RET }, + {BYTE_RET ,BYTES_NOP1 }, + {BYTE_RET ,BYTES_NOP2 }, + {BYTE_RET ,BYTES_NOP3 }, + {BYTE_RET ,BYTES_NOP4 }, + }; + +if (len <1 || len >5 ) { +WARN ("invalid RET size: %d\n" , len); +return NULL ; + } + +return ret[len-1 ]; +} +/* asm/alternative.h ? */ #define ALTINSTR_FLAG_INV (1 << 15)
tools/objtool/check.c +84 -74
213 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -0
@@ -82,6 +82,7 @@ unsigned long arch_jump_destination(struct instruction *insn);unsigned long arch_dest_reloc_offset (int addend);const char *arch_nop_insn (int len); +const char *arch_ret_insn (int len);int arch_decode_hint_reg (u8 sp_reg,int *base);
Peter Zijlstra
maintainerPATCH v2 4/24 x86/kvm: Always inline sev_*guest()
In reply to Peter Zijlstravmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x4d: call to sev_es_guest() leaves .noinstr.text section vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x50: call to sev_guest() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kvm/svm/svm.h +3 -3
@@ -204,12 +204,12 @@ DECLARE_PER_CPU(struct svm_cpu_data *, svoid recalc_intercepts (struct vcpu_svm *svm); -static inline struct kvm_svm *to_kvm_svm (struct kvm *kvm) +static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm) { return container_of(kvm, struct kvm_svm, kvm); } -static inline bool sev_guest (struct kvm *kvm) +static __always_inline bool sev_guest(struct kvm *kvm) {#ifdef CONFIG_KVM_AMD_SEV struct kvm_sev_info *sev = &to_kvm_svm (kvm)->sev_info;
@@ -220,7 +220,7 @@ static inline bool sev_guest(struct kvm#endif } -static inline bool sev_es_guest (struct kvm *kvm) +static __always_inline bool sev_es_guest(struct kvm *kvm) {#ifdef CONFIG_KVM_AMD_SEV struct kvm_sev_info *sev = &to_kvm_svm (kvm)->sev_info;
[tip: objtool/core] x86/kvm: Always inline sev_*guest()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 2b2f72d4d81936bc08c18c426f40b7df70e2f8e7 Gitweb: https://git.kernel.org/tip/2b2f72d4d81936bc08c18c426f40b7df70e2f8e7 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:03 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00
x86/kvm: Always inline sev_*guest()
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x4d: call to sev_es_guest() leaves .noinstr.text section vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x50: call to sev_guest() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kvm/svm/svm.h +3 -3
@@ -218,12 +218,12 @@ DECLARE_PER_CPU(struct svm_cpu_data *, svm_data);void recalc_intercepts (struct vcpu_svm *svm); -static inline struct kvm_svm *to_kvm_svm (struct kvm *kvm) +static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm) { return container_of(kvm, struct kvm_svm, kvm); } -static inline bool sev_guest (struct kvm *kvm) +static __always_inline bool sev_guest(struct kvm *kvm) {#ifdef CONFIG_KVM_AMD_SEV struct kvm_sev_info *sev = &to_kvm_svm (kvm)->sev_info;
@@ -234,7 +234,7 @@ static inline bool sev_guest(struct kvm *kvm)#endif } -static inline bool sev_es_guest (struct kvm *kvm) +static __always_inline bool sev_es_guest(struct kvm *kvm) {#ifdef CONFIG_KVM_AMD_SEV struct kvm_sev_info *sev = &to_kvm_svm (kvm)->sev_info;
Peter Zijlstra
maintainerPATCH v2 5/24 x86/kvm: Always inline vmload() / vmsave()
In reply to Peter Zijlstravmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0xea: call to vmload() leaves .noinstr.text section vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x133: call to vmsave() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/svm_ops.h +2 -2
@@ -56,12 +56,12 @@ static inline void invlpga(unsigned long* VMSAVE, VMLOAD, etc... is still controlled by the effective address size, * hence 'unsigned long' instead of 'hpa_t'. */ -static inline void vmsave (unsigned long pa) +static __always_inline void vmsave(unsigned long pa) {svm_asm1 (vmsave,"a" (pa),"memory" ); } -static inline void vmload (unsigned long pa) +static __always_inline void vmload(unsigned long pa) {svm_asm1 (vmload,"a" (pa),"memory" ); }
[tip: objtool/core] x86/kvm: Always inline vmload() / vmsave()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: a168233a440d01d60ca65ea41e876661466f108b Gitweb: https://git.kernel.org/tip/a168233a440d01d60ca65ea41e876661466f108b Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:04 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:45 +02:00
x86/kvm: Always inline vmload() / vmsave()
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0xea: call to vmload() leaves .noinstr.text section vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x133: call to vmsave() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/svm_ops.h +2 -2
@@ -56,12 +56,12 @@ static inline void invlpga(unsigned long addr, u32 asid)* VMSAVE, VMLOAD, etc... is still controlled by the effective address size, * hence 'unsigned long' instead of 'hpa_t'. */ -static inline void vmsave (unsigned long pa) +static __always_inline void vmsave(unsigned long pa) {svm_asm1 (vmsave,"a" (pa),"memory" ); } -static inline void vmload (unsigned long pa) +static __always_inline void vmload(unsigned long pa) {svm_asm1 (vmload,"a" (pa),"memory" ); }
Peter Zijlstra
maintainerPATCH v2 6/24 x86: Always inline context_tracking_guest_enter()
In reply to Peter ZijlstraYes, it really did out-of-line this....
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section
000000000019f660 <context_tracking_guest_enter>:
19f660: e8 00 00 00 00 callq 19f665 <context_tracking_guest_enter+0x5> 19f661: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4 19f665: 31 c0 xor %eax,%eax 19f667: c3 retq
--- include/linux/context_tracking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/context_tracking.h +1 -1
@@ -105,7 +105,7 @@ static inline void user_exit_irqoff(voidstatic inline enum ctx_state exception_enter (void ) {return 0 ; }static inline void exception_exit (enum ctx_state prev_ctx) { }static inline enum ctx_state ct_state (void ) {return CONTEXT_DISABLED ; } -static inline bool context_tracking_guest_enter (void ) {return false; } +static __always_inline bool context_tracking_guest_enter(void) { return false; }static inline void context_tracking_guest_exit (void ) { }#endif /* !CONFIG_CONTEXT_TRACKING */
Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
Quoted 10 lines · Peter Zijlstra
Yes, it really did out-of-line this....
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to
context_tracking_guest_enter()leaves .noinstr.text section
000000000019f660<context_tracking_guest_enter>:19f660: e8 00 00 00 00 callq 19f665 <context_tracking_guest_enter+0x5> 19f661: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4 19f665: 31 c0 xor %eax,%eax 19f667: c3 retqSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Ha. I'm guessing this was from CONFIG_DEBUG_SECTION_MISMATCH, which is only good for triggering a lot of these useless __always_inline patches.
I have a patch somewhere to get rid of it.
Signature · 1 line
Josh
Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
Quoted 10 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
Yes, it really did out-of-line this....
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to
context_tracking_guest_enter()leaves .noinstr.text section
000000000019f660<context_tracking_guest_enter>:19f660: e8 00 00 00 00 callq 19f665 <context_tracking_guest_enter+0x5> 19f661: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4 19f665: 31 c0 xor %eax,%eax 19f667: c3 retq
Quoted 6 lines
Quoted 1 line
Signed-off-by Peter Zijlstra (Intel) <[email protected]>Ha. I'm guessing this was from
CONFIG_DEBUG_SECTION_MISMATCH, which is only good for triggering a lot of these useless__always_inlinepatches.I have a patch somewhere to get rid of it.
Found it.
WARNING: This patch may shrink your patch set and improve your sanity.
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] kbuild: Remove CONFIG_DEBUG_SECTION_MISMATCH
Modpost's section mismatch detection warns when a non-init function references an __init function. The warning is needed because __init memory is freed during boot, so the non-init function might end up calling into some random memory.
CONFIG_DEBUG_SECTION_MISMATCH is intended to root out more of these issues by adding the -fno-inline-functions-called-once compiler flag, which forces once-called static functions to not be inlined. As described in the option's help description:
- Add the option -fno-inline-functions-called-once to gcc commands. When inlining a function annotated with __init in a non-init function, we would lose the section information and thus the analysis would not catch the illegal reference. This option tells gcc to inline less (but it does result in a larger kernel).
It's true that if an __init function is inlined in a non-init function, it's no longer __init. But that's not actually a problem.
If an inlined __init function doesn't access any other __init functions or data, the inlining is harmless.
If the inlined __init function does access other __init functions/data, __init relocations will be generated for a non-init section, and modpost's section mismatch detection will discover it.
So the option isn't actually useful. It's not even useful for finding issues on other configs, which might have different inlining decisions, because with -O2, once-called static functions are always inlined. And anyway, nowadays we have build bots everywhere, which are great at finding such edge cases.
I get the feeling this option has been responsible for dozens of "convert inline to __always_inline" patches over the years. Such patches usually complain about the compiler's inlining decisions being unpredictable. Turns out the culprit is this CONFIG_DEBUG_SECTION_MISMATCH option, at least for once-called functions.
This option really has no benefits, and only drawbacks, causing needless churn. Remove it.
--- Makefile | 5 ----- arch/arc/configs/tb10x_defconfig | 1 - arch/nds32/configs/defconfig | 1 - arch/s390/configs/debug_defconfig | 1 - arch/s390/configs/defconfig | 1 - lib/Kconfig.debug | 21 ------------------- .../selftests/wireguard/qemu/debug.config | 1 - 7 files changed, 31 deletions(-)
Makefile +0 -5
@@ -913,11 +913,6 @@ KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING) KBUILD_AFLAGS += $(CC_FLAGS_USING) endif -# We trigger additional mismatches with less inlining -ifdef CONFIG_DEBUG_SECTION_MISMATCH -KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) -endif - ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections LDFLAGS_vmlinux += --gc-sections
arch/arc/configs/tb10x_defconfig +0 -1
@@ -96,7 +96,6 @@ CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y CONFIG_HEADERS_INSTALL=y CONFIG_HEADERS_CHECK=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y
arch/nds32/configs/defconfig +0 -1
@@ -93,7 +93,6 @@ CONFIG_GDB_SCRIPTS=y CONFIG_READABLE_ASM=y CONFIG_HEADERS_INSTALL=y CONFIG_HEADERS_CHECK=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_PANIC_ON_OOPS=y
arch/s390/configs/debug_defconfig +0 -1
@@ -782,7 +782,6 @@ CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_GDB_SCRIPTS=y CONFIG_HEADERS_INSTALL=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_PAGE_OWNER=y
arch/s390/configs/defconfig +0 -1
@@ -767,7 +767,6 @@ CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_GDB_SCRIPTS=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_WX=y CONFIG_PTDUMP_DEBUGFS=y
lib/Kconfig.debug +0 -21
@@ -381,27 +381,6 @@ config HEADERS_INSTALL user-space program samples. It is also needed by some features such as uapi header sanity checks. -config DEBUG_SECTION_MISMATCH - bool "Enable full Section mismatch analysis" - help - The section mismatch analysis checks if there are illegal - references from one section to another section. - During linktime or runtime, some sections are dropped; - any use of code/data previously in these sections would - most likely result in an oops. - In the code, functions and variables are annotated with - __init,, etc. (see the full list in include/linux/init.h), - which results in the code/data being placed in specific sections. - The section mismatch analysis is always performed after a full - kernel build, and enabling this option causes the following - additional step to occur: - - Add the option -fno-inline-functions-called-once to gcc commands. - When inlining a function annotated with __init in a non-init - function, we would lose the section information and thus - the analysis would not catch the illegal reference. - This option tells gcc to inline less (but it does result in - a larger kernel). - config SECTION_MISMATCH_WARN_ONLY bool "Make section mismatch errors non-fatal" default y
tools/testing/selftests/wireguard/qemu/debug.config +0 -1
@@ -57,7 +57,6 @@ CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_DEBUG_SG=y CONFIG_DEBUG_NOTIFIERS=y CONFIG_X86_DEBUG_FPU=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
Signature · 1 line
2.31.1
Peter Zijlstra
maintainerRe: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
Quoted 1 line · Josh Poimboeuf
WARNING: This patch may shrink your patch set and improve your sanity.
I'll go rebuild me some kernels to see how many __always_inline things I can drop.
Lets add a few Cc's though.
Quoted 168 lines
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] kbuild: RemoveCONFIG_DEBUG_SECTION_MISMATCHModpost's section mismatch detection warns when a non-init function references an
__initfunction. The warning is needed because__initmemory is freed during boot, so the non-init function might end up calling into some random memory.
CONFIG_DEBUG_SECTION_MISMATCHis intended to root out more of these issues by adding the -fno-inline-functions-called-once compiler flag, which forces once-called static functions to not be inlined. As described in the option's help description:- Add the option -fno-inline-functions-called-once to gcc commands. When inlining a function annotated with
__initin a non-init function, we would lose the section information and thus the analysis would not catch the illegal reference. This option tells gcc to inline less (but it does result in a larger kernel).It's true that if an
__initfunction is inlined in a non-init function, it's no longer__init. But that's not actually a problem.If an inlined
__initfunction doesn't access any other__initfunctions or data, the inlining is harmless.If the inlined
__initfunction does access other__initfunctions/data,__initrelocations will be generated for a non-init section, and modpost's section mismatch detection will discover it.So the option isn't actually useful. It's not even useful for finding issues on other configs, which might have different inlining decisions, because with -O2, once-called static functions are always inlined. And anyway, nowadays we have build bots everywhere, which are great at finding such edge cases.
I get the feeling this option has been responsible for dozens of "convert inline to
__always_inline" patches over the years. Such patches usually complain about the compiler's inlining decisions being unpredictable. Turns out the culprit is thisCONFIG_DEBUG_SECTION_MISMATCHoption, at least for once-called functions.This option really has no benefits, and only drawbacks, causing needless churn. Remove it.
Signed-off-by Josh Poimboeuf <[email protected]>--- Makefile | 5 ----- arch/arc/configs/tb10x_defconfig | 1 - arch/nds32/configs/defconfig | 1 - arch/s390/configs/debug_defconfig | 1 - arch/s390/configs/defconfig | 1 - lib/Kconfig.debug | 21 ------------------- .../selftests/wireguard/qemu/debug.config | 1 - 7 files changed, 31 deletions(-)Makefile +0
-5@@ -913,11 +913,6 @@ KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING) KBUILD_AFLAGS += $(CC_FLAGS_USING) endif -# We trigger additional mismatches with less inlining -ifdef CONFIG_DEBUG_SECTION_MISMATCH -KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) -endif - ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections LDFLAGS_vmlinux += --gc-sectionsarch/arc/configs/tb10x_defconfig +0
-1@@ -96,7 +96,6 @@ CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y CONFIG_HEADERS_INSTALL=y CONFIG_HEADERS_CHECK=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=yarch/nds32/configs/defconfig +0
-1@@ -93,7 +93,6 @@ CONFIG_GDB_SCRIPTS=y CONFIG_READABLE_ASM=y CONFIG_HEADERS_INSTALL=y CONFIG_HEADERS_CHECK=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_PANIC_ON_OOPS=yarch/s390/configs/debug_defconfig +0
-1@@ -782,7 +782,6 @@ CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_GDB_SCRIPTS=y CONFIG_HEADERS_INSTALL=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_PAGE_OWNER=yarch/s390/configs/defconfig +0
-1@@ -767,7 +767,6 @@ CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_GDB_SCRIPTS=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_WX=y CONFIG_PTDUMP_DEBUGFS=ylib/Kconfig.debug +0
-21@@ -381,27 +381,6 @@ config HEADERS_INSTALL user-space program samples. It is also needed by some features such as uapi header sanity checks. -config DEBUG_SECTION_MISMATCH - bool "Enable full Section mismatch analysis" - help - The section mismatch analysis checks if there are illegal - references from one section to another section. - During linktime or runtime, some sections are dropped; - any use of code/data previously in these sections would - most likely result in an oops. - In the code, functions and variables are annotated with - __init,, etc. (see the full list in include/linux/init.h), - which results in the code/data being placed in specific sections. - The section mismatch analysis is always performed after a full - kernel build, and enabling this option causes the following - additional step to occur: - - Add the option -fno-inline-functions-called-once to gcc commands. - When inlining a function annotated with __init in a non-init - function, we would lose the section information and thus - the analysis would not catch the illegal reference. - This option tells gcc to inline less (but it does result in - a larger kernel). - config SECTION_MISMATCH_WARN_ONLY bool "Make section mismatch errors non-fatal" default ytools/testing/selftests/wireguard/qemu/debug.config +0
-1@@ -57,7 +57,6 @@ CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_DEBUG_SG=y CONFIG_DEBUG_NOTIFIERS=y CONFIG_X86_DEBUG_FPU=y -CONFIG_DEBUG_SECTION_MISMATCH=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y CONFIG_DEBUG_WW_MUTEX_SLOWPATH=ySignature · 1 line
2.31.1
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
Quoted 28 lines · Sam Ravnborg
Hi Josh,
Quoted 15 lines · Peter Zijlstra
Quoted 1 line · Josh Poimboeuf
WARNING: This patch may shrink your patch set and improve your sanity.
I'll go rebuild me some kernels to see how many
__always_inlinethings I can drop.Lets add a few Cc's though.
Quoted 6 lines
From: Josh Poimboeuf <[email protected]>
Subject: [PATCH] kbuild: RemoveCONFIG_DEBUG_SECTION_MISMATCHSo the option isn't actually useful. It's not even useful for finding issues on other configs, which might have different inlining decisions, because with -O2, once-called static functions are always inlined.
We have following -O possibilities:
ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE KBUILD_CFLAGS += -O2 else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3 KBUILD_CFLAGS += -O3 else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os endif
Quoted 3 lines
We always built with -Os or -O2 (and ARC supports -O3).
Do we know that gcc and clang will always inline once-called functions with -O2 and -Os for the relevant architectures?
Hm, I should have read the GCC manual a little closer:
-finline-functions-called-once
Consider all "static" functions called once for inlining into their caller even if they are not marked "inline".
So it's not necessarily a guarantee that once-called functions will always be inlined. Looking at GCC code, there at least some theoretical edge cases involving optimization mismatches between caller and callee, though as a rule the kernel avoids function-specific optimizations.
Still, I think the patch is a net benefit. I'll update the patch description and post it again separately since Peter doesn't seem to need it here.
Quoted 5 lines
If you can answer yes to this with some confidence then you can add my:
Acked-by Sam Ravnborg <[email protected]>Note: I added this option long time ago and is unhappy if this only have resulted in useless code changes.
It might have been useful in the days before we had all the automated build bots doing randconfigs. Nowadays any __init mismatch issues which would only be seen in obscure config/compiler combinations will be rooted out by the bots reporting modpost section mismatch warnings.
Signature · 1 line
Josh
Peter Zijlstra
maintainerRe: [PATCH v2 06/24] x86: Always inline context_tracking_guest_enter()
In reply to Josh PoimboeufQuoted 11 lines · Josh Poimboeuf
Quoted 10 lines · Josh Poimboeuf
Quoted 9 lines · Peter Zijlstra
Yes, it really did out-of-line this....
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to
context_tracking_guest_enter()leaves .noinstr.text section
000000000019f660<context_tracking_guest_enter>:19f660: e8 00 00 00 00 callq 19f665 <context_tracking_guest_enter+0x5> 19f661: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4 19f665: 31 c0 xor %eax,%eax 19f667: c3 retq
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
Signed-off-by Peter Zijlstra (Intel) <[email protected]>Ha. I'm guessing this was from
CONFIG_DEBUG_SECTION_MISMATCH, which is only good for triggering a lot of these useless__always_inlinepatches.I have a patch somewhere to get rid of it.
Found it.
Even with your patch applied, x86_64-allyesconfig still gives me the above. In fact, I had to re-instate 4 of the 6 __always_inline patches, so I've kept them all for now.
[tip: objtool/core] x86: Always inline context_tracking_guest_enter()
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: e25b694bf1d9ef4a3f36c0b85348f8e780f22139 Gitweb: https://git.kernel.org/tip/e25b694bf1d9ef4a3f36c0b85348f8e780f22139 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:05 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00
x86: Always inline context_tracking_guest_enter()
Yes, it really did out-of-line this....
vmlinux.o: warning: objtool: vmx_vcpu_enter_exit()+0x31: call to context_tracking_guest_enter() leaves .noinstr.text section
000000000019f660 <context_tracking_guest_enter>:
19f660: e8 00 00 00 00 callq 19f665 <context_tracking_guest_enter+0x5> 19f661: R_X86_64_PLT32 __sanitizer_cov_trace_pc-0x4 19f665: 31 c0 xor %eax,%eax 19f667: c3 retq
--- include/linux/context_tracking.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/context_tracking.h +1 -1
@@ -105,7 +105,7 @@ static inline void user_exit_irqoff(void) { }static inline enum ctx_state exception_enter (void ) {return 0 ; }static inline void exception_exit (enum ctx_state prev_ctx) { }static inline enum ctx_state ct_state (void ) {return CONTEXT_DISABLED ; } -static inline bool context_tracking_guest_enter (void ) {return false; } +static __always_inline bool context_tracking_guest_enter(void) { return false; }static inline void context_tracking_guest_exit (void ) { }#endif /* !CONFIG_CONTEXT_TRACKING */
Peter Zijlstra
maintainerPATCH v2 7/24 x86/kvm: Always inline to_svm()
In reply to Peter Zijlstravmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x13: call to to_svm() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/svm/svm.h +1 -1
@@ -252,7 +252,7 @@ static inline bool vmcb_is_dirty(structreturn !test_bit (bit, (unsigned long *)&vmcb->control.clean); } -static inline struct vcpu_svm *to_svm (struct kvm_vcpu *vcpu) +static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) { return container_of(vcpu, struct vcpu_svm, vcpu); }
[tip: objtool/core] x86/kvm: Always inline to_svm()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: aee045ed0a6b22100f4d5945ee2deb75db6a0dd5 Gitweb: https://git.kernel.org/tip/aee045ed0a6b22100f4d5945ee2deb75db6a0dd5 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:06 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00
x86/kvm: Always inline to_svm()
vmlinux.o: warning: objtool: svm_vcpu_enter_exit()+0x13: call to to_svm() leaves .noinstr.text section
--- arch/x86/kvm/svm/svm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/svm/svm.h +1 -1
@@ -271,7 +271,7 @@ static inline bool vmcb_is_dirty(struct vmcb *vmcb, int bit)return !test_bit (bit, (unsigned long *)&vmcb->control.clean); } -static inline struct vcpu_svm *to_svm (struct kvm_vcpu *vcpu) +static __always_inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) { return container_of(vcpu, struct vcpu_svm, vcpu); }
Peter Zijlstra
maintainerPATCH v2 8/24 x86/kvm: Always inline evmcs_write64()
In reply to Peter Zijlstravmlinux.o: warning: objtool: vmx_update_host_rsp()+0x64: call to evmcs_write64() leaves .noinstr.text section
--- arch/x86/kvm/vmx/evmcs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/evmcs.h +2 -2
@@ -97,7 +97,7 @@ static __always_inline int get_evmcs_off#undef ROL16 -static inline void evmcs_write64 (unsigned long field,u64 value) +static __always_inline void evmcs_write64(unsigned long field, u64 value) {u16 clean_field;int offset =get_evmcs_offset (field, &clean_field);
@@ -187,7 +187,7 @@ static inline void evmcs_load(u64 phys_a__init void evmcs_sanitize_exec_ctrls (struct vmcs_config *vmcs_conf);#else /* !IS_ENABLED(CONFIG_HYPERV) */ -static inline void evmcs_write64 (unsigned long field,u64 value) {} +static __always_inline void evmcs_write64(unsigned long field, u64 value) {}static inline void evmcs_write32 (unsigned long field,u32 value) {}static inline void evmcs_write16 (unsigned long field,u16 value) {}static inline u64 evmcs_read64 (unsigned long field) {return 0 ; }
[tip: objtool/core] x86/kvm: Always inline evmcs_write64()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 010050a86393703f43859a4704d2193be49126d6 Gitweb: https://git.kernel.org/tip/010050a86393703f43859a4704d2193be49126d6 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:07 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:46 +02:00
x86/kvm: Always inline evmcs_write64()
vmlinux.o: warning: objtool: vmx_update_host_rsp()+0x64: call to evmcs_write64() leaves .noinstr.text section
--- arch/x86/kvm/vmx/evmcs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/vmx/evmcs.h +2 -2
@@ -93,7 +93,7 @@ static __always_inline int get_evmcs_offset(unsigned long field,return evmcs_field->offset; } -static inline void evmcs_write64 (unsigned long field,u64 value) +static __always_inline void evmcs_write64(unsigned long field, u64 value) {u16 clean_field;int offset =get_evmcs_offset (field, &clean_field);
@@ -183,7 +183,7 @@ static inline void evmcs_load(u64 phys_addr)__init void evmcs_sanitize_exec_ctrls (struct vmcs_config *vmcs_conf);#else /* !IS_ENABLED(CONFIG_HYPERV) */ -static inline void evmcs_write64 (unsigned long field,u64 value) {} +static __always_inline void evmcs_write64(unsigned long field, u64 value) {}static inline void evmcs_write32 (unsigned long field,u32 value) {}static inline void evmcs_write16 (unsigned long field,u16 value) {}static inline u64 evmcs_read64 (unsigned long field) {return 0 ; }
Peter Zijlstra
maintainerPATCH v2 9/24 x86: Always inline ip_within_syscall_gap()
In reply to Peter Zijlstravmlinux.o: warning: objtool: vc_switch_off_ist()+0x20: call to ip_within_syscall_gap.isra.0() leaves .noinstr.text section
--- arch/x86/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/ptrace.h +1 -1
@@ -181,7 +181,7 @@ static inline bool any_64bit_mode(struct#define current_user_stack_pointer () current_pt_regs()->sp#define compat_user_stack_pointer () current_pt_regs()->sp -static inline bool ip_within_syscall_gap (struct pt_regs *regs) +static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) {bool ret = (regs->ip >= (unsigned long )entry_SYSCALL_64 && regs->ip < (unsigned long )entry_SYSCALL_64_safe_stack);
[tip: objtool/core] x86: Always inline ip_within_syscall_gap()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: c6b01dace2cd7f6b3e9174d4d1411755608486f1 Gitweb: https://git.kernel.org/tip/c6b01dace2cd7f6b3e9174d4d1411755608486f1 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:08 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00
x86: Always inline ip_within_syscall_gap()
vmlinux.o: warning: objtool: vc_switch_off_ist()+0x20: call to ip_within_syscall_gap.isra.0() leaves .noinstr.text section
--- arch/x86/include/asm/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/ptrace.h +1 -1
@@ -181,7 +181,7 @@ static inline bool any_64bit_mode(struct pt_regs *regs)#define current_user_stack_pointer () current_pt_regs()->sp#define compat_user_stack_pointer () current_pt_regs()->sp -static inline bool ip_within_syscall_gap (struct pt_regs *regs) +static __always_inline bool ip_within_syscall_gap(struct pt_regs *regs) {bool ret = (regs->ip >= (unsigned long )entry_SYSCALL_64 && regs->ip < (unsigned long )entry_SYSCALL_64_safe_stack);
Peter Zijlstra
maintainerPATCH v2 10/24 x86/sev: Fix noinstr for vc_ghcb_invalidate()
In reply to Peter Zijlstravmlinux.o: warning: objtool: __sev_put_ghcb()+0x88: call to __memset() leaves .noinstr.text section vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0x39: call to __memset() leaves .noinstr.text section
--- arch/x86/kernel/sev-shared.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/sev-shared.c +1 -1
@@ -64,7 +64,7 @@ static bool sev_es_negotiate_protocol(vo static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb) { ghcb->save.sw_exit_code =0 ; -memset (ghcb->save.valid_bitmap,0 ,sizeof (ghcb->save.valid_bitmap)); +__builtin_memset (ghcb->save.valid_bitmap,0 ,sizeof (ghcb->save.valid_bitmap)); }static bool vc_decoding_needed (unsigned long exit_code)
[tip: objtool/core] x86/sev: Fix noinstr for vc_ghcb_invalidate()
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 2c36d87be49355931da5b29ef7621505e0e46ce9 Gitweb: https://git.kernel.org/tip/2c36d87be49355931da5b29ef7621505e0e46ce9 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:09 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00
x86/sev: Fix noinstr for vc_ghcb_invalidate()
vmlinux.o: warning: objtool: __sev_put_ghcb()+0x88: call to __memset() leaves .noinstr.text section vmlinux.o: warning: objtool: __sev_es_nmi_complete()+0x39: call to __memset() leaves .noinstr.text section
--- arch/x86/kernel/sev-shared.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/sev-shared.c +1 -1
@@ -64,7 +64,7 @@ static bool sev_es_negotiate_protocol(void) static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb) { ghcb->save.sw_exit_code =0 ; -memset (ghcb->save.valid_bitmap,0 ,sizeof (ghcb->save.valid_bitmap)); +__builtin_memset (ghcb->save.valid_bitmap,0 ,sizeof (ghcb->save.valid_bitmap)); }static bool vc_decoding_needed (unsigned long exit_code)
Peter Zijlstra
maintainerPATCH v2 11/24 locking/lockdep: Avoid RCU-induced noinstr fail
In reply to Peter Zijlstravmlinux.o: warning: objtool: look_up_lock_class()+0xc7: call to rcu_read_lock_any_held() leaves .noinstr.text section
--- kernel/locking/lockdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/locking/lockdep.c +1 -1
@@ -888,7 +888,7 @@ look_up_lock_class(const struct lockdep_if (DEBUG_LOCKS_WARN_ON (!irqs_disabled ()))return NULL ; -hlist_for_each_entry_rcu (class, hash_head, hash_entry) { +hlist_for_each_entry_rcu_notrace (class, hash_head, hash_entry) {if (class->key == key) {/* * Huh! same key, different name? Did someone trample
[tip: objtool/core] locking/lockdep: Avoid RCU-induced noinstr fail
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: ce0b9c805dd66d5e49fd53ec5415ae398f4c56e6 Gitweb: https://git.kernel.org/tip/ce0b9c805dd66d5e49fd53ec5415ae398f4c56e6 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:10 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00
locking/lockdep: Avoid RCU-induced noinstr fail
vmlinux.o: warning: objtool: look_up_lock_class()+0xc7: call to rcu_read_lock_any_held() leaves .noinstr.text section
--- kernel/locking/lockdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/locking/lockdep.c +1 -1
@@ -888,7 +888,7 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)if (DEBUG_LOCKS_WARN_ON (!irqs_disabled ()))return NULL ; -hlist_for_each_entry_rcu (class, hash_head, hash_entry) { +hlist_for_each_entry_rcu_notrace (class, hash_head, hash_entry) {if (class->key == key) {/* * Huh! same key, different name? Did someone trample
Peter Zijlstra
maintainerPATCH v2 12/24 x86/paravirt: Mark arch_local_irq_*() __always_inline
In reply to Peter Zijlstravmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to arch_local_save_flags() leaves .noinstr.text section vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to arch_local_save_flags() leaves .noinstr.text section vmlinux.o: warning: objtool: match_held_lock()+0x11f: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to arch_local_irq_save() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to arch_local_irq_disable() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to arch_local_irq_enable() leaves .noinstr.text section
It makes no sense to not inline these things.
--- arch/x86/include/asm/paravirt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/paravirt.h +4 -4
@@ -681,23 +681,23 @@ bool __raw_callee_save___native_vcpu_is_ ((struct paravirt_callee_save) { func })#ifdef CONFIG_PARAVIRT_XXL -static inline notrace unsigned long arch_local_save_flags (void ) +static __always_inline unsigned long arch_local_save_flags (void ) { return PVOP_ALT_CALLEE0(unsigned long, irq.save_fl, "pushf; pop %%rax;",ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace void arch_local_irq_disable(void) +static __always_inline void arch_local_irq_disable(void) {PVOP_ALT_VCALLEE0 (irq.irq_disable,"cli;" ,ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace void arch_local_irq_enable(void) +static __always_inline void arch_local_irq_enable(void) {PVOP_ALT_VCALLEE0 (irq.irq_enable,"sti;" ,ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace unsigned long arch_local_irq_save (void ) +static __always_inline unsigned long arch_local_irq_save (void ) {unsigned long f;
Re: [PATCH v2 12/24] x86/paravirt: Mark arch_local_irq_*() __always_inline
Quoted 6 lines · Peter Zijlstra
vmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to
arch_local_save_flags()leaves .noinstr.text section vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call toarch_local_save_flags()leaves .noinstr.text section vmlinux.o: warning: objtool: match_held_lock()+0x11f: call toarch_local_save_flags()leaves .noinstr.text sectionvmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to
arch_local_irq_save()leaves .noinstr.text section
Quoted 7 lines
vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to
arch_local_irq_disable()leaves .noinstr.text sectionvmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to
arch_local_irq_enable()leaves .noinstr.text sectionIt makes no sense to not inline these things.
Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/paravirt: Mark arch_local_irq_*() __always_inline
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: e9382440de18718fb6f878986c0844c30abc6f99 Gitweb: https://git.kernel.org/tip/e9382440de18718fb6f878986c0844c30abc6f99 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:11 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:47 +02:00
x86/paravirt: Mark arch_local_irq_*() __always_inline
vmlinux.o: warning: objtool: lockdep_hardirqs_on()+0x72: call to arch_local_save_flags() leaves .noinstr.text section vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to arch_local_save_flags() leaves .noinstr.text section vmlinux.o: warning: objtool: match_held_lock()+0x11f: call to arch_local_save_flags() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0x4e: call to arch_local_irq_save() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0x65: call to arch_local_irq_disable() leaves .noinstr.text section
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to arch_local_irq_enable() leaves .noinstr.text section
It makes no sense to not inline these things.
--- arch/x86/include/asm/paravirt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/paravirt.h +4 -4
@@ -678,23 +678,23 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); ((struct paravirt_callee_save) { func })#ifdef CONFIG_PARAVIRT_XXL -static inline notrace unsigned long arch_local_save_flags (void ) +static __always_inline unsigned long arch_local_save_flags (void ) { return PVOP_ALT_CALLEE0(unsigned long, irq.save_fl, "pushf; pop %%rax;",ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace void arch_local_irq_disable(void) +static __always_inline void arch_local_irq_disable(void) {PVOP_ALT_VCALLEE0 (irq.irq_disable,"cli;" ,ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace void arch_local_irq_enable(void) +static __always_inline void arch_local_irq_enable(void) {PVOP_ALT_VCALLEE0 (irq.irq_enable,"sti;" ,ALT_NOT (X86_FEATURE_XENPV )); } -static inline notrace unsigned long arch_local_irq_save (void ) +static __always_inline unsigned long arch_local_irq_save (void ) {unsigned long f;
Peter Zijlstra
maintainerPATCH v2 13/24 x86/paravirt: Use PVOP_* for paravirt calls
In reply to Peter ZijlstraDoing unconditional indirect calls through the pv_ops vector is weird.
--- arch/x86/include/asm/paravirt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/paravirt.h +4 -4
@@ -52,11 +52,11 @@ void __init paravirt_set_cap(void);/* The paravirtualized I/O functions */ static inline void slow_down_io (void ) { - pv_ops.cpu.io_delay (); +PVOP_VCALL0 (cpu.io_delay);#ifdef REALLY_SLOW_IO - pv_ops.cpu.io_delay (); - pv_ops.cpu.io_delay (); - pv_ops.cpu.io_delay (); +PVOP_VCALL0 (cpu.io_delay); +PVOP_VCALL0 (cpu.io_delay); +PVOP_VCALL0 (cpu.io_delay);#endif }
Re: [PATCH v2 13/24] x86/paravirt: Use PVOP_* for paravirt calls
Quoted 3 lines · Peter Zijlstra
Doing unconditional indirect calls through the
pv_opsvector is weird.Signed-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/paravirt: Use PVOP_* for paravirt calls
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: eac46b323b28215ad19d53390737df4aa336ac14 Gitweb: https://git.kernel.org/tip/eac46b323b28215ad19d53390737df4aa336ac14 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:12 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00
x86/paravirt: Use PVOP_* for paravirt calls
Doing unconditional indirect calls through the pv_ops vector is weird.
--- arch/x86/include/asm/paravirt.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/x86/include/asm/paravirt.h +4 -4
@@ -52,11 +52,11 @@ void __init paravirt_set_cap(void);/* The paravirtualized I/O functions */ static inline void slow_down_io (void ) { - pv_ops.cpu.io_delay (); +PVOP_VCALL0 (cpu.io_delay);#ifdef REALLY_SLOW_IO - pv_ops.cpu.io_delay (); - pv_ops.cpu.io_delay (); - pv_ops.cpu.io_delay (); +PVOP_VCALL0 (cpu.io_delay); +PVOP_VCALL0 (cpu.io_delay); +PVOP_VCALL0 (cpu.io_delay);#endif }
Peter Zijlstra
maintainerPATCH v2 14/24 x86/xen: Make read_cr2() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/xen-asm.S | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned loPVOP_VCALL1 (cpu.write_cr0, x); } -static inline unsigned long read_cr2 (void ) +static __always_inline unsigned long read_cr2 (void ) { return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2, "mov %%cr2, %%rax;",
arch/x86/kernel/paravirt.c +6 -1
@@ -238,6 +238,11 @@ struct pv_info pv_info = {/* 64-bit pagetable entries */ #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) +static noinstr unsigned long pv_native_read_cr2 (void ) +{ +return native_read_cr2 (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops = .mmu.exit_mmap = paravirt_nop, #ifdef CONFIG_PARAVIRT_XXL - .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (native_read_cr2), + .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (pv_native_read_cr2), .mmu.write_cr2 = native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/xen-asm.S +2 -0
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events) ret SYM_FUNC_END(check_events) +.pushsection .noinstr.text, "ax" SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct) FRAME_END ret SYM_FUNC_END(xen_read_cr2_direct); +.popsection .macro xen_pv_trap name SYM_CODE_START(xen_\name)
Re: [PATCH v2 14/24] x86/xen: Make read_cr2() noinstr
Quoted 6 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[41]:
native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]:xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]:xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make read_cr2() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: ee6781aba03fc3040e3dfaa57fe8c2cea751ee35 Gitweb: https://git.kernel.org/tip/ee6781aba03fc3040e3dfaa57fe8c2cea751ee35 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:13 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00
x86/xen: Make read_cr2() noinstr
vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/xen-asm.S | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned long x)PVOP_VCALL1 (cpu.write_cr0, x); } -static inline unsigned long read_cr2 (void ) +static __always_inline unsigned long read_cr2 (void ) { return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2, "mov %%cr2, %%rax;",
arch/x86/kernel/paravirt.c +6 -1
@@ -238,6 +238,11 @@ struct pv_info pv_info = {/* 64-bit pagetable entries */ #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) +static noinstr unsigned long pv_native_read_cr2 (void ) +{ +return native_read_cr2 (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops = { .mmu.exit_mmap = paravirt_nop, #ifdef CONFIG_PARAVIRT_XXL - .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (native_read_cr2), + .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (pv_native_read_cr2), .mmu.write_cr2 = native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/xen-asm.S +2 -0
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events) ret SYM_FUNC_END(check_events) +.pushsection .noinstr.text, "ax" SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct) FRAME_END ret SYM_FUNC_END(xen_read_cr2_direct); +.popsection .macro xen_pv_trap name SYM_CODE_START(xen_\name)
[tip: objtool/core] x86/xen: Make read_cr2() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 0a53c9acf4da51a75392b0b543ce5eaae78a567f Gitweb: https://git.kernel.org/tip/0a53c9acf4da51a75392b0b543ce5eaae78a567f Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:13 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:11:50 +02:00
x86/xen: Make read_cr2() noinstr
vmlinux.o: warning: objtool: pv_ops[41]: native_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2
vmlinux.o: warning: objtool: pv_ops[41]: xen_read_cr2_direct
vmlinux.o: warning: objtool: exc_double_fault()+0x15: call to pv_ops[41]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/xen-asm.S | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -133,7 +133,7 @@ static inline void write_cr0(unsigned long x)PVOP_VCALL1 (cpu.write_cr0, x); } -static inline unsigned long read_cr2 (void ) +static __always_inline unsigned long read_cr2 (void ) { return PVOP_ALT_CALLEE0(unsigned long, mmu.read_cr2, "mov %%cr2, %%rax;",
arch/x86/kernel/paravirt.c +6 -1
@@ -218,6 +218,11 @@ void paravirt_end_context_switch(struct task_struct *next)if (test_and_clear_ti_thread_flag (task_thread_info (next),TIF_LAZY_MMU_UPDATES )) arch_enter_lazy_mmu_mode(); } + +static noinstr unsigned long pv_native_read_cr2 (void ) +{ +return native_read_cr2 (); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -298,7 +303,7 @@ struct paravirt_patch_template pv_ops = { .mmu.exit_mmap = paravirt_nop, #ifdef CONFIG_PARAVIRT_XXL - .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (native_read_cr2), + .mmu.read_cr2 =__PV_IS_CALLEE_SAVE (pv_native_read_cr2), .mmu.write_cr2 = native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/xen-asm.S +2 -0
@@ -102,6 +102,7 @@ SYM_FUNC_START(check_events) ret SYM_FUNC_END(check_events) +.pushsection .noinstr.text, "ax" SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
@@ -116,6 +117,7 @@ SYM_FUNC_START(xen_read_cr2_direct) FRAME_END ret SYM_FUNC_END(xen_read_cr2_direct); +.popsection .macro xen_pv_trap name SYM_CODE_START(xen_\name)
Peter Zijlstra
maintainerPATCH v2 15/24 x86/xen: Make write_cr2() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/mmu_pv.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -140,7 +140,7 @@ static __always_inline unsigned long rea ALT_NOT(X86_FEATURE_XENPV)); } -static inline void write_cr2 (unsigned long x) +static __always_inline void write_cr2(unsigned long x) {PVOP_VCALL1 (mmu.write_cr2, x); }
arch/x86/kernel/paravirt.c +6 -1
@@ -243,6 +243,11 @@ static noinstr unsigned long pv_native_rreturn native_read_cr2 (); } +static noinstr void pv_native_write_cr2(unsigned long val) +{ +native_write_cr2 (val); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops =#ifdef CONFIG_PARAVIRT_XXL .mmu.read_cr2 = __PV_IS_CALLEE_SAVE(pv_native_read_cr2), - .mmu.write_cr2 = native_write_cr2, + .mmu.write_cr2 = pv_native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/mmu_pv.c +2 -1
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(voxen_remap_memory ();xen_setup_mfn_list_list (); } -static void xen_write_cr2 (unsigned long cr2) + +static noinstr void xen_write_cr2(unsigned long cr2) {this_cpu_read (xen_vcpu)->arch.cr2 = cr2; }
Re: [PATCH v2 15/24] x86/xen: Make write_cr2() noinstr
Quoted 5 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[42]:
native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]:xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make write_cr2() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 80de642654653a8f86b34e9072a4d2fb95c32683 Gitweb: https://git.kernel.org/tip/80de642654653a8f86b34e9072a4d2fb95c32683 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:14 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:48 +02:00
x86/xen: Make write_cr2() noinstr
vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/mmu_pv.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -140,7 +140,7 @@ static __always_inline unsigned long read_cr2(void) ALT_NOT(X86_FEATURE_XENPV)); } -static inline void write_cr2 (unsigned long x) +static __always_inline void write_cr2(unsigned long x) {PVOP_VCALL1 (mmu.write_cr2, x); }
arch/x86/kernel/paravirt.c +6 -1
@@ -243,6 +243,11 @@ static noinstr unsigned long pv_native_read_cr2(void)return native_read_cr2 (); } +static noinstr void pv_native_write_cr2(unsigned long val) +{ +native_write_cr2 (val); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL .mmu.read_cr2 = __PV_IS_CALLEE_SAVE(pv_native_read_cr2), - .mmu.write_cr2 = native_write_cr2, + .mmu.write_cr2 = pv_native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/mmu_pv.c +2 -1
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(void)xen_remap_memory ();xen_setup_mfn_list_list (); } -static void xen_write_cr2 (unsigned long cr2) + +static noinstr void xen_write_cr2(unsigned long cr2) {this_cpu_read (xen_vcpu)->arch.cr2 = cr2; }
[tip: objtool/core] x86/xen: Make write_cr2() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 209cfd0cbb6722d3461e4f928dc150e4c3811948 Gitweb: https://git.kernel.org/tip/209cfd0cbb6722d3461e4f928dc150e4c3811948 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:14 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:12:16 +02:00
x86/xen: Make write_cr2() noinstr
vmlinux.o: warning: objtool: pv_ops[42]: native_write_cr2
vmlinux.o: warning: objtool: pv_ops[42]: xen_write_cr2
vmlinux.o: warning: objtool: exc_nmi()+0x127: call to pv_ops[42]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/mmu_pv.c | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -140,7 +140,7 @@ static __always_inline unsigned long read_cr2(void) ALT_NOT(X86_FEATURE_XENPV)); } -static inline void write_cr2 (unsigned long x) +static __always_inline void write_cr2(unsigned long x) {PVOP_VCALL1 (mmu.write_cr2, x); }
arch/x86/kernel/paravirt.c +6 -1
@@ -223,6 +223,11 @@ static noinstr unsigned long pv_native_read_cr2(void) {return native_read_cr2 (); } + +static noinstr void pv_native_write_cr2(unsigned long val) +{ +native_write_cr2 (val); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -304,7 +309,7 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL .mmu.read_cr2 = __PV_IS_CALLEE_SAVE(pv_native_read_cr2), - .mmu.write_cr2 = native_write_cr2, + .mmu.write_cr2 = pv_native_write_cr2, .mmu.read_cr3 = __native_read_cr3, .mmu.write_cr3 = native_write_cr3,
arch/x86/xen/mmu_pv.c +2 -1
@@ -1204,7 +1204,8 @@ static void __init xen_pagetable_init(void)xen_remap_memory ();xen_setup_mfn_list_list (); } -static void xen_write_cr2 (unsigned long cr2) + +static noinstr void xen_write_cr2(unsigned long cr2) {this_cpu_read (xen_vcpu)->arch.cr2 = cr2; }
Peter Zijlstra
maintainerPATCH v2 16/24 x86/xen: Make get_debugreg() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 8 ++++++-- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int/* * These special macros can be used to get or set a debugging register */ -static inline unsigned long paravirt_get_debugreg (int reg) +static __always_inline unsigned long paravirt_get_debugreg (int reg) { return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsignereturn _hypercall2 (int, set_debugreg, reg, value); } -static inline unsigned long +static __always_inline unsigned long HYPERVISOR_get_debugreg (int reg) { return _hypercall1(unsigned long, get_debugreg, reg);
arch/x86/kernel/paravirt.c +6 -2
@@ -248,13 +248,18 @@ static noinstr void pv_native_write_cr2(native_write_cr2 (val); } +static noinstr unsigned long pv_native_get_debugreg (int regno) +{ +return native_get_debugreg (regno); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay, #ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, - .cpu.get_debugreg = native_get_debugreg, + .cpu.get_debugreg = pv_native_get_debugreg, .cpu.set_debugreg = native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops =#ifdef CONFIG_PARAVIRT_XXL /* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_get_debugreg);NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);
arch/x86/xen/enlighten_pv.c +1 -1
@@ -317,7 +317,7 @@ static void xen_set_debugreg(int reg, unHYPERVISOR_set_debugreg (reg, val); } -static unsigned long xen_get_debugreg (int reg) +static noinstr unsigned long xen_get_debugreg (int reg) {return HYPERVISOR_get_debugreg (reg); }
Re: [PATCH v2 16/24] x86/xen: Make get_debugreg() noinstr
Quoted 5 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[1]:
xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]:native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make get_debugreg() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 737196b197f21326b96ba969a5b1205c90f25cdc Gitweb: https://git.kernel.org/tip/737196b197f21326b96ba969a5b1205c90f25cdc Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:15 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00
x86/xen: Make get_debugreg() noinstr
vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 8 ++++++-- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,/* * These special macros can be used to get or set a debugging register */ -static inline unsigned long paravirt_get_debugreg (int reg) +static __always_inline unsigned long paravirt_get_debugreg (int reg) { return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsigned long value)return _hypercall2 (int, set_debugreg, reg, value); } -static inline unsigned long +static __always_inline unsigned long HYPERVISOR_get_debugreg (int reg) { return _hypercall1(unsigned long, get_debugreg, reg);
arch/x86/kernel/paravirt.c +6 -2
@@ -248,13 +248,18 @@ static noinstr void pv_native_write_cr2(unsigned long val)native_write_cr2 (val); } +static noinstr unsigned long pv_native_get_debugreg (int regno) +{ +return native_get_debugreg (regno); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay, #ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, - .cpu.get_debugreg = native_get_debugreg, + .cpu.get_debugreg = pv_native_get_debugreg, .cpu.set_debugreg = native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL /* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_get_debugreg);NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);
arch/x86/xen/enlighten_pv.c +1 -1
@@ -316,7 +316,7 @@ static void xen_set_debugreg(int reg, unsigned long val)HYPERVISOR_set_debugreg (reg, val); } -static unsigned long xen_get_debugreg (int reg) +static noinstr unsigned long xen_get_debugreg (int reg) {return HYPERVISOR_get_debugreg (reg); }
[tip: objtool/core] x86/xen: Make get_debugreg() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: f4afb713e5c3a4419ba7aaecc31a8c8bd91d13fb Gitweb: https://git.kernel.org/tip/f4afb713e5c3a4419ba7aaecc31a8c8bd91d13fb Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:15 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:12:34 +02:00
x86/xen: Make get_debugreg() noinstr
vmlinux.o: warning: objtool: pv_ops[1]: xen_get_debugreg
vmlinux.o: warning: objtool: pv_ops[1]: native_get_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x25: call to pv_ops[1]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 8 ++++++-- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -113,7 +113,7 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,/* * These special macros can be used to get or set a debugging register */ -static inline unsigned long paravirt_get_debugreg (int reg) +static __always_inline unsigned long paravirt_get_debugreg (int reg) { return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -314,7 +314,7 @@ HYPERVISOR_set_debugreg(int reg, unsigned long value)return _hypercall2 (int, set_debugreg, reg, value); } -static inline unsigned long +static __always_inline unsigned long HYPERVISOR_get_debugreg (int reg) { return _hypercall1(unsigned long, get_debugreg, reg);
arch/x86/kernel/paravirt.c +6 -2
@@ -228,6 +228,11 @@ static noinstr void pv_native_write_cr2(unsigned long val) {native_write_cr2 (val); } + +static noinstr unsigned long pv_native_get_debugreg (int regno) +{ +return native_get_debugreg (regno); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -254,7 +259,7 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, - .cpu.get_debugreg = native_get_debugreg, + .cpu.get_debugreg = pv_native_get_debugreg, .cpu.set_debugreg = native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0,
@@ -382,7 +387,6 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL /* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_get_debugreg);NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);
arch/x86/xen/enlighten_pv.c +1 -1
@@ -316,7 +316,7 @@ static void xen_set_debugreg(int reg, unsigned long val)HYPERVISOR_set_debugreg (reg, val); } -static unsigned long xen_get_debugreg (int reg) +static noinstr unsigned long xen_get_debugreg (int reg) {return HYPERVISOR_get_debugreg (reg); }
Peter Zijlstra
maintainerPATCH v2 17/24 x86/xen: Make set_debugreg() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 9 ++++++--- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -118,7 +118,7 @@ static __always_inline unsigned long par return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }#define get_debugreg (var, reg) var = paravirt_get_debugreg(reg) -static inline void set_debugreg (unsigned long val,int reg) +static __always_inline void set_debugreg(unsigned long val, int reg) {PVOP_VCALL2 (cpu.set_debugreg, reg, val); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platforeturn _hypercall1 (int, platform_op, op); } -static inline int +static __always_inline intHYPERVISOR_set_debugreg (int reg,unsigned long value) {return _hypercall2 (int, set_debugreg, reg, value);
arch/x86/kernel/paravirt.c +6 -3
@@ -253,6 +253,11 @@ static noinstr unsigned long pv_native_greturn native_get_debugreg (regno); } +static noinstr void pv_native_set_debugreg(int regno, unsigned long val) +{ +native_set_debugreg (regno, val); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops =#ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, .cpu.get_debugreg = pv_native_get_debugreg, - .cpu.set_debugreg = native_set_debugreg, + .cpu.set_debugreg = pv_native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0, .cpu.write_cr4 = native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops = };#ifdef CONFIG_PARAVIRT_XXL -/* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);void (*paravirt_iret)(void ) = native_iret;
arch/x86/xen/enlighten_pv.c +1 -1
@@ -312,7 +312,7 @@ static void __init xen_init_capabilities } } -static void xen_set_debugreg (int reg,unsigned long val) +static noinstr void xen_set_debugreg(int reg, unsigned long val) {HYPERVISOR_set_debugreg (reg, val); }
Re: [PATCH v2 17/24] x86/xen: Make set_debugreg() noinstr
Quoted 5 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[2]:
xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]:native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make set_debugreg() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 9da62cacc7ed17e2186f82273762fe850078c8c3 Gitweb: https://git.kernel.org/tip/9da62cacc7ed17e2186f82273762fe850078c8c3 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:16 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00
x86/xen: Make set_debugreg() noinstr
vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 9 ++++++--- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -118,7 +118,7 @@ static __always_inline unsigned long paravirt_get_debugreg(int reg) return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }#define get_debugreg (var, reg) var = paravirt_get_debugreg(reg) -static inline void set_debugreg (unsigned long val,int reg) +static __always_inline void set_debugreg(unsigned long val, int reg) {PVOP_VCALL2 (cpu.set_debugreg, reg, val); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platform_op *op)return _hypercall1 (int, platform_op, op); } -static inline int +static __always_inline intHYPERVISOR_set_debugreg (int reg,unsigned long value) {return _hypercall2 (int, set_debugreg, reg, value);
arch/x86/kernel/paravirt.c +6 -3
@@ -253,6 +253,11 @@ static noinstr unsigned long pv_native_get_debugreg(int regno)return native_get_debugreg (regno); } +static noinstr void pv_native_set_debugreg(int regno, unsigned long val) +{ +native_set_debugreg (regno, val); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, .cpu.get_debugreg = pv_native_get_debugreg, - .cpu.set_debugreg = native_set_debugreg, + .cpu.set_debugreg = pv_native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0, .cpu.write_cr4 = native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops = { };#ifdef CONFIG_PARAVIRT_XXL -/* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);void (*paravirt_iret)(void ) = native_iret;
arch/x86/xen/enlighten_pv.c +1 -1
@@ -311,7 +311,7 @@ static void __init xen_init_capabilities(void) } } -static void xen_set_debugreg (int reg,unsigned long val) +static noinstr void xen_set_debugreg(int reg, unsigned long val) {HYPERVISOR_set_debugreg (reg, val); }
[tip: objtool/core] x86/xen: Make set_debugreg() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 7361fac0465ba96ec8f7559459e3c70818ba6c78 Gitweb: https://git.kernel.org/tip/7361fac0465ba96ec8f7559459e3c70818ba6c78 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:16 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:14:39 +02:00
x86/xen: Make set_debugreg() noinstr
vmlinux.o: warning: objtool: pv_ops[2]: xen_set_debugreg
vmlinux.o: warning: objtool: pv_ops[2]: native_set_debugreg
vmlinux.o: warning: objtool: exc_debug()+0x3b: call to pv_ops[2]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 2 +- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/kernel/paravirt.c | 9 ++++++--- arch/x86/xen/enlighten_pv.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-)
arch/x86/include/asm/paravirt.h +1 -1
@@ -118,7 +118,7 @@ static __always_inline unsigned long paravirt_get_debugreg(int reg) return PVOP_CALL1(unsigned long, cpu.get_debugreg, reg); }#define get_debugreg (var, reg) var = paravirt_get_debugreg(reg) -static inline void set_debugreg (unsigned long val,int reg) +static __always_inline void set_debugreg(unsigned long val, int reg) {PVOP_VCALL2 (cpu.set_debugreg, reg, val); }
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -308,7 +308,7 @@ HYPERVISOR_platform_op(struct xen_platform_op *op)return _hypercall1 (int, platform_op, op); } -static inline int +static __always_inline intHYPERVISOR_set_debugreg (int reg,unsigned long value) {return _hypercall2 (int, set_debugreg, reg, value);
arch/x86/kernel/paravirt.c +6 -3
@@ -233,6 +233,11 @@ static noinstr unsigned long pv_native_get_debugreg(int regno) {return native_get_debugreg (regno); } + +static noinstr void pv_native_set_debugreg(int regno, unsigned long val) +{ +native_set_debugreg (regno, val); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -260,7 +265,7 @@ struct paravirt_patch_template pv_ops = {#ifdef CONFIG_PARAVIRT_XXL .cpu.cpuid = native_cpuid, .cpu.get_debugreg = pv_native_get_debugreg, - .cpu.set_debugreg = native_set_debugreg, + .cpu.set_debugreg = pv_native_set_debugreg, .cpu.read_cr0 = native_read_cr0, .cpu.write_cr0 = native_write_cr0, .cpu.write_cr4 = native_write_cr4,
@@ -386,8 +391,6 @@ struct paravirt_patch_template pv_ops = { };#ifdef CONFIG_PARAVIRT_XXL -/* At this point, native_get/set_debugreg has real function entries */ -NOKPROBE_SYMBOL (native_set_debugreg);NOKPROBE_SYMBOL (native_load_idt);void (*paravirt_iret)(void ) = native_iret;
arch/x86/xen/enlighten_pv.c +1 -1
@@ -311,7 +311,7 @@ static void __init xen_init_capabilities(void) } } -static void xen_set_debugreg (int reg,unsigned long val) +static noinstr void xen_set_debugreg(int reg, unsigned long val) {HYPERVISOR_set_debugreg (reg, val); }
Peter Zijlstra
maintainerPATCH v2 18/24 x86/xen: Make save_fl() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 7 +++++-- arch/x86/kernel/irqflags.S | 2 ++ arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 32 ++++++++++++++++---------------- 4 files changed, 25 insertions(+), 20 deletions(-)
arch/x86/include/asm/paravirt.h +5 -2
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_* functions. */ #define PV_THUNK_NAME (func) "__raw_callee_save_" #func -#define PV_CALLEE_SAVE_REGS_THUNK (func) \ +#define __PV_CALLEE_SAVE_REGS_THUNK (func, section) \ extern typeof(func) __raw_callee_save_##func; \ \ - asm(".pushsection .text;" \ + asm(".pushsection " section ", \"ax\";" \ ".globl " PV_THUNK_NAME(func) ";" \ ".type " PV_THUNK_NAME(func) ", @function;" \ PV_THUNK_NAME(func) ":" \
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_ ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";" \ ".popsection") +#define PV_CALLEE_SAVE_REGS_THUNK (func) \ + __PV_CALLEE_SAVE_REGS_THUNK(func, ".text") +/* Get a reference to a callee-save function */ #define PV_CALLEE_SAVE (func) \ ((struct paravirt_callee_save) { __raw_callee_save_##func })
arch/x86/kernel/irqflags.S +2 -0
@@ -7,9 +7,11 @@ /* * unsigned long native_save_fl(void) */ +.pushsection .noinstr.text, "ax" SYM_FUNC_START(native_save_fl) pushf pop %_ASM_AX ret SYM_FUNC_END(native_save_fl) +.popsection EXPORT_SYMBOL(native_save_fl)
arch/x86/xen/irq.c +2 -2
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void) (void )HYPERVISOR_xen_version (0 ,NULL ); } -asmlinkage __visible unsigned long xen_save_fl(void) +asmlinkage __visible noinstr unsigned long xen_save_fl(void) {struct vcpu_info *vcpu;unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_s*/ return (-flags) &X86_EFLAGS_IF ; } -PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl); +__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); asmlinkage __visible void xen_irq_disable(void) {
arch/x86/xen/xen-asm.S +16 -16
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct) SYM_FUNC_END(xen_irq_disable_direct) /* - * (xen_)save_fl is used to get the current interrupt enable status. - * Callers expect the status to be in X86_EFLAGS_IF, and other bits - * may be set in the return value. We take advantage of this by - * making sure that X86_EFLAGS_IF has the right value (and other bits - * in that byte are 0), but other bits in the return value are - * undefined. We need to toggle the state of the bit, because Xen and - * x86 use opposite senses (mask vs enable). - */ -SYM_FUNC_START(xen_save_fl_direct) - testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask - setz %ah - addb %ah, %ah - ret -SYM_FUNC_END(xen_save_fl_direct) - -/* * Force an event check by making a hypercall, but preserve regs * before making the call. */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events) SYM_FUNC_END(check_events) .pushsection .noinstr.text, "ax" +/* + * (xen_)save_fl is used to get the current interrupt enable status. + * Callers expect the status to be in X86_EFLAGS_IF, and other bits + * may be set in the return value. We take advantage of this by + * making sure that X86_EFLAGS_IF has the right value (and other bits + * in that byte are 0), but other bits in the return value are + * undefined. We need to toggle the state of the bit, because Xen and + * x86 use opposite senses (mask vs enable). + */ +SYM_FUNC_START(xen_save_fl_direct) + testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask + setz %ah + addb %ah, %ah + ret +SYM_FUNC_END(xen_save_fl_direct) + SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
Re: [PATCH v2 18/24] x86/xen: Make save_fl() noinstr
Quoted 6 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[30]:
native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]:__raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]:xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make save_fl() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 1126696d60d04b844be88db50099f8fdb43d8166 Gitweb: https://git.kernel.org/tip/1126696d60d04b844be88db50099f8fdb43d8166 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:17 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:49 +02:00
x86/xen: Make save_fl() noinstr
vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 7 +++++-- arch/x86/kernel/irqflags.S | 2 ++- arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 32 ++++++++++++++++---------------- 4 files changed, 25 insertions(+), 20 deletions(-)
arch/x86/include/asm/paravirt.h +5 -2
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);* functions. */ #define PV_THUNK_NAME (func) "__raw_callee_save_" #func -#define PV_CALLEE_SAVE_REGS_THUNK (func) \ +#define __PV_CALLEE_SAVE_REGS_THUNK (func, section) \ extern typeof(func) __raw_callee_save_##func; \ \ - asm(".pushsection .text;" \ + asm(".pushsection " section ", \"ax\";" \ ".globl " PV_THUNK_NAME(func) ";" \ ".type " PV_THUNK_NAME(func) ", @function;" \ PV_THUNK_NAME(func) ":" \
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";" \ ".popsection") +#define PV_CALLEE_SAVE_REGS_THUNK (func) \ + __PV_CALLEE_SAVE_REGS_THUNK(func, ".text") +/* Get a reference to a callee-save function */ #define PV_CALLEE_SAVE (func) \ ((struct paravirt_callee_save) { __raw_callee_save_##func })
arch/x86/kernel/irqflags.S +2 -0
@@ -7,9 +7,11 @@ /* * unsigned long native_save_fl(void) */ +.pushsection .noinstr.text, "ax" SYM_FUNC_START(native_save_fl) pushf pop %_ASM_AX ret SYM_FUNC_END(native_save_fl) +.popsection EXPORT_SYMBOL(native_save_fl)
arch/x86/xen/irq.c +2 -2
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void) (void )HYPERVISOR_xen_version (0 ,NULL ); } -asmlinkage __visible unsigned long xen_save_fl(void) +asmlinkage __visible noinstr unsigned long xen_save_fl(void) {struct vcpu_info *vcpu;unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_save_fl(void)*/ return (-flags) &X86_EFLAGS_IF ; } -PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl); +__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); asmlinkage __visible void xen_irq_disable(void) {
arch/x86/xen/xen-asm.S +16 -16
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct) SYM_FUNC_END(xen_irq_disable_direct) /* - * (xen_)save_fl is used to get the current interrupt enable status. - * Callers expect the status to be in X86_EFLAGS_IF, and other bits - * may be set in the return value. We take advantage of this by - * making sure that X86_EFLAGS_IF has the right value (and other bits - * in that byte are 0), but other bits in the return value are - * undefined. We need to toggle the state of the bit, because Xen and - * x86 use opposite senses (mask vs enable). - */ -SYM_FUNC_START(xen_save_fl_direct) - testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask - setz %ah - addb %ah, %ah - ret -SYM_FUNC_END(xen_save_fl_direct) - -/* * Force an event check by making a hypercall, but preserve regs * before making the call. */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events) SYM_FUNC_END(check_events) .pushsection .noinstr.text, "ax" +/* + * (xen_)save_fl is used to get the current interrupt enable status. + * Callers expect the status to be in X86_EFLAGS_IF, and other bits + * may be set in the return value. We take advantage of this by + * making sure that X86_EFLAGS_IF has the right value (and other bits + * in that byte are 0), but other bits in the return value are + * undefined. We need to toggle the state of the bit, because Xen and + * x86 use opposite senses (mask vs enable). + */ +SYM_FUNC_START(xen_save_fl_direct) + testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask + setz %ah + addb %ah, %ah + ret +SYM_FUNC_END(xen_save_fl_direct) + SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
[tip: objtool/core] x86/xen: Make save_fl() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 20125c872a3f129cef7fdec2b7681da98502a55d Gitweb: https://git.kernel.org/tip/20125c872a3f129cef7fdec2b7681da98502a55d Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:17 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:14:44 +02:00
x86/xen: Make save_fl() noinstr
vmlinux.o: warning: objtool: pv_ops[30]: native_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: __raw_callee_save_xen_save_fl
vmlinux.o: warning: objtool: pv_ops[30]: xen_save_fl_direct
vmlinux.o: warning: objtool: lockdep_hardirqs_off()+0x73: call to pv_ops[30]() leaves .noinstr.text section
--- arch/x86/include/asm/paravirt.h | 7 +++++-- arch/x86/kernel/irqflags.S | 2 ++- arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 32 ++++++++++++++++---------------- 4 files changed, 25 insertions(+), 20 deletions(-)
arch/x86/include/asm/paravirt.h +5 -2
@@ -653,10 +653,10 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu);* functions. */ #define PV_THUNK_NAME (func) "__raw_callee_save_" #func -#define PV_CALLEE_SAVE_REGS_THUNK (func) \ +#define __PV_CALLEE_SAVE_REGS_THUNK (func, section) \ extern typeof(func) __raw_callee_save_##func; \ \ - asm(".pushsection .text;" \ + asm(".pushsection " section ", \"ax\";" \ ".globl " PV_THUNK_NAME(func) ";" \ ".type " PV_THUNK_NAME(func) ", @function;" \ PV_THUNK_NAME(func) ":" \
@@ -669,6 +669,9 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); ".size " PV_THUNK_NAME(func) ", .-" PV_THUNK_NAME(func) ";" \ ".popsection") +#define PV_CALLEE_SAVE_REGS_THUNK (func) \ + __PV_CALLEE_SAVE_REGS_THUNK(func, ".text") +/* Get a reference to a callee-save function */ #define PV_CALLEE_SAVE (func) \ ((struct paravirt_callee_save) { __raw_callee_save_##func })
arch/x86/kernel/irqflags.S +2 -0
@@ -7,9 +7,11 @@ /* * unsigned long native_save_fl(void) */ +.pushsection .noinstr.text, "ax" SYM_FUNC_START(native_save_fl) pushf pop %_ASM_AX ret SYM_FUNC_END(native_save_fl) +.popsection EXPORT_SYMBOL(native_save_fl)
arch/x86/xen/irq.c +2 -2
@@ -24,7 +24,7 @@ void xen_force_evtchn_callback(void) (void )HYPERVISOR_xen_version (0 ,NULL ); } -asmlinkage __visible unsigned long xen_save_fl(void) +asmlinkage __visible noinstr unsigned long xen_save_fl(void) {struct vcpu_info *vcpu;unsigned long flags;
@@ -40,7 +40,7 @@ asmlinkage __visible unsigned long xen_save_fl(void)*/ return (-flags) &X86_EFLAGS_IF ; } -PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl); +__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); asmlinkage __visible void xen_irq_disable(void) {
arch/x86/xen/xen-asm.S +16 -16
@@ -58,22 +58,6 @@ SYM_FUNC_START(xen_irq_disable_direct) SYM_FUNC_END(xen_irq_disable_direct) /* - * (xen_)save_fl is used to get the current interrupt enable status. - * Callers expect the status to be in X86_EFLAGS_IF, and other bits - * may be set in the return value. We take advantage of this by - * making sure that X86_EFLAGS_IF has the right value (and other bits - * in that byte are 0), but other bits in the return value are - * undefined. We need to toggle the state of the bit, because Xen and - * x86 use opposite senses (mask vs enable). - */ -SYM_FUNC_START(xen_save_fl_direct) - testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask - setz %ah - addb %ah, %ah - ret -SYM_FUNC_END(xen_save_fl_direct) - -/* * Force an event check by making a hypercall, but preserve regs * before making the call. */
@@ -103,6 +87,22 @@ SYM_FUNC_START(check_events) SYM_FUNC_END(check_events) .pushsection .noinstr.text, "ax" +/* + * (xen_)save_fl is used to get the current interrupt enable status. + * Callers expect the status to be in X86_EFLAGS_IF, and other bits + * may be set in the return value. We take advantage of this by + * making sure that X86_EFLAGS_IF has the right value (and other bits + * in that byte are 0), but other bits in the return value are + * undefined. We need to toggle the state of the bit, because Xen and + * x86 use opposite senses (mask vs enable). + */ +SYM_FUNC_START(xen_save_fl_direct) + testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask + setz %ah + addb %ah, %ah + ret +SYM_FUNC_END(xen_save_fl_direct) + SYM_FUNC_START(xen_read_cr2) FRAME_BEGIN _ASM_MOV PER_CPU_VAR(xen_vcpu), %_ASM_AX
Peter Zijlstra
maintainerPATCH v2 19/24 x86/xen: Make hypercall_page noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section
--- arch/x86/xen/xen-head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/xen-head.S +1 -1
@@ -64,7 +64,7 @@ SYM_CODE_END(asm_cpu_bringup_and_idle) #endif #endif -.pushsection .text +.pushsection .noinstr.text, "ax" .balign PAGE_SIZE SYM_CODE_START(hypercall_page) .rept (PAGE_SIZE / 32)
Re: [PATCH v2 19/24] x86/xen: Make hypercall_page noinstr
Quoted 5 lines · Peter Zijlstra
vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to
hypercall_page()leaves .noinstr.text section vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call tohypercall_page()leaves .noinstr.text section vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call tohypercall_page()leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make hypercall_page noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 9f38b2a0baf1e5c7a1d1231cd8fe706c6f769a73 Gitweb: https://git.kernel.org/tip/9f38b2a0baf1e5c7a1d1231cd8fe706c6f769a73 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:18 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00
x86/xen: Make hypercall_page noinstr
vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section
--- arch/x86/xen/xen-head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/xen-head.S +1 -1
@@ -20,7 +20,7 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> -.pushsection .text +.pushsection .noinstr.text, "ax" .balign PAGE_SIZE SYM_CODE_START(hypercall_page) .rept (PAGE_SIZE / 32)
[tip: objtool/core] x86/xen: Make hypercall_page noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 74ea805b79d2b6eb472daa2540ed35ccb4ed23e7 Gitweb: https://git.kernel.org/tip/74ea805b79d2b6eb472daa2540ed35ccb4ed23e7 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:18 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:14:44 +02:00
x86/xen: Make hypercall_page noinstr
vmlinux.o: warning: objtool: xen_set_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_get_debugreg()+0x3: call to hypercall_page() leaves .noinstr.text section vmlinux.o: warning: objtool: xen_irq_enable()+0x24: call to hypercall_page() leaves .noinstr.text section
--- arch/x86/xen/xen-head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/xen-head.S +1 -1
@@ -20,7 +20,7 @@ #include <xen/interface/xen-mca.h> #include <asm/xen/interface.h> -.pushsection .text +.pushsection .noinstr.text, "ax" .balign PAGE_SIZE SYM_CODE_START(hypercall_page) .rept (PAGE_SIZE / 32)
Peter Zijlstra
maintainerPATCH v2 20/24 x86/xen: Make irq_enable() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++- arch/x86/xen/irq.c | 4 +-- arch/x86/xen/xen-asm.S | 56 ++++++++++++++++++++++----------------------- 3 files changed, 36 insertions(+), 31 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -258,6 +258,11 @@ static noinstr void pv_native_set_debugrnative_set_debugreg (regno, val); } +static noinstr void pv_native_irq_enable(void) +{ +native_irq_enable (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops =/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), - .irq.irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), + .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,#endif /* CONFIG_PARAVIRT_XXL */
arch/x86/xen/irq.c +2 -2
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disabl }PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); -asmlinkage __visible void xen_irq_enable(void) +asmlinkage __visible noinstr void xen_irq_enable(void) {struct vcpu_info *vcpu;
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enablepreempt_enable (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable,".noinstr.text" );static void xen_safe_halt (void ) {
arch/x86/xen/xen-asm.S +28 -28
74 lines not on this page · raw message
Re: [PATCH v2 20/24] x86/xen: Make irq_enable() noinstr
Quoted 6 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[32]:
native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]:__raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]:xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make irq_enable() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 92e34bb9bdc242045b29269fc93942ee9befc521 Gitweb: https://git.kernel.org/tip/92e34bb9bdc242045b29269fc93942ee9befc521 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:19 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00
x86/xen: Make irq_enable() noinstr
vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++- arch/x86/xen/irq.c | 4 +-- arch/x86/xen/xen-asm.S | 56 ++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 31 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -258,6 +258,11 @@ static noinstr void pv_native_set_debugreg(int regno, unsigned long val)native_set_debugreg (regno, val); } +static noinstr void pv_native_irq_enable(void) +{ +native_irq_enable (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops = {/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), - .irq.irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), + .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,#endif /* CONFIG_PARAVIRT_XXL */
arch/x86/xen/irq.c +2 -2
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disable(void) }PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); -asmlinkage __visible void xen_irq_enable(void) +asmlinkage __visible noinstr void xen_irq_enable(void) {struct vcpu_info *vcpu;
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enable(void)preempt_enable (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable,".noinstr.text" );static void xen_safe_halt (void ) {
arch/x86/xen/xen-asm.S +28 -28
74 lines not on this page · raw message
[tip: objtool/core] x86/xen: Make irq_enable() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: d7bfc7d57cbe13382fd3eb739667fd0e2f74122b Gitweb: https://git.kernel.org/tip/d7bfc7d57cbe13382fd3eb739667fd0e2f74122b Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:19 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:17:12 +02:00
x86/xen: Make irq_enable() noinstr
vmlinux.o: warning: objtool: pv_ops[32]: native_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: __raw_callee_save_xen_irq_enable
vmlinux.o: warning: objtool: pv_ops[32]: xen_irq_enable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0xfe: call to pv_ops[32]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++- arch/x86/xen/irq.c | 4 +-- arch/x86/xen/xen-asm.S | 56 ++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 31 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -238,6 +238,11 @@ static noinstr void pv_native_set_debugreg(int regno, unsigned long val) {native_set_debugreg (regno, val); } + +static noinstr void pv_native_irq_enable(void) +{ +native_irq_enable (); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -302,7 +307,7 @@ struct paravirt_patch_template pv_ops = {/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), - .irq.irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), + .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,#endif /* CONFIG_PARAVIRT_XXL */
arch/x86/xen/irq.c +2 -2
@@ -53,7 +53,7 @@ asmlinkage __visible void xen_irq_disable(void) }PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); -asmlinkage __visible void xen_irq_enable(void) +asmlinkage __visible noinstr void xen_irq_enable(void) {struct vcpu_info *vcpu;
@@ -76,7 +76,7 @@ asmlinkage __visible void xen_irq_enable(void)preempt_enable (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_enable,".noinstr.text" );static void xen_safe_halt (void ) {
arch/x86/xen/xen-asm.S +28 -28
74 lines not on this page · raw message
Peter Zijlstra
maintainerPATCH v2 21/24 x86/xen: Make irq_disable() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -263,6 +263,11 @@ static noinstr void pv_native_irq_enablenative_irq_enable (); } +static noinstr void pv_native_irq_disable(void) +{ +native_irq_disable (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops =/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), - .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), + .irq.irq_disable = __PV_IS_CALLEE_SAVE(pv_native_irq_disable), .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,
arch/x86/xen/irq.c +2 -2
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned lo }__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); -asmlinkage __visible void xen_irq_disable(void) +asmlinkage __visible noinstr void xen_irq_disable(void) {/* There's a one instruction preempt window here. We need to make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disablthis_cpu_read (xen_vcpu)->evtchn_upcall_mask =1 ;preempt_enable_no_resched (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable,".noinstr.text" ); asmlinkage __visible noinstr void xen_irq_enable(void) {
arch/x86/xen/xen-asm.S +1 -2
@@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/linkage.h> +.pushsection .noinstr.text, "ax" /* * Disabling events is simply a matter of making the event mask * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct) ret SYM_FUNC_END(xen_irq_disable_direct) -.pushsection .noinstr.text, "ax" - /* * Force an event check by making a hypercall, but preserve regs * before making the call.
Re: [PATCH v2 21/24] x86/xen: Make irq_disable() noinstr
Quoted 6 lines · Peter Zijlstra
vmlinux.o: warning: objtool: pv_ops[31]:
native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]:__raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]:xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Make irq_disable() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: bf10b01f581231dc9d25a12dcfec272b981745dc Gitweb: https://git.kernel.org/tip/bf10b01f581231dc9d25a12dcfec272b981745dc Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:20 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:50 +02:00
x86/xen: Make irq_disable() noinstr
vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -263,6 +263,11 @@ static noinstr void pv_native_irq_enable(void)native_irq_enable (); } +static noinstr void pv_native_irq_disable(void) +{ +native_irq_disable (); +} +struct paravirt_patch_template pv_ops = {/* Cpu ops. */ .cpu.io_delay = native_io_delay,
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops = {/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), - .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), + .irq.irq_disable = __PV_IS_CALLEE_SAVE(pv_native_irq_disable), .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,
arch/x86/xen/irq.c +2 -2
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned long xen_save_fl(void) }__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); -asmlinkage __visible void xen_irq_disable(void) +asmlinkage __visible noinstr void xen_irq_disable(void) {/* There's a one instruction preempt window here. We need to make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disable(void)this_cpu_read (xen_vcpu)->evtchn_upcall_mask =1 ;preempt_enable_no_resched (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable,".noinstr.text" ); asmlinkage __visible noinstr void xen_irq_enable(void) {
arch/x86/xen/xen-asm.S +1 -2
@@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/linkage.h> +.pushsection .noinstr.text, "ax" /* * Disabling events is simply a matter of making the event mask * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct) ret SYM_FUNC_END(xen_irq_disable_direct) -.pushsection .noinstr.text, "ax" - /* * Force an event check by making a hypercall, but preserve regs * before making the call.
[tip: objtool/core] x86/xen: Make irq_disable() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 09c413071e2de71d1f28813c560ae0c06b344520 Gitweb: https://git.kernel.org/tip/09c413071e2de71d1f28813c560ae0c06b344520 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:20 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:20:23 +02:00
x86/xen: Make irq_disable() noinstr
vmlinux.o: warning: objtool: pv_ops[31]: native_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: __raw_callee_save_xen_irq_disable
vmlinux.o: warning: objtool: pv_ops[31]: xen_irq_disable_direct
vmlinux.o: warning: objtool: lock_is_held_type()+0x5b: call to pv_ops[31]() leaves .noinstr.text section
--- arch/x86/kernel/paravirt.c | 7 ++++++- arch/x86/xen/irq.c | 4 ++-- arch/x86/xen/xen-asm.S | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-)
arch/x86/kernel/paravirt.c +6 -1
@@ -243,6 +243,11 @@ static noinstr void pv_native_irq_enable(void) {native_irq_enable (); } + +static noinstr void pv_native_irq_disable(void) +{ +native_irq_disable (); +}#endif enum paravirt_lazy_mode paravirt_get_lazy_mode (void )
@@ -306,7 +311,7 @@ struct paravirt_patch_template pv_ops = {/* Irq ops. */ .irq.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl), - .irq.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable), + .irq.irq_disable = __PV_IS_CALLEE_SAVE(pv_native_irq_disable), .irq.irq_enable = __PV_IS_CALLEE_SAVE(pv_native_irq_enable), .irq.safe_halt = native_safe_halt, .irq.halt = native_halt,
arch/x86/xen/irq.c +2 -2
@@ -42,7 +42,7 @@ asmlinkage __visible noinstr unsigned long xen_save_fl(void) }__PV_CALLEE_SAVE_REGS_THUNK (xen_save_fl,".noinstr.text" ); -asmlinkage __visible void xen_irq_disable(void) +asmlinkage __visible noinstr void xen_irq_disable(void) {/* There's a one instruction preempt window here. We need to make sure we're don't switch CPUs between getting the vcpu
@@ -51,7 +51,7 @@ asmlinkage __visible void xen_irq_disable(void)this_cpu_read (xen_vcpu)->evtchn_upcall_mask =1 ;preempt_enable_no_resched (); } -PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable); +__PV_CALLEE_SAVE_REGS_THUNK (xen_irq_disable,".noinstr.text" ); asmlinkage __visible noinstr void xen_irq_enable(void) {
arch/x86/xen/xen-asm.S +1 -2
@@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/linkage.h> +.pushsection .noinstr.text, "ax" /* * Disabling events is simply a matter of making the event mask * non-zero.
@@ -30,8 +31,6 @@ SYM_FUNC_START(xen_irq_disable_direct) ret SYM_FUNC_END(xen_irq_disable_direct) -.pushsection .noinstr.text, "ax" - /* * Force an event check by making a hypercall, but preserve regs * before making the call.
Peter Zijlstra
maintainerPATCH v2 22/24 x86/xen: Mark xen_force_evtchn_callback() noinstr
In reply to Peter Zijlstravmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section
--- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/xen/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, voireturn _hypercall2 (int, event_channel_op, cmd, arg); } -static inline int +static __always_inline intHYPERVISOR_xen_version (int cmd,void *arg) {return _hypercall2 (int, xen_version, cmd, arg);
arch/x86/xen/irq.c +1 -1
@@ -19,7 +19,7 @@* callback mask. We do this in a very simple manner, by making a call * down into Xen. The pending flag will be checked by Xen on return. */ -void xen_force_evtchn_callback (void ) +noinstr void xen_force_evtchn_callback(void) { (void )HYPERVISOR_xen_version (0 ,NULL ); }
Re: [PATCH v2 22/24] x86/xen: Mark xen_force_evtchn_callback() noinstr
Quoted 3 lines · Peter Zijlstra
vmlinux.o: warning: objtool: check_events()+0xd: call to
xen_force_evtchn_callback()leaves .noinstr.text sectionSigned-off-by Peter Zijlstra (Intel) <[email protected]>
Juergen
[tip: objtool/core] x86/xen: Mark xen_force_evtchn_callback() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 41b8edc60d7232d1f3e49165fb6de20f424c4385 Gitweb: https://git.kernel.org/tip/41b8edc60d7232d1f3e49165fb6de20f424c4385 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:21 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00
x86/xen: Mark xen_force_evtchn_callback() noinstr
vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section
--- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/xen/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, void *arg)return _hypercall2 (int, event_channel_op, cmd, arg); } -static inline int +static __always_inline intHYPERVISOR_xen_version (int cmd,void *arg) {return _hypercall2 (int, xen_version, cmd, arg);
arch/x86/xen/irq.c +1 -1
@@ -19,7 +19,7 @@* callback mask. We do this in a very simple manner, by making a call * down into Xen. The pending flag will be checked by Xen on return. */ -void xen_force_evtchn_callback (void ) +noinstr void xen_force_evtchn_callback(void) { (void )HYPERVISOR_xen_version (0 ,NULL ); }
[tip: objtool/core] x86/xen: Mark xen_force_evtchn_callback() noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 847d9317b2b9c7ecc14b953e6ecf9c12bcdb42e9 Gitweb: https://git.kernel.org/tip/847d9317b2b9c7ecc14b953e6ecf9c12bcdb42e9 Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:21 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:20:25 +02:00
x86/xen: Mark xen_force_evtchn_callback() noinstr
vmlinux.o: warning: objtool: check_events()+0xd: call to xen_force_evtchn_callback() leaves .noinstr.text section
--- arch/x86/include/asm/xen/hypercall.h | 2 +- arch/x86/xen/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/x86/include/asm/xen/hypercall.h +1 -1
@@ -358,7 +358,7 @@ HYPERVISOR_event_channel_op(int cmd, void *arg)return _hypercall2 (int, event_channel_op, cmd, arg); } -static inline int +static __always_inline intHYPERVISOR_xen_version (int cmd,void *arg) {return _hypercall2 (int, xen_version, cmd, arg);
arch/x86/xen/irq.c +1 -1
@@ -19,7 +19,7 @@* callback mask. We do this in a very simple manner, by making a call * down into Xen. The pending flag will be checked by Xen on return. */ -void xen_force_evtchn_callback (void ) +noinstr void xen_force_evtchn_callback(void) { (void )HYPERVISOR_xen_version (0 ,NULL ); }
Peter Zijlstra
maintainerPATCH v2 23/24 x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays
In reply to Peter ZijlstraIn order to allow objtool to make sense of all the various paravirt functions, it needs to either parse whole pv_ops[] tables, or observe individual assignments in the form:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and xen_mmu_ops[] are not.
Worse, both the latter two are compiled into the individual assignment for by current GCC, but that's not something one can rely on.
Therefore, convert all three into full pv_ops[] tables. This has the benefit of not needing to teach objtool about the offsets and resulting in more conservative code-gen.
--- arch/x86/xen/enlighten_pv.c | 66 ++++++++++++++++--------------- arch/x86/xen/irq.c | 17 ++++---- arch/x86/xen/mmu_pv.c | 92 ++++++++++++++++++++++---------------------- 3 files changed, 91 insertions(+), 84 deletions(-)
arch/x86/xen/enlighten_pv.c +34 -32
@@ -1051,52 +1051,54 @@ static const struct pv_info xen_info __i .name = "Xen", }; -static const struct pv_cpu_ops xen_cpu_ops__initconst = { - .cpuid = xen_cpuid, +static const typeof (pv_ops) xen_cpu_ops__initconst = { + .cpu = { + .cpuid = xen_cpuid, - .set_debugreg = xen_set_debugreg, - .get_debugreg = xen_get_debugreg, + .set_debugreg = xen_set_debugreg, + .get_debugreg = xen_get_debugreg, - .read_cr0 = xen_read_cr0, - .write_cr0 = xen_write_cr0, + .read_cr0 = xen_read_cr0, + .write_cr0 = xen_write_cr0, - .write_cr4 = xen_write_cr4, + .write_cr4 = xen_write_cr4, - .wbinvd = native_wbinvd, + .wbinvd = native_wbinvd, - .read_msr = xen_read_msr, - .write_msr = xen_write_msr, + .read_msr = xen_read_msr, + .write_msr = xen_write_msr, - .read_msr_safe = xen_read_msr_safe, - .write_msr_safe = xen_write_msr_safe, + .read_msr_safe = xen_read_msr_safe, + .write_msr_safe = xen_write_msr_safe, - .read_pmc = xen_read_pmc, + .read_pmc = xen_read_pmc, - .load_tr_desc = paravirt_nop, - .set_ldt = xen_set_ldt, - .load_gdt = xen_load_gdt, - .load_idt = xen_load_idt, - .load_tls = xen_load_tls, - .load_gs_index = xen_load_gs_index, + .load_tr_desc = paravirt_nop, + .set_ldt = xen_set_ldt, + .load_gdt = xen_load_gdt, + .load_idt = xen_load_idt, + .load_tls = xen_load_tls, + .load_gs_index = xen_load_gs_index, - .alloc_ldt = xen_alloc_ldt, - .free_ldt = xen_free_ldt, + .alloc_ldt = xen_alloc_ldt, + .free_ldt = xen_free_ldt, - .store_tr = xen_store_tr, + .store_tr = xen_store_tr, - .write_ldt_entry = xen_write_ldt_entry, - .write_gdt_entry = xen_write_gdt_entry, - .write_idt_entry = xen_write_idt_entry, - .load_sp0 = xen_load_sp0, + .write_ldt_entry = xen_write_ldt_entry, + .write_gdt_entry = xen_write_gdt_entry, + .write_idt_entry = xen_write_idt_entry, + .load_sp0 = xen_load_sp0, #ifdef CONFIG_X86_IOPL_IOPERM - .invalidate_io_bitmap = xen_invalidate_io_bitmap, - .update_io_bitmap = xen_update_io_bitmap, + .invalidate_io_bitmap = xen_invalidate_io_bitmap, + .update_io_bitmap = xen_update_io_bitmap, #endif - .io_delay = xen_io_delay, + .io_delay = xen_io_delay, - .start_context_switch = paravirt_start_context_switch, - .end_context_switch = xen_end_context_switch, + .start_context_switch = paravirt_start_context_switch, + .end_context_switch = xen_end_context_switch, + }, };static void xen_restart (char *msg)
@@ -1232,7 +1234,7 @@ asmlinkage __visible void __init xen_sta/* Install Xen paravirt ops */ pv_info = xen_info; - pv_ops.cpu = xen_cpu_ops; + pv_ops.cpu = xen_cpu_ops.cpu; paravirt_iret = xen_iret;xen_init_irq_ops ();
arch/x86/xen/irq.c +10 -7
@@ -94,17 +94,20 @@ static void xen_halt(void)xen_safe_halt (); } -static const struct pv_irq_ops xen_irq_ops__initconst = { - .save_fl =PV_CALLEE_SAVE (xen_save_fl), - .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), - .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), +static const typeof (pv_ops) xen_irq_ops__initconst = { + .irq = { - .safe_halt = xen_safe_halt, - .halt = xen_halt, + .save_fl =PV_CALLEE_SAVE (xen_save_fl), + .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), + .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), + + .safe_halt = xen_safe_halt, + .halt = xen_halt, + }, };void __init xen_init_irq_ops (void ) { - pv_ops.irq = xen_irq_ops; + pv_ops.irq = xen_irq_ops.irq; x86_init.irqs.intr_init = xen_init_IRQ; }
arch/x86/xen/mmu_pv.c +47 -45
121 lines not on this page · raw message
Re: [PATCH v2 23/24] x86/xen: Rework the xen_{cpu,irq,mmu}_ops[] arrays
Quoted 12 lines · Peter Zijlstra
In order to allow objtool to make sense of all the various paravirt functions, it needs to either parse whole pv_ops[] tables, or observe individual assignments in the form:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip) bf92 <xen_init_spinlocks+0x5f> bf8a: R_X86_64_PC32 pv_ops+0x268As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and xen_mmu_ops[] are not.
Quoted 8 lines
Worse, both the latter two are compiled into the individual assignment for by current GCC, but that's not something one can rely on.
Therefore, convert all three into full pv_ops[] tables. This has the benefit of not needing to teach objtool about the offsets and resulting in more conservative code-gen.
Signed-off-by Peter Zijlstra (Intel) <[email protected]>
First I was worried by the additional memory consumption, but as the modified tables are all tagged to be __init I don't think this matters.
So:
Juergen
[tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 723a80b05f0b118c53a69ff20384d28b84219afa Gitweb: https://git.kernel.org/tip/723a80b05f0b118c53a69ff20384d28b84219afa Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:22 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00
x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
In order to allow objtool to make sense of all the various paravirt functions, it needs to either parse whole pv_ops[] tables, or observe individual assignments in the form:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and xen_mmu_ops[] are not.
Worse, both the latter two are compiled into the individual assignment for by current GCC, but that's not something one can rely on.
Therefore, convert all three into full pv_ops[] tables. This has the benefit of not needing to teach objtool about the offsets and resulting in more conservative code-gen.
--- arch/x86/xen/enlighten_pv.c | 66 +++++++++++++------------- arch/x86/xen/irq.c | 17 ++++--- arch/x86/xen/mmu_pv.c | 90 ++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 83 deletions(-)
arch/x86/xen/enlighten_pv.c +34 -32
@@ -1050,52 +1050,54 @@ static const struct pv_info xen_info __initconst = { .name = "Xen", }; -static const struct pv_cpu_ops xen_cpu_ops__initconst = { - .cpuid = xen_cpuid, +static const typeof (pv_ops) xen_cpu_ops__initconst = { + .cpu = { + .cpuid = xen_cpuid, - .set_debugreg = xen_set_debugreg, - .get_debugreg = xen_get_debugreg, + .set_debugreg = xen_set_debugreg, + .get_debugreg = xen_get_debugreg, - .read_cr0 = xen_read_cr0, - .write_cr0 = xen_write_cr0, + .read_cr0 = xen_read_cr0, + .write_cr0 = xen_write_cr0, - .write_cr4 = xen_write_cr4, + .write_cr4 = xen_write_cr4, - .wbinvd = native_wbinvd, + .wbinvd = native_wbinvd, - .read_msr = xen_read_msr, - .write_msr = xen_write_msr, + .read_msr = xen_read_msr, + .write_msr = xen_write_msr, - .read_msr_safe = xen_read_msr_safe, - .write_msr_safe = xen_write_msr_safe, + .read_msr_safe = xen_read_msr_safe, + .write_msr_safe = xen_write_msr_safe, - .read_pmc = xen_read_pmc, + .read_pmc = xen_read_pmc, - .load_tr_desc = paravirt_nop, - .set_ldt = xen_set_ldt, - .load_gdt = xen_load_gdt, - .load_idt = xen_load_idt, - .load_tls = xen_load_tls, - .load_gs_index = xen_load_gs_index, + .load_tr_desc = paravirt_nop, + .set_ldt = xen_set_ldt, + .load_gdt = xen_load_gdt, + .load_idt = xen_load_idt, + .load_tls = xen_load_tls, + .load_gs_index = xen_load_gs_index, - .alloc_ldt = xen_alloc_ldt, - .free_ldt = xen_free_ldt, + .alloc_ldt = xen_alloc_ldt, + .free_ldt = xen_free_ldt, - .store_tr = xen_store_tr, + .store_tr = xen_store_tr, - .write_ldt_entry = xen_write_ldt_entry, - .write_gdt_entry = xen_write_gdt_entry, - .write_idt_entry = xen_write_idt_entry, - .load_sp0 = xen_load_sp0, + .write_ldt_entry = xen_write_ldt_entry, + .write_gdt_entry = xen_write_gdt_entry, + .write_idt_entry = xen_write_idt_entry, + .load_sp0 = xen_load_sp0, #ifdef CONFIG_X86_IOPL_IOPERM - .invalidate_io_bitmap = xen_invalidate_io_bitmap, - .update_io_bitmap = xen_update_io_bitmap, + .invalidate_io_bitmap = xen_invalidate_io_bitmap, + .update_io_bitmap = xen_update_io_bitmap, #endif - .io_delay = xen_io_delay, + .io_delay = xen_io_delay, - .start_context_switch = paravirt_start_context_switch, - .end_context_switch = xen_end_context_switch, + .start_context_switch = paravirt_start_context_switch, + .end_context_switch = xen_end_context_switch, + }, };static void xen_restart (char *msg)
@@ -1231,7 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)/* Install Xen paravirt ops */ pv_info = xen_info; - pv_ops.cpu = xen_cpu_ops; + pv_ops.cpu = xen_cpu_ops.cpu; paravirt_iret = xen_iret;xen_init_irq_ops ();
arch/x86/xen/irq.c +10 -7
@@ -94,17 +94,20 @@ static void xen_halt(void)xen_safe_halt (); } -static const struct pv_irq_ops xen_irq_ops__initconst = { - .save_fl =PV_CALLEE_SAVE (xen_save_fl), - .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), - .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), +static const typeof (pv_ops) xen_irq_ops__initconst = { + .irq = { - .safe_halt = xen_safe_halt, - .halt = xen_halt, + .save_fl =PV_CALLEE_SAVE (xen_save_fl), + .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), + .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), + + .safe_halt = xen_safe_halt, + .halt = xen_halt, + }, };void __init xen_init_irq_ops (void ) { - pv_ops.irq = xen_irq_ops; + pv_ops.irq = xen_irq_ops.irq; x86_init.irqs.intr_init = xen_init_IRQ; }
arch/x86/xen/mmu_pv.c +46 -44
120 lines not on this page · raw message
[tip: objtool/core] x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 1462eb381b4c27576a3e818bc9f918765d327fdf Gitweb: https://git.kernel.org/tip/1462eb381b4c27576a3e818bc9f918765d327fdf Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:22 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:20:26 +02:00
x86/xen: Rework the xen_{cpu,irq,mmu}_opsarrays
In order to allow objtool to make sense of all the various paravirt functions, it needs to either parse whole pv_ops[] tables, or observe individual assignments in the form:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268As is, xen_cpu_ops[] is at offset +0 in pv_ops[] and could thus be parsed as a 'normal' pv_ops[] table, however xen_irq_ops[] and xen_mmu_ops[] are not.
Worse, both the latter two are compiled into the individual assignment for by current GCC, but that's not something one can rely on.
Therefore, convert all three into full pv_ops[] tables. This has the benefit of not needing to teach objtool about the offsets and resulting in more conservative code-gen.
--- arch/x86/xen/enlighten_pv.c | 66 +++++++++++++------------- arch/x86/xen/irq.c | 17 ++++--- arch/x86/xen/mmu_pv.c | 90 ++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 83 deletions(-)
arch/x86/xen/enlighten_pv.c +34 -32
@@ -1050,52 +1050,54 @@ static const struct pv_info xen_info __initconst = { .name = "Xen", }; -static const struct pv_cpu_ops xen_cpu_ops__initconst = { - .cpuid = xen_cpuid, +static const typeof (pv_ops) xen_cpu_ops__initconst = { + .cpu = { + .cpuid = xen_cpuid, - .set_debugreg = xen_set_debugreg, - .get_debugreg = xen_get_debugreg, + .set_debugreg = xen_set_debugreg, + .get_debugreg = xen_get_debugreg, - .read_cr0 = xen_read_cr0, - .write_cr0 = xen_write_cr0, + .read_cr0 = xen_read_cr0, + .write_cr0 = xen_write_cr0, - .write_cr4 = xen_write_cr4, + .write_cr4 = xen_write_cr4, - .wbinvd = native_wbinvd, + .wbinvd = native_wbinvd, - .read_msr = xen_read_msr, - .write_msr = xen_write_msr, + .read_msr = xen_read_msr, + .write_msr = xen_write_msr, - .read_msr_safe = xen_read_msr_safe, - .write_msr_safe = xen_write_msr_safe, + .read_msr_safe = xen_read_msr_safe, + .write_msr_safe = xen_write_msr_safe, - .read_pmc = xen_read_pmc, + .read_pmc = xen_read_pmc, - .load_tr_desc = paravirt_nop, - .set_ldt = xen_set_ldt, - .load_gdt = xen_load_gdt, - .load_idt = xen_load_idt, - .load_tls = xen_load_tls, - .load_gs_index = xen_load_gs_index, + .load_tr_desc = paravirt_nop, + .set_ldt = xen_set_ldt, + .load_gdt = xen_load_gdt, + .load_idt = xen_load_idt, + .load_tls = xen_load_tls, + .load_gs_index = xen_load_gs_index, - .alloc_ldt = xen_alloc_ldt, - .free_ldt = xen_free_ldt, + .alloc_ldt = xen_alloc_ldt, + .free_ldt = xen_free_ldt, - .store_tr = xen_store_tr, + .store_tr = xen_store_tr, - .write_ldt_entry = xen_write_ldt_entry, - .write_gdt_entry = xen_write_gdt_entry, - .write_idt_entry = xen_write_idt_entry, - .load_sp0 = xen_load_sp0, + .write_ldt_entry = xen_write_ldt_entry, + .write_gdt_entry = xen_write_gdt_entry, + .write_idt_entry = xen_write_idt_entry, + .load_sp0 = xen_load_sp0, #ifdef CONFIG_X86_IOPL_IOPERM - .invalidate_io_bitmap = xen_invalidate_io_bitmap, - .update_io_bitmap = xen_update_io_bitmap, + .invalidate_io_bitmap = xen_invalidate_io_bitmap, + .update_io_bitmap = xen_update_io_bitmap, #endif - .io_delay = xen_io_delay, + .io_delay = xen_io_delay, - .start_context_switch = paravirt_start_context_switch, - .end_context_switch = xen_end_context_switch, + .start_context_switch = paravirt_start_context_switch, + .end_context_switch = xen_end_context_switch, + }, };static void xen_restart (char *msg)
@@ -1231,7 +1233,7 @@ asmlinkage __visible void __init xen_start_kernel(void)/* Install Xen paravirt ops */ pv_info = xen_info; - pv_ops.cpu = xen_cpu_ops; + pv_ops.cpu = xen_cpu_ops.cpu; paravirt_iret = xen_iret;xen_init_irq_ops ();
arch/x86/xen/irq.c +10 -7
@@ -94,17 +94,20 @@ static void xen_halt(void)xen_safe_halt (); } -static const struct pv_irq_ops xen_irq_ops__initconst = { - .save_fl =PV_CALLEE_SAVE (xen_save_fl), - .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), - .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), +static const typeof (pv_ops) xen_irq_ops__initconst = { + .irq = { - .safe_halt = xen_safe_halt, - .halt = xen_halt, + .save_fl =PV_CALLEE_SAVE (xen_save_fl), + .irq_disable =PV_CALLEE_SAVE (xen_irq_disable), + .irq_enable =PV_CALLEE_SAVE (xen_irq_enable), + + .safe_halt = xen_safe_halt, + .halt = xen_halt, + }, };void __init xen_init_irq_ops (void ) { - pv_ops.irq = xen_irq_ops; + pv_ops.irq = xen_irq_ops.irq; x86_init.irqs.intr_init = xen_init_IRQ; }
arch/x86/xen/mmu_pv.c +46 -44
120 lines not on this page · raw message
Peter Zijlstra
maintainerPATCH v2 24/24 objtool: Support pv_opsindirect calls for noinstr
In reply to Peter ZijlstraNormally objtool will now follow indirect calls; there is no need.
However, this becomes a problem with noinstr validation; if there's an indirect call from noinstr code, we very much need to know it is to another noinstr function. Luckily there aren't many indirect calls in entry code with the obvious exception of paravirt. As such, noinstr validation didn't work with paravirt kernels.
In order to track pv_ops[] call targets, objtool reads the static pv_ops[] tables as well as direct assignments to the pv_ops[] array, provided the compiler makes them a single instruction like:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268There are, as of yet, no warnings for when this goes wrong :/
Using the functions found with the above means, all pv_ops[] calls are now subject to noinstr validation.
--- lib/Kconfig.debug | 2 tools/objtool/arch/x86/decode.c | 34 ++++++- tools/objtool/check.c | 151 +++++++++++++++++++++++++++++--- tools/objtool/include/objtool/arch.h | 2 tools/objtool/include/objtool/elf.h | 1 tools/objtool/include/objtool/objtool.h | 9 + tools/objtool/objtool.c | 22 ++++ 7 files changed, 208 insertions(+), 13 deletions(-)
lib/Kconfig.debug +1 -1
@@ -445,7 +445,7 @@ config STACK_VALIDATION config VMLINUX_VALIDATION bool - depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT + depends on STACK_VALIDATION && DEBUG_ENTRY default y config VMLINUX_MAP
tools/objtool/arch/x86/decode.c +33 -1
@@ -20,6 +20,7 @@#include <objtool/arch.h> #include <objtool/warn.h> #include <objtool/endianness.h> +#include <objtool/builtin.h> #include <arch/elf.h> static int is_x86_64 (const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(stru#define rm_is_mem (reg) (mod_is_mem() && !is_RIP() && rm_is(reg))#define rm_is_reg (reg) (mod_is_reg() && modrm_rm == (reg)) -int arch_decode_instruction (const struct elf *elf,const struct section *sec, +int arch_decode_instruction (struct objtool_file *file,const struct section *sec,unsigned long offset,unsigned int maxlen,unsigned int *len,enum insn_type *type,unsigned long *immediate,struct list_head *ops_list) { +const struct elf *elf = file->elf;struct insn insn;int x86_64, ret; unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct *type =INSN_RETURN ;break ; +case 0xc7 :/* mov imm, r/m */ +if (!noinstr) +break ; + +if (insn.length ==3 +4 +4 && !strncmp (sec->name,".init.text" ,10 )) { +struct reloc *immr, *disp; +struct symbol *func; +int idx; + + immr =find_reloc_by_dest (elf, (void *)sec, offset+3 ); + disp =find_reloc_by_dest (elf, (void *)sec, offset+7 ); + +if (!immr ||strcmp (immr->sym->name,"pv_ops" )) +break ; + + idx = (immr->addend +8 ) /sizeof (void *); + + func = disp->sym; +if (disp->sym->type ==STT_SECTION ) + func =find_symbol_by_offset (disp->sym->sec, disp->addend); +if (!func) { +WARN ("no func for pv_ops[]" ); +return -1 ; + } + +objtool_pv_add (file, idx, func); + } + +break ; +case 0xcf :/* iret */ /* * Handle sync_core(), which has an IRET to self.
tools/objtool/check.c +141 -10
231 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -1
@@ -69,7 +69,7 @@ struct instruction;void arch_initial_func_cfi_state (struct cfi_init_state *state); -int arch_decode_instruction(const struct elf *elf, const struct section *sec, +int arch_decode_instruction(struct objtool_file *file, const struct section *sec, unsigned long offset, unsigned int maxlen, unsigned int *len, enum insn_type *type, unsigned long *immediate,
tools/objtool/include/objtool/elf.h +1 -0
@@ -57,6 +57,7 @@ struct symbol {struct symbol *pfunc, *cfunc, *alias;bool uaccess_safe;bool static_call_tramp; +struct list_head pv_target; };struct reloc {
tools/objtool/include/objtool/objtool.h +9 -0
@@ -14,6 +14,11 @@#define __weak __attribute__((weak)) +struct pv_state { +bool clean; +struct list_head targets; +}; +struct objtool_file {struct elf *elf;struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {unsigned long jl_short, jl_long;unsigned long jl_nop_short, jl_nop_long; + +struct pv_state *pv_ops; };struct objtool_file *objtool_open_read (const char *_objname); +void objtool_pv_add (struct objtool_file *file,int idx,struct symbol *func); +int check (struct objtool_file *file);int orc_dump (const char *objname);int orc_create (struct objtool_file *file);
tools/objtool/objtool.c +22 -0
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(creturn &file; } +void objtool_pv_add (struct objtool_file *f,int idx,struct symbol *func) +{ +if (!noinstr) +return ; + +if (!f->pv_ops) { +WARN ("paravirt confusion" ); +return ; + } + +/* +* These functions will be patched into native code, +* see paravirt_patch(). +*/ +if (!strcmp (func->name,"_paravirt_nop" ) || + !strcmp (func->name,"_paravirt_ident_64" )) +return ; + +list_add (&func->pv_target, &f->pv_ops[idx].targets); + f->pv_ops[idx].clean = false; +} +static void cmd_usage (void ) {unsigned int i, longest =0 ;
[tip: objtool/core] objtool: Support pv_opsindirect calls for noinstr
The following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 55a918e61cf45f28157a2f0bb2535fa79e4a137d Gitweb: https://git.kernel.org/tip/55a918e61cf45f28157a2f0bb2535fa79e4a137d Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:23 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Wed, 15 Sep 2021 15:51:51 +02:00
objtool: Support pv_opsindirect calls for noinstr
Normally objtool will now follow indirect calls; there is no need.
However, this becomes a problem with noinstr validation; if there's an indirect call from noinstr code, we very much need to know it is to another noinstr function. Luckily there aren't many indirect calls in entry code with the obvious exception of paravirt. As such, noinstr validation didn't work with paravirt kernels.
In order to track pv_ops[] call targets, objtool reads the static pv_ops[] tables as well as direct assignments to the pv_ops[] array, provided the compiler makes them a single instruction like:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268There are, as of yet, no warnings for when this goes wrong :/
Using the functions found with the above means, all pv_ops[] calls are now subject to noinstr validation.
--- lib/Kconfig.debug | 2 +- tools/objtool/arch/x86/decode.c | 34 ++++- tools/objtool/check.c | 151 +++++++++++++++++++++-- tools/objtool/include/objtool/arch.h | 2 +- tools/objtool/include/objtool/elf.h | 1 +- tools/objtool/include/objtool/objtool.h | 9 +- tools/objtool/objtool.c | 22 +++- 7 files changed, 208 insertions(+), 13 deletions(-)
lib/Kconfig.debug +1 -1
@@ -458,7 +458,7 @@ config STACK_VALIDATION config VMLINUX_VALIDATION bool - depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT + depends on STACK_VALIDATION && DEBUG_ENTRY default y config VMLINUX_MAP
tools/objtool/arch/x86/decode.c +33 -1
@@ -20,6 +20,7 @@#include <objtool/arch.h> #include <objtool/warn.h> #include <objtool/endianness.h> +#include <objtool/builtin.h> #include <arch/elf.h> static int is_x86_64 (const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(struct instruction *insn)#define rm_is_mem (reg) (mod_is_mem() && !is_RIP() && rm_is(reg))#define rm_is_reg (reg) (mod_is_reg() && modrm_rm == (reg)) -int arch_decode_instruction (const struct elf *elf,const struct section *sec, +int arch_decode_instruction (struct objtool_file *file,const struct section *sec,unsigned long offset,unsigned int maxlen,unsigned int *len,enum insn_type *type,unsigned long *immediate,struct list_head *ops_list) { +const struct elf *elf = file->elf;struct insn insn;int x86_64, ret; unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, *type =INSN_RETURN ;break ; +case 0xc7 :/* mov imm, r/m */ +if (!noinstr) +break ; + +if (insn.length ==3 +4 +4 && !strncmp (sec->name,".init.text" ,10 )) { +struct reloc *immr, *disp; +struct symbol *func; +int idx; + + immr =find_reloc_by_dest (elf, (void *)sec, offset+3 ); + disp =find_reloc_by_dest (elf, (void *)sec, offset+7 ); + +if (!immr ||strcmp (immr->sym->name,"pv_ops" )) +break ; + + idx = (immr->addend +8 ) /sizeof (void *); + + func = disp->sym; +if (disp->sym->type ==STT_SECTION ) + func =find_symbol_by_offset (disp->sym->sec, disp->addend); +if (!func) { +WARN ("no func for pv_ops[]" ); +return -1 ; + } + +objtool_pv_add (file, idx, func); + } + +break ; +case 0xcf :/* iret */ /* * Handle sync_core(), which has an IRET to self.
tools/objtool/check.c +141 -10
231 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -1
@@ -69,7 +69,7 @@ struct instruction;void arch_initial_func_cfi_state (struct cfi_init_state *state); -int arch_decode_instruction(const struct elf *elf, const struct section *sec, +int arch_decode_instruction(struct objtool_file *file, const struct section *sec, unsigned long offset, unsigned int maxlen, unsigned int *len, enum insn_type *type, unsigned long *immediate,
tools/objtool/include/objtool/elf.h +1 -0
@@ -57,6 +57,7 @@ struct symbol {struct symbol *pfunc, *cfunc, *alias;bool uaccess_safe;bool static_call_tramp; +struct list_head pv_target; };struct reloc {
tools/objtool/include/objtool/objtool.h +9 -0
@@ -14,6 +14,11 @@#define __weak __attribute__((weak)) +struct pv_state { +bool clean; +struct list_head targets; +}; +struct objtool_file {struct elf *elf;struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {unsigned long jl_short, jl_long;unsigned long jl_nop_short, jl_nop_long; + +struct pv_state *pv_ops; };struct objtool_file *objtool_open_read (const char *_objname); +void objtool_pv_add (struct objtool_file *file,int idx,struct symbol *func); +int check (struct objtool_file *file);int orc_dump (const char *objname);int orc_create (struct objtool_file *file);
tools/objtool/objtool.c +22 -0
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(const char *_objname)return &file; } +void objtool_pv_add (struct objtool_file *f,int idx,struct symbol *func) +{ +if (!noinstr) +return ; + +if (!f->pv_ops) { +WARN ("paravirt confusion" ); +return ; + } + +/* +* These functions will be patched into native code, +* see paravirt_patch(). +*/ +if (!strcmp (func->name,"_paravirt_nop" ) || + !strcmp (func->name,"_paravirt_ident_64" )) +return ; + +list_add (&func->pv_target, &f->pv_ops[idx].targets); + f->pv_ops[idx].clean = false; +} +static void cmd_usage (void ) {unsigned int i, longest =0 ;
[tip: objtool/core] objtool: Support pv_opsindirect calls for noinstr
In reply to Peter ZijlstraThe following commit has been merged into the objtool/core branch of tip:
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: db2b0c5d7b6f19b3c2cab08c531b65342eb5252b Gitweb: https://git.kernel.org/tip/db2b0c5d7b6f19b3c2cab08c531b65342eb5252b Author: Peter Zijlstra <[email protected]> AuthorDate: Thu, 24 Jun 2021 11:41:23 +02:00 Committer: Peter Zijlstra <[email protected]> CommitterDate: Fri, 17 Sep 2021 13:20:26 +02:00
objtool: Support pv_opsindirect calls for noinstr
Normally objtool will now follow indirect calls; there is no need.
However, this becomes a problem with noinstr validation; if there's an indirect call from noinstr code, we very much need to know it is to another noinstr function. Luckily there aren't many indirect calls in entry code with the obvious exception of paravirt. As such, noinstr validation didn't work with paravirt kernels.
In order to track pv_ops[] call targets, objtool reads the static pv_ops[] tables as well as direct assignments to the pv_ops[] array, provided the compiler makes them a single instruction like:
bf87: 48 c7 05 00 00 00 00 00 00 00 00 movq $0x0,0x0(%rip)
bf92 <xen_init_spinlocks+0x5f>
bf8a: R_X86_64_PC32 pv_ops+0x268There are, as of yet, no warnings for when this goes wrong :/
Using the functions found with the above means, all pv_ops[] calls are now subject to noinstr validation.
--- lib/Kconfig.debug | 2 +- tools/objtool/arch/x86/decode.c | 34 ++++- tools/objtool/check.c | 151 +++++++++++++++++++++-- tools/objtool/include/objtool/arch.h | 2 +- tools/objtool/include/objtool/elf.h | 1 +- tools/objtool/include/objtool/objtool.h | 9 +- tools/objtool/objtool.c | 22 +++- 7 files changed, 208 insertions(+), 13 deletions(-)
lib/Kconfig.debug +1 -1
@@ -458,7 +458,7 @@ config STACK_VALIDATION config VMLINUX_VALIDATION bool - depends on STACK_VALIDATION && DEBUG_ENTRY && !PARAVIRT + depends on STACK_VALIDATION && DEBUG_ENTRY default y config VMLINUX_MAP
tools/objtool/arch/x86/decode.c +33 -1
@@ -20,6 +20,7 @@#include <objtool/arch.h> #include <objtool/warn.h> #include <objtool/endianness.h> +#include <objtool/builtin.h> #include <arch/elf.h> static int is_x86_64 (const struct elf *elf)
@@ -102,12 +103,13 @@ unsigned long arch_jump_destination(struct instruction *insn)#define rm_is_mem (reg) (mod_is_mem() && !is_RIP() && rm_is(reg))#define rm_is_reg (reg) (mod_is_reg() && modrm_rm == (reg)) -int arch_decode_instruction (const struct elf *elf,const struct section *sec, +int arch_decode_instruction (struct objtool_file *file,const struct section *sec,unsigned long offset,unsigned int maxlen,unsigned int *len,enum insn_type *type,unsigned long *immediate,struct list_head *ops_list) { +const struct elf *elf = file->elf;struct insn insn;int x86_64, ret; unsigned char op1, op2,
@@ -544,6 +546,36 @@ int arch_decode_instruction(const struct elf *elf, const struct section *sec, *type =INSN_RETURN ;break ; +case 0xc7 :/* mov imm, r/m */ +if (!noinstr) +break ; + +if (insn.length ==3 +4 +4 && !strncmp (sec->name,".init.text" ,10 )) { +struct reloc *immr, *disp; +struct symbol *func; +int idx; + + immr =find_reloc_by_dest (elf, (void *)sec, offset+3 ); + disp =find_reloc_by_dest (elf, (void *)sec, offset+7 ); + +if (!immr ||strcmp (immr->sym->name,"pv_ops" )) +break ; + + idx = (immr->addend +8 ) /sizeof (void *); + + func = disp->sym; +if (disp->sym->type ==STT_SECTION ) + func =find_symbol_by_offset (disp->sym->sec, disp->addend); +if (!func) { +WARN ("no func for pv_ops[]" ); +return -1 ; + } + +objtool_pv_add (file, idx, func); + } + +break ; +case 0xcf :/* iret */ /* * Handle sync_core(), which has an IRET to self.
tools/objtool/check.c +141 -10
231 lines not on this page · raw message
tools/objtool/include/objtool/arch.h +1 -1
@@ -69,7 +69,7 @@ struct instruction;void arch_initial_func_cfi_state (struct cfi_init_state *state); -int arch_decode_instruction(const struct elf *elf, const struct section *sec, +int arch_decode_instruction(struct objtool_file *file, const struct section *sec, unsigned long offset, unsigned int maxlen, unsigned int *len, enum insn_type *type, unsigned long *immediate,
tools/objtool/include/objtool/elf.h +1 -0
@@ -57,6 +57,7 @@ struct symbol {struct symbol *pfunc, *cfunc, *alias;bool uaccess_safe;bool static_call_tramp; +struct list_head pv_target; };struct reloc {
tools/objtool/include/objtool/objtool.h +9 -0
@@ -14,6 +14,11 @@#define __weak __attribute__((weak)) +struct pv_state { +bool clean; +struct list_head targets; +}; +struct objtool_file {struct elf *elf;struct list_head insn_list;
@@ -25,10 +30,14 @@ struct objtool_file {unsigned long jl_short, jl_long;unsigned long jl_nop_short, jl_nop_long; + +struct pv_state *pv_ops; };struct objtool_file *objtool_open_read (const char *_objname); +void objtool_pv_add (struct objtool_file *file,int idx,struct symbol *func); +int check (struct objtool_file *file);int orc_dump (const char *objname);int orc_create (struct objtool_file *file);
tools/objtool/objtool.c +22 -0
@@ -135,6 +135,28 @@ struct objtool_file *objtool_open_read(const char *_objname)return &file; } +void objtool_pv_add (struct objtool_file *f,int idx,struct symbol *func) +{ +if (!noinstr) +return ; + +if (!f->pv_ops) { +WARN ("paravirt confusion" ); +return ; + } + +/* +* These functions will be patched into native code, +* see paravirt_patch(). +*/ +if (!strcmp (func->name,"_paravirt_nop" ) || + !strcmp (func->name,"_paravirt_ident_64" )) +return ; + +list_add (&func->pv_target, &f->pv_ops[idx].targets); + f->pv_ops[idx].clean = false; +} +static void cmd_usage (void ) {unsigned int i, longest =0 ;
Quoted 1 line · On Thu, 24 Jun 2021 11:40:59 +0200 Peter Zijlstra <[email protected]> wrote:
Steve, can I please delete
TRACE_BRANCH_PROFILINGandPROFILE_ALL_BRANCHESalready?
The TRACE_BRANCH_PROFILING, I never used, so I'm happy to delete it, but I still use the PROFILE_ALL_BRANCHES.
But I'm curious, what's the issue with the PROFILE_ALL_BRANCHES?
You can make it ignore files, by simply adding a:
#define DISABLE_BRANCH_PROFILING
at the top of the file (before any of the includes).
So if your issue is that it makes it hard for some code, simply add that to the top of the file, and it should just work.
-- Steve