x86/idt: Minor improvements to _update_gate_addr_lower()

After some experimentation, using .a/.b makes far better logic than using the
named fields, as both Clang and GCC spill idte to the stack when named fields
are used.

GCC seems to do something very daft for the addr1 field.  It takes addr,
shifts it by 32, then ANDs with 0xffff0000000000000UL, which requires
manifesting a MOVABS.

Clang follows the C, whereby it ANDs with $imm32, then shifts, avoiding the
MOVABS entirely.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2025-08-13 13:13:08 +01:00
1 parent 64d6d5cbf9
commit cf8fdef99f
1 file changed
+7 -6
+7 -6
View File
@@ -92,15 +92,16 @@ static inline void _set_gate_lower(idt_entry_t *gate, unsigned long type,
* Update the lower half handler of an IDT entry, without changing any other
* configuration.
*/
static inline void _update_gate_addr_lower(idt_entry_t *gate, void *addr)
static inline void _update_gate_addr_lower(idt_entry_t *gate, void *_addr)
{
unsigned long addr = (unsigned long)_addr;
unsigned int addr1 = addr & 0xffff0000U; /* GCC: force better codegen. */
idt_entry_t idte;
idte.a = gate->a;
idte.b = ((unsigned long)(addr) >> 32);
idte.a &= 0x0000FFFFFFFF0000ULL;
idte.a |= (((unsigned long)(addr) & 0xFFFF0000UL) << 32) |
((unsigned long)(addr) & 0xFFFFUL);
idte.b = addr >> 32;
idte.a = gate->a & 0x0000ffffffff0000UL;
idte.a |= (unsigned long)addr1 << 32;
idte.a |= addr & 0xffff;
_write_gate_lower(gate, &idte);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.