1 /* 2 * Copyright (C) 2014-2016 Broadcom Corporation 3 * Copyright (c) 2017 Red Hat, Inc. 4 * Written by Prem Mallappa, Eric Auger 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * Author: Prem Mallappa <pmallapp@broadcom.com> 16 * 17 */ 18 19 #include "qemu/osdep.h" 20 #include "trace.h" 21 #include "exec/target_page.h" 22 #include "hw/core/cpu.h" 23 #include "hw/qdev-properties.h" 24 #include "qapi/error.h" 25 #include "qemu/jhash.h" 26 #include "qemu/module.h" 27 28 #include "qemu/error-report.h" 29 #include "hw/arm/smmu-common.h" 30 #include "smmu-internal.h" 31 32 /* IOTLB Management */ 33 34 static guint smmu_iotlb_key_hash(gconstpointer v) 35 { 36 SMMUIOTLBKey *key = (SMMUIOTLBKey *)v; 37 uint32_t a, b, c; 38 39 /* Jenkins hash */ 40 a = b = c = JHASH_INITVAL + sizeof(*key); 41 a += key->asid + key->vmid + key->level + key->tg; 42 b += extract64(key->iova, 0, 32); 43 c += extract64(key->iova, 32, 32); 44 45 __jhash_mix(a, b, c); 46 __jhash_final(a, b, c); 47 48 return c; 49 } 50 51 static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2) 52 { 53 SMMUIOTLBKey *k1 = (SMMUIOTLBKey *)v1, *k2 = (SMMUIOTLBKey *)v2; 54 55 return (k1->asid == k2->asid) && (k1->iova == k2->iova) && 56 (k1->level == k2->level) && (k1->tg == k2->tg) && 57 (k1->vmid == k2->vmid); 58 } 59 60 SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova, 61 uint8_t tg, uint8_t level) 62 { 63 SMMUIOTLBKey key = {.asid = asid, .vmid = vmid, .iova = iova, 64 .tg = tg, .level = level}; 65 66 return key; 67 } 68 69 SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg, 70 SMMUTransTableInfo *tt, hwaddr iova) 71 { 72 uint8_t tg = (tt->granule_sz - 10) / 2; 73 uint8_t inputsize = 64 - tt->tsz; 74 uint8_t stride = tt->granule_sz - 3; 75 uint8_t level = 4 - (inputsize - 4) / stride; 76 SMMUTLBEntry *entry = NULL; 77 78 while (level <= 3) { 79 uint64_t subpage_size = 1ULL << level_shift(level, tt->granule_sz); 80 uint64_t mask = subpage_size - 1; 81 SMMUIOTLBKey key; 82 83 key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, 84 iova & ~mask, tg, level); 85 entry = g_hash_table_lookup(bs->iotlb, &key); 86 if (entry) { 87 break; 88 } 89 level++; 90 } 91 92 if (entry) { 93 cfg->iotlb_hits++; 94 trace_smmu_iotlb_lookup_hit(cfg->asid, cfg->s2cfg.vmid, iova, 95 cfg->iotlb_hits, cfg->iotlb_misses, 96 100 * cfg->iotlb_hits / 97 (cfg->iotlb_hits + cfg->iotlb_misses)); 98 } else { 99 cfg->iotlb_misses++; 100 trace_smmu_iotlb_lookup_miss(cfg->asid, cfg->s2cfg.vmid, iova, 101 cfg->iotlb_hits, cfg->iotlb_misses, 102 100 * cfg->iotlb_hits / 103 (cfg->iotlb_hits + cfg->iotlb_misses)); 104 } 105 return entry; 106 } 107 108 void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new) 109 { 110 SMMUIOTLBKey *key = g_new0(SMMUIOTLBKey, 1); 111 uint8_t tg = (new->granule - 10) / 2; 112 113 if (g_hash_table_size(bs->iotlb) >= SMMU_IOTLB_MAX_SIZE) { 114 smmu_iotlb_inv_all(bs); 115 } 116 117 *key = smmu_get_iotlb_key(cfg->asid, cfg->s2cfg.vmid, new->entry.iova, 118 tg, new->level); 119 trace_smmu_iotlb_insert(cfg->asid, cfg->s2cfg.vmid, new->entry.iova, 120 tg, new->level); 121 g_hash_table_insert(bs->iotlb, key, new); 122 } 123 124 void smmu_iotlb_inv_all(SMMUState *s) 125 { 126 trace_smmu_iotlb_inv_all(); 127 g_hash_table_remove_all(s->iotlb); 128 } 129 130 static gboolean smmu_hash_remove_by_asid(gpointer key, gpointer value, 131 gpointer user_data) 132 { 133 uint16_t asid = *(uint16_t *)user_data; 134 SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key; 135 136 return SMMU_IOTLB_ASID(*iotlb_key) == asid; 137 } 138 139 static gboolean smmu_hash_remove_by_vmid(gpointer key, gpointer value, 140 gpointer user_data) 141 { 142 uint16_t vmid = *(uint16_t *)user_data; 143 SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key; 144 145 return SMMU_IOTLB_VMID(*iotlb_key) == vmid; 146 } 147 148 static gboolean smmu_hash_remove_by_asid_vmid_iova(gpointer key, gpointer value, 149 gpointer user_data) 150 { 151 SMMUTLBEntry *iter = (SMMUTLBEntry *)value; 152 IOMMUTLBEntry *entry = &iter->entry; 153 SMMUIOTLBPageInvInfo *info = (SMMUIOTLBPageInvInfo *)user_data; 154 SMMUIOTLBKey iotlb_key = *(SMMUIOTLBKey *)key; 155 156 if (info->asid >= 0 && info->asid != SMMU_IOTLB_ASID(iotlb_key)) { 157 return false; 158 } 159 if (info->vmid >= 0 && info->vmid != SMMU_IOTLB_VMID(iotlb_key)) { 160 return false; 161 } 162 return ((info->iova & ~entry->addr_mask) == entry->iova) || 163 ((entry->iova & ~info->mask) == info->iova); 164 } 165 166 void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, 167 uint8_t tg, uint64_t num_pages, uint8_t ttl) 168 { 169 /* if tg is not set we use 4KB range invalidation */ 170 uint8_t granule = tg ? tg * 2 + 10 : 12; 171 172 if (ttl && (num_pages == 1) && (asid >= 0)) { 173 SMMUIOTLBKey key = smmu_get_iotlb_key(asid, vmid, iova, tg, ttl); 174 175 if (g_hash_table_remove(s->iotlb, &key)) { 176 return; 177 } 178 /* 179 * if the entry is not found, let's see if it does not 180 * belong to a larger IOTLB entry 181 */ 182 } 183 184 SMMUIOTLBPageInvInfo info = { 185 .asid = asid, .iova = iova, 186 .vmid = vmid, 187 .mask = (num_pages * 1 << granule) - 1}; 188 189 g_hash_table_foreach_remove(s->iotlb, 190 smmu_hash_remove_by_asid_vmid_iova, 191 &info); 192 } 193 194 void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid) 195 { 196 trace_smmu_iotlb_inv_asid(asid); 197 g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid); 198 } 199 200 void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid) 201 { 202 trace_smmu_iotlb_inv_vmid(vmid); 203 g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_vmid, &vmid); 204 } 205 206 /* VMSAv8-64 Translation */ 207 208 /** 209 * get_pte - Get the content of a page table entry located at 210 * @base_addr[@index] 211 */ 212 static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte, 213 SMMUPTWEventInfo *info) 214 { 215 int ret; 216 dma_addr_t addr = baseaddr + index * sizeof(*pte); 217 218 /* TODO: guarantee 64-bit single-copy atomicity */ 219 ret = ldq_le_dma(&address_space_memory, addr, pte, MEMTXATTRS_UNSPECIFIED); 220 221 if (ret != MEMTX_OK) { 222 info->type = SMMU_PTW_ERR_WALK_EABT; 223 info->addr = addr; 224 return -EINVAL; 225 } 226 trace_smmu_get_pte(baseaddr, index, addr, *pte); 227 return 0; 228 } 229 230 /* VMSAv8-64 Translation Table Format Descriptor Decoding */ 231 232 /** 233 * get_page_pte_address - returns the L3 descriptor output address, 234 * ie. the page frame 235 * ARM ARM spec: Figure D4-17 VMSAv8-64 level 3 descriptor format 236 */ 237 static inline hwaddr get_page_pte_address(uint64_t pte, int granule_sz) 238 { 239 return PTE_ADDRESS(pte, granule_sz); 240 } 241 242 /** 243 * get_table_pte_address - return table descriptor output address, 244 * ie. address of next level table 245 * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats 246 */ 247 static inline hwaddr get_table_pte_address(uint64_t pte, int granule_sz) 248 { 249 return PTE_ADDRESS(pte, granule_sz); 250 } 251 252 /** 253 * get_block_pte_address - return block descriptor output address and block size 254 * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats 255 */ 256 static inline hwaddr get_block_pte_address(uint64_t pte, int level, 257 int granule_sz, uint64_t *bsz) 258 { 259 int n = level_shift(level, granule_sz); 260 261 *bsz = 1ULL << n; 262 return PTE_ADDRESS(pte, n); 263 } 264 265 SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova) 266 { 267 bool tbi = extract64(iova, 55, 1) ? TBI1(cfg->tbi) : TBI0(cfg->tbi); 268 uint8_t tbi_byte = tbi * 8; 269 270 if (cfg->tt[0].tsz && 271 !extract64(iova, 64 - cfg->tt[0].tsz, cfg->tt[0].tsz - tbi_byte)) { 272 /* there is a ttbr0 region and we are in it (high bits all zero) */ 273 return &cfg->tt[0]; 274 } else if (cfg->tt[1].tsz && 275 sextract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte) == -1) { 276 /* there is a ttbr1 region and we are in it (high bits all one) */ 277 return &cfg->tt[1]; 278 } else if (!cfg->tt[0].tsz) { 279 /* ttbr0 region is "everything not in the ttbr1 region" */ 280 return &cfg->tt[0]; 281 } else if (!cfg->tt[1].tsz) { 282 /* ttbr1 region is "everything not in the ttbr0 region" */ 283 return &cfg->tt[1]; 284 } 285 /* in the gap between the two regions, this is a Translation fault */ 286 return NULL; 287 } 288 289 /** 290 * smmu_ptw_64_s1 - VMSAv8-64 Walk of the page tables for a given IOVA 291 * @cfg: translation config 292 * @iova: iova to translate 293 * @perm: access type 294 * @tlbe: SMMUTLBEntry (out) 295 * @info: handle to an error info 296 * 297 * Return 0 on success, < 0 on error. In case of error, @info is filled 298 * and tlbe->perm is set to IOMMU_NONE. 299 * Upon success, @tlbe is filled with translated_addr and entry 300 * permission rights. 301 */ 302 static int smmu_ptw_64_s1(SMMUTransCfg *cfg, 303 dma_addr_t iova, IOMMUAccessFlags perm, 304 SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info) 305 { 306 dma_addr_t baseaddr, indexmask; 307 int stage = cfg->stage; 308 SMMUTransTableInfo *tt = select_tt(cfg, iova); 309 uint8_t level, granule_sz, inputsize, stride; 310 311 if (!tt || tt->disabled) { 312 info->type = SMMU_PTW_ERR_TRANSLATION; 313 goto error; 314 } 315 316 granule_sz = tt->granule_sz; 317 stride = VMSA_STRIDE(granule_sz); 318 inputsize = 64 - tt->tsz; 319 level = 4 - (inputsize - 4) / stride; 320 indexmask = VMSA_IDXMSK(inputsize, stride, level); 321 baseaddr = extract64(tt->ttb, 0, 48); 322 baseaddr &= ~indexmask; 323 324 while (level < VMSA_LEVELS) { 325 uint64_t subpage_size = 1ULL << level_shift(level, granule_sz); 326 uint64_t mask = subpage_size - 1; 327 uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz); 328 uint64_t pte, gpa; 329 dma_addr_t pte_addr = baseaddr + offset * sizeof(pte); 330 uint8_t ap; 331 332 if (get_pte(baseaddr, offset, &pte, info)) { 333 goto error; 334 } 335 trace_smmu_ptw_level(stage, level, iova, subpage_size, 336 baseaddr, offset, pte); 337 338 if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) { 339 trace_smmu_ptw_invalid_pte(stage, level, baseaddr, 340 pte_addr, offset, pte); 341 break; 342 } 343 344 if (is_table_pte(pte, level)) { 345 ap = PTE_APTABLE(pte); 346 347 if (is_permission_fault(ap, perm) && !tt->had) { 348 info->type = SMMU_PTW_ERR_PERMISSION; 349 goto error; 350 } 351 baseaddr = get_table_pte_address(pte, granule_sz); 352 level++; 353 continue; 354 } else if (is_page_pte(pte, level)) { 355 gpa = get_page_pte_address(pte, granule_sz); 356 trace_smmu_ptw_page_pte(stage, level, iova, 357 baseaddr, pte_addr, pte, gpa); 358 } else { 359 uint64_t block_size; 360 361 gpa = get_block_pte_address(pte, level, granule_sz, 362 &block_size); 363 trace_smmu_ptw_block_pte(stage, level, baseaddr, 364 pte_addr, pte, iova, gpa, 365 block_size >> 20); 366 } 367 368 /* 369 * QEMU does not currently implement HTTU, so if AFFD and PTE.AF 370 * are 0 we take an Access flag fault. (5.4. Context Descriptor) 371 * An Access flag fault takes priority over a Permission fault. 372 */ 373 if (!PTE_AF(pte) && !cfg->affd) { 374 info->type = SMMU_PTW_ERR_ACCESS; 375 goto error; 376 } 377 378 ap = PTE_AP(pte); 379 if (is_permission_fault(ap, perm)) { 380 info->type = SMMU_PTW_ERR_PERMISSION; 381 goto error; 382 } 383 384 tlbe->entry.translated_addr = gpa; 385 tlbe->entry.iova = iova & ~mask; 386 tlbe->entry.addr_mask = mask; 387 tlbe->entry.perm = PTE_AP_TO_PERM(ap); 388 tlbe->level = level; 389 tlbe->granule = granule_sz; 390 return 0; 391 } 392 info->type = SMMU_PTW_ERR_TRANSLATION; 393 394 error: 395 info->stage = 1; 396 tlbe->entry.perm = IOMMU_NONE; 397 return -EINVAL; 398 } 399 400 /** 401 * smmu_ptw_64_s2 - VMSAv8-64 Walk of the page tables for a given ipa 402 * for stage-2. 403 * @cfg: translation config 404 * @ipa: ipa to translate 405 * @perm: access type 406 * @tlbe: SMMUTLBEntry (out) 407 * @info: handle to an error info 408 * 409 * Return 0 on success, < 0 on error. In case of error, @info is filled 410 * and tlbe->perm is set to IOMMU_NONE. 411 * Upon success, @tlbe is filled with translated_addr and entry 412 * permission rights. 413 */ 414 static int smmu_ptw_64_s2(SMMUTransCfg *cfg, 415 dma_addr_t ipa, IOMMUAccessFlags perm, 416 SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info) 417 { 418 const int stage = 2; 419 int granule_sz = cfg->s2cfg.granule_sz; 420 /* ARM DDI0487I.a: Table D8-7. */ 421 int inputsize = 64 - cfg->s2cfg.tsz; 422 int level = get_start_level(cfg->s2cfg.sl0, granule_sz); 423 int stride = VMSA_STRIDE(granule_sz); 424 int idx = pgd_concat_idx(level, granule_sz, ipa); 425 /* 426 * Get the ttb from concatenated structure. 427 * The offset is the idx * size of each ttb(number of ptes * (sizeof(pte)) 428 */ 429 uint64_t baseaddr = extract64(cfg->s2cfg.vttb, 0, 48) + (1 << stride) * 430 idx * sizeof(uint64_t); 431 dma_addr_t indexmask = VMSA_IDXMSK(inputsize, stride, level); 432 433 baseaddr &= ~indexmask; 434 435 /* 436 * On input, a stage 2 Translation fault occurs if the IPA is outside the 437 * range configured by the relevant S2T0SZ field of the STE. 438 */ 439 if (ipa >= (1ULL << inputsize)) { 440 info->type = SMMU_PTW_ERR_TRANSLATION; 441 goto error; 442 } 443 444 while (level < VMSA_LEVELS) { 445 uint64_t subpage_size = 1ULL << level_shift(level, granule_sz); 446 uint64_t mask = subpage_size - 1; 447 uint32_t offset = iova_level_offset(ipa, inputsize, level, granule_sz); 448 uint64_t pte, gpa; 449 dma_addr_t pte_addr = baseaddr + offset * sizeof(pte); 450 uint8_t s2ap; 451 452 if (get_pte(baseaddr, offset, &pte, info)) { 453 goto error; 454 } 455 trace_smmu_ptw_level(stage, level, ipa, subpage_size, 456 baseaddr, offset, pte); 457 if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) { 458 trace_smmu_ptw_invalid_pte(stage, level, baseaddr, 459 pte_addr, offset, pte); 460 break; 461 } 462 463 if (is_table_pte(pte, level)) { 464 baseaddr = get_table_pte_address(pte, granule_sz); 465 level++; 466 continue; 467 } else if (is_page_pte(pte, level)) { 468 gpa = get_page_pte_address(pte, granule_sz); 469 trace_smmu_ptw_page_pte(stage, level, ipa, 470 baseaddr, pte_addr, pte, gpa); 471 } else { 472 uint64_t block_size; 473 474 gpa = get_block_pte_address(pte, level, granule_sz, 475 &block_size); 476 trace_smmu_ptw_block_pte(stage, level, baseaddr, 477 pte_addr, pte, ipa, gpa, 478 block_size >> 20); 479 } 480 481 /* 482 * If S2AFFD and PTE.AF are 0 => fault. (5.2. Stream Table Entry) 483 * An Access fault takes priority over a Permission fault. 484 */ 485 if (!PTE_AF(pte) && !cfg->s2cfg.affd) { 486 info->type = SMMU_PTW_ERR_ACCESS; 487 goto error; 488 } 489 490 s2ap = PTE_AP(pte); 491 if (is_permission_fault_s2(s2ap, perm)) { 492 info->type = SMMU_PTW_ERR_PERMISSION; 493 goto error; 494 } 495 496 /* 497 * The address output from the translation causes a stage 2 Address 498 * Size fault if it exceeds the effective PA output range. 499 */ 500 if (gpa >= (1ULL << cfg->s2cfg.eff_ps)) { 501 info->type = SMMU_PTW_ERR_ADDR_SIZE; 502 goto error; 503 } 504 505 tlbe->entry.translated_addr = gpa; 506 tlbe->entry.iova = ipa & ~mask; 507 tlbe->entry.addr_mask = mask; 508 tlbe->entry.perm = s2ap; 509 tlbe->level = level; 510 tlbe->granule = granule_sz; 511 return 0; 512 } 513 info->type = SMMU_PTW_ERR_TRANSLATION; 514 515 error: 516 info->stage = 2; 517 tlbe->entry.perm = IOMMU_NONE; 518 return -EINVAL; 519 } 520 521 /** 522 * smmu_ptw - Walk the page tables for an IOVA, according to @cfg 523 * 524 * @cfg: translation configuration 525 * @iova: iova to translate 526 * @perm: tentative access type 527 * @tlbe: returned entry 528 * @info: ptw event handle 529 * 530 * return 0 on success 531 */ 532 int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm, 533 SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info) 534 { 535 if (cfg->stage == 1) { 536 return smmu_ptw_64_s1(cfg, iova, perm, tlbe, info); 537 } else if (cfg->stage == 2) { 538 /* 539 * If bypassing stage 1(or unimplemented), the input address is passed 540 * directly to stage 2 as IPA. If the input address of a transaction 541 * exceeds the size of the IAS, a stage 1 Address Size fault occurs. 542 * For AA64, IAS = OAS according to (IHI 0070.E.a) "3.4 Address sizes" 543 */ 544 if (iova >= (1ULL << cfg->oas)) { 545 info->type = SMMU_PTW_ERR_ADDR_SIZE; 546 info->stage = 1; 547 tlbe->entry.perm = IOMMU_NONE; 548 return -EINVAL; 549 } 550 551 return smmu_ptw_64_s2(cfg, iova, perm, tlbe, info); 552 } 553 554 g_assert_not_reached(); 555 } 556 557 /** 558 * The bus number is used for lookup when SID based invalidation occurs. 559 * In that case we lazily populate the SMMUPciBus array from the bus hash 560 * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus 561 * numbers may not be always initialized yet. 562 */ 563 SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num) 564 { 565 SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num]; 566 GHashTableIter iter; 567 568 if (smmu_pci_bus) { 569 return smmu_pci_bus; 570 } 571 572 g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr); 573 while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) { 574 if (pci_bus_num(smmu_pci_bus->bus) == bus_num) { 575 s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus; 576 return smmu_pci_bus; 577 } 578 } 579 580 return NULL; 581 } 582 583 static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn) 584 { 585 SMMUState *s = opaque; 586 SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus); 587 SMMUDevice *sdev; 588 static unsigned int index; 589 590 if (!sbus) { 591 sbus = g_malloc0(sizeof(SMMUPciBus) + 592 sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX); 593 sbus->bus = bus; 594 g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus); 595 } 596 597 sdev = sbus->pbdev[devfn]; 598 if (!sdev) { 599 char *name = g_strdup_printf("%s-%d-%d", s->mrtypename, devfn, index++); 600 601 sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1); 602 603 sdev->smmu = s; 604 sdev->bus = bus; 605 sdev->devfn = devfn; 606 607 memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu), 608 s->mrtypename, 609 OBJECT(s), name, UINT64_MAX); 610 address_space_init(&sdev->as, 611 MEMORY_REGION(&sdev->iommu), name); 612 trace_smmu_add_mr(name); 613 g_free(name); 614 } 615 616 return &sdev->as; 617 } 618 619 static const PCIIOMMUOps smmu_ops = { 620 .get_address_space = smmu_find_add_as, 621 }; 622 623 IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid) 624 { 625 uint8_t bus_n, devfn; 626 SMMUPciBus *smmu_bus; 627 SMMUDevice *smmu; 628 629 bus_n = PCI_BUS_NUM(sid); 630 smmu_bus = smmu_find_smmu_pcibus(s, bus_n); 631 if (smmu_bus) { 632 devfn = SMMU_PCI_DEVFN(sid); 633 smmu = smmu_bus->pbdev[devfn]; 634 if (smmu) { 635 return &smmu->iommu; 636 } 637 } 638 return NULL; 639 } 640 641 /* Unmap all notifiers attached to @mr */ 642 static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr) 643 { 644 IOMMUNotifier *n; 645 646 trace_smmu_inv_notifiers_mr(mr->parent_obj.name); 647 IOMMU_NOTIFIER_FOREACH(n, mr) { 648 memory_region_unmap_iommu_notifier_range(n); 649 } 650 } 651 652 /* Unmap all notifiers of all mr's */ 653 void smmu_inv_notifiers_all(SMMUState *s) 654 { 655 SMMUDevice *sdev; 656 657 QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) { 658 smmu_inv_notifiers_mr(&sdev->iommu); 659 } 660 } 661 662 static void smmu_base_realize(DeviceState *dev, Error **errp) 663 { 664 SMMUState *s = ARM_SMMU(dev); 665 SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev); 666 Error *local_err = NULL; 667 668 sbc->parent_realize(dev, &local_err); 669 if (local_err) { 670 error_propagate(errp, local_err); 671 return; 672 } 673 s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free); 674 s->iotlb = g_hash_table_new_full(smmu_iotlb_key_hash, smmu_iotlb_key_equal, 675 g_free, g_free); 676 s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL); 677 678 if (s->primary_bus) { 679 pci_setup_iommu(s->primary_bus, &smmu_ops, s); 680 } else { 681 error_setg(errp, "SMMU is not attached to any PCI bus!"); 682 } 683 } 684 685 static void smmu_base_reset_hold(Object *obj, ResetType type) 686 { 687 SMMUState *s = ARM_SMMU(obj); 688 689 memset(s->smmu_pcibus_by_bus_num, 0, sizeof(s->smmu_pcibus_by_bus_num)); 690 691 g_hash_table_remove_all(s->configs); 692 g_hash_table_remove_all(s->iotlb); 693 } 694 695 static Property smmu_dev_properties[] = { 696 DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0), 697 DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus, 698 TYPE_PCI_BUS, PCIBus *), 699 DEFINE_PROP_END_OF_LIST(), 700 }; 701 702 static void smmu_base_class_init(ObjectClass *klass, void *data) 703 { 704 DeviceClass *dc = DEVICE_CLASS(klass); 705 ResettableClass *rc = RESETTABLE_CLASS(klass); 706 SMMUBaseClass *sbc = ARM_SMMU_CLASS(klass); 707 708 device_class_set_props(dc, smmu_dev_properties); 709 device_class_set_parent_realize(dc, smmu_base_realize, 710 &sbc->parent_realize); 711 rc->phases.hold = smmu_base_reset_hold; 712 } 713 714 static const TypeInfo smmu_base_info = { 715 .name = TYPE_ARM_SMMU, 716 .parent = TYPE_SYS_BUS_DEVICE, 717 .instance_size = sizeof(SMMUState), 718 .class_data = NULL, 719 .class_size = sizeof(SMMUBaseClass), 720 .class_init = smmu_base_class_init, 721 .abstract = true, 722 }; 723 724 static void smmu_base_register_types(void) 725 { 726 type_register_static(&smmu_base_info); 727 } 728 729 type_init(smmu_base_register_types) 730 731