Signed-off-by: Anton Johansson <anjo@rev.ng>
---
include/qemu/target-info-impl.h | 2 ++
include/qemu/target-info.h | 8 ++++++++
target-info.c | 5 +++++
3 files changed, 15 insertions(+)
diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
index 17887f64e2..80d1613128 100644
--- a/include/qemu/target-info-impl.h
+++ b/include/qemu/target-info-impl.h
@@ -18,6 +18,8 @@ typedef struct TargetInfo {
SysEmuTarget target_arch;
/* runtime equivalent of TARGET_LONG_BITS definition */
unsigned long_bits;
+ /* runtime equivalent of TARGET_PHYS_ADDR_SPACE_BITS definition */
+ unsigned phys_addr_space_bits;
/* runtime equivalent of CPU_RESOLVING_TYPE definition */
const char *cpu_type;
/* QOM typename machines for this binary must implement */
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
index abcf25db6f..8474c43404 100644
--- a/include/qemu/target-info.h
+++ b/include/qemu/target-info.h
@@ -23,6 +23,14 @@ const char *target_name(void);
*/
unsigned target_long_bits(void);
+/**
+ * target_phys_addr_space_bits:
+ *
+ * Returns: number of bits needed to represent the targets physical
+ * address space.
+ */
+unsigned target_phys_addr_space_bits(void);
+
/**
* target_machine_typename:
*
diff --git a/target-info.c b/target-info.c
index 3110ab32f7..3d696ae0b3 100644
--- a/target-info.c
+++ b/target-info.c
@@ -22,6 +22,11 @@ unsigned target_long_bits(void)
return target_info()->long_bits;
}
+unsigned target_phys_addr_space_bits(void)
+{
+ return target_info()->phys_addr_space_bits;
+}
+
SysEmuTarget target_arch(void)
{
SysEmuTarget arch = target_info()->target_arch;
--
2.51.0
On 15/10/25 15:27, Anton Johansson wrote:
> Signed-off-by: Anton Johansson <anjo@rev.ng>
> ---
> include/qemu/target-info-impl.h | 2 ++
> include/qemu/target-info.h | 8 ++++++++
> target-info.c | 5 +++++
> 3 files changed, 15 insertions(+)
>
> diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
> index 17887f64e2..80d1613128 100644
> --- a/include/qemu/target-info-impl.h
> +++ b/include/qemu/target-info-impl.h
> @@ -18,6 +18,8 @@ typedef struct TargetInfo {
> SysEmuTarget target_arch;
> /* runtime equivalent of TARGET_LONG_BITS definition */
> unsigned long_bits;
> + /* runtime equivalent of TARGET_PHYS_ADDR_SPACE_BITS definition */
> + unsigned phys_addr_space_bits;
> /* runtime equivalent of CPU_RESOLVING_TYPE definition */
> const char *cpu_type;
> /* QOM typename machines for this binary must implement */
> diff --git a/target-info.c b/target-info.c
> index 3110ab32f7..3d696ae0b3 100644
> --- a/target-info.c
> +++ b/target-info.c
> @@ -22,6 +22,11 @@ unsigned target_long_bits(void)
> return target_info()->long_bits;
> }
>
> +unsigned target_phys_addr_space_bits(void)
> +{
> + return target_info()->phys_addr_space_bits;
> +}
Missing field initialization in target_info_stub[].
BTW this definition seems unused by common code since commit
2e8fe327eb6 ("accel/tcg: Simplify L1_MAP_ADDR_SPACE_BITS").
Do we still need to expose it to common components?
On 15/10/25, Philippe Mathieu-Daudé wrote:
> On 15/10/25 15:27, Anton Johansson wrote:
> > Signed-off-by: Anton Johansson <anjo@rev.ng>
> > ---
> > include/qemu/target-info-impl.h | 2 ++
> > include/qemu/target-info.h | 8 ++++++++
> > target-info.c | 5 +++++
> > 3 files changed, 15 insertions(+)
> >
> > diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
> > index 17887f64e2..80d1613128 100644
> > --- a/include/qemu/target-info-impl.h
> > +++ b/include/qemu/target-info-impl.h
> > @@ -18,6 +18,8 @@ typedef struct TargetInfo {
> > SysEmuTarget target_arch;
> > /* runtime equivalent of TARGET_LONG_BITS definition */
> > unsigned long_bits;
> > + /* runtime equivalent of TARGET_PHYS_ADDR_SPACE_BITS definition */
> > + unsigned phys_addr_space_bits;
> > /* runtime equivalent of CPU_RESOLVING_TYPE definition */
> > const char *cpu_type;
> > /* QOM typename machines for this binary must implement */
>
>
> > diff --git a/target-info.c b/target-info.c
> > index 3110ab32f7..3d696ae0b3 100644
> > --- a/target-info.c
> > +++ b/target-info.c
> > @@ -22,6 +22,11 @@ unsigned target_long_bits(void)
> > return target_info()->long_bits;
> > }
> > +unsigned target_phys_addr_space_bits(void)
> > +{
> > + return target_info()->phys_addr_space_bits;
> > +}
>
> Missing field initialization in target_info_stub[].
Ugh right, thanks!
>
> BTW this definition seems unused by common code since commit
> 2e8fe327eb6 ("accel/tcg: Simplify L1_MAP_ADDR_SPACE_BITS").
>
> Do we still need to expose it to common components?
>
Hmm you're right looking at git grep -C1 TARGET_PHYS_ADDR_SPACE_BITS
(output below excluding the hw/riscv change in the following patch),
there are really aren't that many uses left and none in common code.
We still got to move it to a runtime value somewhere though, what
would be a more suitable location? Maybe as a field in CPUArchState or
some parent QOM machine as only i386, hppa, loongarch, riscv, alpha
actually use the definition.
hw/loongarch/boot.c: return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
--
hw/loongarch/boot.c- *kernel_entry = extract64(le64_to_cpu(hdr->kernel_entry),
hw/loongarch/boot.c: 0, TARGET_PHYS_ADDR_SPACE_BITS);
hw/loongarch/boot.c- *kernel_low = extract64(le64_to_cpu(hdr->load_offset),
hw/loongarch/boot.c: 0, TARGET_PHYS_ADDR_SPACE_BITS);
--
linux-user/alpha/target_proc.h- "L3 cache\t\t: n/a\n",
linux-user/alpha/target_proc.h: model, TARGET_PAGE_SIZE, TARGET_PHYS_ADDR_SPACE_BITS,
linux-user/alpha/target_proc.h- max_cpus, num_cpus, cpu_mask);
--
target/hppa/mem_helper.c: QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
target/hppa/mem_helper.c: return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS);
--
target/hppa/mem_helper.c: addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4);
--
target/hppa/mem_helper.c- /* Ignore the bits beyond physical address space. */
target/hppa/mem_helper.c: ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS);
--
target/i386/cpu.c- if (cpu->phys_bits &&
target/i386/cpu.c: (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
target/i386/cpu.c- cpu->phys_bits < 32)) {
--
target/i386/cpu.c- " (but is %u)",
target/i386/cpu.c: TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
--
target/i386/kvm/kvm.c: QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 52);
target/i386/kvm/kvm.c: assert(cpu->phys_bits <= TARGET_PHYS_ADDR_SPACE_BITS);
--
target/i386/tcg/helper-tcg.h:QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS > TARGET_PHYS_ADDR_SPACE_BITS);
--
target/loongarch/internals.h:#define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS)
target/loongarch/internals.h-#define TARGET_VIRT_MASK MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS)
On 10/17/25 09:11, Anton Johansson wrote:
> Hmm you're right looking at git grep -C1 TARGET_PHYS_ADDR_SPACE_BITS
> (output below excluding the hw/riscv change in the following patch),
> there are really aren't that many uses left and none in common code.
>
> We still got to move it to a runtime value somewhere though, what
> would be a more suitable location? Maybe as a field in CPUArchState or
> some parent QOM machine as only i386, hppa, loongarch, riscv, alpha
> actually use the definition.
A fair few of these are arguably wrong.
> hw/loongarch/boot.c: return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
> --
> hw/loongarch/boot.c- *kernel_entry = extract64(le64_to_cpu(hdr->kernel_entry),
> hw/loongarch/boot.c: 0, TARGET_PHYS_ADDR_SPACE_BITS);
> hw/loongarch/boot.c- *kernel_low = extract64(le64_to_cpu(hdr->load_offset),
> hw/loongarch/boot.c: 0, TARGET_PHYS_ADDR_SPACE_BITS);
This is cpu_loongarch_virt_to_phys, and some repetitions.
This should probably use a loongarch-specific runtime function to find the address space
range supported by the chosen cpu. Or perhaps just a target-specific constant mask.
> linux-user/alpha/target_proc.h- "L3 cache\t\t: n/a\n",
> linux-user/alpha/target_proc.h: model, TARGET_PAGE_SIZE, TARGET_PHYS_ADDR_SPACE_BITS,
> linux-user/alpha/target_proc.h- max_cpus, num_cpus, cpu_mask);
This is the alpha-linux-user implementation of /proc/cpuinfo.
Ideally this should be a target-specific function; see
/* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44. */
#define TARGET_PHYS_ADDR_SPACE_BITS 44
It's certainly not generic, and it's also not really important.
> --
> target/hppa/mem_helper.c: QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
> target/hppa/mem_helper.c: return sextract64(addr, 0, TARGET_PHYS_ADDR_SPACE_BITS);
> --
> target/hppa/mem_helper.c: addr |= -1ull << (TARGET_PHYS_ADDR_SPACE_BITS - 4);
> --
> target/hppa/mem_helper.c- /* Ignore the bits beyond physical address space. */
> target/hppa/mem_helper.c: ent->pa = sextract64(ent->pa, 0, TARGET_PHYS_ADDR_SPACE_BITS);
Similarly
/* ??? PA-8000 through 8600 have 40 bits; PA-8700 and 8900 have 44 bits. */
# define TARGET_PHYS_ADDR_SPACE_BITS 40
While we don't actually name concrete cpu models, bios advertises the (32-bit) HP B160L
machine, which originally had a 7300LC, and the (64-bit) which had a 8700.
I can't find definitive documentation, but I suspect the 7300LC has only 32 physical
address bits. And according to our own comment we get the 8700 value wrong.
In either case, it's not exposed to generic code.
> --
> target/i386/cpu.c- if (cpu->phys_bits &&
> target/i386/cpu.c: (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
> target/i386/cpu.c- cpu->phys_bits < 32)) {
> --
> target/i386/cpu.c- " (but is %u)",
> target/i386/cpu.c: TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
> --
> target/i386/kvm/kvm.c: QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 52);
> target/i386/kvm/kvm.c: assert(cpu->phys_bits <= TARGET_PHYS_ADDR_SPACE_BITS);
All of these are simply making sure that cpu->phys_bits is "in range", which is now
irrelevant because TARGET_PHYS_ADDR_SPACE_BITS itself is no longer in use. They can all
be removed.
> --
> target/i386/tcg/helper-tcg.h:QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS > TARGET_PHYS_ADDR_SPACE_BITS);
Likewise.
> target/loongarch/internals.h:#define TARGET_PHYS_MASK MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS)
This is used by target/loongarch/tcg/tlb_helper.c.
I'm not sure what the implications are.
Should it be using a common function with the loongarch boot virt-to-phys?
Is it re-using TARGET_PHYS_ADDR_SPACE_BITS just because it was convienient?
In either case, it's not exposed to generic code.
r~
On 2025/10/18 上午2:47, Richard Henderson wrote:
> On 10/17/25 09:11, Anton Johansson wrote:
>> Hmm you're right looking at git grep -C1 TARGET_PHYS_ADDR_SPACE_BITS
>> (output below excluding the hw/riscv change in the following patch),
>> there are really aren't that many uses left and none in common code.
>>
>> We still got to move it to a runtime value somewhere though, what
>> would be a more suitable location? Maybe as a field in CPUArchState or
>> some parent QOM machine as only i386, hppa, loongarch, riscv, alpha
>> actually use the definition.
>
> A fair few of these are arguably wrong.
>
>
>> hw/loongarch/boot.c: return addr & MAKE_64BIT_MASK(0,
>> TARGET_PHYS_ADDR_SPACE_BITS);
>> --
>> hw/loongarch/boot.c- *kernel_entry =
>> extract64(le64_to_cpu(hdr->kernel_entry),
>> hw/loongarch/boot.c: 0,
>> TARGET_PHYS_ADDR_SPACE_BITS);
>> hw/loongarch/boot.c- *kernel_low =
>> extract64(le64_to_cpu(hdr->load_offset),
>> hw/loongarch/boot.c: 0,
>> TARGET_PHYS_ADDR_SPACE_BITS);
>
> This is cpu_loongarch_virt_to_phys, and some repetitions.
>
> This should probably use a loongarch-specific runtime function to find
> the address space range supported by the chosen cpu. Or perhaps just a
> target-specific constant mask.
>
>
>> linux-user/alpha/target_proc.h- "L3 cache\t\t: n/a\n",
>> linux-user/alpha/target_proc.h: model, TARGET_PAGE_SIZE,
>> TARGET_PHYS_ADDR_SPACE_BITS,
>> linux-user/alpha/target_proc.h- max_cpus, num_cpus,
>> cpu_mask);
>
> This is the alpha-linux-user implementation of /proc/cpuinfo.
>
> Ideally this should be a target-specific function; see
>
> /* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44. */
> #define TARGET_PHYS_ADDR_SPACE_BITS 44
>
> It's certainly not generic, and it's also not really important.
>
>> --
>> target/hppa/mem_helper.c:
>> QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 54);
>> target/hppa/mem_helper.c: return sextract64(addr, 0,
>> TARGET_PHYS_ADDR_SPACE_BITS);
>> --
>> target/hppa/mem_helper.c: addr |= -1ull <<
>> (TARGET_PHYS_ADDR_SPACE_BITS - 4);
>> --
>> target/hppa/mem_helper.c- /* Ignore the bits beyond physical
>> address space. */
>> target/hppa/mem_helper.c: ent->pa = sextract64(ent->pa, 0,
>> TARGET_PHYS_ADDR_SPACE_BITS);
>
> Similarly
>
> /* ??? PA-8000 through 8600 have 40 bits; PA-8700 and 8900 have 44 bits. */
> # define TARGET_PHYS_ADDR_SPACE_BITS 40
>
> While we don't actually name concrete cpu models, bios advertises the
> (32-bit) HP B160L machine, which originally had a 7300LC, and the
> (64-bit) which had a 8700.
>
> I can't find definitive documentation, but I suspect the 7300LC has only
> 32 physical address bits. And according to our own comment we get the
> 8700 value wrong.
>
> In either case, it's not exposed to generic code.
>
>> --
>> target/i386/cpu.c- if (cpu->phys_bits &&
>> target/i386/cpu.c: (cpu->phys_bits >
>> TARGET_PHYS_ADDR_SPACE_BITS ||
>> target/i386/cpu.c- cpu->phys_bits < 32)) {
>> --
>> target/i386/cpu.c- " (but is %u)",
>> target/i386/cpu.c:
>> TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
>> --
>> target/i386/kvm/kvm.c:
>> QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > 52);
>> target/i386/kvm/kvm.c: assert(cpu->phys_bits <=
>> TARGET_PHYS_ADDR_SPACE_BITS);
>
> All of these are simply making sure that cpu->phys_bits is "in range",
> which is now irrelevant because TARGET_PHYS_ADDR_SPACE_BITS itself is no
> longer in use. They can all be removed.
>
>> --
>> target/i386/tcg/helper-tcg.h:QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS >
>> TARGET_PHYS_ADDR_SPACE_BITS);
>
> Likewise.
>
>
>> target/loongarch/internals.h:#define TARGET_PHYS_MASK
>> MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS)
>
> This is used by target/loongarch/tcg/tlb_helper.c.
>
> I'm not sure what the implications are.
It is to convert it to physical address for compatible issue. With page
directory table, HW discards bits higher than
TARGET_PHYS_ADDR_SPACE_BITS for compatible issue since SW has already
used in this way.
SW sets higher bit and treats it as virtual address, software can use it
directly with set_pXd() and needs not convert to physical address. In
future SW can use page directory table with physical address method,
however there is no obvious benefits and motivation :(
Regards
Bibo Mao
> Should it be using a common function with the loongarch boot virt-to-phys?
> Is it re-using TARGET_PHYS_ADDR_SPACE_BITS just because it was convienient?
>
> In either case, it's not exposed to generic code.
>
>
> r~
© 2016 - 2026 Red Hat, Inc.