* [PATCH-for-9.1 v3 0/2] target/mips: Use correct MMU index in get_pte()
@ 2024-08-13 13:53 Philippe Mathieu-Daudé
2024-08-13 13:53 ` [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte() Philippe Mathieu-Daudé
2024-08-13 13:53 ` [PATCH-for-9.1 v3 2/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
0 siblings, 2 replies; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-08-13 13:53 UTC (permalink / raw)
To: qemu-devel
Cc: Thomas Petazzoni, Richard Henderson, Aleksandar Rikalo,
Waldemar Brodkorb, Philippe Mathieu-Daudé, Aurelien Jarno,
Jiaxun Yang
Since v2:
- Use MemOp (rth)
Propage ptw_mmu_idx to get_pte() and use it via
the cpu_ld/st_code_mmu() API.
Philippe Mathieu-Daudé (2):
target/mips: Pass page table entry size as MemOp to get_pte()
target/mips: Use correct MMU index in get_pte()
target/mips/tcg/sysemu/tlb_helper.c | 70 ++++++++++++++---------------
1 file changed, 35 insertions(+), 35 deletions(-)
--
2.45.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte()
2024-08-13 13:53 [PATCH-for-9.1 v3 0/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
@ 2024-08-13 13:53 ` Philippe Mathieu-Daudé
2024-08-13 21:44 ` Richard Henderson
2024-08-13 13:53 ` [PATCH-for-9.1 v3 2/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
1 sibling, 1 reply; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-08-13 13:53 UTC (permalink / raw)
To: qemu-devel
Cc: Thomas Petazzoni, Richard Henderson, Aleksandar Rikalo,
Waldemar Brodkorb, Philippe Mathieu-Daudé, Aurelien Jarno,
Jiaxun Yang
In order to simplify the next commit, pass the PTE size as MemOp.
Rename:
native_shift -> native_op
directory_shift -> directory_mop
leaf_shift -> leaf_mop
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/mips/tcg/sysemu/tlb_helper.c | 59 +++++++++++++----------------
1 file changed, 27 insertions(+), 32 deletions(-)
diff --git a/target/mips/tcg/sysemu/tlb_helper.c b/target/mips/tcg/sysemu/tlb_helper.c
index 3ba6d369a6..75a26131ca 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -592,13 +592,13 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
* resulting in a TLB or XTLB Refill exception.
*/
-static bool get_pte(CPUMIPSState *env, uint64_t vaddr, int entry_size,
+static bool get_pte(CPUMIPSState *env, uint64_t vaddr, MemOp op,
uint64_t *pte)
{
- if ((vaddr & ((entry_size >> 3) - 1)) != 0) {
+ if ((vaddr & (memop_size(op) - 1)) != 0) {
return false;
}
- if (entry_size == 64) {
+ if (op == MO_64) {
*pte = cpu_ldq_code(env, vaddr);
} else {
*pte = cpu_ldl_code(env, vaddr);
@@ -607,11 +607,11 @@ static bool get_pte(CPUMIPSState *env, uint64_t vaddr, int entry_size,
}
static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
- int entry_size, int ptei)
+ MemOp op, int ptei)
{
uint64_t result = entry;
uint64_t rixi;
- if (ptei > entry_size) {
+ if (ptei > memop_size(op)) {
ptei -= 32;
}
result >>= (ptei - 2);
@@ -624,14 +624,12 @@ static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
int directory_index, bool *huge_page, bool *hgpg_directory_hit,
uint64_t *pw_entrylo0, uint64_t *pw_entrylo1,
- unsigned directory_shift, unsigned leaf_shift, int ptw_mmu_idx)
+ MemOp directory_mop, MemOp leaf_mop, int ptw_mmu_idx)
{
int dph = (env->CP0_PWCtl >> CP0PC_DPH) & 0x1;
int psn = (env->CP0_PWCtl >> CP0PC_PSN) & 0x3F;
int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
int pf_ptew = (env->CP0_PWField >> CP0PF_PTEW) & 0x3F;
- uint32_t direntry_size = 1 << (directory_shift + 3);
- uint32_t leafentry_size = 1 << (leaf_shift + 3);
uint64_t entry;
uint64_t paddr;
int prot;
@@ -643,14 +641,14 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
/* wrong base address */
return 0;
}
- if (!get_pte(env, *vaddr, direntry_size, &entry)) {
+ if (!get_pte(env, *vaddr, directory_mop, &entry)) {
return 0;
}
if ((entry & (1 << psn)) && hugepg) {
*huge_page = true;
*hgpg_directory_hit = true;
- entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew);
+ entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
w = directory_index - 1;
if (directory_index & 0x1) {
/* Generate adjacent page from same PTE for odd TLB page */
@@ -658,7 +656,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
*pw_entrylo0 = entry & ~lsb; /* even page */
*pw_entrylo1 = entry | lsb; /* odd page */
} else if (dph) {
- int oddpagebit = 1 << leaf_shift;
+ int oddpagebit = 1 << leaf_mop;
uint64_t vaddr2 = *vaddr ^ oddpagebit;
if (*vaddr & oddpagebit) {
*pw_entrylo1 = entry;
@@ -669,10 +667,10 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
ptw_mmu_idx) != TLBRET_MATCH) {
return 0;
}
- if (!get_pte(env, vaddr2, leafentry_size, &entry)) {
+ if (!get_pte(env, vaddr2, leaf_mop, &entry)) {
return 0;
}
- entry = get_tlb_entry_layout(env, entry, leafentry_size, pf_ptew);
+ entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
if (*vaddr & oddpagebit) {
*pw_entrylo0 = entry;
} else {
@@ -711,7 +709,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
/* Native pointer size */
/*For the 32-bit architectures, this bit is fixed to 0.*/
- int native_shift = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? 2 : 3;
+ MemOp native_op = (((env->CP0_PWSize >> CP0PS_PS) & 1) == 0) ? MO_32 : MO_64;
/* Indices from PWField */
int pf_gdw = (env->CP0_PWField >> CP0PF_GDW) & 0x3F;
@@ -728,11 +726,10 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
/* Other HTW configs */
int hugepg = (env->CP0_PWCtl >> CP0PC_HUGEPG) & 0x1;
- unsigned directory_shift, leaf_shift;
+ MemOp directory_mop, leaf_mop;
/* Offsets into tables */
unsigned goffset, uoffset, moffset, ptoffset0, ptoffset1;
- uint32_t leafentry_size;
/* Starting address - Page Table Base */
uint64_t vaddr = env->CP0_PWBase;
@@ -759,23 +756,21 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
}
/* HTW Shift values (depend on entry size) */
- directory_shift = (hugepg && (ptew == 1)) ? native_shift + 1 : native_shift;
- leaf_shift = (ptew == 1) ? native_shift + 1 : native_shift;
+ directory_mop = (hugepg && (ptew == 1)) ? native_op + 1 : native_op;
+ leaf_mop = (ptew == 1) ? native_op + 1 : native_op;
- goffset = gindex << directory_shift;
- uoffset = uindex << directory_shift;
- moffset = mindex << directory_shift;
- ptoffset0 = (ptindex >> 1) << (leaf_shift + 1);
- ptoffset1 = ptoffset0 | (1 << (leaf_shift));
-
- leafentry_size = 1 << (leaf_shift + 3);
+ goffset = gindex << directory_mop;
+ uoffset = uindex << directory_mop;
+ moffset = mindex << directory_mop;
+ ptoffset0 = (ptindex >> 1) << (leaf_mop + 1);
+ ptoffset1 = ptoffset0 | (1 << (leaf_mop));
/* Global Directory */
if (gdw > 0) {
vaddr |= goffset;
switch (walk_directory(env, &vaddr, pf_gdw, &huge_page, &hgpg_gdhit,
&pw_entrylo0, &pw_entrylo1,
- directory_shift, leaf_shift, ptw_mmu_idx))
+ directory_mop, leaf_mop, ptw_mmu_idx))
{
case 0:
return false;
@@ -792,7 +787,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
vaddr |= uoffset;
switch (walk_directory(env, &vaddr, pf_udw, &huge_page, &hgpg_udhit,
&pw_entrylo0, &pw_entrylo1,
- directory_shift, leaf_shift, ptw_mmu_idx))
+ directory_mop, leaf_mop, ptw_mmu_idx))
{
case 0:
return false;
@@ -809,7 +804,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
vaddr |= moffset;
switch (walk_directory(env, &vaddr, pf_mdw, &huge_page, &hgpg_mdhit,
&pw_entrylo0, &pw_entrylo1,
- directory_shift, leaf_shift, ptw_mmu_idx))
+ directory_mop, leaf_mop, ptw_mmu_idx))
{
case 0:
return false;
@@ -827,10 +822,10 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
ptw_mmu_idx) != TLBRET_MATCH) {
return false;
}
- if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) {
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry)) {
return false;
}
- dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew);
+ dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
pw_entrylo0 = dir_entry;
/* Leaf Level Page Table - Second half of PTE pair */
@@ -839,10 +834,10 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
ptw_mmu_idx) != TLBRET_MATCH) {
return false;
}
- if (!get_pte(env, vaddr, leafentry_size, &dir_entry)) {
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry)) {
return false;
}
- dir_entry = get_tlb_entry_layout(env, dir_entry, leafentry_size, pf_ptew);
+ dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
pw_entrylo1 = dir_entry;
refill:
--
2.45.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH-for-9.1 v3 2/2] target/mips: Use correct MMU index in get_pte()
2024-08-13 13:53 [PATCH-for-9.1 v3 0/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
2024-08-13 13:53 ` [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte() Philippe Mathieu-Daudé
@ 2024-08-13 13:53 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-08-13 13:53 UTC (permalink / raw)
To: qemu-devel
Cc: Thomas Petazzoni, Richard Henderson, Aleksandar Rikalo,
Waldemar Brodkorb, Philippe Mathieu-Daudé, Aurelien Jarno,
Jiaxun Yang
When refactoring page_table_walk_refill() in commit 4e999bf419
we missed the indirect call to cpu_mmu_index() in get_pte():
page_table_walk_refill()
-> get_pte()
-> cpu_ld[lq]_code()
-> cpu_mmu_index()
Since we don't mask anymore the modes in hflags, cpu_mmu_index()
can return UM or SM, while we only expect KM or ERL.
Fix by propagating ptw_mmu_idx to get_pte(), and use the
cpu_ld/st_code_mmu() API with the correct MemOpIdx.
Reported-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Reported-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2470
Fixes: 4e999bf419 ("target/mips: Pass ptw_mmu_idx down from mips_cpu_tlb_fill")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/mips/tcg/sysemu/tlb_helper.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/target/mips/tcg/sysemu/tlb_helper.c b/target/mips/tcg/sysemu/tlb_helper.c
index 75a26131ca..5bff4cb72f 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -593,16 +593,21 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
*/
static bool get_pte(CPUMIPSState *env, uint64_t vaddr, MemOp op,
- uint64_t *pte)
+ uint64_t *pte, unsigned ptw_mmu_idx)
{
+ MemOpIdx oi;
+
if ((vaddr & (memop_size(op) - 1)) != 0) {
return false;
}
+
+ oi = make_memop_idx(op | MO_TE, ptw_mmu_idx);
if (op == MO_64) {
- *pte = cpu_ldq_code(env, vaddr);
+ *pte = cpu_ldq_code_mmu(env, vaddr, oi, 0);
} else {
- *pte = cpu_ldl_code(env, vaddr);
+ *pte = cpu_ldl_code_mmu(env, vaddr, oi, 0);
}
+
return true;
}
@@ -641,7 +646,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
/* wrong base address */
return 0;
}
- if (!get_pte(env, *vaddr, directory_mop, &entry)) {
+ if (!get_pte(env, *vaddr, directory_mop, &entry, ptw_mmu_idx)) {
return 0;
}
@@ -667,7 +672,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
ptw_mmu_idx) != TLBRET_MATCH) {
return 0;
}
- if (!get_pte(env, vaddr2, leaf_mop, &entry)) {
+ if (!get_pte(env, vaddr2, leaf_mop, &entry, ptw_mmu_idx)) {
return 0;
}
entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
@@ -822,7 +827,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
ptw_mmu_idx) != TLBRET_MATCH) {
return false;
}
- if (!get_pte(env, vaddr, leaf_mop, &dir_entry)) {
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
return false;
}
dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
@@ -834,7 +839,7 @@ static bool page_table_walk_refill(CPUMIPSState *env, vaddr address,
ptw_mmu_idx) != TLBRET_MATCH) {
return false;
}
- if (!get_pte(env, vaddr, leaf_mop, &dir_entry)) {
+ if (!get_pte(env, vaddr, leaf_mop, &dir_entry, ptw_mmu_idx)) {
return false;
}
dir_entry = get_tlb_entry_layout(env, dir_entry, leaf_mop, pf_ptew);
--
2.45.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte()
2024-08-13 13:53 ` [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte() Philippe Mathieu-Daudé
@ 2024-08-13 21:44 ` Richard Henderson
2024-08-14 8:58 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2024-08-13 21:44 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Thomas Petazzoni, Aleksandar Rikalo, Waldemar Brodkorb,
Aurelien Jarno, Jiaxun Yang
On 8/13/24 23:53, Philippe Mathieu-Daudé wrote:
> @@ -607,11 +607,11 @@ static bool get_pte(CPUMIPSState *env, uint64_t vaddr, int entry_size,
> }
>
> static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
> - int entry_size, int ptei)
> + MemOp op, int ptei)
> {
> uint64_t result = entry;
> uint64_t rixi;
> - if (ptei > entry_size) {
> + if (ptei > memop_size(op)) {
entry_size had been 32/64, now you're comparing against 4/8.
Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte()
2024-08-13 21:44 ` Richard Henderson
@ 2024-08-14 8:58 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-08-14 8:58 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: Thomas Petazzoni, Aleksandar Rikalo, Waldemar Brodkorb,
Aurelien Jarno, Jiaxun Yang
On 13/8/24 23:44, Richard Henderson wrote:
> On 8/13/24 23:53, Philippe Mathieu-Daudé wrote:
>> @@ -607,11 +607,11 @@ static bool get_pte(CPUMIPSState *env, uint64_t
>> vaddr, int entry_size,
>> }
>> static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
>> - int entry_size, int ptei)
>> + MemOp op, int ptei)
>> {
>> uint64_t result = entry;
>> uint64_t rixi;
>> - if (ptei > entry_size) {
>> + if (ptei > memop_size(op)) {
>
> entry_size had been 32/64, now you're comparing against 4/8.
Doh good catch, thanks! I'm squashing:
-- >8 --
diff --git a/target/mips/tcg/sysemu/tlb_helper.c
b/target/mips/tcg/sysemu/tlb_helper.c
index 7050ea78df..3836137750 100644
--- a/target/mips/tcg/sysemu/tlb_helper.c
+++ b/target/mips/tcg/sysemu/tlb_helper.c
@@ -614,9 +614,10 @@ static bool get_pte(CPUMIPSState *env, uint64_t
vaddr, MemOp op,
static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
MemOp op, int ptei)
{
+ unsigned entry_size = memop_size(op) << 3;
uint64_t result = entry;
uint64_t rixi;
- if (ptei > memop_size(op)) {
+ if (ptei > entry_size) {
ptei -= 32;
}
result >>= (ptei - 2);
---
so this hunk becomes:
-- >8 --
@@ -607,8 +607,9 @@ static bool get_pte(CPUMIPSState *env, uint64_t
vaddr, int entry_size,
}
static uint64_t get_tlb_entry_layout(CPUMIPSState *env, uint64_t entry,
- int entry_size, int ptei)
+ MemOp op, int ptei)
{
+ unsigned entry_size = memop_size(op) << 3;
uint64_t result = entry;
uint64_t rixi;
if (ptei > entry_size) {
---
> Otherwise,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Thanks!
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-08-14 8:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-13 13:53 [PATCH-for-9.1 v3 0/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
2024-08-13 13:53 ` [PATCH-for-9.1 v3 1/2] target/mips: Pass page table entry size as MemOp to get_pte() Philippe Mathieu-Daudé
2024-08-13 21:44 ` Richard Henderson
2024-08-14 8:58 ` Philippe Mathieu-Daudé
2024-08-13 13:53 ` [PATCH-for-9.1 v3 2/2] target/mips: Use correct MMU index in get_pte() Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).