mirror of https://github.com/xemu-project/xemu.git
target/ppc: Move no-execute and guarded page checking into new function
A pte entry has bit fields which can be used to make a page no-execute or guarded, if either of these bits are set then an instruction access to this page will fail. Currently these bits are checked with the pp_prot function however the ISA specifies that the access authority controlled by the key-pp value pair should only be checked on an instruction access after the no-execute and guard bits have already been verified to permit the access. Move the no-execute and guard bit checking into a new separate function. Note that we can remove the check for the no-execute bit in the slb entry since this check was already performed above when we obtained the slb entry. In the event that the no-execute or guard bits are set, an ISI should be generated with the SRR1_NOEXEC_GUARD (0x10000000) bit set in srr1. Add a define for this for clarity. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> [dwg: Move constants to cpu.h since they're not MMUv3 specific] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
347a5c73ba
commit
07a68f9907
target/ppc
|
@ -475,6 +475,7 @@ struct ppc_slb_t {
|
||||||
|
|
||||||
/* SRR1 error code fields */
|
/* SRR1 error code fields */
|
||||||
|
|
||||||
|
#define SRR1_NOEXEC_GUARD 0x10000000
|
||||||
#define SRR1_PROTFAULT 0x08000000
|
#define SRR1_PROTFAULT 0x08000000
|
||||||
#define SRR1_IAMR 0x00200000
|
#define SRR1_IAMR 0x00200000
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,16 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check No-Execute or Guarded Storage */
|
||||||
|
static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu,
|
||||||
|
ppc_hash_pte64_t pte)
|
||||||
|
{
|
||||||
|
/* Exec permissions CANNOT take away read or write permissions */
|
||||||
|
return (pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G) ?
|
||||||
|
PAGE_READ | PAGE_WRITE : PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check Basic Storage Protection */
|
||||||
static int ppc_hash64_pte_prot(PowerPCCPU *cpu,
|
static int ppc_hash64_pte_prot(PowerPCCPU *cpu,
|
||||||
ppc_slb_t *slb, ppc_hash_pte64_t pte)
|
ppc_slb_t *slb, ppc_hash_pte64_t pte)
|
||||||
{
|
{
|
||||||
|
@ -333,12 +343,6 @@ static int ppc_hash64_pte_prot(PowerPCCPU *cpu,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No execute if either noexec or guarded bits set */
|
|
||||||
if (!(pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G)
|
|
||||||
|| (slb->vsid & SLB_VSID_N)) {
|
|
||||||
prot |= PAGE_EXEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prot;
|
return prot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +700,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
|
||||||
unsigned apshift;
|
unsigned apshift;
|
||||||
hwaddr ptex;
|
hwaddr ptex;
|
||||||
ppc_hash_pte64_t pte;
|
ppc_hash_pte64_t pte;
|
||||||
int pp_prot, amr_prot, prot;
|
int exec_prot, pp_prot, amr_prot, prot;
|
||||||
uint64_t new_pte1, dsisr;
|
uint64_t new_pte1, dsisr;
|
||||||
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
|
const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
|
||||||
hwaddr raddr;
|
hwaddr raddr;
|
||||||
|
@ -803,16 +807,19 @@ skip_slb_search:
|
||||||
|
|
||||||
/* 5. Check access permissions */
|
/* 5. Check access permissions */
|
||||||
|
|
||||||
|
exec_prot = ppc_hash64_pte_noexec_guard(cpu, pte);
|
||||||
pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);
|
pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);
|
||||||
amr_prot = ppc_hash64_amr_prot(cpu, pte);
|
amr_prot = ppc_hash64_amr_prot(cpu, pte);
|
||||||
prot = pp_prot & amr_prot;
|
prot = exec_prot & pp_prot & amr_prot;
|
||||||
|
|
||||||
if ((need_prot[rwx] & ~prot) != 0) {
|
if ((need_prot[rwx] & ~prot) != 0) {
|
||||||
/* Access right violation */
|
/* Access right violation */
|
||||||
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
|
qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
|
||||||
if (rwx == 2) {
|
if (rwx == 2) {
|
||||||
int srr1 = 0;
|
int srr1 = 0;
|
||||||
if (PAGE_EXEC & ~pp_prot) {
|
if (PAGE_EXEC & ~exec_prot) {
|
||||||
|
srr1 |= SRR1_NOEXEC_GUARD; /* Access violates noexec or guard */
|
||||||
|
} else if (PAGE_EXEC & ~pp_prot) {
|
||||||
srr1 |= SRR1_PROTFAULT; /* Access violates access authority */
|
srr1 |= SRR1_PROTFAULT; /* Access violates access authority */
|
||||||
}
|
}
|
||||||
if (PAGE_EXEC & ~amr_prot) {
|
if (PAGE_EXEC & ~amr_prot) {
|
||||||
|
|
Loading…
Reference in New Issue