On Tue, Mar 4, 2025 at 12:55 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > On Mon, Mar 03, 2025 at 09:28:34PM +0800, Menglong Dong wrote: > > For now, the layout of cfi and fineibt is hard coded, and the padding is > > fixed on 16 bytes. > > > > Factor out FINEIBT_INSN_OFFSET and CFI_INSN_OFFSET. CFI_INSN_OFFSET is > > the offset of cfi, which is the same as FUNCTION_ALIGNMENT when > > CALL_PADDING is enabled. And FINEIBT_INSN_OFFSET is the offset where we > > put the fineibt preamble on, which is 16 for now. > > > > When the FUNCTION_ALIGNMENT is bigger than 16, we place the fineibt > > preamble on the last 16 bytes of the padding for better performance, which > > means the fineibt preamble don't use the space that cfi uses. > > > > The FINEIBT_INSN_OFFSET is not used in fineibt_caller_start and > > fineibt_paranoid_start, as it is always "0x10". Note that we need to > > update the offset in fineibt_caller_start and fineibt_paranoid_start if > > FINEIBT_INSN_OFFSET changes. > > > > Signed-off-by: Menglong Dong <dongml2@xxxxxxxxxxxxxxx> > > I'm confused as to what exactly you mean. > > Preamble will have __cfi symbol and some number of NOPs right before > actual symbol like: > > __cfi_foo: > mov $0x12345678, %reg > nop > nop > nop > ... > foo: > > FineIBT must be at foo-16, has nothing to do with performance. This 16 > can also be spelled: fineibt_preamble_size. > > The total size of the preamble is FUNCTION_PADDING_BYTES + CFI_CLANG*5. > > If you increase FUNCTION_PADDING_BYTES by another 5, which is what you > want I think, then we'll have total preamble of 21 bytes; 5 bytes kCFI, > 16 bytes nop. Hello, sorry that I forgot to add something to the changelog. In fact, I don't add extra 5-bytes anymore, which you can see in the 3rd patch. The thing is that we can't add extra 5-bytes if CFI is enabled. Without CFI, we can make the padding space any value, such as 5-bytes, and the layout will be like this: __align: nop nop nop nop nop foo: -- __align +5 However, the CFI will always make the cfi insn 16-bytes aligned. When we set the FUNCTION_PADDING_BYTES to (11 + 5), the layout will be like this: __cfi_foo: nop (11) mov $0x12345678, %reg nop (16) foo: and the padding space is 32-bytes actually. So, we can just select FUNCTION_ALIGNMENT_32B instead, which makes the padding space 32-bytes too, and have the following layout: __cfi_foo: mov $0x12345678, %reg nop (27) foo: And the layout will be like this if fineibt and function metadata is both used: __cfi_foo: mov -- 5 -- cfi, not used anymore if fineibt is used nop nop nop mov -- 5 -- function metadata nop nop nop fineibt -- 16 -- fineibt foo: nopw -- 4 ...... The things that I make in this commit is to make sure that the code in arch/x86/kernel/alternative.c can find the location of cfi hash and fineibt depends on the FUNCTION_ALIGNMENT. the offset of cfi and fineibt is different now, so we need to do some adjustment here. In the beginning, I thought to make the layout like this to ensure that the offset of cfi and fineibt the same: __cfi_foo: fineibt -- 16 -- fineibt mov -- 5 -- function metadata nop(11) foo: nopw -- 4 ...... The adjustment will be easier in this mode. However, it may have impact on the performance. That way I say it doesn't impact the performance in this commit. Sorry that I didn't describe it clearly in the commit log, and I'll add the things above to the commit log too in the next version. Thanks! Menglong Dong > > Then kCFI expects hash to be at -20, while FineIBT must be at -16. > > This then means there is no unambiguous hole for you to stick your > meta-data thing (whatever that is). > > There are two options: make meta data location depend on cfi_mode, or > have __apply_fineibt() rewrite kCFI to also be at -16, so that you can > have -21 for your 5 bytes. > > I think I prefer latter. > > In any case, I don't think we need *_INSN_OFFSET. At most we need > PREAMBLE_SIZE. > > Hmm?