mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-10 11:04:58 -06:00
target/hppa: fix access_id check
PA2.0 provides 8 instead of 4 PID registers. Signed-off-by: Sven Schnelle <svens@stackframe.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20240319161921.487080-4-svens@stackframe.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
d37fad0ae5
commit
ae157fc250
1 changed files with 62 additions and 18 deletions
|
@ -152,6 +152,49 @@ static HPPATLBEntry *hppa_alloc_tlb_ent(CPUHPPAState *env)
|
||||||
return ent;
|
return ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ACCESS_ID_MASK 0xffff
|
||||||
|
|
||||||
|
/* Return the set of protections allowed by a PID match. */
|
||||||
|
static int match_prot_id_1(uint32_t access_id, uint32_t prot_id)
|
||||||
|
{
|
||||||
|
if (((access_id ^ (prot_id >> 1)) & ACCESS_ID_MASK) == 0) {
|
||||||
|
return (prot_id & 1
|
||||||
|
? PAGE_EXEC | PAGE_READ
|
||||||
|
: PAGE_EXEC | PAGE_READ | PAGE_WRITE);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int match_prot_id32(CPUHPPAState *env, uint32_t access_id)
|
||||||
|
{
|
||||||
|
int r, i;
|
||||||
|
|
||||||
|
for (i = CR_PID1; i <= CR_PID4; ++i) {
|
||||||
|
r = match_prot_id_1(access_id, env->cr[i]);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int match_prot_id64(CPUHPPAState *env, uint32_t access_id)
|
||||||
|
{
|
||||||
|
int r, i;
|
||||||
|
|
||||||
|
for (i = CR_PID1; i <= CR_PID4; ++i) {
|
||||||
|
r = match_prot_id_1(access_id, env->cr[i]);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
r = match_prot_id_1(access_id, env->cr[i] >> 32);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
|
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
|
||||||
int type, hwaddr *pphys, int *pprot,
|
int type, hwaddr *pphys, int *pprot,
|
||||||
HPPATLBEntry **tlb_entry)
|
HPPATLBEntry **tlb_entry)
|
||||||
|
@ -224,29 +267,30 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* access_id == 0 means public page and no check is performed */
|
/*
|
||||||
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
|
* No guest access type indicates a non-architectural access from
|
||||||
/* If bits [31:1] match, and bit 0 is set, suppress write. */
|
* within QEMU. Bypass checks for access, D, B, P and T bits.
|
||||||
int match = ent->access_id * 2 + 1;
|
*/
|
||||||
|
|
||||||
if (match == env->cr[CR_PID1] || match == env->cr[CR_PID2] ||
|
|
||||||
match == env->cr[CR_PID3] || match == env->cr[CR_PID4]) {
|
|
||||||
prot &= PAGE_READ | PAGE_EXEC;
|
|
||||||
if (type == PAGE_WRITE) {
|
|
||||||
ret = EXCP_DMPI;
|
|
||||||
goto egress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No guest access type indicates a non-architectural access from
|
|
||||||
within QEMU. Bypass checks for access, D, B and T bits. */
|
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
goto egress;
|
goto egress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* access_id == 0 means public page and no check is performed */
|
||||||
|
if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
|
||||||
|
int access_prot = (hppa_is_pa20(env)
|
||||||
|
? match_prot_id64(env, ent->access_id)
|
||||||
|
: match_prot_id32(env, ent->access_id));
|
||||||
|
if (unlikely(!(type & access_prot))) {
|
||||||
|
/* Not allowed -- Inst/Data Memory Protection Id Fault. */
|
||||||
|
ret = type & PAGE_EXEC ? EXCP_IMP : EXCP_DMPI;
|
||||||
|
goto egress;
|
||||||
|
}
|
||||||
|
/* Otherwise exclude permissions not allowed (i.e WD). */
|
||||||
|
prot &= access_prot;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(!(prot & type))) {
|
if (unlikely(!(prot & type))) {
|
||||||
/* The access isn't allowed -- Inst/Data Memory Protection Fault. */
|
/* Not allowed -- Inst/Data Memory Access Rights Fault. */
|
||||||
ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
|
ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
|
||||||
goto egress;
|
goto egress;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue