Skip to content

Commit f84fc4e

Browse files
committed
Merge tag 's390-5.15-5' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
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
2 parents 5d6ab0b + a46044a commit f84fc4e

File tree

5 files changed

+46
-16
lines changed

5 files changed

+46
-16
lines changed

arch/s390/include/asm/pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ int zpci_enable_device(struct zpci_dev *);
207207
int zpci_disable_device(struct zpci_dev *);
208208
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
209209
int zpci_deconfigure_device(struct zpci_dev *zdev);
210+
void zpci_device_reserved(struct zpci_dev *zdev);
211+
bool zpci_is_device_configured(struct zpci_dev *zdev);
210212

211213
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
212214
int zpci_unregister_ioat(struct zpci_dev *, u8);

arch/s390/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
18261826
jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
18271827
if (jit.addrs == NULL) {
18281828
fp = orig_fp;
1829-
goto out;
1829+
goto free_addrs;
18301830
}
18311831
/*
18321832
* Three initial passes:

arch/s390/pci/pci.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void zpci_remove_reserved_devices(void)
9292
spin_unlock(&zpci_list_lock);
9393

9494
list_for_each_entry_safe(zdev, tmp, &remove, entry)
95-
zpci_zdev_put(zdev);
95+
zpci_device_reserved(zdev);
9696
}
9797

9898
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)
751751
return ERR_PTR(rc);
752752
}
753753

754+
bool zpci_is_device_configured(struct zpci_dev *zdev)
755+
{
756+
enum zpci_state state = zdev->state;
757+
758+
return state != ZPCI_FN_STATE_RESERVED &&
759+
state != ZPCI_FN_STATE_STANDBY;
760+
}
761+
754762
/**
755763
* zpci_scan_configured_device() - Scan a freshly configured zpci_dev
756764
* @zdev: The zpci_dev to be configured
@@ -822,6 +830,31 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
822830
return 0;
823831
}
824832

833+
/**
834+
* zpci_device_reserved() - Mark device as resverved
835+
* @zdev: the zpci_dev that was reserved
836+
*
837+
* Handle the case that a given zPCI function was reserved by another system.
838+
* After a call to this function the zpci_dev can not be found via
839+
* get_zdev_by_fid() anymore but may still be accessible via existing
840+
* references though it will not be functional anymore.
841+
*/
842+
void zpci_device_reserved(struct zpci_dev *zdev)
843+
{
844+
if (zdev->has_hp_slot)
845+
zpci_exit_slot(zdev);
846+
/*
847+
* Remove device from zpci_list as it is going away. This also
848+
* makes sure we ignore subsequent zPCI events for this device.
849+
*/
850+
spin_lock(&zpci_list_lock);
851+
list_del(&zdev->entry);
852+
spin_unlock(&zpci_list_lock);
853+
zdev->state = ZPCI_FN_STATE_RESERVED;
854+
zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
855+
zpci_zdev_put(zdev);
856+
}
857+
825858
void zpci_release_device(struct kref *kref)
826859
{
827860
struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
@@ -843,6 +876,12 @@ void zpci_release_device(struct kref *kref)
843876
case ZPCI_FN_STATE_STANDBY:
844877
if (zdev->has_hp_slot)
845878
zpci_exit_slot(zdev);
879+
spin_lock(&zpci_list_lock);
880+
list_del(&zdev->entry);
881+
spin_unlock(&zpci_list_lock);
882+
zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
883+
fallthrough;
884+
case ZPCI_FN_STATE_RESERVED:
846885
if (zdev->has_resources)
847886
zpci_cleanup_bus_resources(zdev);
848887
zpci_bus_device_unregister(zdev);
@@ -851,10 +890,6 @@ void zpci_release_device(struct kref *kref)
851890
default:
852891
break;
853892
}
854-
855-
spin_lock(&zpci_list_lock);
856-
list_del(&zdev->entry);
857-
spin_unlock(&zpci_list_lock);
858893
zpci_dbg(3, "rem fid:%x\n", zdev->fid);
859894
kfree(zdev);
860895
}

arch/s390/pci/pci_event.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
140140
/* The 0x0304 event may immediately reserve the device */
141141
if (!clp_get_state(zdev->fid, &state) &&
142142
state == ZPCI_FN_STATE_RESERVED) {
143-
zpci_zdev_put(zdev);
143+
zpci_device_reserved(zdev);
144144
}
145145
}
146146
break;
@@ -151,7 +151,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
151151
case 0x0308: /* Standby -> Reserved */
152152
if (!zdev)
153153
break;
154-
zpci_zdev_put(zdev);
154+
zpci_device_reserved(zdev);
155155
break;
156156
default:
157157
break;

drivers/pci/hotplug/s390_pci_hpc.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
6262
struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
6363
hotplug_slot);
6464

65-
switch (zdev->state) {
66-
case ZPCI_FN_STATE_STANDBY:
67-
*value = 0;
68-
break;
69-
default:
70-
*value = 1;
71-
break;
72-
}
65+
*value = zpci_is_device_configured(zdev) ? 1 : 0;
7366
return 0;
7467
}
7568

0 commit comments

Comments
 (0)