summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorLeandro Lupori2022-06-28 15:39:57 +0200
committerDaniel Henrique Barboza2022-07-18 18:59:43 +0200
commit3c2e80ad2fcf004fcf74bf690dc1c952320a5b52 (patch)
tree233b4f9e2594a618c86ab3e92904a0cd3dc77a3b /target
parenttarget/ppc: check tb_env != 0 before printing TBU/TBL/DECR (diff)
downloadqemu-3c2e80ad2fcf004fcf74bf690dc1c952320a5b52.tar.gz
qemu-3c2e80ad2fcf004fcf74bf690dc1c952320a5b52.tar.xz
qemu-3c2e80ad2fcf004fcf74bf690dc1c952320a5b52.zip
ppc: Check partition and process table alignment
Check if partition and process tables are properly aligned, in their size, according to PowerISA 3.1B, Book III 6.7.6 programming note. Hardware and KVM also raise an exception in these cases. Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br> Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com> Message-Id: <20220628133959.15131-2-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/mmu-book3s-v3.c5
-rw-r--r--target/ppc/mmu-radix64.c17
2 files changed, 18 insertions, 4 deletions
diff --git a/target/ppc/mmu-book3s-v3.c b/target/ppc/mmu-book3s-v3.c
index f4985bae78..c8f69b3df9 100644
--- a/target/ppc/mmu-book3s-v3.c
+++ b/target/ppc/mmu-book3s-v3.c
@@ -28,6 +28,11 @@ bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid, ppc_v3_pate_t *entry)
uint64_t patb = cpu->env.spr[SPR_PTCR] & PTCR_PATB;
uint64_t pats = cpu->env.spr[SPR_PTCR] & PTCR_PATS;
+ /* Check if partition table is properly aligned */
+ if (patb & MAKE_64BIT_MASK(0, pats + 12)) {
+ return false;
+ }
+
/* Calculate number of entries */
pats = 1ull << (pats + 12 - 4);
if (pats <= lpid) {
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 21ac958e48..9a8a2e2875 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -383,7 +383,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu,
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
- uint64_t offset, size, prtbe_addr, prtbe0, base_addr, nls, index, pte;
+ uint64_t offset, size, prtb, prtbe_addr, prtbe0, base_addr, nls, index, pte;
int fault_cause = 0, h_page_size, h_prot;
hwaddr h_raddr, pte_addr;
int ret;
@@ -393,9 +393,18 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu,
__func__, access_str(access_type),
eaddr, mmu_idx, pid);
+ prtb = (pate.dw1 & PATE1_R_PRTB);
+ size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
+ if (prtb & (size - 1)) {
+ /* Process Table not properly aligned */
+ if (guest_visible) {
+ ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_R_BADCONFIG);
+ }
+ return 1;
+ }
+
/* Index Process Table by PID to Find Corresponding Process Table Entry */
offset = pid * sizeof(struct prtb_entry);
- size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12);
if (offset >= size) {
/* offset exceeds size of the process table */
if (guest_visible) {
@@ -403,7 +412,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu,
}
return 1;
}
- prtbe_addr = (pate.dw1 & PATE1_R_PRTB) + offset;
+ prtbe_addr = prtb + offset;
if (vhyp_flat_addressing(cpu)) {
prtbe0 = ldq_phys(cs->as, prtbe_addr);
@@ -568,7 +577,7 @@ static bool ppc_radix64_xlate_impl(PowerPCCPU *cpu, vaddr eaddr,
return false;
}
- /* Get Process Table */
+ /* Get Partition Table */
if (cpu->vhyp) {
PPCVirtualHypervisorClass *vhc;
vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);