Define apic_page construct to unionize APIC register 32bit/64bit accesses and use it in apic_{get|set}*() to avoid using type casting. As Secure AVIC APIC driver requires accessing APIC page at byte offsets (to get an APIC register's bitmap start address), support byte access granularity in apic_page (in addition to 32-bit and 64-bit accesses). One caveat of this change is that the generated code is slighly larger. Below is the code generation for apic_get_reg() using gcc-14.2: - Without change: apic_get_reg: 89 f6 mov %esi,%esi 8b 04 37 mov (%rdi,%rsi,1),%eax c3 ret - With change: apic_get_reg: c1 ee 02 shr $0x2,%esi 8b 04 b7 mov (%rdi,%rsi,4),%eax c3 ret lapic.o text size change is shown below: Obj Old-size New-size lapic.o 28800 28832 Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@xxxxxxx> --- Changes since v7: - Commit log update. arch/x86/include/asm/apic.h | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 07ba4935e873..b7cbe9ba363e 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -525,26 +525,43 @@ static inline int apic_find_highest_vector(void *bitmap) return -1; } +struct apic_page { + union { + u64 regs64[PAGE_SIZE / 8]; + u32 regs[PAGE_SIZE / 4]; + u8 bytes[PAGE_SIZE]; + }; +} __aligned(PAGE_SIZE); + static inline u32 apic_get_reg(void *regs, int reg) { - return *((u32 *) (regs + reg)); + struct apic_page *ap = regs; + + return ap->regs[reg / 4]; } static inline void apic_set_reg(void *regs, int reg, u32 val) { - *((u32 *) (regs + reg)) = val; + struct apic_page *ap = regs; + + ap->regs[reg / 4] = val; } static __always_inline u64 apic_get_reg64(void *regs, int reg) { + struct apic_page *ap = regs; + BUILD_BUG_ON(reg != APIC_ICR); - return *((u64 *) (regs + reg)); + + return ap->regs64[reg / 8]; } static __always_inline void apic_set_reg64(void *regs, int reg, u64 val) { + struct apic_page *ap = regs; + BUILD_BUG_ON(reg != APIC_ICR); - *((u64 *) (regs + reg)) = val; + ap->regs64[reg / 8] = val; } static inline void apic_clear_vector(int vec, void *bitmap) -- 2.34.1