Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: s390: pci: add routines to start/stop interpretive execution

These routines will be invoked at the time an s390x vfio-pci device is
associated with a KVM (or when the association is removed), allowing
the zPCI device to enable or disable load/store intepretation mode;
this requires the host zPCI device to inform firmware of the unique
token (GISA designation) that is associated with the owning KVM.

Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Acked-by: Pierre Morel <pmorel@linux.ibm.com>
Link: https://lore.kernel.org/r/20220606203325.110625-17-mjrosato@linux.ibm.com
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>

authored by

Matthew Rosato and committed by
Christian Borntraeger
09340b2f 3c5a1b6f

+205
+18
arch/s390/include/asm/kvm_host.h
··· 19 19 #include <linux/kvm.h> 20 20 #include <linux/seqlock.h> 21 21 #include <linux/module.h> 22 + #include <linux/pci.h> 22 23 #include <asm/debug.h> 23 24 #include <asm/cpu.h> 24 25 #include <asm/fpu/api.h> ··· 968 967 DECLARE_BITMAP(idle_mask, KVM_MAX_VCPUS); 969 968 struct kvm_s390_gisa_interrupt gisa_int; 970 969 struct kvm_s390_pv pv; 970 + struct list_head kzdev_list; 971 + spinlock_t kzdev_list_lock; 971 972 }; 972 973 973 974 #define KVM_HVA_ERR_BAD (-1UL) ··· 1019 1016 struct kvm_memory_slot *slot) {} 1020 1017 static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} 1021 1018 static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} 1019 + 1020 + #define __KVM_HAVE_ARCH_VM_FREE 1021 + void kvm_arch_free_vm(struct kvm *kvm); 1022 + 1023 + #ifdef CONFIG_VFIO_PCI_ZDEV_KVM 1024 + int kvm_s390_pci_register_kvm(struct zpci_dev *zdev, struct kvm *kvm); 1025 + void kvm_s390_pci_unregister_kvm(struct zpci_dev *zdev); 1026 + #else 1027 + static inline int kvm_s390_pci_register_kvm(struct zpci_dev *dev, 1028 + struct kvm *kvm) 1029 + { 1030 + return -EPERM; 1031 + } 1032 + static inline void kvm_s390_pci_unregister_kvm(struct zpci_dev *dev) {} 1033 + #endif 1022 1034 1023 1035 #endif
+1
arch/s390/include/asm/pci.h
··· 194 194 /* IOMMU and passthrough */ 195 195 struct s390_domain *s390_domain; /* s390 IOMMU domain data */ 196 196 struct kvm_zdev *kzdev; 197 + struct mutex kzdev_lock; 197 198 }; 198 199 199 200 static inline bool zdev_enabled(struct zpci_dev *zdev)
+15
arch/s390/kvm/kvm-s390.c
··· 2790 2790 kvm->arch.sca = NULL; 2791 2791 } 2792 2792 2793 + void kvm_arch_free_vm(struct kvm *kvm) 2794 + { 2795 + if (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) 2796 + kvm_s390_pci_clear_list(kvm); 2797 + 2798 + __kvm_arch_free_vm(kvm); 2799 + } 2800 + 2793 2801 int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) 2794 2802 { 2795 2803 gfp_t alloc_flags = GFP_KERNEL_ACCOUNT; ··· 2879 2871 kvm->arch.model.ibc = sclp.ibc & 0x0fff; 2880 2872 2881 2873 kvm_s390_crypto_init(kvm); 2874 + 2875 + if (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) { 2876 + mutex_lock(&kvm->lock); 2877 + kvm_s390_pci_init_list(kvm); 2878 + kvm_s390_vcpu_pci_enable_interp(kvm); 2879 + mutex_unlock(&kvm->lock); 2880 + } 2882 2881 2883 2882 mutex_init(&kvm->arch.float_int.ais_lock); 2884 2883 spin_lock_init(&kvm->arch.float_int.lock);
+162
arch/s390/kvm/pci.c
··· 12 12 #include <asm/pci.h> 13 13 #include <asm/pci_insn.h> 14 14 #include <asm/pci_io.h> 15 + #include <asm/sclp.h> 15 16 #include "pci.h" 17 + #include "kvm-s390.h" 16 18 17 19 struct zpci_aift *aift; 18 20 ··· 423 421 WARN_ON(kzdev->zdev != zdev); 424 422 zdev->kzdev = NULL; 425 423 kfree(kzdev); 424 + } 425 + 426 + 427 + /* 428 + * Register device with the specified KVM. If interpetation facilities are 429 + * available, enable them and let userspace indicate whether or not they will 430 + * be used (specify SHM bit to disable). 431 + */ 432 + int kvm_s390_pci_register_kvm(struct zpci_dev *zdev, struct kvm *kvm) 433 + { 434 + int rc; 435 + 436 + if (!zdev) 437 + return -EINVAL; 438 + 439 + mutex_lock(&zdev->kzdev_lock); 440 + 441 + if (zdev->kzdev || zdev->gisa != 0 || !kvm) { 442 + mutex_unlock(&zdev->kzdev_lock); 443 + return -EINVAL; 444 + } 445 + 446 + kvm_get_kvm(kvm); 447 + 448 + mutex_lock(&kvm->lock); 449 + 450 + rc = kvm_s390_pci_dev_open(zdev); 451 + if (rc) 452 + goto err; 453 + 454 + /* 455 + * If interpretation facilities aren't available, add the device to 456 + * the kzdev list but don't enable for interpretation. 457 + */ 458 + if (!kvm_s390_pci_interp_allowed()) 459 + goto out; 460 + 461 + /* 462 + * If this is the first request to use an interpreted device, make the 463 + * necessary vcpu changes 464 + */ 465 + if (!kvm->arch.use_zpci_interp) 466 + kvm_s390_vcpu_pci_enable_interp(kvm); 467 + 468 + if (zdev_enabled(zdev)) { 469 + rc = zpci_disable_device(zdev); 470 + if (rc) 471 + goto err; 472 + } 473 + 474 + /* 475 + * Store information about the identity of the kvm guest allowed to 476 + * access this device via interpretation to be used by host CLP 477 + */ 478 + zdev->gisa = (u32)virt_to_phys(&kvm->arch.sie_page2->gisa); 479 + 480 + rc = zpci_enable_device(zdev); 481 + if (rc) 482 + goto clear_gisa; 483 + 484 + /* Re-register the IOMMU that was already created */ 485 + rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, 486 + virt_to_phys(zdev->dma_table)); 487 + if (rc) 488 + goto clear_gisa; 489 + 490 + out: 491 + zdev->kzdev->kvm = kvm; 492 + 493 + spin_lock(&kvm->arch.kzdev_list_lock); 494 + list_add_tail(&zdev->kzdev->entry, &kvm->arch.kzdev_list); 495 + spin_unlock(&kvm->arch.kzdev_list_lock); 496 + 497 + mutex_unlock(&kvm->lock); 498 + mutex_unlock(&zdev->kzdev_lock); 499 + return 0; 500 + 501 + clear_gisa: 502 + zdev->gisa = 0; 503 + err: 504 + if (zdev->kzdev) 505 + kvm_s390_pci_dev_release(zdev); 506 + mutex_unlock(&kvm->lock); 507 + mutex_unlock(&zdev->kzdev_lock); 508 + kvm_put_kvm(kvm); 509 + return rc; 510 + } 511 + EXPORT_SYMBOL_GPL(kvm_s390_pci_register_kvm); 512 + 513 + void kvm_s390_pci_unregister_kvm(struct zpci_dev *zdev) 514 + { 515 + struct kvm *kvm; 516 + 517 + if (!zdev) 518 + return; 519 + 520 + mutex_lock(&zdev->kzdev_lock); 521 + 522 + if (WARN_ON(!zdev->kzdev)) { 523 + mutex_unlock(&zdev->kzdev_lock); 524 + return; 525 + } 526 + 527 + kvm = zdev->kzdev->kvm; 528 + mutex_lock(&kvm->lock); 529 + 530 + /* 531 + * A 0 gisa means interpretation was never enabled, just remove the 532 + * device from the list. 533 + */ 534 + if (zdev->gisa == 0) 535 + goto out; 536 + 537 + /* Forwarding must be turned off before interpretation */ 538 + if (zdev->kzdev->fib.fmt0.aibv != 0) 539 + kvm_s390_pci_aif_disable(zdev, true); 540 + 541 + /* Remove the host CLP guest designation */ 542 + zdev->gisa = 0; 543 + 544 + if (zdev_enabled(zdev)) { 545 + if (zpci_disable_device(zdev)) 546 + goto out; 547 + } 548 + 549 + if (zpci_enable_device(zdev)) 550 + goto out; 551 + 552 + /* Re-register the IOMMU that was already created */ 553 + zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, 554 + virt_to_phys(zdev->dma_table)); 555 + 556 + out: 557 + spin_lock(&kvm->arch.kzdev_list_lock); 558 + list_del(&zdev->kzdev->entry); 559 + spin_unlock(&kvm->arch.kzdev_list_lock); 560 + kvm_s390_pci_dev_release(zdev); 561 + 562 + mutex_unlock(&kvm->lock); 563 + mutex_unlock(&zdev->kzdev_lock); 564 + 565 + kvm_put_kvm(kvm); 566 + } 567 + EXPORT_SYMBOL_GPL(kvm_s390_pci_unregister_kvm); 568 + 569 + void kvm_s390_pci_init_list(struct kvm *kvm) 570 + { 571 + spin_lock_init(&kvm->arch.kzdev_list_lock); 572 + INIT_LIST_HEAD(&kvm->arch.kzdev_list); 573 + } 574 + 575 + void kvm_s390_pci_clear_list(struct kvm *kvm) 576 + { 577 + /* 578 + * This list should already be empty, either via vfio device closures 579 + * or kvm fd cleanup. 580 + */ 581 + spin_lock(&kvm->arch.kzdev_list_lock); 582 + WARN_ON_ONCE(!list_empty(&kvm->arch.kzdev_list)); 583 + spin_unlock(&kvm->arch.kzdev_list_lock); 426 584 } 427 585 428 586 int kvm_s390_pci_init(void)
+5
arch/s390/kvm/pci.h
··· 13 13 #include <linux/kvm_host.h> 14 14 #include <linux/pci.h> 15 15 #include <linux/mutex.h> 16 + #include <linux/kvm.h> 16 17 #include <linux/kvm_host.h> 17 18 #include <asm/airq.h> 18 19 #include <asm/cpu.h> ··· 22 21 struct zpci_dev *zdev; 23 22 struct kvm *kvm; 24 23 struct zpci_fib fib; 24 + struct list_head entry; 25 25 }; 26 26 27 27 struct zpci_gaite { ··· 55 53 56 54 int kvm_s390_pci_aen_init(u8 nisc); 57 55 void kvm_s390_pci_aen_exit(void); 56 + 57 + void kvm_s390_pci_init_list(struct kvm *kvm); 58 + void kvm_s390_pci_clear_list(struct kvm *kvm); 58 59 59 60 int kvm_s390_pci_init(void); 60 61 void kvm_s390_pci_exit(void);
+4
arch/s390/pci/pci.c
··· 132 132 zpci_dbg(3, "reg ioat fid:%x, cc:%d, status:%d\n", zdev->fid, cc, status); 133 133 return cc; 134 134 } 135 + EXPORT_SYMBOL_GPL(zpci_register_ioat); 135 136 136 137 /* Modify PCI: Unregister I/O address translation parameters */ 137 138 int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) ··· 713 712 zpci_update_fh(zdev, fh); 714 713 return rc; 715 714 } 715 + EXPORT_SYMBOL_GPL(zpci_enable_device); 716 716 717 717 int zpci_disable_device(struct zpci_dev *zdev) 718 718 { ··· 737 735 } 738 736 return rc; 739 737 } 738 + EXPORT_SYMBOL_GPL(zpci_disable_device); 740 739 741 740 /** 742 741 * zpci_hot_reset_device - perform a reset of the given zPCI function ··· 831 828 832 829 kref_init(&zdev->kref); 833 830 mutex_init(&zdev->lock); 831 + mutex_init(&zdev->kzdev_lock); 834 832 835 833 rc = zpci_init_iommu(zdev); 836 834 if (rc)