Commit 317fab7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
 "As everyone back came back from conferences, here are the pending
  patches for Linux 6.0.

  ARM:

   - Fix for kmemleak with pKVM

  s390:

   - Fixes for VFIO with zPCI

   - smatch fix

  x86:

   - Ensure XSAVE-capable hosts always allow FP and SSE state to be
     saved and restored via KVM_{GET,SET}_XSAVE

   - Fix broken max_mmu_rmap_size stat

   - Fix compile error with old glibc that doesn't have gettid()"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: x86: Inject #UD on emulated XSETBV if XSAVES isn't enabled
  KVM: x86: Always enable legacy FP/SSE in allowed user XFEATURES
  KVM: x86: Reinstate kvm_vcpu_arch.guest_supported_xcr0
  KVM: x86/mmu: add missing update to max_mmu_rmap_size
  selftests: kvm: Fix a compile error in selftests/kvm/rseq_test.c
  KVM: s390: pci: register pci hooks without interpretation
  KVM: s390: pci: fix GAIT physical vs virtual pointers usage
  KVM: s390: Pass initialized arg even if unused
  KVM: s390: pci: fix plain integer as NULL pointer warnings
  KVM: arm64: Use kmemleak_free_part_phys() to unregister hyp_mem_base
parents 526e8262 69604fe7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2114,7 +2114,7 @@ static int finalize_hyp_mode(void)
	 * at, which would end badly once inaccessible.
	 */
	kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
	kmemleak_free_part(__va(hyp_mem_base), hyp_mem_size);
	kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size);
	return pkvm_drop_host_privileges();
}

+13 −3
Original line number Diff line number Diff line
@@ -489,6 +489,8 @@ enum prot_type {
	PROT_TYPE_ALC  = 2,
	PROT_TYPE_DAT  = 3,
	PROT_TYPE_IEP  = 4,
	/* Dummy value for passing an initialized value when code != PGM_PROTECTION */
	PROT_NONE,
};

static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva, u8 ar,
@@ -504,6 +506,10 @@ static int trans_exc_ending(struct kvm_vcpu *vcpu, int code, unsigned long gva,
	switch (code) {
	case PGM_PROTECTION:
		switch (prot) {
		case PROT_NONE:
			/* We should never get here, acts like termination */
			WARN_ON_ONCE(1);
			break;
		case PROT_TYPE_IEP:
			tec->b61 = 1;
			fallthrough;
@@ -968,8 +974,10 @@ static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
				return rc;
		} else {
			gpa = kvm_s390_real_to_abs(vcpu, ga);
			if (kvm_is_error_gpa(vcpu->kvm, gpa))
			if (kvm_is_error_gpa(vcpu->kvm, gpa)) {
				rc = PGM_ADDRESSING;
				prot = PROT_NONE;
			}
		}
		if (rc)
			return trans_exc(vcpu, rc, ga, ar, mode, prot);
@@ -1112,8 +1120,6 @@ int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
		if (rc == PGM_PROTECTION && try_storage_prot_override)
			rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx],
							data, fragment_len, PAGE_SPO_ACC);
		if (rc == PGM_PROTECTION)
			prot = PROT_TYPE_KEYC;
		if (rc)
			break;
		len -= fragment_len;
@@ -1123,6 +1129,10 @@ int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
	if (rc > 0) {
		bool terminate = (mode == GACC_STORE) && (idx > 0);

		if (rc == PGM_PROTECTION)
			prot = PROT_TYPE_KEYC;
		else
			prot = PROT_NONE;
		rc = trans_exc_ending(vcpu, rc, ga, ar, mode, prot, terminate);
	}
out_unlock:
+1 −1
Original line number Diff line number Diff line
@@ -3324,7 +3324,7 @@ static void aen_host_forward(unsigned long si)
	if (gaite->count == 0)
		return;
	if (gaite->aisb != 0)
		set_bit_inv(gaite->aisbo, (unsigned long *)gaite->aisb);
		set_bit_inv(gaite->aisbo, phys_to_virt(gaite->aisb));

	kvm = kvm_s390_pci_si_to_kvm(aift, si);
	if (!kvm)
+2 −2
Original line number Diff line number Diff line
@@ -505,7 +505,7 @@ int kvm_arch_init(void *opaque)
		goto out;
	}

	if (kvm_s390_pci_interp_allowed()) {
	if (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM)) {
		rc = kvm_s390_pci_init();
		if (rc) {
			pr_err("Unable to allocate AIFT for PCI\n");
@@ -527,7 +527,7 @@ int kvm_arch_init(void *opaque)
void kvm_arch_exit(void)
{
	kvm_s390_gib_destroy();
	if (kvm_s390_pci_interp_allowed())
	if (IS_ENABLED(CONFIG_VFIO_PCI_ZDEV_KVM))
		kvm_s390_pci_exit();
	debug_unregister(kvm_s390_dbf);
	debug_unregister(kvm_s390_dbf_uv);
+14 −6
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ static int zpci_setup_aipb(u8 nisc)
	if (!zpci_aipb)
		return -ENOMEM;

	aift->sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC, 0);
	aift->sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC, NULL);
	if (!aift->sbv) {
		rc = -ENOMEM;
		goto free_aipb;
@@ -71,7 +71,7 @@ static int zpci_setup_aipb(u8 nisc)
		rc = -ENOMEM;
		goto free_sbv;
	}
	aift->gait = (struct zpci_gaite *)page_to_phys(page);
	aift->gait = (struct zpci_gaite *)page_to_virt(page);

	zpci_aipb->aipb.faisb = virt_to_phys(aift->sbv->vector);
	zpci_aipb->aipb.gait = virt_to_phys(aift->gait);
@@ -373,7 +373,7 @@ static int kvm_s390_pci_aif_disable(struct zpci_dev *zdev, bool force)
		gaite->gisc = 0;
		gaite->aisbo = 0;
		gaite->gisa = 0;
		aift->kzdev[zdev->aisb] = 0;
		aift->kzdev[zdev->aisb] = NULL;
		/* Clear zdev info */
		airq_iv_free_bit(aift->sbv, zdev->aisb);
		airq_iv_release(zdev->aibv);
@@ -672,23 +672,31 @@ int kvm_s390_pci_zpci_op(struct kvm *kvm, struct kvm_s390_zpci_op *args)

int kvm_s390_pci_init(void)
{
	zpci_kvm_hook.kvm_register = kvm_s390_pci_register_kvm;
	zpci_kvm_hook.kvm_unregister = kvm_s390_pci_unregister_kvm;

	if (!kvm_s390_pci_interp_allowed())
		return 0;

	aift = kzalloc(sizeof(struct zpci_aift), GFP_KERNEL);
	if (!aift)
		return -ENOMEM;

	spin_lock_init(&aift->gait_lock);
	mutex_init(&aift->aift_lock);
	zpci_kvm_hook.kvm_register = kvm_s390_pci_register_kvm;
	zpci_kvm_hook.kvm_unregister = kvm_s390_pci_unregister_kvm;

	return 0;
}

void kvm_s390_pci_exit(void)
{
	mutex_destroy(&aift->aift_lock);
	zpci_kvm_hook.kvm_register = NULL;
	zpci_kvm_hook.kvm_unregister = NULL;

	if (!kvm_s390_pci_interp_allowed())
		return;

	mutex_destroy(&aift->aift_lock);

	kfree(aift);
}
Loading