mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/APIC: handle overflow in TMICT calculation
With an expiry value on the order of 10 hours, and with a bus scale value of 256k (as supplied by qemu), the (signed) multiplication will be UB. As we've checked that the value is positive, we mean unsigned multiplication anyway. Yet let's play safe against even larger expiry and bus scale values, leveraging the compiler builtin that there is for this purpose. While there also drop the stray cast from the actual TMICT write. Fixes:9062553a0d("added time and accurate timer support") Fixes:b95beb1858("x86: Clean up APIC local timer handling") Reported-by: Stewart Hildebrand <stewart.hildebrand@amd.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> Tested-by: Stewart Hildebrand <stewart.hildebrand@amd.com> master commit:4f14d97a62master date: 2026-04-16 10:29:54 +0200
This commit is contained in:
1 parent
9c79644d35
commit
76b359a878
1 file changed
+9
-3
+9
-3
@@ -1224,10 +1224,16 @@ int reprogram_timer(s_time_t timeout)
|
||||
}
|
||||
|
||||
if ( timeout && ((expire = timeout - NOW()) > 0) )
|
||||
apic_tmict = min_t(uint64_t, (bus_scale * expire) >> BUS_SCALE_SHIFT,
|
||||
UINT32_MAX);
|
||||
{
|
||||
unsigned long product;
|
||||
|
||||
apic_write(APIC_TMICT, (unsigned long)apic_tmict);
|
||||
apic_tmict = UINT32_MAX;
|
||||
if ( !__builtin_umull_overflow(bus_scale, expire, &product) &&
|
||||
(product >>= BUS_SCALE_SHIFT) < apic_tmict )
|
||||
apic_tmict = product;
|
||||
}
|
||||
|
||||
apic_write(APIC_TMICT, apic_tmict);
|
||||
|
||||
return apic_tmict || !timeout;
|
||||
}
|
||||
|
||||