1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2021 Western Digital Corporation or its affiliates. 4 * Copyright (C) 2022 Ventana Micro Systems Inc. 5 * 6 * Authors: 7 * Anup Patel <apatel@ventanamicro.com> 8 */ 9 10 #include <linux/irqchip/riscv-aplic.h> 11 #include <linux/kvm_host.h> 12 #include <linux/math.h> 13 #include <linux/nospec.h> 14 #include <linux/spinlock.h> 15 #include <linux/swab.h> 16 #include <kvm/iodev.h> 17 18 struct aplic_irq { 19 raw_spinlock_t lock; 20 u32 sourcecfg; 21 u32 state; 22 #define APLIC_IRQ_STATE_PENDING BIT(0) 23 #define APLIC_IRQ_STATE_ENABLED BIT(1) 24 #define APLIC_IRQ_STATE_ENPEND (APLIC_IRQ_STATE_PENDING | \ 25 APLIC_IRQ_STATE_ENABLED) 26 #define APLIC_IRQ_STATE_INPUT BIT(8) 27 u32 target; 28 }; 29 30 struct aplic { 31 struct kvm_io_device iodev; 32 33 u32 domaincfg; 34 u32 genmsi; 35 36 u32 nr_irqs; 37 u32 nr_words; 38 struct aplic_irq *irqs; 39 }; 40 41 static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq) 42 { 43 u32 ret; 44 unsigned long flags; 45 struct aplic_irq *irqd; 46 47 if (!irq || aplic->nr_irqs <= irq) 48 return 0; 49 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 50 51 raw_spin_lock_irqsave(&irqd->lock, flags); 52 ret = irqd->sourcecfg; 53 raw_spin_unlock_irqrestore(&irqd->lock, flags); 54 55 return ret; 56 } 57 58 static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val) 59 { 60 unsigned long flags; 61 struct aplic_irq *irqd; 62 63 if (!irq || aplic->nr_irqs <= irq) 64 return; 65 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 66 67 if (val & APLIC_SOURCECFG_D) 68 val = 0; 69 else 70 val &= APLIC_SOURCECFG_SM_MASK; 71 72 raw_spin_lock_irqsave(&irqd->lock, flags); 73 irqd->sourcecfg = val; 74 raw_spin_unlock_irqrestore(&irqd->lock, flags); 75 } 76 77 static u32 aplic_read_target(struct aplic *aplic, u32 irq) 78 { 79 u32 ret; 80 unsigned long flags; 81 struct aplic_irq *irqd; 82 83 if (!irq || aplic->nr_irqs <= irq) 84 return 0; 85 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 86 87 raw_spin_lock_irqsave(&irqd->lock, flags); 88 ret = irqd->target; 89 raw_spin_unlock_irqrestore(&irqd->lock, flags); 90 91 return ret; 92 } 93 94 static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val) 95 { 96 unsigned long flags; 97 struct aplic_irq *irqd; 98 99 if (!irq || aplic->nr_irqs <= irq) 100 return; 101 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 102 103 val &= APLIC_TARGET_EIID_MASK | 104 (APLIC_TARGET_HART_IDX_MASK << APLIC_TARGET_HART_IDX_SHIFT) | 105 (APLIC_TARGET_GUEST_IDX_MASK << APLIC_TARGET_GUEST_IDX_SHIFT); 106 107 raw_spin_lock_irqsave(&irqd->lock, flags); 108 irqd->target = val; 109 raw_spin_unlock_irqrestore(&irqd->lock, flags); 110 } 111 112 static bool aplic_read_pending(struct aplic *aplic, u32 irq) 113 { 114 bool ret; 115 unsigned long flags; 116 struct aplic_irq *irqd; 117 118 if (!irq || aplic->nr_irqs <= irq) 119 return false; 120 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 121 122 raw_spin_lock_irqsave(&irqd->lock, flags); 123 ret = (irqd->state & APLIC_IRQ_STATE_PENDING) ? true : false; 124 raw_spin_unlock_irqrestore(&irqd->lock, flags); 125 126 return ret; 127 } 128 129 static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending) 130 { 131 unsigned long flags, sm; 132 struct aplic_irq *irqd; 133 134 if (!irq || aplic->nr_irqs <= irq) 135 return; 136 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 137 138 raw_spin_lock_irqsave(&irqd->lock, flags); 139 140 sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK; 141 if (sm == APLIC_SOURCECFG_SM_INACTIVE) 142 goto skip_write_pending; 143 144 if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH || 145 sm == APLIC_SOURCECFG_SM_LEVEL_LOW) { 146 if (!pending) 147 goto noskip_write_pending; 148 if ((irqd->state & APLIC_IRQ_STATE_INPUT) && 149 sm == APLIC_SOURCECFG_SM_LEVEL_LOW) 150 goto skip_write_pending; 151 if (!(irqd->state & APLIC_IRQ_STATE_INPUT) && 152 sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) 153 goto skip_write_pending; 154 } 155 156 noskip_write_pending: 157 if (pending) 158 irqd->state |= APLIC_IRQ_STATE_PENDING; 159 else 160 irqd->state &= ~APLIC_IRQ_STATE_PENDING; 161 162 skip_write_pending: 163 raw_spin_unlock_irqrestore(&irqd->lock, flags); 164 } 165 166 static bool aplic_read_enabled(struct aplic *aplic, u32 irq) 167 { 168 bool ret; 169 unsigned long flags; 170 struct aplic_irq *irqd; 171 172 if (!irq || aplic->nr_irqs <= irq) 173 return false; 174 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 175 176 raw_spin_lock_irqsave(&irqd->lock, flags); 177 ret = (irqd->state & APLIC_IRQ_STATE_ENABLED) ? true : false; 178 raw_spin_unlock_irqrestore(&irqd->lock, flags); 179 180 return ret; 181 } 182 183 static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled) 184 { 185 unsigned long flags; 186 struct aplic_irq *irqd; 187 188 if (!irq || aplic->nr_irqs <= irq) 189 return; 190 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 191 192 raw_spin_lock_irqsave(&irqd->lock, flags); 193 if (enabled) 194 irqd->state |= APLIC_IRQ_STATE_ENABLED; 195 else 196 irqd->state &= ~APLIC_IRQ_STATE_ENABLED; 197 raw_spin_unlock_irqrestore(&irqd->lock, flags); 198 } 199 200 static bool aplic_read_input(struct aplic *aplic, u32 irq) 201 { 202 u32 sourcecfg, sm, raw_input, irq_inverted; 203 struct aplic_irq *irqd; 204 unsigned long flags; 205 bool ret = false; 206 207 if (!irq || aplic->nr_irqs <= irq) 208 return false; 209 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 210 211 raw_spin_lock_irqsave(&irqd->lock, flags); 212 213 sourcecfg = irqd->sourcecfg; 214 if (sourcecfg & APLIC_SOURCECFG_D) 215 goto skip; 216 217 sm = sourcecfg & APLIC_SOURCECFG_SM_MASK; 218 if (sm == APLIC_SOURCECFG_SM_INACTIVE) 219 goto skip; 220 221 raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0; 222 irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW || 223 sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0; 224 ret = !!(raw_input ^ irq_inverted); 225 226 skip: 227 raw_spin_unlock_irqrestore(&irqd->lock, flags); 228 229 return ret; 230 } 231 232 static void aplic_inject_msi(struct kvm *kvm, u32 irq, u32 target) 233 { 234 u32 hart_idx, guest_idx, eiid; 235 236 hart_idx = target >> APLIC_TARGET_HART_IDX_SHIFT; 237 hart_idx &= APLIC_TARGET_HART_IDX_MASK; 238 guest_idx = target >> APLIC_TARGET_GUEST_IDX_SHIFT; 239 guest_idx &= APLIC_TARGET_GUEST_IDX_MASK; 240 eiid = target & APLIC_TARGET_EIID_MASK; 241 kvm_riscv_aia_inject_msi_by_id(kvm, hart_idx, guest_idx, eiid); 242 } 243 244 static void aplic_update_irq_range(struct kvm *kvm, u32 first, u32 last) 245 { 246 bool inject; 247 u32 irq, target; 248 unsigned long flags; 249 struct aplic_irq *irqd; 250 struct aplic *aplic = kvm->arch.aia.aplic_state; 251 252 if (!(aplic->domaincfg & APLIC_DOMAINCFG_IE)) 253 return; 254 255 for (irq = first; irq <= last; irq++) { 256 if (!irq || aplic->nr_irqs <= irq) 257 continue; 258 irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; 259 260 raw_spin_lock_irqsave(&irqd->lock, flags); 261 262 inject = false; 263 target = irqd->target; 264 if ((irqd->state & APLIC_IRQ_STATE_ENPEND) == 265 APLIC_IRQ_STATE_ENPEND) { 266 irqd->state &= ~APLIC_IRQ_STATE_PENDING; 267 inject = true; 268 } 269 270 raw_spin_unlock_irqrestore(&irqd->lock, flags); 271 272 if (inject) 273 aplic_inject_msi(kvm, irq, target); 274 } 275 } 276 277 int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level) 278 { 279 u32 target; 280 bool inject = false, ie; 281 unsigned long flags; 282 struct aplic_irq *irqd; 283 struct aplic *aplic = kvm->arch.aia.aplic_state; 284 285 if (!aplic || !source || (aplic->nr_irqs <= source)) 286 return -ENODEV; 287 irqd = &aplic->irqs[array_index_nospec(source, aplic->nr_irqs)]; 288 ie = (aplic->domaincfg & APLIC_DOMAINCFG_IE) ? true : false; 289 290 raw_spin_lock_irqsave(&irqd->lock, flags); 291 292 if (irqd->sourcecfg & APLIC_SOURCECFG_D) 293 goto skip_unlock; 294 295 switch (irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK) { 296 case APLIC_SOURCECFG_SM_EDGE_RISE: 297 if (level && !(irqd->state & APLIC_IRQ_STATE_INPUT) && 298 !(irqd->state & APLIC_IRQ_STATE_PENDING)) 299 irqd->state |= APLIC_IRQ_STATE_PENDING; 300 break; 301 case APLIC_SOURCECFG_SM_EDGE_FALL: 302 if (!level && (irqd->state & APLIC_IRQ_STATE_INPUT) && 303 !(irqd->state & APLIC_IRQ_STATE_PENDING)) 304 irqd->state |= APLIC_IRQ_STATE_PENDING; 305 break; 306 case APLIC_SOURCECFG_SM_LEVEL_HIGH: 307 if (level && !(irqd->state & APLIC_IRQ_STATE_PENDING)) 308 irqd->state |= APLIC_IRQ_STATE_PENDING; 309 break; 310 case APLIC_SOURCECFG_SM_LEVEL_LOW: 311 if (!level && !(irqd->state & APLIC_IRQ_STATE_PENDING)) 312 irqd->state |= APLIC_IRQ_STATE_PENDING; 313 break; 314 } 315 316 if (level) 317 irqd->state |= APLIC_IRQ_STATE_INPUT; 318 else 319 irqd->state &= ~APLIC_IRQ_STATE_INPUT; 320 321 target = irqd->target; 322 if (ie && ((irqd->state & APLIC_IRQ_STATE_ENPEND) == 323 APLIC_IRQ_STATE_ENPEND)) { 324 irqd->state &= ~APLIC_IRQ_STATE_PENDING; 325 inject = true; 326 } 327 328 skip_unlock: 329 raw_spin_unlock_irqrestore(&irqd->lock, flags); 330 331 if (inject) 332 aplic_inject_msi(kvm, source, target); 333 334 return 0; 335 } 336 337 static u32 aplic_read_input_word(struct aplic *aplic, u32 word) 338 { 339 u32 i, ret = 0; 340 341 for (i = 0; i < 32; i++) 342 ret |= aplic_read_input(aplic, word * 32 + i) ? BIT(i) : 0; 343 344 return ret; 345 } 346 347 static u32 aplic_read_pending_word(struct aplic *aplic, u32 word) 348 { 349 u32 i, ret = 0; 350 351 for (i = 0; i < 32; i++) 352 ret |= aplic_read_pending(aplic, word * 32 + i) ? BIT(i) : 0; 353 354 return ret; 355 } 356 357 static void aplic_write_pending_word(struct aplic *aplic, u32 word, 358 u32 val, bool pending) 359 { 360 u32 i; 361 362 for (i = 0; i < 32; i++) { 363 if (val & BIT(i)) 364 aplic_write_pending(aplic, word * 32 + i, pending); 365 } 366 } 367 368 static u32 aplic_read_enabled_word(struct aplic *aplic, u32 word) 369 { 370 u32 i, ret = 0; 371 372 for (i = 0; i < 32; i++) 373 ret |= aplic_read_enabled(aplic, word * 32 + i) ? BIT(i) : 0; 374 375 return ret; 376 } 377 378 static void aplic_write_enabled_word(struct aplic *aplic, u32 word, 379 u32 val, bool enabled) 380 { 381 u32 i; 382 383 for (i = 0; i < 32; i++) { 384 if (val & BIT(i)) 385 aplic_write_enabled(aplic, word * 32 + i, enabled); 386 } 387 } 388 389 static int aplic_mmio_read_offset(struct kvm *kvm, gpa_t off, u32 *val32) 390 { 391 u32 i; 392 struct aplic *aplic = kvm->arch.aia.aplic_state; 393 394 if ((off & 0x3) != 0) 395 return -EOPNOTSUPP; 396 397 if (off == APLIC_DOMAINCFG) { 398 *val32 = APLIC_DOMAINCFG_RDONLY | 399 aplic->domaincfg | APLIC_DOMAINCFG_DM; 400 } else if ((off >= APLIC_SOURCECFG_BASE) && 401 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { 402 i = ((off - APLIC_SOURCECFG_BASE) >> 2) + 1; 403 *val32 = aplic_read_sourcecfg(aplic, i); 404 } else if ((off >= APLIC_SETIP_BASE) && 405 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { 406 i = (off - APLIC_SETIP_BASE) >> 2; 407 *val32 = aplic_read_pending_word(aplic, i); 408 } else if (off == APLIC_SETIPNUM) { 409 *val32 = 0; 410 } else if ((off >= APLIC_CLRIP_BASE) && 411 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { 412 i = (off - APLIC_CLRIP_BASE) >> 2; 413 *val32 = aplic_read_input_word(aplic, i); 414 } else if (off == APLIC_CLRIPNUM) { 415 *val32 = 0; 416 } else if ((off >= APLIC_SETIE_BASE) && 417 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { 418 i = (off - APLIC_SETIE_BASE) >> 2; 419 *val32 = aplic_read_enabled_word(aplic, i); 420 } else if (off == APLIC_SETIENUM) { 421 *val32 = 0; 422 } else if ((off >= APLIC_CLRIE_BASE) && 423 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { 424 *val32 = 0; 425 } else if (off == APLIC_CLRIENUM) { 426 *val32 = 0; 427 } else if (off == APLIC_SETIPNUM_LE) { 428 *val32 = 0; 429 } else if (off == APLIC_SETIPNUM_BE) { 430 *val32 = 0; 431 } else if (off == APLIC_GENMSI) { 432 *val32 = aplic->genmsi; 433 } else if ((off >= APLIC_TARGET_BASE) && 434 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { 435 i = ((off - APLIC_TARGET_BASE) >> 2) + 1; 436 *val32 = aplic_read_target(aplic, i); 437 } else 438 return -ENODEV; 439 440 return 0; 441 } 442 443 static int aplic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, 444 gpa_t addr, int len, void *val) 445 { 446 if (len != 4) 447 return -EOPNOTSUPP; 448 449 return aplic_mmio_read_offset(vcpu->kvm, 450 addr - vcpu->kvm->arch.aia.aplic_addr, 451 val); 452 } 453 454 static int aplic_mmio_write_offset(struct kvm *kvm, gpa_t off, u32 val32) 455 { 456 u32 i; 457 struct aplic *aplic = kvm->arch.aia.aplic_state; 458 459 if ((off & 0x3) != 0) 460 return -EOPNOTSUPP; 461 462 if (off == APLIC_DOMAINCFG) { 463 /* Only IE bit writeable */ 464 aplic->domaincfg = val32 & APLIC_DOMAINCFG_IE; 465 } else if ((off >= APLIC_SOURCECFG_BASE) && 466 (off < (APLIC_SOURCECFG_BASE + (aplic->nr_irqs - 1) * 4))) { 467 i = ((off - APLIC_SOURCECFG_BASE) >> 2) + 1; 468 aplic_write_sourcecfg(aplic, i, val32); 469 } else if ((off >= APLIC_SETIP_BASE) && 470 (off < (APLIC_SETIP_BASE + aplic->nr_words * 4))) { 471 i = (off - APLIC_SETIP_BASE) >> 2; 472 aplic_write_pending_word(aplic, i, val32, true); 473 } else if (off == APLIC_SETIPNUM) { 474 aplic_write_pending(aplic, val32, true); 475 } else if ((off >= APLIC_CLRIP_BASE) && 476 (off < (APLIC_CLRIP_BASE + aplic->nr_words * 4))) { 477 i = (off - APLIC_CLRIP_BASE) >> 2; 478 aplic_write_pending_word(aplic, i, val32, false); 479 } else if (off == APLIC_CLRIPNUM) { 480 aplic_write_pending(aplic, val32, false); 481 } else if ((off >= APLIC_SETIE_BASE) && 482 (off < (APLIC_SETIE_BASE + aplic->nr_words * 4))) { 483 i = (off - APLIC_SETIE_BASE) >> 2; 484 aplic_write_enabled_word(aplic, i, val32, true); 485 } else if (off == APLIC_SETIENUM) { 486 aplic_write_enabled(aplic, val32, true); 487 } else if ((off >= APLIC_CLRIE_BASE) && 488 (off < (APLIC_CLRIE_BASE + aplic->nr_words * 4))) { 489 i = (off - APLIC_CLRIE_BASE) >> 2; 490 aplic_write_enabled_word(aplic, i, val32, false); 491 } else if (off == APLIC_CLRIENUM) { 492 aplic_write_enabled(aplic, val32, false); 493 } else if (off == APLIC_SETIPNUM_LE) { 494 aplic_write_pending(aplic, val32, true); 495 } else if (off == APLIC_SETIPNUM_BE) { 496 aplic_write_pending(aplic, __swab32(val32), true); 497 } else if (off == APLIC_GENMSI) { 498 aplic->genmsi = val32 & ~(APLIC_TARGET_GUEST_IDX_MASK << 499 APLIC_TARGET_GUEST_IDX_SHIFT); 500 kvm_riscv_aia_inject_msi_by_id(kvm, 501 val32 >> APLIC_TARGET_HART_IDX_SHIFT, 0, 502 val32 & APLIC_TARGET_EIID_MASK); 503 } else if ((off >= APLIC_TARGET_BASE) && 504 (off < (APLIC_TARGET_BASE + (aplic->nr_irqs - 1) * 4))) { 505 i = ((off - APLIC_TARGET_BASE) >> 2) + 1; 506 aplic_write_target(aplic, i, val32); 507 } else 508 return -ENODEV; 509 510 aplic_update_irq_range(kvm, 1, aplic->nr_irqs - 1); 511 512 return 0; 513 } 514 515 static int aplic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, 516 gpa_t addr, int len, const void *val) 517 { 518 if (len != 4) 519 return -EOPNOTSUPP; 520 521 return aplic_mmio_write_offset(vcpu->kvm, 522 addr - vcpu->kvm->arch.aia.aplic_addr, 523 *((const u32 *)val)); 524 } 525 526 static struct kvm_io_device_ops aplic_iodoev_ops = { 527 .read = aplic_mmio_read, 528 .write = aplic_mmio_write, 529 }; 530 531 int kvm_riscv_aia_aplic_set_attr(struct kvm *kvm, unsigned long type, u32 v) 532 { 533 int rc; 534 535 if (!kvm->arch.aia.aplic_state) 536 return -ENODEV; 537 538 rc = aplic_mmio_write_offset(kvm, type, v); 539 if (rc) 540 return rc; 541 542 return 0; 543 } 544 545 int kvm_riscv_aia_aplic_get_attr(struct kvm *kvm, unsigned long type, u32 *v) 546 { 547 int rc; 548 549 if (!kvm->arch.aia.aplic_state) 550 return -ENODEV; 551 552 rc = aplic_mmio_read_offset(kvm, type, v); 553 if (rc) 554 return rc; 555 556 return 0; 557 } 558 559 int kvm_riscv_aia_aplic_has_attr(struct kvm *kvm, unsigned long type) 560 { 561 int rc; 562 u32 val; 563 564 if (!kvm->arch.aia.aplic_state) 565 return -ENODEV; 566 567 rc = aplic_mmio_read_offset(kvm, type, &val); 568 if (rc) 569 return rc; 570 571 return 0; 572 } 573 574 int kvm_riscv_aia_aplic_init(struct kvm *kvm) 575 { 576 int i, ret = 0; 577 struct aplic *aplic; 578 579 /* Do nothing if we have zero sources */ 580 if (!kvm->arch.aia.nr_sources) 581 return 0; 582 583 /* Allocate APLIC global state */ 584 aplic = kzalloc_obj(*aplic); 585 if (!aplic) 586 return -ENOMEM; 587 kvm->arch.aia.aplic_state = aplic; 588 589 /* Setup APLIC IRQs */ 590 aplic->nr_irqs = kvm->arch.aia.nr_sources + 1; 591 aplic->nr_words = DIV_ROUND_UP(aplic->nr_irqs, 32); 592 aplic->irqs = kzalloc_objs(*aplic->irqs, aplic->nr_irqs); 593 if (!aplic->irqs) { 594 ret = -ENOMEM; 595 goto fail_free_aplic; 596 } 597 for (i = 0; i < aplic->nr_irqs; i++) 598 raw_spin_lock_init(&aplic->irqs[i].lock); 599 600 /* Setup IO device */ 601 kvm_iodevice_init(&aplic->iodev, &aplic_iodoev_ops); 602 mutex_lock(&kvm->slots_lock); 603 ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, 604 kvm->arch.aia.aplic_addr, 605 KVM_DEV_RISCV_APLIC_SIZE, 606 &aplic->iodev); 607 mutex_unlock(&kvm->slots_lock); 608 if (ret) 609 goto fail_free_aplic_irqs; 610 611 /* Setup default IRQ routing */ 612 ret = kvm_riscv_setup_default_irq_routing(kvm, aplic->nr_irqs); 613 if (ret) 614 goto fail_unreg_iodev; 615 616 return 0; 617 618 fail_unreg_iodev: 619 mutex_lock(&kvm->slots_lock); 620 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); 621 mutex_unlock(&kvm->slots_lock); 622 fail_free_aplic_irqs: 623 kfree(aplic->irqs); 624 fail_free_aplic: 625 kvm->arch.aia.aplic_state = NULL; 626 kfree(aplic); 627 return ret; 628 } 629 630 void kvm_riscv_aia_aplic_cleanup(struct kvm *kvm) 631 { 632 struct aplic *aplic = kvm->arch.aia.aplic_state; 633 634 if (!aplic) 635 return; 636 637 mutex_lock(&kvm->slots_lock); 638 kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &aplic->iodev); 639 mutex_unlock(&kvm->slots_lock); 640 641 kfree(aplic->irqs); 642 643 kvm->arch.aia.aplic_state = NULL; 644 kfree(aplic); 645 } 646