xen: Split muldiv64() out of lib.h

muldiv64() has 7 users across all architectures, and is limited to time
handling functions.  Therefore, move it's declaration out of lib.h into a
dedicated header.

Rename the library function to generic_muldiv64(), as x86 is going to provide
an arch_muldiv64() in a subsequent change.

Explain what the function does, including the limitations; x86's version will
suffer a divide error rather than truncate the result to 64 bits.

Annotate it with attr_const, not that this allows the optimiser to improve any
of Xen's current users.  Add one selftest to check the internal precision,
putting it in bitops.c for want of any better place to put it.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
Andrew Cooper committed 2026-01-07 11:53:01 +00:00
1 parent fe0e477e25
commit 7a459b8df7
8 files changed
+37 -10

No files matched your search

+1 -1
View File
@@ -16,8 +16,8 @@
#include <xen/event.h>
#include <xen/init.h>
#include <xen/irq.h>
#include <xen/lib.h>
#include <xen/mm.h>
#include <xen/muldiv64.h>
#include <xen/notifier.h>
#include <xen/sched.h>
#include <xen/sched.h>
+2 -2
View File
@@ -3,8 +3,8 @@
#define ASM__RISCV__TIME_H
#include <xen/bug.h>
#include <xen/lib.h>
#include <xen/types.h>
#include <xen/muldiv64.h>
#include <asm/csr.h>
/* Clock cycles count at Xen startup */
+1 -1
View File
@@ -25,8 +25,8 @@
*/
#include <xen/errno.h>
#include <xen/lib.h>
#include <xen/mm.h>
#include <xen/muldiv64.h>
#include <xen/sched.h>
#include <xen/trace.h>
#include <xen/xmalloc.h>
+1 -1
View File
@@ -17,7 +17,7 @@
#include <xen/init.h>
#include <xen/irq.h>
#include <xen/keyhandler.h>
#include <xen/lib.h>
#include <xen/muldiv64.h>
#include <xen/param.h>
#include <xen/pci_ids.h>
#include <xen/sched.h>
+12
View File
@@ -247,3 +247,15 @@ static void __init __constructor test_bitops(void)
test_multiple_bits_set();
test_hweight();
}
#include <xen/muldiv64.h>
/* Not a bitop, but here in lieu of any any better location */
static void __init __constructor test_muldiv64(void)
{
uint64_t res = muldiv64(0xffffffffffffffffULL,
HIDE(0xffffffffU),
HIDE(0xffffffffU));
if ( res != 0xffffffffffffffffULL )
panic("muldiv64(), expecting -1ULL, got %#"PRIx64"\n", res);
}
-2
View File
@@ -136,8 +136,6 @@ unsigned long long simple_strtoull(
unsigned long long parse_size_and_unit(const char *s, const char **ps);
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
/*
* A slightly more typesafe variant of cmpxchg() when the entities dealt with
* are pointers.
+18
View File
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef XEN_MULDIV64_H
#define XEN_MULDIV64_H
#include <xen/stdint.h>
uint64_t attr_const generic_muldiv64(uint64_t a, uint32_t b, uint32_t c);
/*
* Calculate a * b / c using at least 96-bit internal precision. The
* behaviour is undefined if the end result does not fit in a uint64_t.
*/
static inline uint64_t attr_const muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
return generic_muldiv64(a, b, c);
}
#endif /* XEN_MULDIV64_H */
+2 -3
View File
@@ -1,7 +1,6 @@
#include <xen/lib.h>
#include <xen/muldiv64.h>
/* Compute with 96 bit intermediate result: (a*b)/c */
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
uint64_t generic_muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
#ifdef CONFIG_X86
asm ( "mulq %1; divq %2" : "+a" (a)
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.