1 /* 2 * PowerPC Radix MMU mulation helpers for QEMU. 3 * 4 * Copyright (c) 2016 Suraj Jitindar Singh, IBM Corporation 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "exec/exec-all.h" 23 #include "exec/helper-proto.h" 24 #include "qemu/error-report.h" 25 #include "sysemu/kvm.h" 26 #include "kvm_ppc.h" 27 #include "exec/log.h" 28 #include "internal.h" 29 #include "mmu-radix64.h" 30 #include "mmu-book3s-v3.h" 31 32 static bool ppc_radix64_get_fully_qualified_addr(const CPUPPCState *env, 33 vaddr eaddr, 34 uint64_t *lpid, uint64_t *pid) 35 { 36 if (msr_hv) { /* MSR[HV] -> Hypervisor/bare metal */ 37 switch (eaddr & R_EADDR_QUADRANT) { 38 case R_EADDR_QUADRANT0: 39 *lpid = 0; 40 *pid = env->spr[SPR_BOOKS_PID]; 41 break; 42 case R_EADDR_QUADRANT1: 43 *lpid = env->spr[SPR_LPIDR]; 44 *pid = env->spr[SPR_BOOKS_PID]; 45 break; 46 case R_EADDR_QUADRANT2: 47 *lpid = env->spr[SPR_LPIDR]; 48 *pid = 0; 49 break; 50 case R_EADDR_QUADRANT3: 51 *lpid = 0; 52 *pid = 0; 53 break; 54 default: 55 g_assert_not_reached(); 56 } 57 } else { /* !MSR[HV] -> Guest */ 58 switch (eaddr & R_EADDR_QUADRANT) { 59 case R_EADDR_QUADRANT0: /* Guest application */ 60 *lpid = env->spr[SPR_LPIDR]; 61 *pid = env->spr[SPR_BOOKS_PID]; 62 break; 63 case R_EADDR_QUADRANT1: /* Illegal */ 64 case R_EADDR_QUADRANT2: 65 return false; 66 case R_EADDR_QUADRANT3: /* Guest OS */ 67 *lpid = env->spr[SPR_LPIDR]; 68 *pid = 0; /* pid set to 0 -> addresses guest operating system */ 69 break; 70 default: 71 g_assert_not_reached(); 72 } 73 } 74 75 return true; 76 } 77 78 static void ppc_radix64_raise_segi(PowerPCCPU *cpu, MMUAccessType access_type, 79 vaddr eaddr) 80 { 81 CPUState *cs = CPU(cpu); 82 CPUPPCState *env = &cpu->env; 83 84 switch (access_type) { 85 case MMU_INST_FETCH: 86 /* Instruction Segment Interrupt */ 87 cs->exception_index = POWERPC_EXCP_ISEG; 88 break; 89 case MMU_DATA_STORE: 90 case MMU_DATA_LOAD: 91 /* Data Segment Interrupt */ 92 cs->exception_index = POWERPC_EXCP_DSEG; 93 env->spr[SPR_DAR] = eaddr; 94 break; 95 default: 96 g_assert_not_reached(); 97 } 98 env->error_code = 0; 99 } 100 101 static void ppc_radix64_raise_si(PowerPCCPU *cpu, MMUAccessType access_type, 102 vaddr eaddr, uint32_t cause) 103 { 104 CPUState *cs = CPU(cpu); 105 CPUPPCState *env = &cpu->env; 106 107 switch (access_type) { 108 case MMU_INST_FETCH: 109 /* Instruction Storage Interrupt */ 110 cs->exception_index = POWERPC_EXCP_ISI; 111 env->error_code = cause; 112 break; 113 case MMU_DATA_STORE: 114 cause |= DSISR_ISSTORE; 115 /* fall through */ 116 case MMU_DATA_LOAD: 117 /* Data Storage Interrupt */ 118 cs->exception_index = POWERPC_EXCP_DSI; 119 env->spr[SPR_DSISR] = cause; 120 env->spr[SPR_DAR] = eaddr; 121 env->error_code = 0; 122 break; 123 default: 124 g_assert_not_reached(); 125 } 126 } 127 128 static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, MMUAccessType access_type, 129 vaddr eaddr, hwaddr g_raddr, uint32_t cause) 130 { 131 CPUState *cs = CPU(cpu); 132 CPUPPCState *env = &cpu->env; 133 134 switch (access_type) { 135 case MMU_INST_FETCH: 136 /* H Instruction Storage Interrupt */ 137 cs->exception_index = POWERPC_EXCP_HISI; 138 env->spr[SPR_ASDR] = g_raddr; 139 env->error_code = cause; 140 break; 141 case MMU_DATA_STORE: 142 cause |= DSISR_ISSTORE; 143 /* fall through */ 144 case MMU_DATA_LOAD: 145 /* H Data Storage Interrupt */ 146 cs->exception_index = POWERPC_EXCP_HDSI; 147 env->spr[SPR_HDSISR] = cause; 148 env->spr[SPR_HDAR] = eaddr; 149 env->spr[SPR_ASDR] = g_raddr; 150 env->error_code = 0; 151 break; 152 default: 153 g_assert_not_reached(); 154 } 155 } 156 157 static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type, 158 uint64_t pte, int *fault_cause, int *prot, 159 bool partition_scoped) 160 { 161 CPUPPCState *env = &cpu->env; 162 int need_prot; 163 164 /* Check Page Attributes (pte58:59) */ 165 if ((pte & R_PTE_ATT) == R_PTE_ATT_NI_IO && access_type == MMU_INST_FETCH) { 166 /* 167 * Radix PTE entries with the non-idempotent I/O attribute are treated 168 * as guarded storage 169 */ 170 *fault_cause |= SRR1_NOEXEC_GUARD; 171 return true; 172 } 173 174 /* Determine permissions allowed by Encoded Access Authority */ 175 if (!partition_scoped && (pte & R_PTE_EAA_PRIV) && msr_pr) { 176 *prot = 0; 177 } else if (msr_pr || (pte & R_PTE_EAA_PRIV) || partition_scoped) { 178 *prot = ppc_radix64_get_prot_eaa(pte); 179 } else { /* !msr_pr && !(pte & R_PTE_EAA_PRIV) && !partition_scoped */ 180 *prot = ppc_radix64_get_prot_eaa(pte); 181 *prot &= ppc_radix64_get_prot_amr(cpu); /* Least combined permissions */ 182 } 183 184 /* Check if requested access type is allowed */ 185 need_prot = prot_for_access_type(access_type); 186 if (need_prot & ~*prot) { /* Page Protected for that Access */ 187 *fault_cause |= DSISR_PROTFAULT; 188 return true; 189 } 190 191 return false; 192 } 193 194 static void ppc_radix64_set_rc(PowerPCCPU *cpu, MMUAccessType access_type, 195 uint64_t pte, hwaddr pte_addr, int *prot) 196 { 197 CPUState *cs = CPU(cpu); 198 uint64_t npte; 199 200 npte = pte | R_PTE_R; /* Always set reference bit */ 201 202 if (access_type == MMU_DATA_STORE) { /* Store/Write */ 203 npte |= R_PTE_C; /* Set change bit */ 204 } else { 205 /* 206 * Treat the page as read-only for now, so that a later write 207 * will pass through this function again to set the C bit. 208 */ 209 *prot &= ~PAGE_WRITE; 210 } 211 212 if (pte ^ npte) { /* If pte has changed then write it back */ 213 stq_phys(cs->as, pte_addr, npte); 214 } 215 } 216 217 static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, 218 uint64_t *pte_addr, uint64_t *nls, 219 int *psize, uint64_t *pte, int *fault_cause) 220 { 221 uint64_t index, pde; 222 223 if (*nls < 5) { /* Directory maps less than 2**5 entries */ 224 *fault_cause |= DSISR_R_BADCONFIG; 225 return 1; 226 } 227 228 /* Read page <directory/table> entry from guest address space */ 229 pde = ldq_phys(as, *pte_addr); 230 if (!(pde & R_PTE_VALID)) { /* Invalid Entry */ 231 *fault_cause |= DSISR_NOPTE; 232 return 1; 233 } 234 235 *pte = pde; 236 *psize -= *nls; 237 if (!(pde & R_PTE_LEAF)) { /* Prepare for next iteration */ 238 *nls = pde & R_PDE_NLS; 239 index = eaddr >> (*psize - *nls); /* Shift */ 240 index &= ((1UL << *nls) - 1); /* Mask */ 241 *pte_addr = (pde & R_PDE_NLB) + (index * sizeof(pde)); 242 } 243 return 0; 244 } 245 246 static int ppc_radix64_walk_tree(AddressSpace *as, vaddr eaddr, 247 uint64_t base_addr, uint64_t nls, 248 hwaddr *raddr, int *psize, uint64_t *pte, 249 int *fault_cause, hwaddr *pte_addr) 250 { 251 uint64_t index, pde, rpn , mask; 252 253 if (nls < 5) { /* Directory maps less than 2**5 entries */ 254 *fault_cause |= DSISR_R_BADCONFIG; 255 return 1; 256 } 257 258 index = eaddr >> (*psize - nls); /* Shift */ 259 index &= ((1UL << nls) - 1); /* Mask */ 260 *pte_addr = base_addr + (index * sizeof(pde)); 261 do { 262 int ret; 263 264 ret = ppc_radix64_next_level(as, eaddr, pte_addr, &nls, psize, &pde, 265 fault_cause); 266 if (ret) { 267 return ret; 268 } 269 } while (!(pde & R_PTE_LEAF)); 270 271 *pte = pde; 272 rpn = pde & R_PTE_RPN; 273 mask = (1UL << *psize) - 1; 274 275 /* Or high bits of rpn and low bits to ea to form whole real addr */ 276 *raddr = (rpn & ~mask) | (eaddr & mask); 277 return 0; 278 } 279 280 static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate) 281 { 282 CPUPPCState *env = &cpu->env; 283 284 if (!(pate->dw0 & PATE0_HR)) { 285 return false; 286 } 287 if (lpid == 0 && !msr_hv) { 288 return false; 289 } 290 if ((pate->dw0 & PATE1_R_PRTS) < 5) { 291 return false; 292 } 293 /* More checks ... */ 294 return true; 295 } 296 297 static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, 298 MMUAccessType access_type, 299 vaddr eaddr, hwaddr g_raddr, 300 ppc_v3_pate_t pate, 301 hwaddr *h_raddr, int *h_prot, 302 int *h_page_size, bool pde_addr, 303 bool guest_visible) 304 { 305 int fault_cause = 0; 306 hwaddr pte_addr; 307 uint64_t pte; 308 309 *h_page_size = PRTBE_R_GET_RTS(pate.dw0); 310 /* No valid pte or access denied due to protection */ 311 if (ppc_radix64_walk_tree(CPU(cpu)->as, g_raddr, pate.dw0 & PRTBE_R_RPDB, 312 pate.dw0 & PRTBE_R_RPDS, h_raddr, h_page_size, 313 &pte, &fault_cause, &pte_addr) || 314 ppc_radix64_check_prot(cpu, access_type, pte, &fault_cause, h_prot, true)) { 315 if (pde_addr) { /* address being translated was that of a guest pde */ 316 fault_cause |= DSISR_PRTABLE_FAULT; 317 } 318 if (guest_visible) { 319 ppc_radix64_raise_hsi(cpu, access_type, eaddr, g_raddr, fault_cause); 320 } 321 return 1; 322 } 323 324 if (guest_visible) { 325 ppc_radix64_set_rc(cpu, access_type, pte, pte_addr, h_prot); 326 } 327 328 return 0; 329 } 330 331 static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, 332 MMUAccessType access_type, 333 vaddr eaddr, uint64_t pid, 334 ppc_v3_pate_t pate, hwaddr *g_raddr, 335 int *g_prot, int *g_page_size, 336 bool guest_visible) 337 { 338 CPUState *cs = CPU(cpu); 339 CPUPPCState *env = &cpu->env; 340 uint64_t offset, size, prtbe_addr, prtbe0, base_addr, nls, index, pte; 341 int fault_cause = 0, h_page_size, h_prot; 342 hwaddr h_raddr, pte_addr; 343 int ret; 344 345 /* Index Process Table by PID to Find Corresponding Process Table Entry */ 346 offset = pid * sizeof(struct prtb_entry); 347 size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); 348 if (offset >= size) { 349 /* offset exceeds size of the process table */ 350 if (guest_visible) { 351 ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_NOPTE); 352 } 353 return 1; 354 } 355 prtbe_addr = (pate.dw1 & PATE1_R_PRTB) + offset; 356 357 if (cpu->vhyp) { 358 prtbe0 = ldq_phys(cs->as, prtbe_addr); 359 } else { 360 /* 361 * Process table addresses are subject to partition-scoped 362 * translation 363 * 364 * On a Radix host, the partition-scoped page table for LPID=0 365 * is only used to translate the effective addresses of the 366 * process table entries. 367 */ 368 ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, prtbe_addr, 369 pate, &h_raddr, &h_prot, 370 &h_page_size, true, 371 guest_visible); 372 if (ret) { 373 return ret; 374 } 375 prtbe0 = ldq_phys(cs->as, h_raddr); 376 } 377 378 /* Walk Radix Tree from Process Table Entry to Convert EA to RA */ 379 *g_page_size = PRTBE_R_GET_RTS(prtbe0); 380 base_addr = prtbe0 & PRTBE_R_RPDB; 381 nls = prtbe0 & PRTBE_R_RPDS; 382 if (msr_hv || cpu->vhyp) { 383 /* 384 * Can treat process table addresses as real addresses 385 */ 386 ret = ppc_radix64_walk_tree(cs->as, eaddr & R_EADDR_MASK, base_addr, 387 nls, g_raddr, g_page_size, &pte, 388 &fault_cause, &pte_addr); 389 if (ret) { 390 /* No valid PTE */ 391 if (guest_visible) { 392 ppc_radix64_raise_si(cpu, access_type, eaddr, fault_cause); 393 } 394 return ret; 395 } 396 } else { 397 uint64_t rpn, mask; 398 399 index = (eaddr & R_EADDR_MASK) >> (*g_page_size - nls); /* Shift */ 400 index &= ((1UL << nls) - 1); /* Mask */ 401 pte_addr = base_addr + (index * sizeof(pte)); 402 403 /* 404 * Each process table address is subject to a partition-scoped 405 * translation 406 */ 407 do { 408 ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, pte_addr, 409 pate, &h_raddr, &h_prot, 410 &h_page_size, true, 411 guest_visible); 412 if (ret) { 413 return ret; 414 } 415 416 ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, &h_raddr, 417 &nls, g_page_size, &pte, &fault_cause); 418 if (ret) { 419 /* No valid pte */ 420 if (guest_visible) { 421 ppc_radix64_raise_si(cpu, access_type, eaddr, fault_cause); 422 } 423 return ret; 424 } 425 pte_addr = h_raddr; 426 } while (!(pte & R_PTE_LEAF)); 427 428 rpn = pte & R_PTE_RPN; 429 mask = (1UL << *g_page_size) - 1; 430 431 /* Or high bits of rpn and low bits to ea to form whole real addr */ 432 *g_raddr = (rpn & ~mask) | (eaddr & mask); 433 } 434 435 if (ppc_radix64_check_prot(cpu, access_type, pte, &fault_cause, g_prot, false)) { 436 /* Access denied due to protection */ 437 if (guest_visible) { 438 ppc_radix64_raise_si(cpu, access_type, eaddr, fault_cause); 439 } 440 return 1; 441 } 442 443 if (guest_visible) { 444 ppc_radix64_set_rc(cpu, access_type, pte, pte_addr, g_prot); 445 } 446 447 return 0; 448 } 449 450 /* 451 * Radix tree translation is a 2 steps translation process: 452 * 453 * 1. Process-scoped translation: Guest Eff Addr -> Guest Real Addr 454 * 2. Partition-scoped translation: Guest Real Addr -> Host Real Addr 455 * 456 * MSR[HV] 457 * +-------------+----------------+---------------+ 458 * | | HV = 0 | HV = 1 | 459 * +-------------+----------------+---------------+ 460 * | Relocation | Partition | No | 461 * | = Off | Scoped | Translation | 462 * Relocation +-------------+----------------+---------------+ 463 * | Relocation | Partition & | Process | 464 * | = On | Process Scoped | Scoped | 465 * +-------------+----------------+---------------+ 466 */ 467 static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, 468 MMUAccessType access_type, 469 bool relocation, 470 hwaddr *raddr, int *psizep, int *protp, 471 bool guest_visible) 472 { 473 CPUPPCState *env = &cpu->env; 474 uint64_t lpid, pid; 475 ppc_v3_pate_t pate; 476 int psize, prot; 477 hwaddr g_raddr; 478 479 /* Virtual Mode Access - get the fully qualified address */ 480 if (!ppc_radix64_get_fully_qualified_addr(&cpu->env, eaddr, &lpid, &pid)) { 481 if (guest_visible) { 482 ppc_radix64_raise_segi(cpu, access_type, eaddr); 483 } 484 return 1; 485 } 486 487 /* Get Process Table */ 488 if (cpu->vhyp) { 489 PPCVirtualHypervisorClass *vhc; 490 vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); 491 vhc->get_pate(cpu->vhyp, &pate); 492 } else { 493 if (!ppc64_v3_get_pate(cpu, lpid, &pate)) { 494 if (guest_visible) { 495 ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_NOPTE); 496 } 497 return 1; 498 } 499 if (!validate_pate(cpu, lpid, &pate)) { 500 if (guest_visible) { 501 ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_R_BADCONFIG); 502 } 503 return 1; 504 } 505 } 506 507 *psizep = INT_MAX; 508 *protp = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 509 510 /* 511 * Perform process-scoped translation if relocation enabled. 512 * 513 * - Translates an effective address to a host real address in 514 * quadrants 0 and 3 when HV=1. 515 * 516 * - Translates an effective address to a guest real address. 517 */ 518 if (relocation) { 519 int ret = ppc_radix64_process_scoped_xlate(cpu, access_type, eaddr, pid, 520 pate, &g_raddr, &prot, 521 &psize, guest_visible); 522 if (ret) { 523 return ret; 524 } 525 *psizep = MIN(*psizep, psize); 526 *protp &= prot; 527 } else { 528 g_raddr = eaddr & R_EADDR_MASK; 529 } 530 531 if (cpu->vhyp) { 532 *raddr = g_raddr; 533 } else { 534 /* 535 * Perform partition-scoped translation if !HV or HV access to 536 * quadrants 1 or 2. Translates a guest real address to a host 537 * real address. 538 */ 539 if (lpid || !msr_hv) { 540 int ret; 541 542 ret = ppc_radix64_partition_scoped_xlate(cpu, access_type, eaddr, 543 g_raddr, pate, raddr, 544 &prot, &psize, false, 545 guest_visible); 546 if (ret) { 547 return ret; 548 } 549 *psizep = MIN(*psizep, psize); 550 *protp &= prot; 551 } else { 552 *raddr = g_raddr; 553 } 554 } 555 556 return 0; 557 } 558 559 int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx, 560 int mmu_idx) 561 { 562 CPUState *cs = CPU(cpu); 563 CPUPPCState *env = &cpu->env; 564 int page_size, prot; 565 bool relocation; 566 MMUAccessType access_type; 567 hwaddr raddr; 568 569 assert(!(msr_hv && cpu->vhyp)); 570 assert((rwx == 0) || (rwx == 1) || (rwx == 2)); 571 access_type = rwx; 572 573 relocation = (access_type == MMU_INST_FETCH ? msr_ir : msr_dr); 574 /* HV or virtual hypervisor Real Mode Access */ 575 if (!relocation && (msr_hv || cpu->vhyp)) { 576 /* In real mode top 4 effective addr bits (mostly) ignored */ 577 raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL; 578 579 /* In HV mode, add HRMOR if top EA bit is clear */ 580 if (msr_hv || !env->has_hv_mode) { 581 if (!(eaddr >> 63)) { 582 raddr |= env->spr[SPR_HRMOR]; 583 } 584 } 585 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, 586 PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx, 587 TARGET_PAGE_SIZE); 588 return 0; 589 } 590 591 /* 592 * Check UPRT (we avoid the check in real mode to deal with 593 * transitional states during kexec. 594 */ 595 if (!ppc64_use_proc_tbl(cpu)) { 596 qemu_log_mask(LOG_GUEST_ERROR, 597 "LPCR:UPRT not set in radix mode ! LPCR=" 598 TARGET_FMT_lx "\n", env->spr[SPR_LPCR]); 599 } 600 601 /* Translate eaddr to raddr (where raddr is addr qemu needs for access) */ 602 if (ppc_radix64_xlate(cpu, eaddr, access_type, relocation, &raddr, 603 &page_size, &prot, true)) { 604 return 1; 605 } 606 607 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK, 608 prot, mmu_idx, 1UL << page_size); 609 return 0; 610 } 611 612 hwaddr ppc_radix64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr) 613 { 614 CPUPPCState *env = &cpu->env; 615 int psize, prot; 616 hwaddr raddr; 617 618 /* Handle Real Mode */ 619 if ((msr_dr == 0) && (msr_hv || cpu->vhyp)) { 620 /* In real mode top 4 effective addr bits (mostly) ignored */ 621 return eaddr & 0x0FFFFFFFFFFFFFFFULL; 622 } 623 624 if (ppc_radix64_xlate(cpu, eaddr, 0, msr_dr, &raddr, &psize, 625 &prot, false)) { 626 return -1; 627 } 628 629 return raddr & TARGET_PAGE_MASK; 630 } 631