Commit f84fc4e3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 fixes from Vasily Gorbik:

 - Fix potential memory leak on a error path in eBPF

 - Fix handling of zpci device on reserve

* tag 's390-5.15-5' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/pci: fix zpci_zdev_put() on reserve
  bpf, s390: Fix potential memory leak about jit_data
parents 5d6ab0bb a46044a9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -207,6 +207,8 @@ int zpci_enable_device(struct zpci_dev *);
int zpci_disable_device(struct zpci_dev *);
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
int zpci_deconfigure_device(struct zpci_dev *zdev);
void zpci_device_reserved(struct zpci_dev *zdev);
bool zpci_is_device_configured(struct zpci_dev *zdev);

int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
int zpci_unregister_ioat(struct zpci_dev *, u8);
+1 −1
Original line number Diff line number Diff line
@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
	jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
	if (jit.addrs == NULL) {
		fp = orig_fp;
		goto out;
		goto free_addrs;
	}
	/*
	 * Three initial passes:
+40 −5
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ void zpci_remove_reserved_devices(void)
	spin_unlock(&zpci_list_lock);

	list_for_each_entry_safe(zdev, tmp, &remove, entry)
		zpci_zdev_put(zdev);
		zpci_device_reserved(zdev);
}

int pci_domain_nr(struct pci_bus *bus)
@@ -751,6 +751,14 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
	return ERR_PTR(rc);
}

bool zpci_is_device_configured(struct zpci_dev *zdev)
{
	enum zpci_state state = zdev->state;

	return state != ZPCI_FN_STATE_RESERVED &&
		state != ZPCI_FN_STATE_STANDBY;
}

/**
 * zpci_scan_configured_device() - Scan a freshly configured zpci_dev
 * @zdev: The zpci_dev to be configured
@@ -822,6 +830,31 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
	return 0;
}

/**
 * zpci_device_reserved() - Mark device as resverved
 * @zdev: the zpci_dev that was reserved
 *
 * Handle the case that a given zPCI function was reserved by another system.
 * After a call to this function the zpci_dev can not be found via
 * get_zdev_by_fid() anymore but may still be accessible via existing
 * references though it will not be functional anymore.
 */
void zpci_device_reserved(struct zpci_dev *zdev)
{
	if (zdev->has_hp_slot)
		zpci_exit_slot(zdev);
	/*
	 * Remove device from zpci_list as it is going away. This also
	 * makes sure we ignore subsequent zPCI events for this device.
	 */
	spin_lock(&zpci_list_lock);
	list_del(&zdev->entry);
	spin_unlock(&zpci_list_lock);
	zdev->state = ZPCI_FN_STATE_RESERVED;
	zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
	zpci_zdev_put(zdev);
}

void zpci_release_device(struct kref *kref)
{
	struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
@@ -843,6 +876,12 @@ void zpci_release_device(struct kref *kref)
	case ZPCI_FN_STATE_STANDBY:
		if (zdev->has_hp_slot)
			zpci_exit_slot(zdev);
		spin_lock(&zpci_list_lock);
		list_del(&zdev->entry);
		spin_unlock(&zpci_list_lock);
		zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
		fallthrough;
	case ZPCI_FN_STATE_RESERVED:
		if (zdev->has_resources)
			zpci_cleanup_bus_resources(zdev);
		zpci_bus_device_unregister(zdev);
@@ -851,10 +890,6 @@ void zpci_release_device(struct kref *kref)
	default:
		break;
	}

	spin_lock(&zpci_list_lock);
	list_del(&zdev->entry);
	spin_unlock(&zpci_list_lock);
	zpci_dbg(3, "rem fid:%x\n", zdev->fid);
	kfree(zdev);
}
+2 −2
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
			/* The 0x0304 event may immediately reserve the device */
			if (!clp_get_state(zdev->fid, &state) &&
			    state == ZPCI_FN_STATE_RESERVED) {
				zpci_zdev_put(zdev);
				zpci_device_reserved(zdev);
			}
		}
		break;
@@ -151,7 +151,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
	case 0x0308: /* Standby -> Reserved */
		if (!zdev)
			break;
		zpci_zdev_put(zdev);
		zpci_device_reserved(zdev);
		break;
	default:
		break;
+1 −8
Original line number Diff line number Diff line
@@ -62,14 +62,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
	struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
					     hotplug_slot);

	switch (zdev->state) {
	case ZPCI_FN_STATE_STANDBY:
		*value = 0;
		break;
	default:
		*value = 1;
		break;
	}
	*value = zpci_is_device_configured(zdev) ? 1 : 0;
	return 0;
}