* Re: [PATCH v4 07/11] powerpc/pseries/iommu: Reorganize iommu_table_setparms*() with new helper
From: Leonardo Brás @ 2021-07-13 4:47 UTC (permalink / raw)
To: Alexey Kardashevskiy, Michael Ellerman, Benjamin Herrenschmidt,
Paul Mackerras, Joel Stanley, Christophe Leroy, Nicolin Chen,
Niklas Schnelle
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <97626d3883ed207b818760a8239babb08a6b5c59.camel@gmail.com>
Hello Alexey,
On Fri, 2021-06-18 at 19:26 -0300, Leonardo Brás wrote:
> >
> > > + unsigned long liobn,
> > > unsigned long win_addr,
> > > + unsigned long
> > > window_size,
> > > unsigned long page_shift,
> > > + unsigned long base,
> > > struct
> > > iommu_table_ops *table_ops)
> >
> >
> > iommu_table_setparms() rather than passing 0 around.
> >
> > The same comment about "liobn" - set it in
> > iommu_table_setparms_lpar().
> > The reviewer will see what field atters in what situation imho.
> >
>
> The idea here was to keep all tbl parameters setting in
> _iommu_table_setparms (or iommu_table_setparms_common).
>
> I understand the idea that each one of those is optional in the other
> case, but should we keep whatever value is present in the other
> variable (not zeroing the other variable), or do someting like:
>
> tbl->it_index = 0;
> tbl->it_base = basep;
> (in iommu_table_setparms)
>
> tbl->it_index = liobn;
> tbl->it_base = 0;
> (in iommu_table_setparms_lpar)
>
This one is supposed to be a question, but I missed the question mark.
Sorry about that.
I would like to get your opinion in this :)
^ permalink raw reply
* [RFC 0/2] Paravirtualize idle CPU wakeup optimization
From: Parth Shah @ 2021-07-13 5:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ego, mikey, srikar, parths1229, svaidy
This patch-set is a revision over HCALL based implementation which can
be found at:
https://lore.kernel.org/linuxppc-dev/20210401115922.1524705-1-parth@linux.ibm.com/
But since the overhead of HCALL is huge, this patch-set uses lppaca
region to update idle-hint, where hypervisor keeps changing the newly
added idle_hint attribute in the VPA region of each vCPUs of all KVMs,
and guest have to just look at this attribute.
This implementation is not aimed for full fledged solution, but is
rather a demonstration of para-virtualizing task scheduler. Hypervisor
can provided better idle-hints about vCPU scheduling and guest can use
it for better scheduling decisions.
Abstract:
=========
The Linux task scheduler searches for an idle cpu for task wakeup
in-order to lower the wakeup latency as much as possible. The process of
determining if a cpu is idle or not has evolved over time.
Currently, in available_idle_cpu(), a cpu is considered idle if
- there are no task running or enqueued to the runqueue of the cpu and
- the cpu is not-preempted, i.e. while running inside a guest, a cpu is
not yielded (determined via vcpu_is_preempted())
While inside the guest, there is no way to deterministically predict
if a vCPU that has been yielded/ceded to the hypervisor can be gotten
back. Hence currently the scheduler considers such CEDEd vCPU as not
"available" idle and would instead pick other busy CPUs for waking up
the wakee task.
In this patch-set we try to further classify idle cpus as instantly
available or not. This is achieved by taking hint from the hypervisor
by quering if the vCPU will be scheduled instantly or not. In most
cases, scheduler prefers prev_cpu of a waking task unless it is busy.
In this patchset, the hypervisor uses this information to figure out
if the prev_cpu used by the task (of the corresponding vCPU) is idle
or not, and passes this information to the guest.
Interface:
===========
This patchset introduces a new attribute in lppaca structure which is
shared by both the hypervisor and the guest. The new attribute, i.e.
idle_hint is updated regularly by the hypervisor. When a particular cpu
goes into idle-state, it updates the idle_hint of all the vCPUs of all
existing KVMs whose prev_cpu == smp_processor_id(). It similarly revert
backs the update when coming out of the idle-state.
Internal working:
========
The code-flow of the current implementation is as follow:
- In do_idle(), when entering an idle-state, walk through all vCPUs of
all KVM guests and find whose prev_cpu of vCPU task was same as the
caller's cpu, and mark the idle_hint=1 in the lppaca region of such
vCPUs.
- Similarly, mark idle_hint=0 for such vCPUs when exiting idle state.
- Guest OS scheduler searches for idle cpu using `avaialable_idle_cpu()`
which also looks if a vcpu_is_preempted() to see if vCPU is yielded or
not.
- If vCPU is yielded, then the GuestOS will additionally see if
idle_hint is marked as 1 or not. If idle_hint==1 then consider the
vCPU as non-preempted and use it for scheduling a task.
The patch-set is based on v5.13 kernel.
Results:
========
- Baseline kernel = v5.13
- Patched kernel = v5.13 + this patch-set
Setup:
All the results are taken on IBM POWER9 baremetal system running patched
kernel. This system consists of 2 NUMA nodes, 22 cores per socket with
SMT-4 mode.
Each KVM guest have identical cpu topology with total 40 CPUs, which are
10 cores with SMT-4 support.
Scenarios:
----------
1. Under-commit case: Only one KVM is active at a time.
- Baseline kernel:
$> schbench -m 20 -t 2 -r 30
Latency percentiles (usec)
50.0000th: 86
75.0000th: 406
90.0000th: 497
95.0000th: 541
*99.0000th: 2572 <-----
99.5000th: 3724
99.9000th: 6904
min=0, max=10007
- With Patched kernel:
$> schbench -m 20 -t 2 -r 30
Latency percentiles (usec)
50.0000th: 386
75.0000th: 470
90.0000th: 529
95.0000th: 589
*99.0000th: 741 (-71%) <-----
99.5000th: 841
99.9000th: 1522
min=0, max=6488
We see a significant reduction in the tail latencies due to being able
to schedule on an yielded/ceded idle CPU with the patchset instead of
waking up the task on a busy CPU.
2. Over-commit case: Multiple KVM guests sharing same set of CPUs.
Two KVMs running baseline kernel is used for creating noise using `schbench
-m 10 -t 2 -r 3000` while only the other KVM is benchmarked.
- Baseline kernel:
$> schbench -m 20 -t 2 -r 30
Latency percentiles (usec)
50.0000th: 289
75.0000th: 1074
90.0000th: 7288
95.0000th: 11248
*99.0000th: 17760
99.5000th: 21088
99.9000th: 28896
min=0, max=36640
- With Patched kernel:
$> schbench -m 20 -t 2 -r 30
Latency percentiles (usec)
50.0000th: 281
75.0000th: 445
90.0000th: 4344
95.0000th: 9168
*99.0000th: 15824
99.5000th: 19296
99.9000th: 26656
min=0, max=36455
The results demonstrates that the proposed method of getting idle-hint
from the hypervisor to better find an idle cpu in the guestOS is very
helpful in under-commmit cases due to higher chance of finding the
previously used physical cpu as idle.
The results also confirms that there is no regression in the over-commit
case where the proposed methodlogy does not affect much.
Parth Shah (2):
powerpc/book3s_hv: Add new idle-hint attribute in VPA region
kernel/idle: Update and use idle-hint in VPA region
arch/powerpc/include/asm/idle_hint.h | 28 +++++++++++++++++++++++
arch/powerpc/include/asm/lppaca.h | 3 ++-
arch/powerpc/include/asm/paravirt.h | 12 ++++++++--
arch/powerpc/kvm/book3s.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 34 ++++++++++++++++++++++++++++
kernel/sched/idle.c | 3 +++
6 files changed, 79 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/include/asm/idle_hint.h
--
2.26.3
^ permalink raw reply
* [RFC 1/2] powerpc/book3s_hv: Add new idle-hint attribute in VPA region
From: Parth Shah @ 2021-07-13 5:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ego, mikey, srikar, parths1229, svaidy
In-Reply-To: <20210713052433.257003-1-parth@linux.ibm.com>
In lppaca region, add a new attribute idle_hint which can allow guest scheduler for
better cpu selection. Hypervisor can update idle_hint attribute based on
the prediction that if vCPU needs to be scheduled then can it be scheduled
instantly or not.
Signed-off-by: Parth Shah <parth@linux.ibm.com>
---
arch/powerpc/include/asm/idle_hint.h | 28 +++++++++++++++++++++++
arch/powerpc/include/asm/lppaca.h | 3 ++-
arch/powerpc/kvm/book3s.h | 2 ++
arch/powerpc/kvm/book3s_hv.c | 34 ++++++++++++++++++++++++++++
4 files changed, 66 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/include/asm/idle_hint.h
diff --git a/arch/powerpc/include/asm/idle_hint.h b/arch/powerpc/include/asm/idle_hint.h
new file mode 100644
index 000000000000..165d65c0275b
--- /dev/null
+++ b/arch/powerpc/include/asm/idle_hint.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_POWERPC_IDLEHINT_H
+#define _ASM_POWERPC_IDLEHINT_H
+
+#include <linux/kvm_host.h>
+
+extern void kvmppc_idle_hint_set(struct kvm_vcpu *vcpu, int idle_hint);
+
+extern int idle_hint_is_active;
+
+extern void set_idle_hint(int cpu, int value);
+
+static inline int prev_cpu_of_kvm(struct kvm_vcpu *vcpu)
+{
+ struct pid *pid;
+ struct task_struct *task = NULL;
+
+ rcu_read_lock();
+ pid = rcu_dereference(vcpu->pid);
+ if (pid)
+ task = get_pid_task(pid, PIDTYPE_PID);
+ rcu_read_unlock();
+
+ if (!task)
+ return -1;
+
+ return task_cpu(task);
+}
+#endif
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index c390ec377bae..ee790a566036 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -111,7 +111,8 @@ struct lppaca {
__be32 page_ins; /* CMO Hint - # page ins by OS */
u8 reserved11[148];
volatile __be64 dtl_idx; /* Dispatch Trace Log head index */
- u8 reserved12[96];
+ volatile __be32 idle_hint; /* Can vCPU be scheduled instantly? */
+ u8 reserved12[92];
} ____cacheline_aligned;
#define lppaca_of(cpu) (*paca_ptrs[cpu]->lppaca_ptr)
diff --git a/arch/powerpc/kvm/book3s.h b/arch/powerpc/kvm/book3s.h
index 740e51def5a5..61b0741c139a 100644
--- a/arch/powerpc/kvm/book3s.h
+++ b/arch/powerpc/kvm/book3s.h
@@ -7,6 +7,8 @@
#ifndef __POWERPC_KVM_BOOK3S_H__
#define __POWERPC_KVM_BOOK3S_H__
+#include <asm/idle_hint.h>
+
extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm,
struct kvm_memory_slot *memslot);
extern bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range);
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index bc0813644666..c008be20294d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -447,6 +447,7 @@ static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa)
{
vpa->__old_status |= LPPACA_OLD_SHARED_PROC;
vpa->yield_count = cpu_to_be32(1);
+ vpa->idle_hint = cpu_to_be32(0);
}
static int set_vpa(struct kvm_vcpu *vcpu, struct kvmppc_vpa *v,
@@ -911,6 +912,17 @@ static int kvm_arch_vcpu_yield_to(struct kvm_vcpu *target)
return kvm_vcpu_yield_to(target);
}
+void kvmppc_idle_hint_set(struct kvm_vcpu *vcpu, int idle_hint)
+{
+ struct lppaca *lppaca;
+
+ if (!vcpu) return;
+
+ lppaca = (struct lppaca *)vcpu->arch.vpa.pinned_addr;
+ if (lppaca)
+ lppaca->idle_hint = cpu_to_be32(idle_hint);
+}
+
static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu)
{
int yield_count = 0;
@@ -2803,6 +2815,28 @@ static int on_primary_thread(void)
return 1;
}
+void set_idle_hint_for_kvm(struct kvm *kvm, int cpu, int value)
+{
+ int i;
+ struct kvm_vcpu *vcpu;
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ if (cpu == prev_cpu_of_kvm(vcpu)) {
+ kvmppc_idle_hint_set(vcpu, value);
+ }
+ }
+}
+
+void set_idle_hint(int cpu, int value)
+{
+ struct kvm *kvm;
+ struct kvm *tmp;
+
+ list_for_each_entry_safe(kvm, tmp, &vm_list, vm_list) {
+ set_idle_hint_for_kvm(kvm, cpu, value);
+ }
+}
+
/*
* A list of virtual cores for each physical CPU.
* These are vcores that could run but their runner VCPU tasks are
--
2.26.3
^ permalink raw reply related
* [RFC 2/2] kernel/idle: Update and use idle-hint in VPA region
From: Parth Shah @ 2021-07-13 5:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ego, mikey, srikar, parths1229, svaidy
In-Reply-To: <20210713052433.257003-1-parth@linux.ibm.com>
In guest, Set idle_hint to 1 when the prev_cpu of a vCPU goes into idle state,
similarly set idle_hint to 0 when exiting an idle state.
Since the idle_hint is in VPA region, the available_idle_cpu() in guest can
read this region every time to find if a vCPU can be scheduled instantly by
the hypervsior or not.
Signed-off-by: Parth Shah <parth@linux.ibm.com>
---
arch/powerpc/include/asm/paravirt.h | 12 ++++++++++--
kernel/sched/idle.c | 3 +++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h
index bcb7b5f917be..b20e4d25bd00 100644
--- a/arch/powerpc/include/asm/paravirt.h
+++ b/arch/powerpc/include/asm/paravirt.h
@@ -21,6 +21,12 @@ static inline bool is_shared_processor(void)
return static_branch_unlikely(&shared_processor);
}
+static inline int idle_hint_of(int cpu)
+{
+ __be32 idle_hint = READ_ONCE(lppaca_of(cpu).idle_hint);
+ return be32_to_cpu(idle_hint);
+}
+
/* If bit 0 is set, the cpu has been preempted */
static inline u32 yield_count_of(int cpu)
{
@@ -109,8 +115,10 @@ static inline bool vcpu_is_preempted(int cpu)
}
#endif
- if (yield_count_of(cpu) & 1)
- return true;
+ if (yield_count_of(cpu) & 1) {
+ if (idle_hint_of(cpu) == 0)
+ return true;
+ }
return false;
}
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 7ca3d3d86c2a..fdc8d1d474f0 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -7,6 +7,7 @@
* tasks which are handled in sched/fair.c )
*/
#include "sched.h"
+#include <asm/idle_hint.h>
#include <trace/events/power.h>
@@ -290,6 +291,7 @@ static void do_idle(void)
arch_cpu_idle_dead();
}
+ set_idle_hint(cpu, 1);
arch_cpu_idle_enter();
rcu_nocb_flush_deferred_wakeup();
@@ -306,6 +308,7 @@ static void do_idle(void)
cpuidle_idle_call();
}
arch_cpu_idle_exit();
+ set_idle_hint(cpu, 0);
}
/*
--
2.26.3
^ permalink raw reply related
* [PATCH v5 3/8] x86_64: Add LKDTM accessor for patching addr
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
When live patching with STRICT_KERNEL_RWX a mapping is installed at a
"patching address" with temporary write permissions. Provide a
LKDTM-only accessor function for this address in preparation for a LKDTM
test which attempts to "hijack" this mapping by writing to it from
another CPU.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
arch/x86/include/asm/text-patching.h | 4 ++++
arch/x86/kernel/alternative.c | 7 +++++++
2 files changed, 11 insertions(+)
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h
index b7421780e4e92..f0caf9ee13bd8 100644
--- a/arch/x86/include/asm/text-patching.h
+++ b/arch/x86/include/asm/text-patching.h
@@ -167,4 +167,8 @@ void int3_emulate_ret(struct pt_regs *regs)
}
#endif /* !CONFIG_UML_X86 */
+#if IS_BUILTIN(CONFIG_LKDTM)
+unsigned long read_cpu_patching_addr(unsigned int cpu);
+#endif
+
#endif /* _ASM_X86_TEXT_PATCHING_H */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index e9da3dc712541..28bb92b695639 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -773,6 +773,13 @@ static inline void unuse_temporary_mm(temp_mm_state_t prev_state)
__ro_after_init struct mm_struct *poking_mm;
__ro_after_init unsigned long poking_addr;
+#if IS_BUILTIN(CONFIG_LKDTM)
+unsigned long read_cpu_patching_addr(unsigned int cpu)
+{
+ return poking_addr;
+}
+#endif
+
static void *__text_poke(void *addr, const void *opcode, size_t len)
{
bool cross_page_boundary = offset_in_page(addr) + len > PAGE_SIZE;
--
2.26.1
^ permalink raw reply related
* [PATCH v5 2/8] lkdtm/powerpc: Add test to hijack a patch mapping
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
When live patching with STRICT_KERNEL_RWX the CPU doing the patching
must temporarily remap the page(s) containing the patch site with +W
permissions. While this temporary mapping is in use, another CPU could
write to the same mapping and maliciously alter kernel text. Implement a
LKDTM test to attempt to exploit such an opening during code patching.
The test is implemented on powerpc and requires LKDTM built into the
kernel (building LKDTM as a module is insufficient).
The LKDTM "hijack" test works as follows:
1. A CPU executes an infinite loop to patch an instruction. This is
the "patching" CPU.
2. Another CPU attempts to write to the address of the temporary
mapping used by the "patching" CPU. This other CPU is the
"hijacker" CPU. The hijack either fails with a fault/error or
succeeds, in which case some kernel text is now overwritten.
The virtual address of the temporary patch mapping is provided via an
LKDTM-specific accessor to the hijacker CPU. This test assumes a
hypothetical situation where this address was leaked previously.
How to run the test:
mount -t debugfs none /sys/kernel/debug
(echo HIJACK_PATCH > /sys/kernel/debug/provoke-crash/DIRECT)
A passing test indicates that it is not possible to overwrite kernel
text from another CPU by using the temporary mapping established by
a CPU for patching.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
v5: * Use `u32*` instead of `struct ppc_inst*` based on new series in
upstream.
v4: * Separate the powerpc and x86_64 bits into individual patches.
* Use __put_kernel_nofault() when attempting to hijack the mapping
* Use raw_smp_processor_id() to avoid triggering the BUG() when
calling smp_processor_id() in preemptible code - the only thing
that matters is that one of the threads is bound to a different
CPU - we are not using smp_processor_id() to access any per-cpu
data or similar where preemption should be disabled.
* Rework the patching_cpu() kthread stop condition to avoid:
https://lwn.net/Articles/628628/
---
drivers/misc/lkdtm/core.c | 1 +
drivers/misc/lkdtm/lkdtm.h | 1 +
drivers/misc/lkdtm/perms.c | 134 +++++++++++++++++++++++++++++++++++++
3 files changed, 136 insertions(+)
diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c
index 8024b6a5cc7fc..fbcb95eda337b 100644
--- a/drivers/misc/lkdtm/core.c
+++ b/drivers/misc/lkdtm/core.c
@@ -147,6 +147,7 @@ static const struct crashtype crashtypes[] = {
CRASHTYPE(WRITE_RO),
CRASHTYPE(WRITE_RO_AFTER_INIT),
CRASHTYPE(WRITE_KERN),
+ CRASHTYPE(HIJACK_PATCH),
CRASHTYPE(REFCOUNT_INC_OVERFLOW),
CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h
index 99f90d3e5e9cb..87e7e6136d962 100644
--- a/drivers/misc/lkdtm/lkdtm.h
+++ b/drivers/misc/lkdtm/lkdtm.h
@@ -62,6 +62,7 @@ void lkdtm_EXEC_USERSPACE(void);
void lkdtm_EXEC_NULL(void);
void lkdtm_ACCESS_USERSPACE(void);
void lkdtm_ACCESS_NULL(void);
+void lkdtm_HIJACK_PATCH(void);
/* refcount.c */
void lkdtm_REFCOUNT_INC_OVERFLOW(void);
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 2dede2ef658f3..39e7456852229 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -9,6 +9,7 @@
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/uaccess.h>
+#include <linux/kthread.h>
#include <asm/cacheflush.h>
/* Whether or not to fill the target memory area with do_nothing(). */
@@ -222,6 +223,139 @@ void lkdtm_ACCESS_NULL(void)
pr_err("FAIL: survived bad write\n");
}
+#if (IS_BUILTIN(CONFIG_LKDTM) && defined(CONFIG_STRICT_KERNEL_RWX) && \
+ defined(CONFIG_PPC))
+/*
+ * This is just a dummy location to patch-over.
+ */
+static void patching_target(void)
+{
+ return;
+}
+
+#include <asm/code-patching.h>
+const u32 *patch_site = (const u32 *)&patching_target;
+
+static inline int lkdtm_do_patch(u32 data)
+{
+ return patch_instruction((u32 *)patch_site, ppc_inst(data));
+}
+
+static inline u32 lkdtm_read_patch_site(void)
+{
+ return READ_ONCE(*patch_site);
+}
+
+/* Returns True if the write succeeds */
+static inline bool lkdtm_try_write(u32 data, u32 *addr)
+{
+ __put_kernel_nofault(addr, &data, u32, err);
+ return true;
+
+err:
+ return false;
+}
+
+static int lkdtm_patching_cpu(void *data)
+{
+ int err = 0;
+ u32 val = 0xdeadbeef;
+
+ pr_info("starting patching_cpu=%d\n", raw_smp_processor_id());
+
+ do {
+ err = lkdtm_do_patch(val);
+ } while (lkdtm_read_patch_site() == val && !err && !kthread_should_stop());
+
+ if (err)
+ pr_warn("XFAIL: patch_instruction returned error: %d\n", err);
+
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+
+ return err;
+}
+
+void lkdtm_HIJACK_PATCH(void)
+{
+ struct task_struct *patching_kthrd;
+ int patching_cpu, hijacker_cpu, attempts;
+ unsigned long addr;
+ bool hijacked;
+ const u32 bad_data = 0xbad00bad;
+ const u32 original_insn = lkdtm_read_patch_site();
+
+ if (!IS_ENABLED(CONFIG_SMP)) {
+ pr_err("XFAIL: this test requires CONFIG_SMP\n");
+ return;
+ }
+
+ if (num_online_cpus() < 2) {
+ pr_warn("XFAIL: this test requires at least two cpus\n");
+ return;
+ }
+
+ hijacker_cpu = raw_smp_processor_id();
+ patching_cpu = cpumask_any_but(cpu_online_mask, hijacker_cpu);
+
+ patching_kthrd = kthread_create_on_node(&lkdtm_patching_cpu, NULL,
+ cpu_to_node(patching_cpu),
+ "lkdtm_patching_cpu");
+ kthread_bind(patching_kthrd, patching_cpu);
+ wake_up_process(patching_kthrd);
+
+ addr = offset_in_page(patch_site) | read_cpu_patching_addr(patching_cpu);
+
+ pr_info("starting hijacker_cpu=%d\n", hijacker_cpu);
+ for (attempts = 0; attempts < 100000; ++attempts) {
+ /* Try to write to the other CPU's temp patch mapping */
+ hijacked = lkdtm_try_write(bad_data, (u32 *)addr);
+
+ if (hijacked) {
+ if (kthread_stop(patching_kthrd)) {
+ pr_info("hijack attempts: %d\n", attempts);
+ pr_err("XFAIL: error stopping patching cpu\n");
+ return;
+ }
+ break;
+ }
+ }
+ pr_info("hijack attempts: %d\n", attempts);
+
+ if (hijacked) {
+ if (lkdtm_read_patch_site() == bad_data)
+ pr_err("overwrote kernel text\n");
+ /*
+ * There are window conditions where the hijacker cpu manages to
+ * write to the patch site but the site gets overwritten again by
+ * the patching cpu. We still consider that a "successful" hijack
+ * since the hijacker cpu did not fault on the write.
+ */
+ pr_err("FAIL: wrote to another cpu's patching area\n");
+ } else {
+ kthread_stop(patching_kthrd);
+ }
+
+ /* Restore the original data to be able to run the test again */
+ lkdtm_do_patch(original_insn);
+}
+
+#else
+
+void lkdtm_HIJACK_PATCH(void)
+{
+ if (!IS_ENABLED(CONFIG_PPC))
+ pr_err("XFAIL: this test only runs on powerpc\n");
+ if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
+ pr_err("XFAIL: this test requires CONFIG_STRICT_KERNEL_RWX\n");
+ if (!IS_BUILTIN(CONFIG_LKDTM))
+ pr_err("XFAIL: this test requires CONFIG_LKDTM=y (not =m!)\n");
+}
+
+#endif
+
void __init lkdtm_perms_init(void)
{
/* Make sure we can write to __ro_after_init values during __init */
--
2.26.1
^ permalink raw reply related
* [PATCH v5 0/8] Use per-CPU temporary mappings for patching on Radix MMU
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
When compiled with CONFIG_STRICT_KERNEL_RWX, the kernel must create
temporary mappings when patching itself. These mappings temporarily
override the strict RWX text protections to permit a write. Currently,
powerpc allocates a per-CPU VM area for patching. Patching occurs as
follows:
1. Map page in per-CPU VM area w/ PAGE_KERNEL protection
2. Patch text
3. Remove the temporary mapping
While the VM area is per-CPU, the mapping is actually inserted into the
kernel page tables. Presumably, this could allow another CPU to access
the normally write-protected text - either malicously or accidentally -
via this same mapping if the address of the VM area is known. Ideally,
the mapping should be kept local to the CPU doing the patching [0].
x86 introduced "temporary mm" structs which allow the creation of mappings
local to a particular CPU [1]. This series intends to bring the notion of a
temporary mm to powerpc's Book3s64 Radix MMU and harden it by using such a
mapping for patching a kernel with strict RWX permissions.
The first four patches implement an LKDTM test "proof-of-concept" which
exploits the potential vulnerability (ie. the temporary mapping during patching
is exposed in the kernel page tables and accessible by other CPUs) using a
simple brute-force approach. This test is implemented for both powerpc and
x86_64. The test passes on powerpc Radix with this new series, fails on
upstream powerpc, passes on upstream x86_64, and fails on an older (ancient)
x86_64 tree without the x86_64 temporary mm patches. The remaining patches add
support for and use a temporary mm for code patching on powerpc with the Radix
MMU.
Tested boot, ftrace, and repeated LKDTM "hijack":
- QEMU+KVM (host: POWER9 Blackbird): Radix MMU w/ KUAP
- QEMU+KVM (host: POWER9 Blackbird): Hash MMU
Tested repeated LKDTM "hijack":
- QEMU+KVM (host: AMD desktop): x86_64 upstream
- QEMU+KVM (host: AMD desktop): x86_64 w/o percpu temp mm to
verify the LKDTM "hijack" test fails
Tested boot and ftrace:
- QEMU+TCG: ppc44x (bamboo)
- QEMU+TCG: g5 (mac99)
I also tested with various extra config options enabled as suggested in
section 12) in Documentation/process/submit-checklist.rst.
v5: * Only support Book3s64 Radix MMU for now. There are some issues with
the previous implementation on the Hash MMU as pointed out by Nick
Piggin. Fixing these is not trivial so we only support the Radix MMU
for now. I tried using realmode (no data translation) to patch with
Hash to at least avoid exposing the patch mapping to other CPUs but
this doesn't reliably work either since we cannot access vmalloc'd
space in realmode.
* Use percpu variables for the patching_mm and patching_addr. This
avoids the need for synchronization mechanisms entirely. Thanks to
Peter Zijlstra for pointing out text_mutex which unfortunately didn't
work out without larger code changes in powerpc. Also thanks to Daniel
Axtens for comments about using percpu variables for the *percpu* temp
mm things off list.
v4: * It's time to revisit this series again since @jpn and @mpe fixed
our known STRICT_*_RWX bugs on powerpc/64s.
* Rebase on linuxppc/next:
commit ee1bc694fbaec ("powerpc/kvm: Fix build error when PPC_MEM_KEYS/PPC_PSERIES=n")
* Completely rework how map_patch() works on book3s64 Hash MMU
* Split the LKDTM x86_64 and powerpc bits into separate patches
* Annotate commit messages with changes from v3 instead of
listing them here completely out-of context...
v3: * Rebase on linuxppc/next: commit 9123e3a74ec7 ("Linux 5.9-rc1")
* Move temporary mm implementation into code-patching.c where it
belongs
* Implement LKDTM hijacker test on x86_64 (on IBM time oof) Do
* not use address zero for the patching address in the
temporary mm (thanks @dja for pointing this out!)
* Wrap the LKDTM test w/ CONFIG_SMP as suggested by Christophe
Leroy
* Comments to clarify PTE pre-allocation and patching addr
selection
v2: * Rebase on linuxppc/next:
commit 105fb38124a4 ("powerpc/8xx: Modify ptep_get()")
* Always dirty pte when mapping patch
* Use `ppc_inst_len` instead of `sizeof` on instructions
* Declare LKDTM patching addr accessor in header where it belongs
v1: * Rebase on linuxppc/next (4336b9337824)
* Save and restore second hw watchpoint
* Use new ppc_inst_* functions for patching check and in LKDTM test
rfc-v2: * Many fixes and improvements mostly based on extensive feedback
and testing by Christophe Leroy (thanks!).
* Make patching_mm and patching_addr static and move
'__ro_after_init' to after the variable name (more common in
other parts of the kernel)
* Use 'asm/debug.h' header instead of 'asm/hw_breakpoint.h' to
fix PPC64e compile
* Add comment explaining why we use BUG_ON() during the init
call to setup for patching later
* Move ptep into patch_mapping to avoid walking page tables a
second time when unmapping the temporary mapping
* Use KUAP under non-radix, also manually dirty the PTE for patch
mapping on non-BOOK3S_64 platforms
* Properly return any error from __patch_instruction
* Do not use 'memcmp' where a simple comparison is appropriate
* Simplify expression for patch address by removing pointer maths
* Add LKDTM test
[0]: https://github.com/linuxppc/issues/issues/224
[1]: https://lore.kernel.org/kernel-hardening/20190426232303.28381-1-nadav.amit@gmail.com/
Christopher M. Riedl (8):
powerpc: Add LKDTM accessor for patching addr
lkdtm/powerpc: Add test to hijack a patch mapping
x86_64: Add LKDTM accessor for patching addr
lkdtm/x86_64: Add test to hijack a patch mapping
powerpc/64s: Introduce temporary mm for Radix MMU
powerpc: Rework and improve STRICT_KERNEL_RWX patching
powerpc/64s: Initialize and use a temporary mm for patching on Radix
lkdtm/powerpc: Fix code patching hijack test
arch/powerpc/include/asm/code-patching.h | 4 +
arch/powerpc/include/asm/debug.h | 1 +
arch/powerpc/kernel/process.c | 5 +
arch/powerpc/lib/code-patching.c | 240 ++++++++++++++++++++---
arch/x86/include/asm/text-patching.h | 4 +
arch/x86/kernel/alternative.c | 7 +
drivers/misc/lkdtm/core.c | 1 +
drivers/misc/lkdtm/lkdtm.h | 1 +
drivers/misc/lkdtm/perms.c | 143 ++++++++++++++
9 files changed, 378 insertions(+), 28 deletions(-)
--
2.26.1
^ permalink raw reply
* [PATCH v5 4/8] lkdtm/x86_64: Add test to hijack a patch mapping
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
A previous commit implemented an LKDTM test on powerpc to exploit the
temporary mapping established when patching code with STRICT_KERNEL_RWX
enabled. Extend the test to work on x86_64 as well.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
drivers/misc/lkdtm/perms.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 39e7456852229..41e87e5f9cc86 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -224,7 +224,7 @@ void lkdtm_ACCESS_NULL(void)
}
#if (IS_BUILTIN(CONFIG_LKDTM) && defined(CONFIG_STRICT_KERNEL_RWX) && \
- defined(CONFIG_PPC))
+ (defined(CONFIG_PPC) || defined(CONFIG_X86_64)))
/*
* This is just a dummy location to patch-over.
*/
@@ -233,12 +233,25 @@ static void patching_target(void)
return;
}
-#include <asm/code-patching.h>
const u32 *patch_site = (const u32 *)&patching_target;
+#ifdef CONFIG_PPC
+#include <asm/code-patching.h>
+#endif
+
+#ifdef CONFIG_X86_64
+#include <asm/text-patching.h>
+#endif
+
static inline int lkdtm_do_patch(u32 data)
{
+#ifdef CONFIG_PPC
return patch_instruction((u32 *)patch_site, ppc_inst(data));
+#endif
+#ifdef CONFIG_X86_64
+ text_poke((void *)patch_site, &data, sizeof(u32));
+ return 0;
+#endif
}
static inline u32 lkdtm_read_patch_site(void)
@@ -249,11 +262,16 @@ static inline u32 lkdtm_read_patch_site(void)
/* Returns True if the write succeeds */
static inline bool lkdtm_try_write(u32 data, u32 *addr)
{
+#ifdef CONFIG_PPC
__put_kernel_nofault(addr, &data, u32, err);
return true;
err:
return false;
+#endif
+#ifdef CONFIG_X86_64
+ return !__put_user(data, addr);
+#endif
}
static int lkdtm_patching_cpu(void *data)
@@ -346,8 +364,8 @@ void lkdtm_HIJACK_PATCH(void)
void lkdtm_HIJACK_PATCH(void)
{
- if (!IS_ENABLED(CONFIG_PPC))
- pr_err("XFAIL: this test only runs on powerpc\n");
+ if (!IS_ENABLED(CONFIG_PPC) && !IS_ENABLED(CONFIG_X86_64))
+ pr_err("XFAIL: this test only runs on powerpc and x86_64\n");
if (!IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
pr_err("XFAIL: this test requires CONFIG_STRICT_KERNEL_RWX\n");
if (!IS_BUILTIN(CONFIG_LKDTM))
--
2.26.1
^ permalink raw reply related
* [PATCH v5 7/8] powerpc/64s: Initialize and use a temporary mm for patching on Radix
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
When code patching a STRICT_KERNEL_RWX kernel the page containing the
address to be patched is temporarily mapped as writeable. Currently, a
per-cpu vmalloc patch area is used for this purpose. While the patch
area is per-cpu, the temporary page mapping is inserted into the kernel
page tables for the duration of patching. The mapping is exposed to CPUs
other than the patching CPU - this is undesirable from a hardening
perspective. Use a temporary mm instead which keeps the mapping local to
the CPU doing the patching.
Use the `poking_init` init hook to prepare a temporary mm and patching
address. Initialize the temporary mm by copying the init mm. Choose a
randomized patching address inside the temporary mm userspace address
space. The patching address is randomized between PAGE_SIZE and
DEFAULT_MAP_WINDOW-PAGE_SIZE.
Bits of entropy with 64K page size on BOOK3S_64:
bits of entropy = log2(DEFAULT_MAP_WINDOW_USER64 / PAGE_SIZE)
PAGE_SIZE=64K, DEFAULT_MAP_WINDOW_USER64=128TB
bits of entropy = log2(128TB / 64K)
bits of entropy = 31
The upper limit is DEFAULT_MAP_WINDOW due to how the Book3s64 Hash MMU
operates - by default the space above DEFAULT_MAP_WINDOW is not
available. Currently the Hash MMU does not use a temporary mm so
technically this upper limit isn't necessary; however, a larger
randomization range does not further "harden" this overall approach and
future work may introduce patching with a temporary mm on Hash as well.
Randomization occurs only once during initialization at boot for each
possible CPU in the system.
Introduce two new functions, map_patch() and unmap_patch(), to
respectively create and remove the temporary mapping with write
permissions at patching_addr. Map the page with PAGE_KERNEL to set
EAA[0] for the PTE which ignores the AMR (so no need to unlock/lock
KUAP) according to PowerISA v3.0b Figure 35 on Radix.
Based on x86 implementation:
commit 4fc19708b165
("x86/alternatives: Initialize temporary mm for patching")
and:
commit b3fd8e83ada0
("x86/alternatives: Use temporary mm for text poking")
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
v5: * Only support Book3s64 Radix MMU for now.
* Use a per-cpu datastructure to hold the patching_addr and
patching_mm to avoid the need for a synchronization lock/mutex.
v4: * In the previous series this was two separate patches: one to init
the temporary mm in poking_init() (unused in powerpc at the time)
and the other to use it for patching (which removed all the
per-cpu vmalloc code). Now that we use poking_init() in the
existing per-cpu vmalloc approach, that separation doesn't work
as nicely anymore so I just merged the two patches into one.
* Preload the SLB entry and hash the page for the patching_addr
when using Hash on book3s64 to avoid taking an SLB and Hash fault
during patching. The previous implementation was a hack which
changed current->mm to allow the SLB and Hash fault handlers to
work with the temporary mm since both of those code-paths always
assume mm == current->mm.
* Also (hmm - seeing a trend here) with the book3s64 Hash MMU we
have to manage the mm->context.active_cpus counter and mm cpumask
since they determine (via mm_is_thread_local()) if the TLB flush
in pte_clear() is local or not - it should always be local when
we're using the temporary mm. On book3s64's Radix MMU we can
just call local_flush_tlb_mm().
* Use HPTE_USE_KERNEL_KEY on Hash to avoid costly lock/unlock of
KUAP.
---
arch/powerpc/lib/code-patching.c | 132 +++++++++++++++++++++++++++++--
1 file changed, 125 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 9f2eba9b70ee4..027dabd42b8dd 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -11,6 +11,7 @@
#include <linux/cpuhotplug.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/random.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
@@ -103,6 +104,7 @@ static inline void unuse_temporary_mm(struct temp_mm *temp_mm)
static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
static DEFINE_PER_CPU(unsigned long, cpu_patching_addr);
+static DEFINE_PER_CPU(struct mm_struct *, cpu_patching_mm);
#if IS_BUILTIN(CONFIG_LKDTM)
unsigned long read_cpu_patching_addr(unsigned int cpu)
@@ -133,6 +135,51 @@ static int text_area_cpu_down(unsigned int cpu)
return 0;
}
+static __always_inline void __poking_init_temp_mm(void)
+{
+ int cpu;
+ spinlock_t *ptl; /* for protecting pte table */
+ pte_t *ptep;
+ struct mm_struct *patching_mm;
+ unsigned long patching_addr;
+
+ for_each_possible_cpu(cpu) {
+ /*
+ * Some parts of the kernel (static keys for example) depend on
+ * successful code patching. Code patching under
+ * STRICT_KERNEL_RWX requires this setup - otherwise we cannot
+ * patch at all. We use BUG_ON() here and later since an early
+ * failure is preferred to buggy behavior and/or strange
+ * crashes later.
+ */
+ patching_mm = copy_init_mm();
+ BUG_ON(!patching_mm);
+
+ per_cpu(cpu_patching_mm, cpu) = patching_mm;
+
+ /*
+ * Choose a randomized, page-aligned address from the range:
+ * [PAGE_SIZE, DEFAULT_MAP_WINDOW - PAGE_SIZE] The lower
+ * address bound is PAGE_SIZE to avoid the zero-page. The
+ * upper address bound is DEFAULT_MAP_WINDOW - PAGE_SIZE to
+ * stay under DEFAULT_MAP_WINDOW with the Book3s64 Hash MMU.
+ */
+ patching_addr = PAGE_SIZE + ((get_random_long() & PAGE_MASK)
+ % (DEFAULT_MAP_WINDOW - 2 * PAGE_SIZE));
+
+ per_cpu(cpu_patching_addr, cpu) = patching_addr;
+
+ /*
+ * PTE allocation uses GFP_KERNEL which means we need to
+ * pre-allocate the PTE here because we cannot do the
+ * allocation during patching when IRQs are disabled.
+ */
+ ptep = get_locked_pte(patching_mm, patching_addr, &ptl);
+ BUG_ON(!ptep);
+ pte_unmap_unlock(ptep, ptl);
+ }
+}
+
/*
* Although BUG_ON() is rude, in this case it should only happen if ENOMEM, and
* we judge it as being preferable to a kernel that will crash later when
@@ -140,6 +187,11 @@ static int text_area_cpu_down(unsigned int cpu)
*/
void __init poking_init(void)
{
+ if (radix_enabled()) {
+ __poking_init_temp_mm();
+ return;
+ }
+
BUG_ON(!cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"powerpc/text_poke:online", text_area_cpu_up,
text_area_cpu_down));
@@ -213,30 +265,96 @@ static inline int unmap_patch_area(void)
return -EINVAL;
}
+struct patch_mapping {
+ spinlock_t *ptl; /* for protecting pte table */
+ pte_t *ptep;
+ struct temp_mm temp_mm;
+};
+
+/*
+ * This can be called for kernel text or a module.
+ */
+static int map_patch(const void *addr, struct patch_mapping *patch_mapping)
+{
+ struct page *page;
+ pte_t pte;
+ pgprot_t pgprot;
+ struct mm_struct *patching_mm = __this_cpu_read(cpu_patching_mm);
+ unsigned long patching_addr = __this_cpu_read(cpu_patching_addr);
+
+ if (is_vmalloc_or_module_addr(addr))
+ page = vmalloc_to_page(addr);
+ else
+ page = virt_to_page(addr);
+
+ patch_mapping->ptep = get_locked_pte(patching_mm, patching_addr,
+ &patch_mapping->ptl);
+ if (unlikely(!patch_mapping->ptep)) {
+ pr_warn("map patch: failed to allocate pte for patching\n");
+ return -1;
+ }
+
+ pgprot = PAGE_KERNEL;
+ pte = mk_pte(page, pgprot);
+ pte = pte_mkdirty(pte);
+ set_pte_at(patching_mm, patching_addr, patch_mapping->ptep, pte);
+
+ init_temp_mm(&patch_mapping->temp_mm, patching_mm);
+ use_temporary_mm(&patch_mapping->temp_mm);
+
+ return 0;
+}
+
+static void unmap_patch(struct patch_mapping *patch_mapping)
+{
+ struct mm_struct *patching_mm = __this_cpu_read(cpu_patching_mm);
+ unsigned long patching_addr = __this_cpu_read(cpu_patching_addr);
+
+ pte_clear(patching_mm, patching_addr, patch_mapping->ptep);
+
+ local_flush_tlb_mm(patching_mm);
+
+ pte_unmap_unlock(patch_mapping->ptep, patch_mapping->ptl);
+
+ unuse_temporary_mm(&patch_mapping->temp_mm);
+}
+
static int do_patch_instruction(u32 *addr, struct ppc_inst instr)
{
int err, rc = 0;
u32 *patch_addr = NULL;
unsigned long flags;
+ struct patch_mapping patch_mapping;
/*
- * During early early boot patch_instruction is called
- * when text_poke_area is not ready, but we still need
- * to allow patching. We just do the plain old patching
+ * During early early boot patch_instruction is called when the
+ * patching_mm/text_poke_area is not ready, but we still need to allow
+ * patching. We just do the plain old patching.
*/
- if (!this_cpu_read(text_poke_area))
- return raw_patch_instruction(addr, instr);
+ if (radix_enabled()) {
+ if (!this_cpu_read(cpu_patching_mm))
+ return raw_patch_instruction(addr, instr);
+ } else {
+ if (!this_cpu_read(text_poke_area))
+ return raw_patch_instruction(addr, instr);
+ }
local_irq_save(flags);
- err = map_patch_area(addr);
+ if (radix_enabled())
+ err = map_patch(addr, &patch_mapping);
+ else
+ err = map_patch_area(addr);
if (err)
goto out;
patch_addr = (u32 *)(__this_cpu_read(cpu_patching_addr) | offset_in_page(addr));
rc = __patch_instruction(addr, instr, patch_addr);
- err = unmap_patch_area();
+ if (radix_enabled())
+ unmap_patch(&patch_mapping);
+ else
+ err = unmap_patch_area();
out:
local_irq_restore(flags);
--
2.26.1
^ permalink raw reply related
* [PATCH v5 1/8] powerpc: Add LKDTM accessor for patching addr
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
When live patching with STRICT_KERNEL_RWX a mapping is installed at a
"patching address" with temporary write permissions. Provide a
LKDTM-only accessor function for this address in preparation for a LKDTM
test which attempts to "hijack" this mapping by writing to it from
another CPU.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
arch/powerpc/include/asm/code-patching.h | 4 ++++
arch/powerpc/lib/code-patching.c | 7 +++++++
2 files changed, 11 insertions(+)
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index a95f63788c6b1..16fbc58a4932f 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -184,4 +184,8 @@ static inline unsigned long ppc_kallsyms_lookup_name(const char *name)
#define PPC_INST_STD_LR PPC_RAW_STD(_R0, _R1, PPC_LR_STKOFF)
#endif /* CONFIG_PPC64 */
+#if IS_BUILTIN(CONFIG_LKDTM) && IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)
+unsigned long read_cpu_patching_addr(unsigned int cpu);
+#endif
+
#endif /* _ASM_POWERPC_CODE_PATCHING_H */
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index f9a3019e37b43..54b6157d44e95 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -47,6 +47,13 @@ int raw_patch_instruction(u32 *addr, struct ppc_inst instr)
#ifdef CONFIG_STRICT_KERNEL_RWX
static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
+#if IS_BUILTIN(CONFIG_LKDTM)
+unsigned long read_cpu_patching_addr(unsigned int cpu)
+{
+ return (unsigned long)(per_cpu(text_poke_area, cpu))->addr;
+}
+#endif
+
static int text_area_cpu_up(unsigned int cpu)
{
struct vm_struct *area;
--
2.26.1
^ permalink raw reply related
* [PATCH v5 8/8] lkdtm/powerpc: Fix code patching hijack test
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
Code patching on powerpc with a STRICT_KERNEL_RWX uses a userspace
address in a temporary mm on Radix now. Use __put_user() to avoid write
failures due to KUAP when attempting a "hijack" on the patching address.
__put_user() also works with the non-userspace, vmalloc-based patching
address on non-Radix MMUs.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
drivers/misc/lkdtm/perms.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index 41e87e5f9cc86..da6a34a0a49fb 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -262,16 +262,7 @@ static inline u32 lkdtm_read_patch_site(void)
/* Returns True if the write succeeds */
static inline bool lkdtm_try_write(u32 data, u32 *addr)
{
-#ifdef CONFIG_PPC
- __put_kernel_nofault(addr, &data, u32, err);
- return true;
-
-err:
- return false;
-#endif
-#ifdef CONFIG_X86_64
return !__put_user(data, addr);
-#endif
}
static int lkdtm_patching_cpu(void *data)
--
2.26.1
^ permalink raw reply related
* [PATCH v5 5/8] powerpc/64s: Introduce temporary mm for Radix MMU
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
x86 supports the notion of a temporary mm which restricts access to
temporary PTEs to a single CPU. A temporary mm is useful for situations
where a CPU needs to perform sensitive operations (such as patching a
STRICT_KERNEL_RWX kernel) requiring temporary mappings without exposing
said mappings to other CPUs. Another benefit is that other CPU TLBs do
not need to be flushed when the temporary mm is torn down.
Mappings in the temporary mm can be set in the userspace portion of the
address-space.
Interrupts must be disabled while the temporary mm is in use. HW
breakpoints, which may have been set by userspace as watchpoints on
addresses now within the temporary mm, are saved and disabled when
loading the temporary mm. The HW breakpoints are restored when unloading
the temporary mm. All HW breakpoints are indiscriminately disabled while
the temporary mm is in use.
Based on x86 implementation:
commit cefa929c034e
("x86/mm: Introduce temporary mm structs")
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
v5: * Drop support for using a temporary mm on Book3s64 Hash MMU.
v4: * Pass the prev mm instead of NULL to switch_mm_irqs_off() when
using/unusing the temp mm as suggested by Jann Horn to keep
the context.active counter in-sync on mm/nohash.
* Disable SLB preload in the temporary mm when initializing the
temp_mm struct.
* Include asm/debug.h header to fix build issue with
ppc44x_defconfig.
---
arch/powerpc/include/asm/debug.h | 1 +
arch/powerpc/kernel/process.c | 5 +++
arch/powerpc/lib/code-patching.c | 56 ++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+)
diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
index 86a14736c76c3..dfd82635ea8b3 100644
--- a/arch/powerpc/include/asm/debug.h
+++ b/arch/powerpc/include/asm/debug.h
@@ -46,6 +46,7 @@ static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
#endif
void __set_breakpoint(int nr, struct arch_hw_breakpoint *brk);
+void __get_breakpoint(int nr, struct arch_hw_breakpoint *brk);
bool ppc_breakpoint_available(void);
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
extern void do_send_trap(struct pt_regs *regs, unsigned long address,
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 185beb2905801..a0776200772e8 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -865,6 +865,11 @@ static inline int set_breakpoint_8xx(struct arch_hw_breakpoint *brk)
return 0;
}
+void __get_breakpoint(int nr, struct arch_hw_breakpoint *brk)
+{
+ memcpy(brk, this_cpu_ptr(¤t_brk[nr]), sizeof(*brk));
+}
+
void __set_breakpoint(int nr, struct arch_hw_breakpoint *brk)
{
memcpy(this_cpu_ptr(¤t_brk[nr]), brk, sizeof(*brk));
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 54b6157d44e95..3122d8e4cc013 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -17,6 +17,9 @@
#include <asm/code-patching.h>
#include <asm/setup.h>
#include <asm/inst.h>
+#include <asm/mmu_context.h>
+#include <asm/debug.h>
+#include <asm/tlb.h>
static int __patch_instruction(u32 *exec_addr, struct ppc_inst instr, u32 *patch_addr)
{
@@ -45,6 +48,59 @@ int raw_patch_instruction(u32 *addr, struct ppc_inst instr)
}
#ifdef CONFIG_STRICT_KERNEL_RWX
+
+struct temp_mm {
+ struct mm_struct *temp;
+ struct mm_struct *prev;
+ struct arch_hw_breakpoint brk[HBP_NUM_MAX];
+};
+
+static inline void init_temp_mm(struct temp_mm *temp_mm, struct mm_struct *mm)
+{
+ /* We currently only support temporary mm on the Book3s64 Radix MMU */
+ WARN_ON(!radix_enabled());
+
+ temp_mm->temp = mm;
+ temp_mm->prev = NULL;
+ memset(&temp_mm->brk, 0, sizeof(temp_mm->brk));
+}
+
+static inline void use_temporary_mm(struct temp_mm *temp_mm)
+{
+ lockdep_assert_irqs_disabled();
+
+ temp_mm->prev = current->active_mm;
+ switch_mm_irqs_off(temp_mm->prev, temp_mm->temp, current);
+
+ WARN_ON(!mm_is_thread_local(temp_mm->temp));
+
+ if (ppc_breakpoint_available()) {
+ struct arch_hw_breakpoint null_brk = {0};
+ int i = 0;
+
+ for (; i < nr_wp_slots(); ++i) {
+ __get_breakpoint(i, &temp_mm->brk[i]);
+ if (temp_mm->brk[i].type != 0)
+ __set_breakpoint(i, &null_brk);
+ }
+ }
+}
+
+static inline void unuse_temporary_mm(struct temp_mm *temp_mm)
+{
+ lockdep_assert_irqs_disabled();
+
+ switch_mm_irqs_off(temp_mm->temp, temp_mm->prev, current);
+
+ if (ppc_breakpoint_available()) {
+ int i = 0;
+
+ for (; i < nr_wp_slots(); ++i)
+ if (temp_mm->brk[i].type != 0)
+ __set_breakpoint(i, &temp_mm->brk[i]);
+ }
+}
+
static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
#if IS_BUILTIN(CONFIG_LKDTM)
--
2.26.1
^ permalink raw reply related
* [PATCH v5 6/8] powerpc: Rework and improve STRICT_KERNEL_RWX patching
From: Christopher M. Riedl @ 2021-07-13 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: keescook, peterz, x86, npiggin, linux-hardening, tglx, dja
In-Reply-To: <20210713053113.4632-1-cmr@linux.ibm.com>
Rework code-patching with STRICT_KERNEL_RWX to prepare for the next
patch which uses a temporary mm for patching under the Book3s64 Radix
MMU. Make improvements by adding a WARN_ON when the patchsite doesn't
match after patching and return the error from __patch_instruction()
properly.
Signed-off-by: Christopher M. Riedl <cmr@linux.ibm.com>
---
v5: * New to series.
---
arch/powerpc/lib/code-patching.c | 51 +++++++++++++++++---------------
1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
index 3122d8e4cc013..9f2eba9b70ee4 100644
--- a/arch/powerpc/lib/code-patching.c
+++ b/arch/powerpc/lib/code-patching.c
@@ -102,11 +102,12 @@ static inline void unuse_temporary_mm(struct temp_mm *temp_mm)
}
static DEFINE_PER_CPU(struct vm_struct *, text_poke_area);
+static DEFINE_PER_CPU(unsigned long, cpu_patching_addr);
#if IS_BUILTIN(CONFIG_LKDTM)
unsigned long read_cpu_patching_addr(unsigned int cpu)
{
- return (unsigned long)(per_cpu(text_poke_area, cpu))->addr;
+ return per_cpu(cpu_patching_addr, cpu);
}
#endif
@@ -121,6 +122,7 @@ static int text_area_cpu_up(unsigned int cpu)
return -1;
}
this_cpu_write(text_poke_area, area);
+ this_cpu_write(cpu_patching_addr, (unsigned long)area->addr);
return 0;
}
@@ -146,7 +148,7 @@ void __init poking_init(void)
/*
* This can be called for kernel text or a module.
*/
-static int map_patch_area(void *addr, unsigned long text_poke_addr)
+static int map_patch_area(void *addr)
{
unsigned long pfn;
int err;
@@ -156,17 +158,20 @@ static int map_patch_area(void *addr, unsigned long text_poke_addr)
else
pfn = __pa_symbol(addr) >> PAGE_SHIFT;
- err = map_kernel_page(text_poke_addr, (pfn << PAGE_SHIFT), PAGE_KERNEL);
+ err = map_kernel_page(__this_cpu_read(cpu_patching_addr),
+ (pfn << PAGE_SHIFT), PAGE_KERNEL);
- pr_devel("Mapped addr %lx with pfn %lx:%d\n", text_poke_addr, pfn, err);
+ pr_devel("Mapped addr %lx with pfn %lx:%d\n",
+ __this_cpu_read(cpu_patching_addr), pfn, err);
if (err)
return -1;
return 0;
}
-static inline int unmap_patch_area(unsigned long addr)
+static inline int unmap_patch_area(void)
{
+ unsigned long addr = __this_cpu_read(cpu_patching_addr);
pte_t *ptep;
pmd_t *pmdp;
pud_t *pudp;
@@ -175,23 +180,23 @@ static inline int unmap_patch_area(unsigned long addr)
pgdp = pgd_offset_k(addr);
if (unlikely(!pgdp))
- return -EINVAL;
+ goto out_err;
p4dp = p4d_offset(pgdp, addr);
if (unlikely(!p4dp))
- return -EINVAL;
+ goto out_err;
pudp = pud_offset(p4dp, addr);
if (unlikely(!pudp))
- return -EINVAL;
+ goto out_err;
pmdp = pmd_offset(pudp, addr);
if (unlikely(!pmdp))
- return -EINVAL;
+ goto out_err;
ptep = pte_offset_kernel(pmdp, addr);
if (unlikely(!ptep))
- return -EINVAL;
+ goto out_err;
pr_devel("clearing mm %p, pte %p, addr %lx\n", &init_mm, ptep, addr);
@@ -202,15 +207,17 @@ static inline int unmap_patch_area(unsigned long addr)
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
return 0;
+
+out_err:
+ pr_warn("failed to unmap %lx\n", addr);
+ return -EINVAL;
}
static int do_patch_instruction(u32 *addr, struct ppc_inst instr)
{
- int err;
+ int err, rc = 0;
u32 *patch_addr = NULL;
unsigned long flags;
- unsigned long text_poke_addr;
- unsigned long kaddr = (unsigned long)addr;
/*
* During early early boot patch_instruction is called
@@ -222,24 +229,20 @@ static int do_patch_instruction(u32 *addr, struct ppc_inst instr)
local_irq_save(flags);
- text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr;
- if (map_patch_area(addr, text_poke_addr)) {
- err = -1;
+ err = map_patch_area(addr);
+ if (err)
goto out;
- }
-
- patch_addr = (u32 *)(text_poke_addr + (kaddr & ~PAGE_MASK));
- __patch_instruction(addr, instr, patch_addr);
+ patch_addr = (u32 *)(__this_cpu_read(cpu_patching_addr) | offset_in_page(addr));
+ rc = __patch_instruction(addr, instr, patch_addr);
- err = unmap_patch_area(text_poke_addr);
- if (err)
- pr_warn("failed to unmap %lx\n", text_poke_addr);
+ err = unmap_patch_area();
out:
local_irq_restore(flags);
+ WARN_ON(!ppc_inst_equal(ppc_inst_read(addr), instr));
- return err;
+ return rc ? rc : err;
}
#else /* !CONFIG_STRICT_KERNEL_RWX */
--
2.26.1
^ permalink raw reply related
* Re: [PATCH v2] fpga: dfl: fme: Fix cpu hotplug issue in performance reporting
From: kajoljain @ 2021-07-13 7:37 UTC (permalink / raw)
To: Wu, Hao, will@kernel.org, mark.rutland@arm.com, Xu, Yilun
Cc: maddy@linux.ibm.com, rnsastry@linux.ibm.com, trix@redhat.com,
linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, linux-perf-users@vger.kernel.org,
atrajeev@linux.vnet.ibm.com, mdf@kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <DM6PR11MB38197304C3BC02672304201A85159@DM6PR11MB3819.namprd11.prod.outlook.com>
On 7/12/21 7:57 AM, Wu, Hao wrote:
>> Subject: [PATCH v2] fpga: dfl: fme: Fix cpu hotplug issue in performance
>> reporting
>>
>> The performance reporting driver added cpu hotplug
>> feature but it didn't add pmu migration call in cpu
>> offline function.
>> This can create an issue incase the current designated
>> cpu being used to collect fme pmu data got offline,
>> as based on current code we are not migrating fme pmu to
>> new target cpu. Because of that perf will still try to
>> fetch data from that offline cpu and hence we will not
>> get counter data.
>>
>> Patch fixed this issue by adding pmu_migrate_context call
>> in fme_perf_offline_cpu function.
>>
>> Fixes: 724142f8c42a ("fpga: dfl: fme: add performance reporting support")
>> Tested-by: Xu Yilun <yilun.xu@intel.com>
>> Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
>
> Thanks for this fixing! And thanks Yilun for the verification too. : )
>
>> Cc: stable@vger.kernel.org
>> ---
>> drivers/fpga/dfl-fme-perf.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> ---
>> Changelog:
>> v1 -> v2:
>> - Add stable@vger.kernel.org in cc list
>>
>> RFC -> PATCH v1
>> - Remove RFC tag
>> - Did nits changes on subject and commit message as suggested by Xu Yilun
>> - Added Tested-by tag
>> - Link to rfc patch: https://lkml.org/lkml/2021/6/28/112
>> ---
>> diff --git a/drivers/fpga/dfl-fme-perf.c b/drivers/fpga/dfl-fme-perf.c
>> index 4299145ef347..b9a54583e505 100644
>> --- a/drivers/fpga/dfl-fme-perf.c
>> +++ b/drivers/fpga/dfl-fme-perf.c
>> @@ -953,6 +953,10 @@ static int fme_perf_offline_cpu(unsigned int cpu, struct
>> hlist_node *node)
>> return 0;
>>
>> priv->cpu = target;
>> +
>> + /* Migrate fme_perf pmu events to the new target cpu */
>
> Only one minor item, this line is not needed. : )
>
> After remove it,
> Acked-by: Wu Hao <hao.wu@intel.com>
Hi Wu Hao,
Sure I will remove this comment and send new patch.
Thanks,
Kajol Jain
>
> Thanks
> Hao
>
>> + perf_pmu_migrate_context(&priv->pmu, cpu, target);
>> +
>> return 0;
>> }
>>
>> --
>> 2.31.1
>
^ permalink raw reply
* [PATCH v3] fpga: dfl: fme: Fix cpu hotplug issue in performance reporting
From: Kajol Jain @ 2021-07-13 7:42 UTC (permalink / raw)
To: will, hao.wu, mark.rutland
Cc: maddy, rnsastry, trix, linux-fpga, linux-kernel, stable,
linux-perf-users, atrajeev, mdf, kjain, linuxppc-dev, yilun.xu
The performance reporting driver added cpu hotplug
feature but it didn't add pmu migration call in cpu
offline function.
This can create an issue incase the current designated
cpu being used to collect fme pmu data got offline,
as based on current code we are not migrating fme pmu to
new target cpu. Because of that perf will still try to
fetch data from that offline cpu and hence we will not
get counter data.
Patch fixed this issue by adding pmu_migrate_context call
in fme_perf_offline_cpu function.
Fixes: 724142f8c42a ("fpga: dfl: fme: add performance reporting support")
Tested-by: Xu Yilun <yilun.xu@intel.com>
Acked-by: Wu Hao <hao.wu@intel.com>
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
Cc: stable@vger.kernel.org
---
drivers/fpga/dfl-fme-perf.c | 2 ++
1 file changed, 2 insertions(+)
---
Changelog:
v2 -> v3:
- Added Acked-by tag
- Removed comment as suggested by Wu Hao
- Link to patch v2: https://lkml.org/lkml/2021/7/9/143
v1 -> v2:
- Add stable@vger.kernel.org in cc list
- Link to patch v1: https://lkml.org/lkml/2021/6/28/275
RFC -> PATCH v1
- Remove RFC tag
- Did nits changes on subject and commit message as suggested by Xu Yilun
- Added Tested-by tag
- Link to rfc patch: https://lkml.org/lkml/2021/6/28/112
---
diff --git a/drivers/fpga/dfl-fme-perf.c b/drivers/fpga/dfl-fme-perf.c
index 4299145ef347..587c82be12f7 100644
--- a/drivers/fpga/dfl-fme-perf.c
+++ b/drivers/fpga/dfl-fme-perf.c
@@ -953,6 +953,8 @@ static int fme_perf_offline_cpu(unsigned int cpu, struct hlist_node *node)
return 0;
priv->cpu = target;
+ perf_pmu_migrate_context(&priv->pmu, cpu, target);
+
return 0;
}
--
2.31.1
^ permalink raw reply related
* Re: [PATCH v5 0/6] Add support for FORM2 associativity
From: Daniel Henrique Barboza @ 2021-07-13 14:27 UTC (permalink / raw)
To: Aneesh Kumar K.V, linuxppc-dev, mpe; +Cc: Nathan Lynch, David Gibson
In-Reply-To: <20210628151117.545935-1-aneesh.kumar@linux.ibm.com>
Aneesh,
This series compiles with a configuration made with "pseries_le_defconfig"
but fails with a config based on an existing RHEL8 config.
The reason, which is hinted in the robot replies in patch 4, is that you defined
a "__vphn_get_associativity" inside a #ifdef CONFIG_PPC_SPLPAR guard but didn't
define how the function would behave without the config, and you ended up
using the function elsewhere.
This fixes the compilation but I'm not sure if this is what you intended
for this function:
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index c68846fc9550..6e8551d16b7a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -680,6 +680,11 @@ static int vphn_get_nid(long lcpu)
}
#else
+static int __vphn_get_associativity(long lcpu, __be32 *associativity)
+{
+ return -1;
+}
+
static int vphn_get_nid(long unused)
{
return NUMA_NO_NODE;
I'll post a new version of the QEMU FORM2 changes using these patches as is (with
the above fixup), but I guess you'll want to post a v6.
Thanks,
Daniel
On 6/28/21 12:11 PM, Aneesh Kumar K.V wrote:
> Form2 associativity adds a much more flexible NUMA topology layout
> than what is provided by Form1. More details can be found in patch 7.
>
> $ numactl -H
> ...
> node distances:
> node 0 1 2 3
> 0: 10 11 222 33
> 1: 44 10 55 66
> 2: 77 88 10 99
> 3: 101 121 132 10
> $
>
> After DAX kmem memory add
> # numactl -H
> available: 5 nodes (0-4)
> ...
> node distances:
> node 0 1 2 3 4
> 0: 10 11 222 33 240
> 1: 44 10 55 66 255
> 2: 77 88 10 99 255
> 3: 101 121 132 10 230
> 4: 255 255 255 230 10
>
>
> PAPR SCM now use the numa distance details to find the numa_node and target_node
> for the device.
>
> kvaneesh@ubuntu-guest:~$ ndctl list -N -v
> [
> {
> "dev":"namespace0.0",
> "mode":"devdax",
> "map":"dev",
> "size":1071644672,
> "uuid":"d333d867-3f57-44c8-b386-d4d3abdc2bf2",
> "raw_uuid":"915361ad-fe6a-42dd-848f-d6dc9f5af362",
> "daxregion":{
> "id":0,
> "size":1071644672,
> "devices":[
> {
> "chardev":"dax0.0",
> "size":1071644672,
> "target_node":4,
> "mode":"devdax"
> }
> ]
> },
> "align":2097152,
> "numa_node":3
> }
> ]
> kvaneesh@ubuntu-guest:~$
>
>
> The above output is with a Qemu command line
>
> -numa node,nodeid=4 \
> -numa dist,src=0,dst=1,val=11 -numa dist,src=0,dst=2,val=222 -numa dist,src=0,dst=3,val=33 -numa dist,src=0,dst=4,val=240 \
> -numa dist,src=1,dst=0,val=44 -numa dist,src=1,dst=2,val=55 -numa dist,src=1,dst=3,val=66 -numa dist,src=1,dst=4,val=255 \
> -numa dist,src=2,dst=0,val=77 -numa dist,src=2,dst=1,val=88 -numa dist,src=2,dst=3,val=99 -numa dist,src=2,dst=4,val=255 \
> -numa dist,src=3,dst=0,val=101 -numa dist,src=3,dst=1,val=121 -numa dist,src=3,dst=2,val=132 -numa dist,src=3,dst=4,val=230 \
> -numa dist,src=4,dst=0,val=255 -numa dist,src=4,dst=1,val=255 -numa dist,src=4,dst=2,val=255 -numa dist,src=4,dst=3,val=230 \
> -object memory-backend-file,id=memnvdimm1,prealloc=yes,mem-path=$PMEM_DISK,share=yes,size=${PMEM_SIZE} \
> -device nvdimm,label-size=128K,memdev=memnvdimm1,id=nvdimm1,slot=4,uuid=72511b67-0b3b-42fd-8d1d-5be3cae8bcaa,node=4
>
> Qemu changes can be found at https://lore.kernel.org/qemu-devel/20210616011944.2996399-1-danielhb413@gmail.com/
>
> Changes from v4:
> * Drop DLPAR related device tree property for now because both Qemu nor PowerVM
> will provide the distance details of all possible NUMA nodes during boot.
> * Rework numa distance code based on review feedback.
>
> Changes from v3:
> * Drop PAPR SCM specific changes and depend completely on NUMA distance information.
>
> Changes from v2:
> * Add nvdimm list to Cc:
> * update PATCH 8 commit message.
>
> Changes from v1:
> * Update FORM2 documentation.
> * rename max_domain_index to max_associativity_domain_index
>
>
> Aneesh Kumar K.V (6):
> powerpc/pseries: rename min_common_depth to primary_domain_index
> powerpc/pseries: rename distance_ref_points_depth to
> max_associativity_domain_index
> powerpc/pseries: Rename TYPE1_AFFINITY to FORM1_AFFINITY
> powerpc/pseries: Consolidate different NUMA distance update code paths
> powerpc/pseries: Add a helper for form1 cpu distance
> powerpc/pseries: Add support for FORM2 associativity
>
> Documentation/powerpc/associativity.rst | 103 +++++
> arch/powerpc/include/asm/firmware.h | 7 +-
> arch/powerpc/include/asm/prom.h | 3 +-
> arch/powerpc/include/asm/topology.h | 4 +-
> arch/powerpc/kernel/prom_init.c | 3 +-
> arch/powerpc/mm/numa.c | 415 +++++++++++++-----
> arch/powerpc/platforms/pseries/firmware.c | 3 +-
> arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +
> .../platforms/pseries/hotplug-memory.c | 2 +
> arch/powerpc/platforms/pseries/lpar.c | 4 +-
> arch/powerpc/platforms/pseries/pseries.h | 1 +
> 11 files changed, 432 insertions(+), 115 deletions(-)
> create mode 100644 Documentation/powerpc/associativity.rst
>
^ permalink raw reply related
* Re: [PATCH v5 0/6] Add support for FORM2 associativity
From: Aneesh Kumar K.V @ 2021-07-13 14:30 UTC (permalink / raw)
To: Daniel Henrique Barboza, linuxppc-dev, mpe; +Cc: Nathan Lynch, David Gibson
In-Reply-To: <ad91ae4e-7c2d-26d6-1a6e-88f2c365fade@gmail.com>
On 7/13/21 7:57 PM, Daniel Henrique Barboza wrote:
> Aneesh,
>
> This series compiles with a configuration made with "pseries_le_defconfig"
> but fails with a config based on an existing RHEL8 config.
>
> The reason, which is hinted in the robot replies in patch 4, is that you
> defined
> a "__vphn_get_associativity" inside a #ifdef CONFIG_PPC_SPLPAR guard but
> didn't
> define how the function would behave without the config, and you ended up
> using the function elsewhere.
>
> This fixes the compilation but I'm not sure if this is what you intended
> for this function:
>
>
> diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
> index c68846fc9550..6e8551d16b7a 100644
> --- a/arch/powerpc/mm/numa.c
> +++ b/arch/powerpc/mm/numa.c
> @@ -680,6 +680,11 @@ static int vphn_get_nid(long lcpu)
>
> }
> #else
> +static int __vphn_get_associativity(long lcpu, __be32 *associativity)
> +{
> + return -1;
> +}
> +
> static int vphn_get_nid(long unused)
> {
> return NUMA_NO_NODE;
>
>
> I'll post a new version of the QEMU FORM2 changes using these patches as
> is (with
> the above fixup), but I guess you'll want to post a v6.
>
kernel test robot did report that earlier and I have that fixed in my
local tree. I haven't posted v6 yet because I want to close the review
on the approach with v5 patchset.
-aneesh
^ permalink raw reply
* Re: [PATCH v2 1/2] sched/topology: Skip updating masks for non-online nodes
From: Valentin Schneider @ 2021-07-13 16:32 UTC (permalink / raw)
To: Srikar Dronamraju
Cc: Nathan Lynch, Gautham R Shenoy, Vincent Guittot, Rik van Riel,
Peter Zijlstra, linuxppc-dev, Geetika Moolchandani, LKML,
Dietmar Eggemann, Thomas Gleixner, Laurent Dufour, Mel Gorman,
Ingo Molnar
In-Reply-To: <20210712124856.GA3836887@linux.vnet.ibm.com>
On 12/07/21 18:18, Srikar Dronamraju wrote:
> Hi Valentin,
>
>> On 01/07/21 09:45, Srikar Dronamraju wrote:
>> > @@ -1891,12 +1894,30 @@ void sched_init_numa(void)
>> > void sched_domains_numa_masks_set(unsigned int cpu)
>> > {
>>
>> Hmph, so we're playing games with masks of offline nodes - is that really
>> necessary? Your modification of sched_init_numa() still scans all of the
>> nodes (regardless of their online status) to build the distance map, and
>> that is never updated (sched_init_numa() is pretty much an __init
>> function).
>>
>> So AFAICT this is all to cope with topology_span_sane() not applying
>> 'cpu_map' to its masks. That seemed fine to me back when I wrote it, but in
>> light of having bogus distance values for offline nodes, not so much...
>>
>> What about the below instead?
>>
>> ---
>> diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
>> index b77ad49dc14f..c2d9caad4aa6 100644
>> --- a/kernel/sched/topology.c
>> +++ b/kernel/sched/topology.c
>> @@ -2075,6 +2075,7 @@ static struct sched_domain *build_sched_domain(struct sched_domain_topology_leve
>> static bool topology_span_sane(struct sched_domain_topology_level *tl,
>> const struct cpumask *cpu_map, int cpu)
>> {
>> + struct cpumask *intersect = sched_domains_tmpmask;
>> int i;
>>
>> /* NUMA levels are allowed to overlap */
>> @@ -2090,14 +2091,17 @@ static bool topology_span_sane(struct sched_domain_topology_level *tl,
>> for_each_cpu(i, cpu_map) {
>> if (i == cpu)
>> continue;
>> +
>> /*
>> - * We should 'and' all those masks with 'cpu_map' to exactly
>> - * match the topology we're about to build, but that can only
>> - * remove CPUs, which only lessens our ability to detect
>> - * overlaps
>> + * We shouldn't have to bother with cpu_map here, unfortunately
>> + * some architectures (powerpc says hello) have to deal with
>> + * offline NUMA nodes reporting bogus distance values. This can
>> + * lead to funky NODE domain spans, but since those are offline
>> + * we can mask them out.
>> */
>> + cpumask_and(intersect, tl->mask(cpu), tl->mask(i));
>> if (!cpumask_equal(tl->mask(cpu), tl->mask(i)) &&
>> - cpumask_intersects(tl->mask(cpu), tl->mask(i)))
>> + cpumask_intersects(intersect, cpu_map))
>> return false;
>> }
>>
>
> Unfortunately this is not helping.
> I tried this patch alone and also with 2/2 patch of this series where
> we update/fill fake topology numbers. However both cases are still failing.
>
Thanks for testing it.
Now, let's take examples from your cover letter:
node distances:
node 0 1 2 3 4 5 6 7
0: 10 20 40 40 40 40 40 40
1: 20 10 40 40 40 40 40 40
2: 40 40 10 20 40 40 40 40
3: 40 40 20 10 40 40 40 40
4: 40 40 40 40 10 20 40 40
5: 40 40 40 40 20 10 40 40
6: 40 40 40 40 40 40 10 20
7: 40 40 40 40 40 40 20 10
But the system boots with just nodes 0 and 1, thus only this distance
matrix is valid:
node 0 1
0: 10 20
1: 20 10
topology_span_sane() is going to use tl->mask(cpu), and as you reported the
NODE topology level should cause issues. Let's assume all offline nodes say
they're 10 distance away from everyone else, and that we have one CPU per
node. This would give us:
NODE->mask(0) == 0,2-7
NODE->mask(1) == 1-7
The intersection is 2-7, we'll trigger the WARN_ON().
Now, with the above snippet, we'll check if that intersection covers any
online CPU. For sched_init_domains(), cpu_map is cpu_active_mask, so we'd
end up with an empty intersection and we shouldn't warn - that's the theory
at least.
Looking at sd_numa_mask(), I think there's a bug with topology_span_sane():
it doesn't run in the right place wrt where sched_domains_curr_level is
updated. Could you try the below on top of the previous snippet?
If that doesn't help, could you share the node distances / topology masks
that lead to the WARN_ON()? Thanks.
---
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index b77ad49dc14f..cda69dfa4065 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -1516,13 +1516,6 @@ sd_init(struct sched_domain_topology_level *tl,
int sd_id, sd_weight, sd_flags = 0;
struct cpumask *sd_span;
-#ifdef CONFIG_NUMA
- /*
- * Ugly hack to pass state to sd_numa_mask()...
- */
- sched_domains_curr_level = tl->numa_level;
-#endif
-
sd_weight = cpumask_weight(tl->mask(cpu));
if (tl->sd_flags)
@@ -2131,7 +2124,12 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att
sd = NULL;
for_each_sd_topology(tl) {
-
+#ifdef CONFIG_NUMA
+ /*
+ * Ugly hack to pass state to sd_numa_mask()...
+ */
+ sched_domains_curr_level = tl->numa_level;
+#endif
if (WARN_ON(!topology_span_sane(tl, cpu_map, i)))
goto error;
^ permalink raw reply related
* [PATCH v3 0/5] bus: Make remove callback return void
From: Uwe Kleine-König @ 2021-07-13 7:40 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: nvdimm, Samuel Iglesias Gonsalvez, Jens Taprogge, Ulf Hansson,
Jaroslav Kysela, Benjamin Tissoires, Paul Mackerras,
Srinivas Pandruvada, K. Y. Srinivasan, Mike Christie, Wei Liu,
Maxim Levitsky, Samuel Holland, Halil Pasic, linux-acpi,
linux-pci, xen-devel, Tomas Winkler, Julien Grall, Ohad Ben-Cohen,
Alex Williamson, Alex Elder, linux-parisc, Geoff Levand,
linux-fpga, linux-usb, Rafael J. Wysocki, linux-kernel, linux-spi,
Kai-Heng Feng, kernel, Jon Mason, linux-ntb, Wu Hao,
David Woodhouse, Krzysztof Wilczyński, Alexandre Belloni,
Manohar Vanga, Matthew Rosato, linux-wireless, Dominik Brodowski,
virtualization, James E.J. Bottomley, target-devel,
Srinivas Kandagatla, linux-i2c, linux-s390, Stefano Stabellini,
Stephen Hemminger, Jiri Slaby, Helge Deller,
Rafał Miłecki, YueHaibing, industrypack-devel,
linux-mips, Len Brown, Eric Farman, Vasily Gorbik, linux-arm-msm,
linux-media, Maxime Ripard, William Breathitt Gray, greybus-dev,
Frank Li, Mark Gross, Boris Ostrovsky, Mika Westerberg,
linux-arm-kernel, Johannes Thumshirn, Mathieu Poirier,
Stephen Boyd, Cornelia Huck, Peter Oberparleiter, Wolfram Sang,
Joey Pabalan, Yehezkel Bernat, Pali Rohár, Alison Schofield,
Heikki Krogerus, Tyrel Datwyler, Alexander Shishkin, Tom Rix,
Jason Wang, SeongJae Park, alsa-devel, platform-driver-x86,
Bjorn Helgaas, netdev, Vineeth Vijayan, Ira Weiny, Rob Herring,
Lorenzo Pieralisi, Dave Jiang, linux-staging, Dexuan Cui,
Jernej Skrabec, Kishon Vijay Abraham I, Christian Borntraeger,
Chen-Yu Tsai, linux-input, Allen Hubbe, Alex Dubov, Haiyang Zhang,
Jiri Kosina, Russell King (Oracle), Ben Widawsky,
Harald Freudenberger, linux-cxl, Michael Buesch, Dan Williams,
Mauro Carvalho Chehab, Cristian Marussi, Thomas Bogendoerfer,
Martin K. Petersen, Martyn Welch, Dmitry Torokhov, linux-mmc,
linux-sunxi, Stefan Richter, Sudeep Holla, David S. Miller,
Sven Van Asbroeck, kvm, Michael S. Tsirkin, linux-remoteproc,
Bjorn Andersson, Kirti Wankhede, Andreas Noever, linux-i3c,
linux1394-devel, Lee Jones, Arnd Bergmann, linux-scsi,
Marc Zyngier, Russell King, Thorsten Scherer, Andy Gross,
linux-serial, Jakub Kicinski, linux-hyperv, Michael Jamet,
Heiko Carstens, Johan Hovold, Hans de Goede, Hannes Reinecke,
Juergen Gross, linuxppc-dev, Takashi Iwai, Alexandre Bounine,
Vinod Koul, Mark Brown, Vishal Verma, dmaengine, Moritz Fischer,
Johannes Berg, Maximilian Luz
Hello,
this is the final patch set for my effort to make struct
bus_type::remove return void.
The first four patches contain cleanups that make some of these
callbacks (more obviously) always return 0. They are acked by the
respective maintainers. Bjorn Helgaas explicitly asked to include the
pci patch (#1) into this series, so Greg taking this is fine. I assume
the s390 people are fine with Greg taking patches #2 to #4, too, they
didn't explicitly said so though.
The last patch actually changes the prototype and so touches quite some
drivers and has the potential to conflict with future developments, so I
consider it beneficial to put these patches into next soon. I expect
that it will be Greg who takes the complete series, he already confirmed
via irc (for v2) to look into this series.
In the last round I failed to send the cover letter to all affected
people, sorry for that, this should be fixed now.
Best regards
Uwe
Changes since v2:
- Add several acks/review tags
- Include patch #1 explicitly
- rebase to v5.14-rc1, build test on amd64, arm64 and s390 using
allmodconfig
Uwe Kleine-König (5):
PCI: endpoint: Make struct pci_epf_driver::remove return void
s390/cio: Make struct css_driver::remove return void
s390/ccwgroup: Drop if with an always false condition
s390/scm: Make struct scm_driver::remove return void
bus: Make remove callback return void
arch/arm/common/locomo.c | 3 +--
arch/arm/common/sa1111.c | 4 +---
arch/arm/mach-rpc/ecard.c | 4 +---
arch/mips/sgi-ip22/ip22-gio.c | 3 +--
arch/parisc/kernel/drivers.c | 5 ++---
arch/powerpc/platforms/ps3/system-bus.c | 3 +--
arch/powerpc/platforms/pseries/ibmebus.c | 3 +--
arch/powerpc/platforms/pseries/vio.c | 3 +--
arch/s390/include/asm/eadm.h | 2 +-
drivers/acpi/bus.c | 3 +--
drivers/amba/bus.c | 4 +---
drivers/base/auxiliary.c | 4 +---
drivers/base/isa.c | 4 +---
drivers/base/platform.c | 4 +---
drivers/bcma/main.c | 6 ++----
drivers/bus/sunxi-rsb.c | 4 +---
drivers/cxl/core.c | 3 +--
drivers/dax/bus.c | 4 +---
drivers/dma/idxd/sysfs.c | 4 +---
drivers/firewire/core-device.c | 4 +---
drivers/firmware/arm_scmi/bus.c | 4 +---
drivers/firmware/google/coreboot_table.c | 4 +---
drivers/fpga/dfl.c | 4 +---
drivers/hid/hid-core.c | 4 +---
drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +---
drivers/hv/vmbus_drv.c | 5 +----
drivers/hwtracing/intel_th/core.c | 4 +---
drivers/i2c/i2c-core-base.c | 5 +----
drivers/i3c/master.c | 4 +---
drivers/input/gameport/gameport.c | 3 +--
drivers/input/serio/serio.c | 3 +--
drivers/ipack/ipack.c | 4 +---
drivers/macintosh/macio_asic.c | 4 +---
drivers/mcb/mcb-core.c | 4 +---
drivers/media/pci/bt8xx/bttv-gpio.c | 3 +--
drivers/memstick/core/memstick.c | 3 +--
drivers/mfd/mcp-core.c | 3 +--
drivers/misc/mei/bus.c | 4 +---
drivers/misc/tifm_core.c | 3 +--
drivers/mmc/core/bus.c | 4 +---
drivers/mmc/core/sdio_bus.c | 4 +---
drivers/net/netdevsim/bus.c | 3 +--
drivers/ntb/core.c | 4 +---
drivers/ntb/ntb_transport.c | 4 +---
drivers/nvdimm/bus.c | 3 +--
drivers/pci/endpoint/pci-epf-core.c | 7 ++-----
drivers/pci/pci-driver.c | 3 +--
drivers/pcmcia/ds.c | 4 +---
drivers/platform/surface/aggregator/bus.c | 4 +---
drivers/platform/x86/wmi.c | 4 +---
drivers/pnp/driver.c | 3 +--
drivers/rapidio/rio-driver.c | 4 +---
drivers/rpmsg/rpmsg_core.c | 7 ++-----
drivers/s390/block/scm_drv.c | 4 +---
drivers/s390/cio/ccwgroup.c | 6 +-----
drivers/s390/cio/chsc_sch.c | 3 +--
drivers/s390/cio/css.c | 7 +++----
drivers/s390/cio/css.h | 2 +-
drivers/s390/cio/device.c | 9 +++------
drivers/s390/cio/eadm_sch.c | 4 +---
drivers/s390/cio/scm.c | 5 +++--
drivers/s390/cio/vfio_ccw_drv.c | 3 +--
drivers/s390/crypto/ap_bus.c | 4 +---
drivers/scsi/scsi_debug.c | 3 +--
drivers/siox/siox-core.c | 4 +---
drivers/slimbus/core.c | 4 +---
drivers/soc/qcom/apr.c | 4 +---
drivers/spi/spi.c | 4 +---
drivers/spmi/spmi.c | 3 +--
drivers/ssb/main.c | 4 +---
drivers/staging/fieldbus/anybuss/host.c | 4 +---
drivers/staging/greybus/gbphy.c | 4 +---
drivers/target/loopback/tcm_loop.c | 5 ++---
drivers/thunderbolt/domain.c | 4 +---
drivers/tty/serdev/core.c | 4 +---
drivers/usb/common/ulpi.c | 4 +---
drivers/usb/serial/bus.c | 4 +---
drivers/usb/typec/bus.c | 4 +---
drivers/vdpa/vdpa.c | 4 +---
drivers/vfio/mdev/mdev_driver.c | 4 +---
drivers/virtio/virtio.c | 3 +--
drivers/vme/vme.c | 4 +---
drivers/xen/xenbus/xenbus.h | 2 +-
drivers/xen/xenbus/xenbus_probe.c | 4 +---
include/linux/device/bus.h | 2 +-
include/linux/pci-epf.h | 2 +-
sound/aoa/soundbus/core.c | 4 +---
87 files changed, 98 insertions(+), 241 deletions(-)
base-commit: e73f0f0ee7541171d89f2e2491130c7771ba58d3
--
2.30.2
^ permalink raw reply
* [PATCH v3 5/5] bus: Make remove callback return void
From: Uwe Kleine-König @ 2021-07-13 7:40 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: nvdimm, Rafael J . Wysocki, Samuel Iglesias Gonsalvez,
Jens Taprogge, Ulf Hansson, Jaroslav Kysela, Benjamin Tissoires,
Paul Mackerras, Srinivas Pandruvada, K. Y. Srinivasan,
Mike Christie, Wei Liu, Maxim Levitsky, Samuel Holland,
linux-acpi, linux-pci, xen-devel, Tomas Winkler, Julien Grall,
Ohad Ben-Cohen, Alex Williamson, Alex Elder, linux-parisc,
Geoff Levand, linux-fpga, linux-usb, Rafael J. Wysocki,
linux-kernel, linux-spi, Kai-Heng Feng, kernel, Jon Mason,
linux-ntb, Wu Hao, David Woodhouse, Krzysztof Wilczyński,
Alexandre Belloni, Manohar Vanga, linux-wireless,
Dominik Brodowski, virtualization, James E.J. Bottomley,
target-devel, Srinivas Kandagatla, linux-i2c, linux-s390,
Stefano Stabellini, Stephen Hemminger, Jiri Slaby, Helge Deller,
Rafał Miłecki, YueHaibing, industrypack-devel,
linux-mips, Len Brown, Vasily Gorbik, linux-arm-msm, linux-media,
Maxime Ripard, William Breathitt Gray, greybus-dev, Frank Li,
Mark Gross, Boris Ostrovsky, Mika Westerberg, linux-arm-kernel,
Johannes Thumshirn, Mathieu Poirier, Stephen Boyd, Cornelia Huck,
Peter Oberparleiter, Wolfram Sang, Joey Pabalan, Yehezkel Bernat,
Pali Rohár, Alison Schofield, Heikki Krogerus,
Tyrel Datwyler, Alexander Shishkin, Tom Rix, Jason Wang,
SeongJae Park, alsa-devel, platform-driver-x86, Bjorn Helgaas,
netdev, Vineeth Vijayan, Ira Weiny, Rob Herring,
Lorenzo Pieralisi, Dave Jiang, linux-staging, Dexuan Cui,
Jernej Skrabec, Kishon Vijay Abraham I, Christian Borntraeger,
Chen-Yu Tsai, linux-input, Allen Hubbe, Alex Dubov, Haiyang Zhang,
Jiri Kosina, Russell King (Oracle), Ben Widawsky,
Harald Freudenberger, linux-cxl, Michael Buesch, Dan Williams,
Mauro Carvalho Chehab, Cristian Marussi, Thomas Bogendoerfer,
Martin K. Petersen, Martyn Welch, Dmitry Torokhov, linux-mmc,
linux-sunxi, Stefan Richter, Sudeep Holla, David S. Miller,
Sven Van Asbroeck, kvm, Michael S. Tsirkin, linux-remoteproc,
Bjorn Andersson, Kirti Wankhede, Andreas Noever, linux-i3c,
linux1394-devel, Lee Jones, Arnd Bergmann, linux-scsi,
Marc Zyngier, Russell King, Thorsten Scherer, Andy Gross,
linux-serial, Jakub Kicinski, linux-hyperv, Michael Jamet,
Heiko Carstens, Johan Hovold, Hans de Goede, Hannes Reinecke,
Juergen Gross, linuxppc-dev, Takashi Iwai, Alexandre Bounine,
Vinod Koul, Mark Brown, Vishal Verma, dmaengine, Moritz Fischer,
Johannes Berg, Johannes Thumshirn, Maximilian Luz
In-Reply-To: <20210713074014.684791-1-u.kleine-koenig@pengutronix.de>
The driver core ignores the return value of this callback because there
is only little it can do when a device disappears.
This is the final bit of a long lasting cleanup quest where several
buses were converted to also return void from their remove callback.
Additionally some resource leaks were fixed that were caused by drivers
returning an error code in the expectation that the driver won't go
away.
With struct bus_type::remove returning void it's prevented that newly
implemented buses return an ignored error code and so don't anticipate
wrong expectations for driver authors.
Acked-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> (For ARM, Amba and related parts)
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org> (for sunxi-rsb)
Acked-by: Pali Rohár <pali@kernel.org>
Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org> (for media)
Acked-by: Hans de Goede <hdegoede@redhat.com> (For drivers/platform)
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-By: Vinod Koul <vkoul@kernel.org>
Acked-by: Juergen Gross <jgross@suse.com> (For xen)
Acked-by: Lee Jones <lee.jones@linaro.org> (For mfd)
Acked-by: Johannes Thumshirn <jth@kernel.org> (For mcb)
Acked-by: Johan Hovold <johan@kernel.org>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> (For slimbus)
Acked-by: Kirti Wankhede <kwankhede@nvidia.com> (For vfio)
Acked-by: Maximilian Luz <luzmaximilian@gmail.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> (For ulpi and typec)
Acked-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> (For ipack)
Reviewed-by: Tom Rix <trix@redhat.com> (For fpga)
Acked-by: Geoff Levand <geoff@infradead.org> (For ps3)
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com> (For thunderbolt)
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> (For intel_th)
Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> (For pcmcia)
Reviewed-by: Cornelia Huck <cohuck@redhat.com> (For drivers/s390 and drivers/vfio)
Acked-by: Rafael J. Wysocki <rafael@kernel.org> (For ACPI)
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org> (rpmsg and apr)
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> (For intel-ish-hid)
Acked-by: Dan Williams <dan.j.williams@intel.com> (For CXL, DAX, and NVDIMM)
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com> (For isa)
Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (For firewire)
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> (For hid)
Acked-by: Thorsten Scherer <t.scherer@eckelmann.de> (For siox)
Acked-by: Sven Van Asbroeck <TheSven73@gmail.com> (For anybuss)
Acked-by: Ulf Hansson <ulf.hansson@linaro.org> (For MMC)
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/arm/common/locomo.c | 3 +--
arch/arm/common/sa1111.c | 4 +---
arch/arm/mach-rpc/ecard.c | 4 +---
arch/mips/sgi-ip22/ip22-gio.c | 3 +--
arch/parisc/kernel/drivers.c | 5 ++---
arch/powerpc/platforms/ps3/system-bus.c | 3 +--
arch/powerpc/platforms/pseries/ibmebus.c | 3 +--
arch/powerpc/platforms/pseries/vio.c | 3 +--
drivers/acpi/bus.c | 3 +--
drivers/amba/bus.c | 4 +---
drivers/base/auxiliary.c | 4 +---
drivers/base/isa.c | 4 +---
drivers/base/platform.c | 4 +---
drivers/bcma/main.c | 6 ++----
drivers/bus/sunxi-rsb.c | 4 +---
drivers/cxl/core.c | 3 +--
drivers/dax/bus.c | 4 +---
drivers/dma/idxd/sysfs.c | 4 +---
drivers/firewire/core-device.c | 4 +---
drivers/firmware/arm_scmi/bus.c | 4 +---
drivers/firmware/google/coreboot_table.c | 4 +---
drivers/fpga/dfl.c | 4 +---
drivers/hid/hid-core.c | 4 +---
drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +---
drivers/hv/vmbus_drv.c | 5 +----
drivers/hwtracing/intel_th/core.c | 4 +---
drivers/i2c/i2c-core-base.c | 5 +----
drivers/i3c/master.c | 4 +---
drivers/input/gameport/gameport.c | 3 +--
drivers/input/serio/serio.c | 3 +--
drivers/ipack/ipack.c | 4 +---
drivers/macintosh/macio_asic.c | 4 +---
drivers/mcb/mcb-core.c | 4 +---
drivers/media/pci/bt8xx/bttv-gpio.c | 3 +--
drivers/memstick/core/memstick.c | 3 +--
drivers/mfd/mcp-core.c | 3 +--
drivers/misc/mei/bus.c | 4 +---
drivers/misc/tifm_core.c | 3 +--
drivers/mmc/core/bus.c | 4 +---
drivers/mmc/core/sdio_bus.c | 4 +---
drivers/net/netdevsim/bus.c | 3 +--
drivers/ntb/core.c | 4 +---
drivers/ntb/ntb_transport.c | 4 +---
drivers/nvdimm/bus.c | 3 +--
drivers/pci/endpoint/pci-epf-core.c | 4 +---
drivers/pci/pci-driver.c | 3 +--
drivers/pcmcia/ds.c | 4 +---
drivers/platform/surface/aggregator/bus.c | 4 +---
drivers/platform/x86/wmi.c | 4 +---
drivers/pnp/driver.c | 3 +--
drivers/rapidio/rio-driver.c | 4 +---
drivers/rpmsg/rpmsg_core.c | 7 ++-----
drivers/s390/cio/ccwgroup.c | 4 +---
drivers/s390/cio/css.c | 4 +---
drivers/s390/cio/device.c | 4 +---
drivers/s390/cio/scm.c | 4 +---
drivers/s390/crypto/ap_bus.c | 4 +---
drivers/scsi/scsi_debug.c | 3 +--
drivers/siox/siox-core.c | 4 +---
drivers/slimbus/core.c | 4 +---
drivers/soc/qcom/apr.c | 4 +---
drivers/spi/spi.c | 4 +---
drivers/spmi/spmi.c | 3 +--
drivers/ssb/main.c | 4 +---
drivers/staging/fieldbus/anybuss/host.c | 4 +---
drivers/staging/greybus/gbphy.c | 4 +---
drivers/target/loopback/tcm_loop.c | 5 ++---
drivers/thunderbolt/domain.c | 4 +---
drivers/tty/serdev/core.c | 4 +---
drivers/usb/common/ulpi.c | 4 +---
drivers/usb/serial/bus.c | 4 +---
drivers/usb/typec/bus.c | 4 +---
drivers/vdpa/vdpa.c | 4 +---
drivers/vfio/mdev/mdev_driver.c | 4 +---
drivers/virtio/virtio.c | 3 +--
drivers/vme/vme.c | 4 +---
drivers/xen/xenbus/xenbus.h | 2 +-
drivers/xen/xenbus/xenbus_probe.c | 4 +---
include/linux/device/bus.h | 2 +-
sound/aoa/soundbus/core.c | 4 +---
80 files changed, 84 insertions(+), 221 deletions(-)
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index e45f4e4e06b6..24d21ba63030 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -834,14 +834,13 @@ static int locomo_bus_probe(struct device *dev)
return ret;
}
-static int locomo_bus_remove(struct device *dev)
+static void locomo_bus_remove(struct device *dev)
{
struct locomo_dev *ldev = LOCOMO_DEV(dev);
struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
if (drv->remove)
drv->remove(ldev);
- return 0;
}
struct bus_type locomo_bus_type = {
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ff5e0d04cb89..092a2ebc0c28 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1364,15 +1364,13 @@ static int sa1111_bus_probe(struct device *dev)
return ret;
}
-static int sa1111_bus_remove(struct device *dev)
+static void sa1111_bus_remove(struct device *dev)
{
struct sa1111_dev *sadev = to_sa1111_device(dev);
struct sa1111_driver *drv = SA1111_DRV(dev->driver);
if (drv->remove)
drv->remove(sadev);
-
- return 0;
}
struct bus_type sa1111_bus_type = {
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index 827b50f1c73e..53813f9464a2 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -1052,7 +1052,7 @@ static int ecard_drv_probe(struct device *dev)
return ret;
}
-static int ecard_drv_remove(struct device *dev)
+static void ecard_drv_remove(struct device *dev)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct ecard_driver *drv = ECARD_DRV(dev->driver);
@@ -1067,8 +1067,6 @@ static int ecard_drv_remove(struct device *dev)
ec->ops = &ecard_default_ops;
barrier();
ec->irq_data = NULL;
-
- return 0;
}
/*
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
index de0768a49ee8..dfc52f661ad0 100644
--- a/arch/mips/sgi-ip22/ip22-gio.c
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -143,14 +143,13 @@ static int gio_device_probe(struct device *dev)
return error;
}
-static int gio_device_remove(struct device *dev)
+static void gio_device_remove(struct device *dev)
{
struct gio_device *gio_dev = to_gio_device(dev);
struct gio_driver *drv = to_gio_driver(dev->driver);
if (dev->driver && drv->remove)
drv->remove(gio_dev);
- return 0;
}
static void gio_device_shutdown(struct device *dev)
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 80fa0650736b..776d624a7207 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -133,14 +133,13 @@ static int parisc_driver_probe(struct device *dev)
return rc;
}
-static int __exit parisc_driver_remove(struct device *dev)
+static void __exit parisc_driver_remove(struct device *dev)
{
struct parisc_device *pa_dev = to_parisc_device(dev);
struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+
if (pa_drv->remove)
pa_drv->remove(pa_dev);
-
- return 0;
}
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 1a5665875165..cc5774c64fae 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -381,7 +381,7 @@ static int ps3_system_bus_probe(struct device *_dev)
return result;
}
-static int ps3_system_bus_remove(struct device *_dev)
+static void ps3_system_bus_remove(struct device *_dev)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
struct ps3_system_bus_driver *drv;
@@ -399,7 +399,6 @@ static int ps3_system_bus_remove(struct device *_dev)
__func__, __LINE__, drv->core.name);
pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
- return 0;
}
static void ps3_system_bus_shutdown(struct device *_dev)
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index c6c79ef55e13..7ee3ed7d6cc2 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -366,14 +366,13 @@ static int ibmebus_bus_device_probe(struct device *dev)
return error;
}
-static int ibmebus_bus_device_remove(struct device *dev)
+static void ibmebus_bus_device_remove(struct device *dev)
{
struct platform_device *of_dev = to_platform_device(dev);
struct platform_driver *drv = to_platform_driver(dev->driver);
if (dev->driver && drv->remove)
drv->remove(of_dev);
- return 0;
}
static void ibmebus_bus_device_shutdown(struct device *dev)
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index e00f3725ec96..58283cecbd52 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -1257,7 +1257,7 @@ static int vio_bus_probe(struct device *dev)
}
/* convert from struct device to struct vio_dev and pass to driver. */
-static int vio_bus_remove(struct device *dev)
+static void vio_bus_remove(struct device *dev)
{
struct vio_dev *viodev = to_vio_dev(dev);
struct vio_driver *viodrv = to_vio_driver(dev->driver);
@@ -1276,7 +1276,6 @@ static int vio_bus_remove(struct device *dev)
vio_cmo_bus_remove(viodev);
put_device(devptr);
- return 0;
}
static void vio_bus_shutdown(struct device *dev)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index f854bcb8d010..b941555cb5e4 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1019,7 +1019,7 @@ static int acpi_device_probe(struct device *dev)
return 0;
}
-static int acpi_device_remove(struct device *dev)
+static void acpi_device_remove(struct device *dev)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = acpi_dev->driver;
@@ -1034,7 +1034,6 @@ static int acpi_device_remove(struct device *dev)
acpi_dev->driver_data = NULL;
put_device(dev);
- return 0;
}
struct bus_type acpi_bus_type = {
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 939ca220bf78..962041148482 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -219,7 +219,7 @@ static int amba_probe(struct device *dev)
return ret;
}
-static int amba_remove(struct device *dev)
+static void amba_remove(struct device *dev)
{
struct amba_device *pcdev = to_amba_device(dev);
struct amba_driver *drv = to_amba_driver(dev->driver);
@@ -236,8 +236,6 @@ static int amba_remove(struct device *dev)
amba_put_disable_pclk(pcdev);
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void amba_shutdown(struct device *dev)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index adc199dfba3c..0c86f5bed9f4 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -79,7 +79,7 @@ static int auxiliary_bus_probe(struct device *dev)
return ret;
}
-static int auxiliary_bus_remove(struct device *dev)
+static void auxiliary_bus_remove(struct device *dev)
{
struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@@ -87,8 +87,6 @@ static int auxiliary_bus_remove(struct device *dev)
if (auxdrv->remove)
auxdrv->remove(auxdev);
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void auxiliary_bus_shutdown(struct device *dev)
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
index aa4737667026..55e3ee2da98f 100644
--- a/drivers/base/isa.c
+++ b/drivers/base/isa.c
@@ -46,14 +46,12 @@ static int isa_bus_probe(struct device *dev)
return 0;
}
-static int isa_bus_remove(struct device *dev)
+static void isa_bus_remove(struct device *dev)
{
struct isa_driver *isa_driver = dev->platform_data;
if (isa_driver && isa_driver->remove)
isa_driver->remove(dev, to_isa_dev(dev)->id);
-
- return 0;
}
static void isa_bus_shutdown(struct device *dev)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8640578f45e9..a94b7f454881 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1438,7 +1438,7 @@ static int platform_probe(struct device *_dev)
return ret;
}
-static int platform_remove(struct device *_dev)
+static void platform_remove(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
@@ -1450,8 +1450,6 @@ static int platform_remove(struct device *_dev)
dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n");
}
dev_pm_domain_detach(_dev, true);
-
- return 0;
}
static void platform_shutdown(struct device *_dev)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 6535614a7dc1..e076630d17bd 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -27,7 +27,7 @@ static DEFINE_MUTEX(bcma_buses_mutex);
static int bcma_bus_match(struct device *dev, struct device_driver *drv);
static int bcma_device_probe(struct device *dev);
-static int bcma_device_remove(struct device *dev);
+static void bcma_device_remove(struct device *dev);
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -614,7 +614,7 @@ static int bcma_device_probe(struct device *dev)
return err;
}
-static int bcma_device_remove(struct device *dev)
+static void bcma_device_remove(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
@@ -623,8 +623,6 @@ static int bcma_device_remove(struct device *dev)
if (adrv->remove)
adrv->remove(core);
put_device(dev);
-
- return 0;
}
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
index d46db132d085..6f225dddc74f 100644
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -169,13 +169,11 @@ static int sunxi_rsb_device_probe(struct device *dev)
return drv->probe(rdev);
}
-static int sunxi_rsb_device_remove(struct device *dev)
+static void sunxi_rsb_device_remove(struct device *dev)
{
const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
drv->remove(to_sunxi_rsb_device(dev));
-
- return 0;
}
static struct bus_type sunxi_rsb_bus = {
diff --git a/drivers/cxl/core.c b/drivers/cxl/core.c
index a2e4d54fc7bc..2b90b7c3b9d7 100644
--- a/drivers/cxl/core.c
+++ b/drivers/cxl/core.c
@@ -1034,13 +1034,12 @@ static int cxl_bus_probe(struct device *dev)
return to_cxl_drv(dev->driver)->probe(dev);
}
-static int cxl_bus_remove(struct device *dev)
+static void cxl_bus_remove(struct device *dev)
{
struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver);
if (cxl_drv->remove)
cxl_drv->remove(dev);
- return 0;
}
struct bus_type cxl_bus_type = {
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
index 5aee26e1bbd6..6cc4da4c713d 100644
--- a/drivers/dax/bus.c
+++ b/drivers/dax/bus.c
@@ -172,15 +172,13 @@ static int dax_bus_probe(struct device *dev)
return 0;
}
-static int dax_bus_remove(struct device *dev)
+static void dax_bus_remove(struct device *dev)
{
struct dax_device_driver *dax_drv = to_dax_drv(dev->driver);
struct dev_dax *dev_dax = to_dev_dax(dev);
if (dax_drv->remove)
dax_drv->remove(dev_dax);
-
- return 0;
}
static struct bus_type dax_bus_type = {
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 0460d58e3941..5a017c62c752 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -260,7 +260,7 @@ static void disable_wq(struct idxd_wq *wq)
dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev));
}
-static int idxd_config_bus_remove(struct device *dev)
+static void idxd_config_bus_remove(struct device *dev)
{
int rc;
@@ -305,8 +305,6 @@ static int idxd_config_bus_remove(struct device *dev)
dev_info(dev, "Device %s disabled\n", dev_name(dev));
}
-
- return 0;
}
static void idxd_config_bus_shutdown(struct device *dev)
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 68216988391f..90ed8fdaba75 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -187,14 +187,12 @@ static int fw_unit_probe(struct device *dev)
return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
}
-static int fw_unit_remove(struct device *dev)
+static void fw_unit_remove(struct device *dev)
{
struct fw_driver *driver =
container_of(dev->driver, struct fw_driver, driver);
driver->remove(fw_unit(dev));
-
- return 0;
}
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 784cf0027da3..2682c3df651c 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -116,15 +116,13 @@ static int scmi_dev_probe(struct device *dev)
return scmi_drv->probe(scmi_dev);
}
-static int scmi_dev_remove(struct device *dev)
+static void scmi_dev_remove(struct device *dev)
{
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
if (scmi_drv->remove)
scmi_drv->remove(scmi_dev);
-
- return 0;
}
static struct bus_type scmi_bus_type = {
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index dc83ea118c67..c52bcaa9def6 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -44,15 +44,13 @@ static int coreboot_bus_probe(struct device *dev)
return ret;
}
-static int coreboot_bus_remove(struct device *dev)
+static void coreboot_bus_remove(struct device *dev)
{
struct coreboot_device *device = CB_DEV(dev);
struct coreboot_driver *driver = CB_DRV(dev->driver);
if (driver->remove)
driver->remove(device);
-
- return 0;
}
static struct bus_type coreboot_bus_type = {
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index 511b20ff35a3..1ae6779a0dd6 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -284,15 +284,13 @@ static int dfl_bus_probe(struct device *dev)
return ddrv->probe(ddev);
}
-static int dfl_bus_remove(struct device *dev)
+static void dfl_bus_remove(struct device *dev)
{
struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
struct dfl_device *ddev = to_dfl_dev(dev);
if (ddrv->remove)
ddrv->remove(ddev);
-
- return 0;
}
static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7db332139f7d..dbed2524fd47 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2302,7 +2302,7 @@ static int hid_device_probe(struct device *dev)
return ret;
}
-static int hid_device_remove(struct device *dev)
+static void hid_device_remove(struct device *dev)
{
struct hid_device *hdev = to_hid_device(dev);
struct hid_driver *hdrv;
@@ -2322,8 +2322,6 @@ static int hid_device_remove(struct device *dev)
if (!hdev->io_started)
up(&hdev->driver_input_lock);
-
- return 0;
}
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index f0802b047ed8..8a51bd9cd093 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -255,7 +255,7 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
*
* Return: Return value from driver remove() call.
*/
-static int ishtp_cl_device_remove(struct device *dev)
+static void ishtp_cl_device_remove(struct device *dev)
{
struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver);
@@ -267,8 +267,6 @@ static int ishtp_cl_device_remove(struct device *dev)
if (driver->remove)
driver->remove(device);
-
- return 0;
}
/**
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 57bbbaa4e8f7..392c1ac4f819 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -922,7 +922,7 @@ static int vmbus_probe(struct device *child_device)
/*
* vmbus_remove - Remove a vmbus device
*/
-static int vmbus_remove(struct device *child_device)
+static void vmbus_remove(struct device *child_device)
{
struct hv_driver *drv;
struct hv_device *dev = device_to_hv_device(child_device);
@@ -932,11 +932,8 @@ static int vmbus_remove(struct device *child_device)
if (drv->remove)
drv->remove(dev);
}
-
- return 0;
}
-
/*
* vmbus_shutdown - Shutdown a vmbus device
*/
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 66eed2dff818..7e753a75d23b 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -95,7 +95,7 @@ static int intel_th_probe(struct device *dev)
static void intel_th_device_remove(struct intel_th_device *thdev);
-static int intel_th_remove(struct device *dev)
+static void intel_th_remove(struct device *dev)
{
struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver);
struct intel_th_device *thdev = to_intel_th_device(dev);
@@ -164,8 +164,6 @@ static int intel_th_remove(struct device *dev)
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
-
- return 0;
}
static struct bus_type intel_th_bus = {
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 84f12bf90644..54964fbe3f03 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -601,7 +601,7 @@ static int i2c_device_probe(struct device *dev)
return status;
}
-static int i2c_device_remove(struct device *dev)
+static void i2c_device_remove(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
@@ -631,9 +631,6 @@ static int i2c_device_remove(struct device *dev)
client->irq = 0;
if (client->flags & I2C_CLIENT_HOST_NOTIFY)
pm_runtime_put(&client->adapter->dev);
-
- /* return always 0 because there is WIP to make remove-functions void */
- return 0;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index e2e12a5585e5..c3b4c677b442 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -322,7 +322,7 @@ static int i3c_device_probe(struct device *dev)
return driver->probe(i3cdev);
}
-static int i3c_device_remove(struct device *dev)
+static void i3c_device_remove(struct device *dev)
{
struct i3c_device *i3cdev = dev_to_i3cdev(dev);
struct i3c_driver *driver = drv_to_i3cdrv(dev->driver);
@@ -331,8 +331,6 @@ static int i3c_device_remove(struct device *dev)
driver->remove(i3cdev);
i3c_device_free_ibi(i3cdev);
-
- return 0;
}
struct bus_type i3c_bus_type = {
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 61fa7e724172..db58a01b23d3 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -697,13 +697,12 @@ static int gameport_driver_probe(struct device *dev)
return gameport->drv ? 0 : -ENODEV;
}
-static int gameport_driver_remove(struct device *dev)
+static void gameport_driver_remove(struct device *dev)
{
struct gameport *gameport = to_gameport_port(dev);
struct gameport_driver *drv = to_gameport_driver(dev->driver);
drv->disconnect(gameport);
- return 0;
}
static void gameport_attach_driver(struct gameport_driver *drv)
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 29f491082926..ec117be3d8d8 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -778,12 +778,11 @@ static int serio_driver_probe(struct device *dev)
return serio_connect_driver(serio, drv);
}
-static int serio_driver_remove(struct device *dev)
+static void serio_driver_remove(struct device *dev)
{
struct serio *serio = to_serio_port(dev);
serio_disconnect_driver(serio);
- return 0;
}
static void serio_cleanup(struct serio *serio)
diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c
index 7de9605cac4f..b1c3198355e7 100644
--- a/drivers/ipack/ipack.c
+++ b/drivers/ipack/ipack.c
@@ -67,15 +67,13 @@ static int ipack_bus_probe(struct device *device)
return drv->ops->probe(dev);
}
-static int ipack_bus_remove(struct device *device)
+static void ipack_bus_remove(struct device *device)
{
struct ipack_device *dev = to_ipack_dev(device);
struct ipack_driver *drv = to_ipack_driver(device->driver);
if (drv->ops->remove)
drv->ops->remove(dev);
-
- return 0;
}
static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 49af60bdac92..c1fdf2896021 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -88,7 +88,7 @@ static int macio_device_probe(struct device *dev)
return error;
}
-static int macio_device_remove(struct device *dev)
+static void macio_device_remove(struct device *dev)
{
struct macio_dev * macio_dev = to_macio_device(dev);
struct macio_driver * drv = to_macio_driver(dev->driver);
@@ -96,8 +96,6 @@ static int macio_device_remove(struct device *dev)
if (dev->driver && drv->remove)
drv->remove(macio_dev);
macio_dev_put(macio_dev);
-
- return 0;
}
static void macio_device_shutdown(struct device *dev)
diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
index 38fbb3b59873..edf4ee6eff25 100644
--- a/drivers/mcb/mcb-core.c
+++ b/drivers/mcb/mcb-core.c
@@ -77,7 +77,7 @@ static int mcb_probe(struct device *dev)
return ret;
}
-static int mcb_remove(struct device *dev)
+static void mcb_remove(struct device *dev)
{
struct mcb_driver *mdrv = to_mcb_driver(dev->driver);
struct mcb_device *mdev = to_mcb_device(dev);
@@ -89,8 +89,6 @@ static int mcb_remove(struct device *dev)
module_put(carrier_mod);
put_device(&mdev->dev);
-
- return 0;
}
static void mcb_shutdown(struct device *dev)
diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c
index b730225ca887..a2b18e2bed1b 100644
--- a/drivers/media/pci/bt8xx/bttv-gpio.c
+++ b/drivers/media/pci/bt8xx/bttv-gpio.c
@@ -46,14 +46,13 @@ static int bttv_sub_probe(struct device *dev)
return sub->probe ? sub->probe(sdev) : -ENODEV;
}
-static int bttv_sub_remove(struct device *dev)
+static void bttv_sub_remove(struct device *dev)
{
struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
if (sub->remove)
sub->remove(sdev);
- return 0;
}
struct bus_type bttv_sub_bus_type = {
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index bb1065990aeb..660df7d269fa 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -91,7 +91,7 @@ static int memstick_device_probe(struct device *dev)
return rc;
}
-static int memstick_device_remove(struct device *dev)
+static void memstick_device_remove(struct device *dev)
{
struct memstick_dev *card = container_of(dev, struct memstick_dev,
dev);
@@ -105,7 +105,6 @@ static int memstick_device_remove(struct device *dev)
}
put_device(dev);
- return 0;
}
#ifdef CONFIG_PM
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index eff9423e90f5..2fa592c37c6f 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -33,13 +33,12 @@ static int mcp_bus_probe(struct device *dev)
return drv->probe(mcp);
}
-static int mcp_bus_remove(struct device *dev)
+static void mcp_bus_remove(struct device *dev)
{
struct mcp *mcp = to_mcp(dev);
struct mcp_driver *drv = to_mcp_driver(dev->driver);
drv->remove(mcp);
- return 0;
}
static struct bus_type mcp_bus_type = {
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 935acc6bbf3c..3bf2bb4fd152 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -884,7 +884,7 @@ static int mei_cl_device_probe(struct device *dev)
*
* Return: 0 on success; < 0 otherwise
*/
-static int mei_cl_device_remove(struct device *dev)
+static void mei_cl_device_remove(struct device *dev)
{
struct mei_cl_device *cldev = to_mei_cl_device(dev);
struct mei_cl_driver *cldrv = to_mei_cl_driver(dev->driver);
@@ -896,8 +896,6 @@ static int mei_cl_device_remove(struct device *dev)
mei_cl_bus_module_put(cldev);
module_put(THIS_MODULE);
-
- return 0;
}
static ssize_t name_show(struct device *dev, struct device_attribute *a,
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 667e574a7df2..52656fc87e99 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -87,7 +87,7 @@ static void tifm_dummy_event(struct tifm_dev *sock)
return;
}
-static int tifm_device_remove(struct device *dev)
+static void tifm_device_remove(struct device *dev)
{
struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
@@ -101,7 +101,6 @@ static int tifm_device_remove(struct device *dev)
}
put_device(dev);
- return 0;
}
#ifdef CONFIG_PM
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 4383c262b3f5..f6b7a9c5bbff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -140,14 +140,12 @@ static int mmc_bus_probe(struct device *dev)
return drv->probe(card);
}
-static int mmc_bus_remove(struct device *dev)
+static void mmc_bus_remove(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
drv->remove(card);
-
- return 0;
}
static void mmc_bus_shutdown(struct device *dev)
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 3d709029e07c..fda03b35c14a 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -203,7 +203,7 @@ static int sdio_bus_probe(struct device *dev)
return ret;
}
-static int sdio_bus_remove(struct device *dev)
+static void sdio_bus_remove(struct device *dev)
{
struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev);
@@ -232,8 +232,6 @@ static int sdio_bus_remove(struct device *dev)
pm_runtime_put_sync(dev);
dev_pm_domain_detach(dev, false);
-
- return 0;
}
static const struct dev_pm_ops sdio_bus_pm_ops = {
diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index ccec29970d5b..14b154929533 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -370,12 +370,11 @@ static int nsim_bus_probe(struct device *dev)
return nsim_dev_probe(nsim_bus_dev);
}
-static int nsim_bus_remove(struct device *dev)
+static void nsim_bus_remove(struct device *dev)
{
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
nsim_dev_remove(nsim_bus_dev);
- return 0;
}
static int nsim_num_vf(struct device *dev)
diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c
index f8f75a504a58..27dd93deff6e 100644
--- a/drivers/ntb/core.c
+++ b/drivers/ntb/core.c
@@ -271,7 +271,7 @@ static int ntb_probe(struct device *dev)
return rc;
}
-static int ntb_remove(struct device *dev)
+static void ntb_remove(struct device *dev)
{
struct ntb_dev *ntb;
struct ntb_client *client;
@@ -283,8 +283,6 @@ static int ntb_remove(struct device *dev)
client->ops.remove(client, ntb);
put_device(dev);
}
-
- return 0;
}
static void ntb_dev_release(struct device *dev)
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 4a02561cfb96..a9b97ebc71ac 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -304,7 +304,7 @@ static int ntb_transport_bus_probe(struct device *dev)
return rc;
}
-static int ntb_transport_bus_remove(struct device *dev)
+static void ntb_transport_bus_remove(struct device *dev)
{
const struct ntb_transport_client *client;
@@ -312,8 +312,6 @@ static int ntb_transport_bus_remove(struct device *dev)
client->remove(dev);
put_device(dev);
-
- return 0;
}
static struct bus_type ntb_transport_bus = {
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index e6aa87043a95..9dc7f3edd42b 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -108,7 +108,7 @@ static int nvdimm_bus_probe(struct device *dev)
return rc;
}
-static int nvdimm_bus_remove(struct device *dev)
+static void nvdimm_bus_remove(struct device *dev)
{
struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
struct module *provider = to_bus_provider(dev);
@@ -123,7 +123,6 @@ static int nvdimm_bus_remove(struct device *dev)
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name,
dev_name(dev));
module_put(provider);
- return 0;
}
static void nvdimm_bus_shutdown(struct device *dev)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 4b9ad96bf1b2..502eb79cd551 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -387,7 +387,7 @@ static int pci_epf_device_probe(struct device *dev)
return driver->probe(epf);
}
-static int pci_epf_device_remove(struct device *dev)
+static void pci_epf_device_remove(struct device *dev)
{
struct pci_epf *epf = to_pci_epf(dev);
struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
@@ -395,8 +395,6 @@ static int pci_epf_device_remove(struct device *dev)
if (driver->remove)
driver->remove(epf);
epf->driver = NULL;
-
- return 0;
}
static struct bus_type pci_epf_bus_type = {
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3a72352aa5cf..a0615395500a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -440,7 +440,7 @@ static int pci_device_probe(struct device *dev)
return error;
}
-static int pci_device_remove(struct device *dev)
+static void pci_device_remove(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *drv = pci_dev->driver;
@@ -476,7 +476,6 @@ static int pci_device_remove(struct device *dev)
*/
pci_dev_put(pci_dev);
- return 0;
}
static void pci_device_shutdown(struct device *dev)
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index bd81aa64d011..5bd1b80424e7 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -350,7 +350,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
return;
}
-static int pcmcia_device_remove(struct device *dev)
+static void pcmcia_device_remove(struct device *dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
@@ -389,8 +389,6 @@ static int pcmcia_device_remove(struct device *dev)
/* references from pcmcia_device_probe */
pcmcia_put_dev(p_dev);
module_put(p_drv->owner);
-
- return 0;
}
diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
index 0169677c243e..0a40dd9c94ed 100644
--- a/drivers/platform/surface/aggregator/bus.c
+++ b/drivers/platform/surface/aggregator/bus.c
@@ -316,14 +316,12 @@ static int ssam_bus_probe(struct device *dev)
->probe(to_ssam_device(dev));
}
-static int ssam_bus_remove(struct device *dev)
+static void ssam_bus_remove(struct device *dev)
{
struct ssam_device_driver *sdrv = to_ssam_device_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_ssam_device(dev));
-
- return 0;
}
struct bus_type ssam_bus_type = {
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 62e0d56a3332..a76313006bdc 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -980,7 +980,7 @@ static int wmi_dev_probe(struct device *dev)
return ret;
}
-static int wmi_dev_remove(struct device *dev)
+static void wmi_dev_remove(struct device *dev)
{
struct wmi_block *wblock = dev_to_wblock(dev);
struct wmi_driver *wdriver =
@@ -997,8 +997,6 @@ static int wmi_dev_remove(struct device *dev)
if (ACPI_FAILURE(wmi_method_enable(wblock, 0)))
dev_warn(dev, "failed to disable device\n");
-
- return 0;
}
static struct class wmi_bus_class = {
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index c29d590c5e4f..cc6757dfa3f1 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -123,7 +123,7 @@ static int pnp_device_probe(struct device *dev)
return error;
}
-static int pnp_device_remove(struct device *dev)
+static void pnp_device_remove(struct device *dev)
{
struct pnp_dev *pnp_dev = to_pnp_dev(dev);
struct pnp_driver *drv = pnp_dev->driver;
@@ -139,7 +139,6 @@ static int pnp_device_remove(struct device *dev)
pnp_disable_dev(pnp_dev);
pnp_device_detach(pnp_dev);
- return 0;
}
static void pnp_device_shutdown(struct device *dev)
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 72874153972e..a72bb0a40fcf 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -112,7 +112,7 @@ static int rio_device_probe(struct device *dev)
* driver, then run the driver remove() method. Then update
* the reference count.
*/
-static int rio_device_remove(struct device *dev)
+static void rio_device_remove(struct device *dev)
{
struct rio_dev *rdev = to_rio_dev(dev);
struct rio_driver *rdrv = rdev->driver;
@@ -124,8 +124,6 @@ static int rio_device_remove(struct device *dev)
}
rio_dev_put(rdev);
-
- return 0;
}
static void rio_device_shutdown(struct device *dev)
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index c1404d3dae2c..9151836190ce 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -530,14 +530,13 @@ static int rpmsg_dev_probe(struct device *dev)
return err;
}
-static int rpmsg_dev_remove(struct device *dev)
+static void rpmsg_dev_remove(struct device *dev)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
- int err = 0;
if (rpdev->ops->announce_destroy)
- err = rpdev->ops->announce_destroy(rpdev);
+ rpdev->ops->announce_destroy(rpdev);
if (rpdrv->remove)
rpdrv->remove(rpdev);
@@ -546,8 +545,6 @@ static int rpmsg_dev_remove(struct device *dev)
if (rpdev->ept)
rpmsg_destroy_ept(rpdev->ept);
-
- return err;
}
static struct bus_type rpmsg_bus = {
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index a6aeab1ea0ae..382c5b5f8cd3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -439,15 +439,13 @@ module_exit(cleanup_ccwgroup);
/************************** driver stuff ******************************/
-static int ccwgroup_remove(struct device *dev)
+static void ccwgroup_remove(struct device *dev)
{
struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
if (gdrv->remove)
gdrv->remove(gdev);
-
- return 0;
}
static void ccwgroup_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 092fd1ea5799..ebc321edba51 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1371,7 +1371,7 @@ static int css_probe(struct device *dev)
return ret;
}
-static int css_remove(struct device *dev)
+static void css_remove(struct device *dev)
{
struct subchannel *sch;
@@ -1379,8 +1379,6 @@ static int css_remove(struct device *dev)
if (sch->driver->remove)
sch->driver->remove(sch);
sch->driver = NULL;
-
- return 0;
}
static void css_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index cd5d2d4d8e46..adf33b653d87 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1741,7 +1741,7 @@ ccw_device_probe (struct device *dev)
return 0;
}
-static int ccw_device_remove(struct device *dev)
+static void ccw_device_remove(struct device *dev)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct ccw_driver *cdrv = cdev->drv;
@@ -1775,8 +1775,6 @@ static int ccw_device_remove(struct device *dev)
spin_unlock_irq(cdev->ccwlock);
io_subchannel_quiesce(sch);
__disable_cmf(cdev);
-
- return 0;
}
static void ccw_device_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c
index b31711307e5a..b6b4589c70bd 100644
--- a/drivers/s390/cio/scm.c
+++ b/drivers/s390/cio/scm.c
@@ -28,15 +28,13 @@ static int scmdev_probe(struct device *dev)
return scmdrv->probe ? scmdrv->probe(scmdev) : -ENODEV;
}
-static int scmdev_remove(struct device *dev)
+static void scmdev_remove(struct device *dev)
{
struct scm_device *scmdev = to_scm_dev(dev);
struct scm_driver *scmdrv = to_scm_drv(dev->driver);
if (scmdrv->remove)
scmdrv->remove(scmdev);
-
- return 0;
}
static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 8d3a1d84a757..0992edcaf1af 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -901,7 +901,7 @@ static int ap_device_probe(struct device *dev)
return rc;
}
-static int ap_device_remove(struct device *dev)
+static void ap_device_remove(struct device *dev)
{
struct ap_device *ap_dev = to_ap_dev(dev);
struct ap_driver *ap_drv = ap_dev->drv;
@@ -926,8 +926,6 @@ static int ap_device_remove(struct device *dev)
ap_dev->drv = NULL;
put_device(dev);
-
- return 0;
}
struct ap_queue *ap_get_qdev(ap_qid_t qid)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 5b3a20a140f9..58f69366bdcc 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -7674,7 +7674,7 @@ static int sdebug_driver_probe(struct device *dev)
return error;
}
-static int sdebug_driver_remove(struct device *dev)
+static void sdebug_driver_remove(struct device *dev)
{
struct sdebug_host_info *sdbg_host;
struct sdebug_dev_info *sdbg_devinfo, *tmp;
@@ -7691,7 +7691,6 @@ static int sdebug_driver_remove(struct device *dev)
}
scsi_host_put(sdbg_host->shost);
- return 0;
}
static int pseudo_lld_bus_match(struct device *dev,
diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c
index 1794ff0106bc..7c4f32d76966 100644
--- a/drivers/siox/siox-core.c
+++ b/drivers/siox/siox-core.c
@@ -520,7 +520,7 @@ static int siox_probe(struct device *dev)
return sdriver->probe(sdevice);
}
-static int siox_remove(struct device *dev)
+static void siox_remove(struct device *dev)
{
struct siox_driver *sdriver =
container_of(dev->driver, struct siox_driver, driver);
@@ -528,8 +528,6 @@ static int siox_remove(struct device *dev)
if (sdriver->remove)
sdriver->remove(sdevice);
-
- return 0;
}
static void siox_shutdown(struct device *dev)
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index 1d2bc181da05..78480e332ab8 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -81,7 +81,7 @@ static int slim_device_probe(struct device *dev)
return ret;
}
-static int slim_device_remove(struct device *dev)
+static void slim_device_remove(struct device *dev)
{
struct slim_device *sbdev = to_slim_device(dev);
struct slim_driver *sbdrv;
@@ -91,8 +91,6 @@ static int slim_device_remove(struct device *dev)
if (sbdrv->remove)
sbdrv->remove(sbdev);
}
-
- return 0;
}
static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index 7abfc8c4fdc7..475a57b435b2 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -217,7 +217,7 @@ static int apr_device_probe(struct device *dev)
return adrv->probe(adev);
}
-static int apr_device_remove(struct device *dev)
+static void apr_device_remove(struct device *dev)
{
struct apr_device *adev = to_apr_device(dev);
struct apr_driver *adrv;
@@ -231,8 +231,6 @@ static int apr_device_remove(struct device *dev)
idr_remove(&apr->svcs_idr, adev->svc_id);
spin_unlock(&apr->svcs_lock);
}
-
- return 0;
}
static int apr_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c99181165321..ad2b558dc9cb 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -405,7 +405,7 @@ static int spi_probe(struct device *dev)
return ret;
}
-static int spi_remove(struct device *dev)
+static void spi_remove(struct device *dev)
{
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
@@ -420,8 +420,6 @@ static int spi_remove(struct device *dev)
}
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void spi_shutdown(struct device *dev)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 51f5aeb65b3b..b37ead9e2fad 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -345,7 +345,7 @@ static int spmi_drv_probe(struct device *dev)
return err;
}
-static int spmi_drv_remove(struct device *dev)
+static void spmi_drv_remove(struct device *dev)
{
const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
@@ -356,7 +356,6 @@ static int spmi_drv_remove(struct device *dev)
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
- return 0;
}
static void spmi_drv_shutdown(struct device *dev)
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 3a29b5570f9f..8a93c83cb6f8 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -283,7 +283,7 @@ static void ssb_device_shutdown(struct device *dev)
ssb_drv->shutdown(ssb_dev);
}
-static int ssb_device_remove(struct device *dev)
+static void ssb_device_remove(struct device *dev)
{
struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
@@ -291,8 +291,6 @@ static int ssb_device_remove(struct device *dev)
if (ssb_drv && ssb_drv->remove)
ssb_drv->remove(ssb_dev);
ssb_device_put(ssb_dev);
-
- return 0;
}
static int ssb_device_probe(struct device *dev)
diff --git a/drivers/staging/fieldbus/anybuss/host.c b/drivers/staging/fieldbus/anybuss/host.c
index 0f730efe9a6d..8a75f6642c78 100644
--- a/drivers/staging/fieldbus/anybuss/host.c
+++ b/drivers/staging/fieldbus/anybuss/host.c
@@ -1186,15 +1186,13 @@ static int anybus_bus_probe(struct device *dev)
return adrv->probe(adev);
}
-static int anybus_bus_remove(struct device *dev)
+static void anybus_bus_remove(struct device *dev)
{
struct anybuss_client_driver *adrv =
to_anybuss_client_driver(dev->driver);
if (adrv->remove)
adrv->remove(to_anybuss_client(dev));
-
- return 0;
}
static struct bus_type anybus_bus = {
diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c
index 13d319860da5..5a5c17a4519b 100644
--- a/drivers/staging/greybus/gbphy.c
+++ b/drivers/staging/greybus/gbphy.c
@@ -169,7 +169,7 @@ static int gbphy_dev_probe(struct device *dev)
return ret;
}
-static int gbphy_dev_remove(struct device *dev)
+static void gbphy_dev_remove(struct device *dev)
{
struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
@@ -180,8 +180,6 @@ static int gbphy_dev_remove(struct device *dev)
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
pm_runtime_dont_use_autosuspend(dev);
-
- return 0;
}
static struct bus_type gbphy_bus_type = {
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 6d0b0e67e79e..cbb2118fb35e 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -81,7 +81,7 @@ static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
}
static int tcm_loop_driver_probe(struct device *);
-static int tcm_loop_driver_remove(struct device *);
+static void tcm_loop_driver_remove(struct device *);
static int pseudo_lld_bus_match(struct device *dev,
struct device_driver *dev_driver)
@@ -363,7 +363,7 @@ static int tcm_loop_driver_probe(struct device *dev)
return 0;
}
-static int tcm_loop_driver_remove(struct device *dev)
+static void tcm_loop_driver_remove(struct device *dev)
{
struct tcm_loop_hba *tl_hba;
struct Scsi_Host *sh;
@@ -373,7 +373,6 @@ static int tcm_loop_driver_remove(struct device *dev)
scsi_remove_host(sh);
scsi_host_put(sh);
- return 0;
}
static void tcm_loop_release_adapter(struct device *dev)
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index a062befcb3b2..7018d959f775 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -86,7 +86,7 @@ static int tb_service_probe(struct device *dev)
return driver->probe(svc, id);
}
-static int tb_service_remove(struct device *dev)
+static void tb_service_remove(struct device *dev)
{
struct tb_service *svc = tb_to_service(dev);
struct tb_service_driver *driver;
@@ -94,8 +94,6 @@ static int tb_service_remove(struct device *dev)
driver = container_of(dev->driver, struct tb_service_driver, driver);
if (driver->remove)
driver->remove(svc);
-
- return 0;
}
static void tb_service_shutdown(struct device *dev)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 9cdfcfe07e87..92498961fd92 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -421,15 +421,13 @@ static int serdev_drv_probe(struct device *dev)
return ret;
}
-static int serdev_drv_remove(struct device *dev)
+static void serdev_drv_remove(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_serdev_device(dev));
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static struct bus_type serdev_bus_type = {
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 7e13b74e60e5..4169cf40a03b 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -78,14 +78,12 @@ static int ulpi_probe(struct device *dev)
return drv->probe(to_ulpi_dev(dev));
}
-static int ulpi_remove(struct device *dev)
+static void ulpi_remove(struct device *dev)
{
struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
if (drv->remove)
drv->remove(to_ulpi_dev(dev));
-
- return 0;
}
static struct bus_type ulpi_bus = {
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 7133818a58b9..9e38142acd38 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -74,7 +74,7 @@ static int usb_serial_device_probe(struct device *dev)
return retval;
}
-static int usb_serial_device_remove(struct device *dev)
+static void usb_serial_device_remove(struct device *dev)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct usb_serial_driver *driver;
@@ -101,8 +101,6 @@ static int usb_serial_device_remove(struct device *dev)
if (!autopm_err)
usb_autopm_put_interface(port->serial->interface);
-
- return 0;
}
static ssize_t new_id_store(struct device_driver *driver,
diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index 7f3c9a8e2bf0..78e0e78954f2 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -382,7 +382,7 @@ static int typec_probe(struct device *dev)
return ret;
}
-static int typec_remove(struct device *dev)
+static void typec_remove(struct device *dev)
{
struct typec_altmode_driver *drv = to_altmode_driver(dev->driver);
struct typec_altmode *adev = to_typec_altmode(dev);
@@ -400,8 +400,6 @@ static int typec_remove(struct device *dev)
adev->desc = NULL;
adev->ops = NULL;
-
- return 0;
}
struct bus_type typec_bus = {
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index bb3f1d1f0422..3fc4525fc05c 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -34,15 +34,13 @@ static int vdpa_dev_probe(struct device *d)
return ret;
}
-static int vdpa_dev_remove(struct device *d)
+static void vdpa_dev_remove(struct device *d)
{
struct vdpa_device *vdev = dev_to_vdpa(d);
struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
if (drv && drv->remove)
drv->remove(vdev);
-
- return 0;
}
static struct bus_type vdpa_bus = {
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index c368ec824e2b..e2cb1ff56f6c 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -57,7 +57,7 @@ static int mdev_probe(struct device *dev)
return ret;
}
-static int mdev_remove(struct device *dev)
+static void mdev_remove(struct device *dev)
{
struct mdev_driver *drv =
container_of(dev->driver, struct mdev_driver, driver);
@@ -67,8 +67,6 @@ static int mdev_remove(struct device *dev)
drv->remove(mdev);
mdev_detach_iommu(mdev);
-
- return 0;
}
static int mdev_match(struct device *dev, struct device_driver *drv)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 4b15c00c0a0a..2a6055c0d4d3 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -278,7 +278,7 @@ static int virtio_dev_probe(struct device *_d)
}
-static int virtio_dev_remove(struct device *_d)
+static void virtio_dev_remove(struct device *_d)
{
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
@@ -292,7 +292,6 @@ static int virtio_dev_remove(struct device *_d)
/* Acknowledge the device's existence again. */
virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
- return 0;
}
static struct bus_type virtio_bus = {
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 1b15afea28ee..8dba20186be3 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -1990,7 +1990,7 @@ static int vme_bus_probe(struct device *dev)
return -ENODEV;
}
-static int vme_bus_remove(struct device *dev)
+static void vme_bus_remove(struct device *dev)
{
struct vme_driver *driver;
struct vme_dev *vdev = dev_to_vme_dev(dev);
@@ -1998,8 +1998,6 @@ static int vme_bus_remove(struct device *dev)
driver = dev->platform_data;
if (driver->remove)
driver->remove(vdev);
-
- return 0;
}
struct bus_type vme_bus_type = {
diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h
index 2a93b7c9c159..2754bdfadcb8 100644
--- a/drivers/xen/xenbus/xenbus.h
+++ b/drivers/xen/xenbus/xenbus.h
@@ -106,7 +106,7 @@ void xs_request_exit(struct xb_req_data *req);
int xenbus_match(struct device *_dev, struct device_driver *_drv);
int xenbus_dev_probe(struct device *_dev);
-int xenbus_dev_remove(struct device *_dev);
+void xenbus_dev_remove(struct device *_dev);
int xenbus_register_driver_common(struct xenbus_driver *drv,
struct xen_bus_type *bus,
struct module *owner,
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 33d09b3f6211..bd003ca8acbe 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -325,7 +325,7 @@ int xenbus_dev_probe(struct device *_dev)
}
EXPORT_SYMBOL_GPL(xenbus_dev_probe);
-int xenbus_dev_remove(struct device *_dev)
+void xenbus_dev_remove(struct device *_dev)
{
struct xenbus_device *dev = to_xenbus_device(_dev);
struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -355,8 +355,6 @@ int xenbus_dev_remove(struct device *_dev)
if (!drv->allow_rebind ||
xenbus_read_driver_state(dev->nodename) == XenbusStateClosing)
xenbus_switch_state(dev, XenbusStateClosed);
-
- return 0;
}
EXPORT_SYMBOL_GPL(xenbus_dev_remove);
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 1ea5e1d1545b..062777a45a74 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -91,7 +91,7 @@ struct bus_type {
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
void (*sync_state)(struct device *dev);
- int (*remove)(struct device *dev);
+ void (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 002fb5bf220b..c9579d97fbab 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -104,7 +104,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
return retval;
}
-static int soundbus_device_remove(struct device *dev)
+static void soundbus_device_remove(struct device *dev)
{
struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
@@ -112,8 +112,6 @@ static int soundbus_device_remove(struct device *dev)
if (dev->driver && drv->remove)
drv->remove(soundbus_dev);
soundbus_dev_put(soundbus_dev);
-
- return 0;
}
static void soundbus_device_shutdown(struct device *dev)
--
2.30.2
^ permalink raw reply related
* [PATCH v4 0/5] bus: Make remove callback return void
From: Uwe Kleine-König @ 2021-07-13 19:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: nvdimm, linux-sh, Samuel Iglesias Gonsalvez, Jens Taprogge,
Ulf Hansson, Jaroslav Kysela, Benjamin Tissoires, Paul Mackerras,
Srinivas Pandruvada, K. Y. Srinivasan, Mike Christie, Wei Liu,
Maxim Levitsky, Samuel Holland, Halil Pasic, linux-acpi,
Geert Uytterhoeven, linux-pci, xen-devel, Tomas Winkler,
Julien Grall, Ohad Ben-Cohen, Yufen Yu, Alex Williamson,
Alex Elder, linux-parisc, Finn Thain, Geoff Levand, linux-fpga,
linux-usb, Rafael J. Wysocki, linux-kernel, linux-spi,
Kai-Heng Feng, kernel, Jon Mason, linux-ntb, Wu Hao,
David Woodhouse, Krzysztof Wilczyński, Alexandre Belloni,
Manohar Vanga, Matthew Rosato, linux-wireless, Dominik Brodowski,
virtualization, James E.J. Bottomley, target-devel,
Srinivas Kandagatla, linux-i2c, linux-s390, Stefano Stabellini,
Stephen Hemminger, Yoshinori Sato, Jiri Slaby, Helge Deller,
Rafał Miłecki, YueHaibing, industrypack-devel,
linux-mips, Len Brown, Eric Farman, Vasily Gorbik, linux-arm-msm,
linux-media, Maxime Ripard, William Breathitt Gray, greybus-dev,
linux-m68k, Florian Fainelli, Rikard Falkeborn, Frank Li,
Mark Gross, Boris Ostrovsky, Mika Westerberg, linux-arm-kernel,
Johannes Thumshirn, Mathieu Poirier, Stephen Boyd, Cornelia Huck,
Peter Oberparleiter, Wolfram Sang, Joey Pabalan, Yehezkel Bernat,
Pali Rohár, Bodo Stroesser, Alison Schofield,
Heikki Krogerus, Tyrel Datwyler, Alexander Shishkin, Tom Rix,
Jason Wang, SeongJae Park, alsa-devel, platform-driver-x86,
Bjorn Helgaas, netdev, Vineeth Vijayan, Ira Weiny, Rob Herring,
Lorenzo Pieralisi, Dave Jiang, linux-staging, Dexuan Cui,
Jernej Skrabec, Kishon Vijay Abraham I, Christian Borntraeger,
Chen-Yu Tsai, linux-input, Allen Hubbe, Alex Dubov, Haiyang Zhang,
Jiri Kosina, Russell King (Oracle), Ben Widawsky,
Harald Freudenberger, linux-cxl, Michael Buesch, Dan Williams,
Mauro Carvalho Chehab, Cristian Marussi, Thomas Bogendoerfer,
Martin K. Petersen, Martyn Welch, Dmitry Torokhov, linux-mmc,
linux-sunxi, Stefan Richter, Sudeep Holla, David S. Miller,
Sven Van Asbroeck, Rich Felker, kvm, Michael S. Tsirkin,
linux-remoteproc, Bjorn Andersson, sparclinux, Kirti Wankhede,
Andreas Noever, linux-i3c, linux1394-devel, Lee Jones,
Arnd Bergmann, linux-scsi, Marc Zyngier, Russell King,
Thorsten Scherer, Andy Gross, linux-serial, Jakub Kicinski,
linux-hyperv, Michael Jamet, Heiko Carstens, Johan Hovold,
Hans de Goede, Hannes Reinecke, Juergen Gross, linuxppc-dev,
Takashi Iwai, Alexandre Bounine, Vinod Koul, Mark Brown,
Vishal Verma, dmaengine, Moritz Fischer, Johannes Berg,
Maximilian Luz
Hello,
this is v4 of the final patch set for my effort to make struct
bus_type::remove return void.
The first four patches contain cleanups that make some of these
callbacks (more obviously) always return 0. They are acked by the
respective maintainers. Bjorn Helgaas explicitly asked to include the
pci patch (#1) into this series, so Greg taking this is fine. I assume
the s390 people are fine with Greg taking patches #2 to #4, too, they
didn't explicitly said so though.
The last patch actually changes the prototype and so touches quite some
drivers and has the potential to conflict with future developments, so I
consider it beneficial to put these patches into next soon. I expect
that it will be Greg who takes the complete series, he already confirmed
via irc (for v2) to look into this series.
The only change compared to v3 is in the fourth patch where I modified a
few more drivers to fix build failures. Some of them were found by build
bots (thanks!), some of them I found myself using a regular expression
search. The newly modified files are:
arch/sparc/kernel/vio.c
drivers/nubus/bus.c
drivers/sh/superhyway/superhyway.c
drivers/vlynq/vlynq.c
drivers/zorro/zorro-driver.c
sound/ac97/bus.c
Best regards
Uwe
Uwe Kleine-König (5):
PCI: endpoint: Make struct pci_epf_driver::remove return void
s390/cio: Make struct css_driver::remove return void
s390/ccwgroup: Drop if with an always false condition
s390/scm: Make struct scm_driver::remove return void
bus: Make remove callback return void
arch/arm/common/locomo.c | 3 +--
arch/arm/common/sa1111.c | 4 +---
arch/arm/mach-rpc/ecard.c | 4 +---
arch/mips/sgi-ip22/ip22-gio.c | 3 +--
arch/parisc/kernel/drivers.c | 5 ++---
arch/powerpc/platforms/ps3/system-bus.c | 3 +--
arch/powerpc/platforms/pseries/ibmebus.c | 3 +--
arch/powerpc/platforms/pseries/vio.c | 3 +--
arch/s390/include/asm/eadm.h | 2 +-
arch/sparc/kernel/vio.c | 4 +---
drivers/acpi/bus.c | 3 +--
drivers/amba/bus.c | 4 +---
drivers/base/auxiliary.c | 4 +---
drivers/base/isa.c | 4 +---
drivers/base/platform.c | 4 +---
drivers/bcma/main.c | 6 ++----
drivers/bus/sunxi-rsb.c | 4 +---
drivers/cxl/core.c | 3 +--
drivers/dax/bus.c | 4 +---
drivers/dma/idxd/sysfs.c | 4 +---
drivers/firewire/core-device.c | 4 +---
drivers/firmware/arm_scmi/bus.c | 4 +---
drivers/firmware/google/coreboot_table.c | 4 +---
drivers/fpga/dfl.c | 4 +---
drivers/hid/hid-core.c | 4 +---
drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +---
drivers/hv/vmbus_drv.c | 5 +----
drivers/hwtracing/intel_th/core.c | 4 +---
drivers/i2c/i2c-core-base.c | 5 +----
drivers/i3c/master.c | 4 +---
drivers/input/gameport/gameport.c | 3 +--
drivers/input/serio/serio.c | 3 +--
drivers/ipack/ipack.c | 4 +---
drivers/macintosh/macio_asic.c | 4 +---
drivers/mcb/mcb-core.c | 4 +---
drivers/media/pci/bt8xx/bttv-gpio.c | 3 +--
drivers/memstick/core/memstick.c | 3 +--
drivers/mfd/mcp-core.c | 3 +--
drivers/misc/mei/bus.c | 4 +---
drivers/misc/tifm_core.c | 3 +--
drivers/mmc/core/bus.c | 4 +---
drivers/mmc/core/sdio_bus.c | 4 +---
drivers/net/netdevsim/bus.c | 3 +--
drivers/ntb/core.c | 4 +---
drivers/ntb/ntb_transport.c | 4 +---
drivers/nubus/bus.c | 6 ++----
drivers/nvdimm/bus.c | 3 +--
drivers/pci/endpoint/pci-epf-core.c | 7 ++-----
drivers/pci/pci-driver.c | 3 +--
drivers/pcmcia/ds.c | 4 +---
drivers/platform/surface/aggregator/bus.c | 4 +---
drivers/platform/x86/wmi.c | 4 +---
drivers/pnp/driver.c | 3 +--
drivers/rapidio/rio-driver.c | 4 +---
drivers/rpmsg/rpmsg_core.c | 7 ++-----
drivers/s390/block/scm_drv.c | 4 +---
drivers/s390/cio/ccwgroup.c | 6 +-----
drivers/s390/cio/chsc_sch.c | 3 +--
drivers/s390/cio/css.c | 7 +++----
drivers/s390/cio/css.h | 2 +-
drivers/s390/cio/device.c | 9 +++------
drivers/s390/cio/eadm_sch.c | 4 +---
drivers/s390/cio/scm.c | 5 +++--
drivers/s390/cio/vfio_ccw_drv.c | 3 +--
drivers/s390/crypto/ap_bus.c | 4 +---
drivers/scsi/scsi_debug.c | 3 +--
drivers/sh/superhyway/superhyway.c | 8 ++------
drivers/siox/siox-core.c | 4 +---
drivers/slimbus/core.c | 4 +---
drivers/soc/qcom/apr.c | 4 +---
drivers/spi/spi.c | 4 +---
drivers/spmi/spmi.c | 3 +--
drivers/ssb/main.c | 4 +---
drivers/staging/fieldbus/anybuss/host.c | 4 +---
drivers/staging/greybus/gbphy.c | 4 +---
drivers/target/loopback/tcm_loop.c | 5 ++---
drivers/thunderbolt/domain.c | 4 +---
drivers/tty/serdev/core.c | 4 +---
drivers/usb/common/ulpi.c | 4 +---
drivers/usb/serial/bus.c | 4 +---
drivers/usb/typec/bus.c | 4 +---
drivers/vdpa/vdpa.c | 4 +---
drivers/vfio/mdev/mdev_driver.c | 4 +---
drivers/virtio/virtio.c | 3 +--
drivers/vlynq/vlynq.c | 4 +---
drivers/vme/vme.c | 4 +---
drivers/xen/xenbus/xenbus.h | 2 +-
drivers/xen/xenbus/xenbus_probe.c | 4 +---
drivers/zorro/zorro-driver.c | 3 +--
include/linux/device/bus.h | 2 +-
include/linux/pci-epf.h | 2 +-
sound/ac97/bus.c | 6 ++----
sound/aoa/soundbus/core.c | 4 +---
93 files changed, 107 insertions(+), 263 deletions(-)
base-commit: e73f0f0ee7541171d89f2e2491130c7771ba58d3
--
2.30.2
^ permalink raw reply
* [PATCH v4 5/5] bus: Make remove callback return void
From: Uwe Kleine-König @ 2021-07-13 19:35 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: nvdimm, linux-sh, Samuel Iglesias Gonsalvez, Jens Taprogge,
Ulf Hansson, Jaroslav Kysela, Benjamin Tissoires, Paul Mackerras,
Srinivas Pandruvada, K. Y. Srinivasan, Mike Christie, Wei Liu,
Maxim Levitsky, Samuel Holland, Rafael J . Wysocki, linux-acpi,
Geert Uytterhoeven, linux-pci, xen-devel, Tomas Winkler,
Julien Grall, Ohad Ben-Cohen, Yufen Yu, Alex Williamson,
Alex Elder, linux-parisc, Finn Thain, Geoff Levand, linux-fpga,
linux-usb, Rafael J. Wysocki, linux-kernel, linux-spi,
Kai-Heng Feng, kernel, Jon Mason, linux-ntb, Wu Hao,
David Woodhouse, Krzysztof Wilczyński, Alexandre Belloni,
Manohar Vanga, linux-wireless, Dominik Brodowski, virtualization,
James E.J. Bottomley, target-devel, Srinivas Kandagatla,
linux-i2c, linux-s390, Stefano Stabellini, Stephen Hemminger,
Yoshinori Sato, Jiri Slaby, Helge Deller, Rafał Miłecki,
YueHaibing, industrypack-devel, linux-mips, Len Brown,
Vasily Gorbik, linux-arm-msm, linux-media, Maxime Ripard,
William Breathitt Gray, greybus-dev, linux-m68k, Florian Fainelli,
Rikard Falkeborn, Frank Li, Mark Gross, Boris Ostrovsky,
Mika Westerberg, linux-arm-kernel, Johannes Thumshirn,
Mathieu Poirier, Stephen Boyd, Cornelia Huck, Peter Oberparleiter,
Wolfram Sang, Joey Pabalan, Yehezkel Bernat, Pali Rohár,
Bodo Stroesser, Alison Schofield, Heikki Krogerus, Tyrel Datwyler,
Alexander Shishkin, Tom Rix, Jason Wang, SeongJae Park,
alsa-devel, platform-driver-x86, Bjorn Helgaas, netdev,
Vineeth Vijayan, Ira Weiny, Rob Herring, Lorenzo Pieralisi,
Dave Jiang, linux-staging, Dexuan Cui, Jernej Skrabec,
Kishon Vijay Abraham I, Christian Borntraeger, Chen-Yu Tsai,
linux-input, Allen Hubbe, Alex Dubov, Haiyang Zhang, Jiri Kosina,
Russell King (Oracle), Ben Widawsky, Harald Freudenberger,
linux-cxl, Michael Buesch, Dan Williams, Mauro Carvalho Chehab,
Cristian Marussi, Thomas Bogendoerfer, Martin K. Petersen,
Martyn Welch, Dmitry Torokhov, linux-mmc, linux-sunxi,
Stefan Richter, Sudeep Holla, David S. Miller, Sven Van Asbroeck,
Rich Felker, kvm, Michael S. Tsirkin, linux-remoteproc,
Bjorn Andersson, sparclinux, Kirti Wankhede, Andreas Noever,
linux-i3c, linux1394-devel, Lee Jones, Arnd Bergmann, linux-scsi,
Marc Zyngier, Russell King, Thorsten Scherer, Andy Gross,
linux-serial, Jakub Kicinski, linux-hyperv, Michael Jamet,
Heiko Carstens, Johan Hovold, Hans de Goede, Hannes Reinecke,
Juergen Gross, linuxppc-dev, Takashi Iwai, Alexandre Bounine,
Vinod Koul, Mark Brown, Vishal Verma, dmaengine, Moritz Fischer,
Johannes Berg, Johannes Thumshirn, Maximilian Luz
In-Reply-To: <20210713193522.1770306-1-u.kleine-koenig@pengutronix.de>
The driver core ignores the return value of this callback because there
is only little it can do when a device disappears.
This is the final bit of a long lasting cleanup quest where several
buses were converted to also return void from their remove callback.
Additionally some resource leaks were fixed that were caused by drivers
returning an error code in the expectation that the driver won't go
away.
With struct bus_type::remove returning void it's prevented that newly
implemented buses return an ignored error code and so don't anticipate
wrong expectations for driver authors.
Acked-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> (For ARM, Amba and related parts)
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org> (for sunxi-rsb)
Acked-by: Pali Rohár <pali@kernel.org>
Acked-by: Mauro Carvalho Chehab <mchehab@kernel.org> (for media)
Acked-by: Hans de Goede <hdegoede@redhat.com> (For drivers/platform)
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-By: Vinod Koul <vkoul@kernel.org>
Acked-by: Juergen Gross <jgross@suse.com> (For xen)
Acked-by: Lee Jones <lee.jones@linaro.org> (For mfd)
Acked-by: Johannes Thumshirn <jth@kernel.org> (For mcb)
Acked-by: Johan Hovold <johan@kernel.org>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> (For slimbus)
Acked-by: Kirti Wankhede <kwankhede@nvidia.com> (For vfio)
Acked-by: Maximilian Luz <luzmaximilian@gmail.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> (For ulpi and typec)
Acked-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> (For ipack)
Reviewed-by: Tom Rix <trix@redhat.com> (For fpga)
Acked-by: Geoff Levand <geoff@infradead.org> (For ps3)
Acked-by: Yehezkel Bernat <YehezkelShB@gmail.com> (For thunderbolt)
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> (For intel_th)
Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> (For pcmcia)
Reviewed-by: Cornelia Huck <cohuck@redhat.com> (For drivers/s390 and drivers/vfio)
Acked-by: Rafael J. Wysocki <rafael@kernel.org> (For ACPI)
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org> (rpmsg and apr)
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> (For intel-ish-hid)
Acked-by: Dan Williams <dan.j.williams@intel.com> (For CXL, DAX, and NVDIMM)
Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com> (For isa)
Acked-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (For firewire)
Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> (For hid)
Acked-by: Thorsten Scherer <t.scherer@eckelmann.de> (For siox)
Acked-by: Sven Van Asbroeck <TheSven73@gmail.com> (For anybuss)
Acked-by: Ulf Hansson <ulf.hansson@linaro.org> (For MMC)
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/arm/common/locomo.c | 3 +--
arch/arm/common/sa1111.c | 4 +---
arch/arm/mach-rpc/ecard.c | 4 +---
arch/mips/sgi-ip22/ip22-gio.c | 3 +--
arch/parisc/kernel/drivers.c | 5 ++---
arch/powerpc/platforms/ps3/system-bus.c | 3 +--
arch/powerpc/platforms/pseries/ibmebus.c | 3 +--
arch/powerpc/platforms/pseries/vio.c | 3 +--
arch/sparc/kernel/vio.c | 4 +---
drivers/acpi/bus.c | 3 +--
drivers/amba/bus.c | 4 +---
drivers/base/auxiliary.c | 4 +---
drivers/base/isa.c | 4 +---
drivers/base/platform.c | 4 +---
drivers/bcma/main.c | 6 ++----
drivers/bus/sunxi-rsb.c | 4 +---
drivers/cxl/core.c | 3 +--
drivers/dax/bus.c | 4 +---
drivers/dma/idxd/sysfs.c | 4 +---
drivers/firewire/core-device.c | 4 +---
drivers/firmware/arm_scmi/bus.c | 4 +---
drivers/firmware/google/coreboot_table.c | 4 +---
drivers/fpga/dfl.c | 4 +---
drivers/hid/hid-core.c | 4 +---
drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +---
drivers/hv/vmbus_drv.c | 5 +----
drivers/hwtracing/intel_th/core.c | 4 +---
drivers/i2c/i2c-core-base.c | 5 +----
drivers/i3c/master.c | 4 +---
drivers/input/gameport/gameport.c | 3 +--
drivers/input/serio/serio.c | 3 +--
drivers/ipack/ipack.c | 4 +---
drivers/macintosh/macio_asic.c | 4 +---
drivers/mcb/mcb-core.c | 4 +---
drivers/media/pci/bt8xx/bttv-gpio.c | 3 +--
drivers/memstick/core/memstick.c | 3 +--
drivers/mfd/mcp-core.c | 3 +--
drivers/misc/mei/bus.c | 4 +---
drivers/misc/tifm_core.c | 3 +--
drivers/mmc/core/bus.c | 4 +---
drivers/mmc/core/sdio_bus.c | 4 +---
drivers/net/netdevsim/bus.c | 3 +--
drivers/ntb/core.c | 4 +---
drivers/ntb/ntb_transport.c | 4 +---
drivers/nubus/bus.c | 6 ++----
drivers/nvdimm/bus.c | 3 +--
drivers/pci/endpoint/pci-epf-core.c | 4 +---
drivers/pci/pci-driver.c | 3 +--
drivers/pcmcia/ds.c | 4 +---
drivers/platform/surface/aggregator/bus.c | 4 +---
drivers/platform/x86/wmi.c | 4 +---
drivers/pnp/driver.c | 3 +--
drivers/rapidio/rio-driver.c | 4 +---
drivers/rpmsg/rpmsg_core.c | 7 ++-----
drivers/s390/cio/ccwgroup.c | 4 +---
drivers/s390/cio/css.c | 4 +---
drivers/s390/cio/device.c | 4 +---
drivers/s390/cio/scm.c | 4 +---
drivers/s390/crypto/ap_bus.c | 4 +---
drivers/scsi/scsi_debug.c | 3 +--
drivers/sh/superhyway/superhyway.c | 8 ++------
drivers/siox/siox-core.c | 4 +---
drivers/slimbus/core.c | 4 +---
drivers/soc/qcom/apr.c | 4 +---
drivers/spi/spi.c | 4 +---
drivers/spmi/spmi.c | 3 +--
drivers/ssb/main.c | 4 +---
drivers/staging/fieldbus/anybuss/host.c | 4 +---
drivers/staging/greybus/gbphy.c | 4 +---
drivers/target/loopback/tcm_loop.c | 5 ++---
drivers/thunderbolt/domain.c | 4 +---
drivers/tty/serdev/core.c | 4 +---
drivers/usb/common/ulpi.c | 4 +---
drivers/usb/serial/bus.c | 4 +---
drivers/usb/typec/bus.c | 4 +---
drivers/vdpa/vdpa.c | 4 +---
drivers/vfio/mdev/mdev_driver.c | 4 +---
drivers/virtio/virtio.c | 3 +--
drivers/vlynq/vlynq.c | 4 +---
drivers/vme/vme.c | 4 +---
drivers/xen/xenbus/xenbus.h | 2 +-
drivers/xen/xenbus/xenbus_probe.c | 4 +---
drivers/zorro/zorro-driver.c | 3 +--
include/linux/device/bus.h | 2 +-
sound/ac97/bus.c | 6 ++----
sound/aoa/soundbus/core.c | 4 +---
86 files changed, 93 insertions(+), 243 deletions(-)
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index e45f4e4e06b6..24d21ba63030 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -834,14 +834,13 @@ static int locomo_bus_probe(struct device *dev)
return ret;
}
-static int locomo_bus_remove(struct device *dev)
+static void locomo_bus_remove(struct device *dev)
{
struct locomo_dev *ldev = LOCOMO_DEV(dev);
struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
if (drv->remove)
drv->remove(ldev);
- return 0;
}
struct bus_type locomo_bus_type = {
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ff5e0d04cb89..092a2ebc0c28 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1364,15 +1364,13 @@ static int sa1111_bus_probe(struct device *dev)
return ret;
}
-static int sa1111_bus_remove(struct device *dev)
+static void sa1111_bus_remove(struct device *dev)
{
struct sa1111_dev *sadev = to_sa1111_device(dev);
struct sa1111_driver *drv = SA1111_DRV(dev->driver);
if (drv->remove)
drv->remove(sadev);
-
- return 0;
}
struct bus_type sa1111_bus_type = {
diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c
index 827b50f1c73e..53813f9464a2 100644
--- a/arch/arm/mach-rpc/ecard.c
+++ b/arch/arm/mach-rpc/ecard.c
@@ -1052,7 +1052,7 @@ static int ecard_drv_probe(struct device *dev)
return ret;
}
-static int ecard_drv_remove(struct device *dev)
+static void ecard_drv_remove(struct device *dev)
{
struct expansion_card *ec = ECARD_DEV(dev);
struct ecard_driver *drv = ECARD_DRV(dev->driver);
@@ -1067,8 +1067,6 @@ static int ecard_drv_remove(struct device *dev)
ec->ops = &ecard_default_ops;
barrier();
ec->irq_data = NULL;
-
- return 0;
}
/*
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
index de0768a49ee8..dfc52f661ad0 100644
--- a/arch/mips/sgi-ip22/ip22-gio.c
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -143,14 +143,13 @@ static int gio_device_probe(struct device *dev)
return error;
}
-static int gio_device_remove(struct device *dev)
+static void gio_device_remove(struct device *dev)
{
struct gio_device *gio_dev = to_gio_device(dev);
struct gio_driver *drv = to_gio_driver(dev->driver);
if (dev->driver && drv->remove)
drv->remove(gio_dev);
- return 0;
}
static void gio_device_shutdown(struct device *dev)
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 80fa0650736b..776d624a7207 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -133,14 +133,13 @@ static int parisc_driver_probe(struct device *dev)
return rc;
}
-static int __exit parisc_driver_remove(struct device *dev)
+static void __exit parisc_driver_remove(struct device *dev)
{
struct parisc_device *pa_dev = to_parisc_device(dev);
struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+
if (pa_drv->remove)
pa_drv->remove(pa_dev);
-
- return 0;
}
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 1a5665875165..cc5774c64fae 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -381,7 +381,7 @@ static int ps3_system_bus_probe(struct device *_dev)
return result;
}
-static int ps3_system_bus_remove(struct device *_dev)
+static void ps3_system_bus_remove(struct device *_dev)
{
struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
struct ps3_system_bus_driver *drv;
@@ -399,7 +399,6 @@ static int ps3_system_bus_remove(struct device *_dev)
__func__, __LINE__, drv->core.name);
pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev_name(&dev->core));
- return 0;
}
static void ps3_system_bus_shutdown(struct device *_dev)
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index c6c79ef55e13..7ee3ed7d6cc2 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -366,14 +366,13 @@ static int ibmebus_bus_device_probe(struct device *dev)
return error;
}
-static int ibmebus_bus_device_remove(struct device *dev)
+static void ibmebus_bus_device_remove(struct device *dev)
{
struct platform_device *of_dev = to_platform_device(dev);
struct platform_driver *drv = to_platform_driver(dev->driver);
if (dev->driver && drv->remove)
drv->remove(of_dev);
- return 0;
}
static void ibmebus_bus_device_shutdown(struct device *dev)
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index e00f3725ec96..58283cecbd52 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -1257,7 +1257,7 @@ static int vio_bus_probe(struct device *dev)
}
/* convert from struct device to struct vio_dev and pass to driver. */
-static int vio_bus_remove(struct device *dev)
+static void vio_bus_remove(struct device *dev)
{
struct vio_dev *viodev = to_vio_dev(dev);
struct vio_driver *viodrv = to_vio_driver(dev->driver);
@@ -1276,7 +1276,6 @@ static int vio_bus_remove(struct device *dev)
vio_cmo_bus_remove(viodev);
put_device(devptr);
- return 0;
}
static void vio_bus_shutdown(struct device *dev)
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c
index 348a88691219..01122a208f94 100644
--- a/arch/sparc/kernel/vio.c
+++ b/arch/sparc/kernel/vio.c
@@ -93,7 +93,7 @@ static int vio_device_probe(struct device *dev)
return drv->probe(vdev, id);
}
-static int vio_device_remove(struct device *dev)
+static void vio_device_remove(struct device *dev)
{
struct vio_dev *vdev = to_vio_dev(dev);
struct vio_driver *drv = to_vio_driver(dev->driver);
@@ -107,8 +107,6 @@ static int vio_device_remove(struct device *dev)
drv->remove(vdev);
}
-
- return 0;
}
static ssize_t devspec_show(struct device *dev,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index f854bcb8d010..b941555cb5e4 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1019,7 +1019,7 @@ static int acpi_device_probe(struct device *dev)
return 0;
}
-static int acpi_device_remove(struct device *dev)
+static void acpi_device_remove(struct device *dev)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
struct acpi_driver *acpi_drv = acpi_dev->driver;
@@ -1034,7 +1034,6 @@ static int acpi_device_remove(struct device *dev)
acpi_dev->driver_data = NULL;
put_device(dev);
- return 0;
}
struct bus_type acpi_bus_type = {
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 939ca220bf78..962041148482 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -219,7 +219,7 @@ static int amba_probe(struct device *dev)
return ret;
}
-static int amba_remove(struct device *dev)
+static void amba_remove(struct device *dev)
{
struct amba_device *pcdev = to_amba_device(dev);
struct amba_driver *drv = to_amba_driver(dev->driver);
@@ -236,8 +236,6 @@ static int amba_remove(struct device *dev)
amba_put_disable_pclk(pcdev);
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void amba_shutdown(struct device *dev)
diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index adc199dfba3c..0c86f5bed9f4 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -79,7 +79,7 @@ static int auxiliary_bus_probe(struct device *dev)
return ret;
}
-static int auxiliary_bus_remove(struct device *dev)
+static void auxiliary_bus_remove(struct device *dev)
{
struct auxiliary_driver *auxdrv = to_auxiliary_drv(dev->driver);
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@@ -87,8 +87,6 @@ static int auxiliary_bus_remove(struct device *dev)
if (auxdrv->remove)
auxdrv->remove(auxdev);
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void auxiliary_bus_shutdown(struct device *dev)
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
index aa4737667026..55e3ee2da98f 100644
--- a/drivers/base/isa.c
+++ b/drivers/base/isa.c
@@ -46,14 +46,12 @@ static int isa_bus_probe(struct device *dev)
return 0;
}
-static int isa_bus_remove(struct device *dev)
+static void isa_bus_remove(struct device *dev)
{
struct isa_driver *isa_driver = dev->platform_data;
if (isa_driver && isa_driver->remove)
isa_driver->remove(dev, to_isa_dev(dev)->id);
-
- return 0;
}
static void isa_bus_shutdown(struct device *dev)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8640578f45e9..a94b7f454881 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1438,7 +1438,7 @@ static int platform_probe(struct device *_dev)
return ret;
}
-static int platform_remove(struct device *_dev)
+static void platform_remove(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
@@ -1450,8 +1450,6 @@ static int platform_remove(struct device *_dev)
dev_warn(_dev, "remove callback returned a non-zero value. This will be ignored.\n");
}
dev_pm_domain_detach(_dev, true);
-
- return 0;
}
static void platform_shutdown(struct device *_dev)
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 6535614a7dc1..e076630d17bd 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -27,7 +27,7 @@ static DEFINE_MUTEX(bcma_buses_mutex);
static int bcma_bus_match(struct device *dev, struct device_driver *drv);
static int bcma_device_probe(struct device *dev);
-static int bcma_device_remove(struct device *dev);
+static void bcma_device_remove(struct device *dev);
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -614,7 +614,7 @@ static int bcma_device_probe(struct device *dev)
return err;
}
-static int bcma_device_remove(struct device *dev)
+static void bcma_device_remove(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
@@ -623,8 +623,6 @@ static int bcma_device_remove(struct device *dev)
if (adrv->remove)
adrv->remove(core);
put_device(dev);
-
- return 0;
}
static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
index d46db132d085..6f225dddc74f 100644
--- a/drivers/bus/sunxi-rsb.c
+++ b/drivers/bus/sunxi-rsb.c
@@ -169,13 +169,11 @@ static int sunxi_rsb_device_probe(struct device *dev)
return drv->probe(rdev);
}
-static int sunxi_rsb_device_remove(struct device *dev)
+static void sunxi_rsb_device_remove(struct device *dev)
{
const struct sunxi_rsb_driver *drv = to_sunxi_rsb_driver(dev->driver);
drv->remove(to_sunxi_rsb_device(dev));
-
- return 0;
}
static struct bus_type sunxi_rsb_bus = {
diff --git a/drivers/cxl/core.c b/drivers/cxl/core.c
index a2e4d54fc7bc..2b90b7c3b9d7 100644
--- a/drivers/cxl/core.c
+++ b/drivers/cxl/core.c
@@ -1034,13 +1034,12 @@ static int cxl_bus_probe(struct device *dev)
return to_cxl_drv(dev->driver)->probe(dev);
}
-static int cxl_bus_remove(struct device *dev)
+static void cxl_bus_remove(struct device *dev)
{
struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver);
if (cxl_drv->remove)
cxl_drv->remove(dev);
- return 0;
}
struct bus_type cxl_bus_type = {
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
index 5aee26e1bbd6..6cc4da4c713d 100644
--- a/drivers/dax/bus.c
+++ b/drivers/dax/bus.c
@@ -172,15 +172,13 @@ static int dax_bus_probe(struct device *dev)
return 0;
}
-static int dax_bus_remove(struct device *dev)
+static void dax_bus_remove(struct device *dev)
{
struct dax_device_driver *dax_drv = to_dax_drv(dev->driver);
struct dev_dax *dev_dax = to_dev_dax(dev);
if (dax_drv->remove)
dax_drv->remove(dev_dax);
-
- return 0;
}
static struct bus_type dax_bus_type = {
diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
index 0460d58e3941..5a017c62c752 100644
--- a/drivers/dma/idxd/sysfs.c
+++ b/drivers/dma/idxd/sysfs.c
@@ -260,7 +260,7 @@ static void disable_wq(struct idxd_wq *wq)
dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev));
}
-static int idxd_config_bus_remove(struct device *dev)
+static void idxd_config_bus_remove(struct device *dev)
{
int rc;
@@ -305,8 +305,6 @@ static int idxd_config_bus_remove(struct device *dev)
dev_info(dev, "Device %s disabled\n", dev_name(dev));
}
-
- return 0;
}
static void idxd_config_bus_shutdown(struct device *dev)
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 68216988391f..90ed8fdaba75 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -187,14 +187,12 @@ static int fw_unit_probe(struct device *dev)
return driver->probe(fw_unit(dev), unit_match(dev, dev->driver));
}
-static int fw_unit_remove(struct device *dev)
+static void fw_unit_remove(struct device *dev)
{
struct fw_driver *driver =
container_of(dev->driver, struct fw_driver, driver);
driver->remove(fw_unit(dev));
-
- return 0;
}
static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index 784cf0027da3..2682c3df651c 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -116,15 +116,13 @@ static int scmi_dev_probe(struct device *dev)
return scmi_drv->probe(scmi_dev);
}
-static int scmi_dev_remove(struct device *dev)
+static void scmi_dev_remove(struct device *dev)
{
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
struct scmi_device *scmi_dev = to_scmi_dev(dev);
if (scmi_drv->remove)
scmi_drv->remove(scmi_dev);
-
- return 0;
}
static struct bus_type scmi_bus_type = {
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index dc83ea118c67..c52bcaa9def6 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -44,15 +44,13 @@ static int coreboot_bus_probe(struct device *dev)
return ret;
}
-static int coreboot_bus_remove(struct device *dev)
+static void coreboot_bus_remove(struct device *dev)
{
struct coreboot_device *device = CB_DEV(dev);
struct coreboot_driver *driver = CB_DRV(dev->driver);
if (driver->remove)
driver->remove(device);
-
- return 0;
}
static struct bus_type coreboot_bus_type = {
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index 511b20ff35a3..1ae6779a0dd6 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -284,15 +284,13 @@ static int dfl_bus_probe(struct device *dev)
return ddrv->probe(ddev);
}
-static int dfl_bus_remove(struct device *dev)
+static void dfl_bus_remove(struct device *dev)
{
struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
struct dfl_device *ddev = to_dfl_dev(dev);
if (ddrv->remove)
ddrv->remove(ddev);
-
- return 0;
}
static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 7db332139f7d..dbed2524fd47 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2302,7 +2302,7 @@ static int hid_device_probe(struct device *dev)
return ret;
}
-static int hid_device_remove(struct device *dev)
+static void hid_device_remove(struct device *dev)
{
struct hid_device *hdev = to_hid_device(dev);
struct hid_driver *hdrv;
@@ -2322,8 +2322,6 @@ static int hid_device_remove(struct device *dev)
if (!hdev->io_started)
up(&hdev->driver_input_lock);
-
- return 0;
}
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c
index f0802b047ed8..8a51bd9cd093 100644
--- a/drivers/hid/intel-ish-hid/ishtp/bus.c
+++ b/drivers/hid/intel-ish-hid/ishtp/bus.c
@@ -255,7 +255,7 @@ static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
*
* Return: Return value from driver remove() call.
*/
-static int ishtp_cl_device_remove(struct device *dev)
+static void ishtp_cl_device_remove(struct device *dev)
{
struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
struct ishtp_cl_driver *driver = to_ishtp_cl_driver(dev->driver);
@@ -267,8 +267,6 @@ static int ishtp_cl_device_remove(struct device *dev)
if (driver->remove)
driver->remove(device);
-
- return 0;
}
/**
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 57bbbaa4e8f7..392c1ac4f819 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -922,7 +922,7 @@ static int vmbus_probe(struct device *child_device)
/*
* vmbus_remove - Remove a vmbus device
*/
-static int vmbus_remove(struct device *child_device)
+static void vmbus_remove(struct device *child_device)
{
struct hv_driver *drv;
struct hv_device *dev = device_to_hv_device(child_device);
@@ -932,11 +932,8 @@ static int vmbus_remove(struct device *child_device)
if (drv->remove)
drv->remove(dev);
}
-
- return 0;
}
-
/*
* vmbus_shutdown - Shutdown a vmbus device
*/
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 66eed2dff818..7e753a75d23b 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -95,7 +95,7 @@ static int intel_th_probe(struct device *dev)
static void intel_th_device_remove(struct intel_th_device *thdev);
-static int intel_th_remove(struct device *dev)
+static void intel_th_remove(struct device *dev)
{
struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver);
struct intel_th_device *thdev = to_intel_th_device(dev);
@@ -164,8 +164,6 @@ static int intel_th_remove(struct device *dev)
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
-
- return 0;
}
static struct bus_type intel_th_bus = {
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 84f12bf90644..54964fbe3f03 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -601,7 +601,7 @@ static int i2c_device_probe(struct device *dev)
return status;
}
-static int i2c_device_remove(struct device *dev)
+static void i2c_device_remove(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_adapter *adap;
@@ -631,9 +631,6 @@ static int i2c_device_remove(struct device *dev)
client->irq = 0;
if (client->flags & I2C_CLIENT_HOST_NOTIFY)
pm_runtime_put(&client->adapter->dev);
-
- /* return always 0 because there is WIP to make remove-functions void */
- return 0;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index e2e12a5585e5..c3b4c677b442 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -322,7 +322,7 @@ static int i3c_device_probe(struct device *dev)
return driver->probe(i3cdev);
}
-static int i3c_device_remove(struct device *dev)
+static void i3c_device_remove(struct device *dev)
{
struct i3c_device *i3cdev = dev_to_i3cdev(dev);
struct i3c_driver *driver = drv_to_i3cdrv(dev->driver);
@@ -331,8 +331,6 @@ static int i3c_device_remove(struct device *dev)
driver->remove(i3cdev);
i3c_device_free_ibi(i3cdev);
-
- return 0;
}
struct bus_type i3c_bus_type = {
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 61fa7e724172..db58a01b23d3 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -697,13 +697,12 @@ static int gameport_driver_probe(struct device *dev)
return gameport->drv ? 0 : -ENODEV;
}
-static int gameport_driver_remove(struct device *dev)
+static void gameport_driver_remove(struct device *dev)
{
struct gameport *gameport = to_gameport_port(dev);
struct gameport_driver *drv = to_gameport_driver(dev->driver);
drv->disconnect(gameport);
- return 0;
}
static void gameport_attach_driver(struct gameport_driver *drv)
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 29f491082926..ec117be3d8d8 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -778,12 +778,11 @@ static int serio_driver_probe(struct device *dev)
return serio_connect_driver(serio, drv);
}
-static int serio_driver_remove(struct device *dev)
+static void serio_driver_remove(struct device *dev)
{
struct serio *serio = to_serio_port(dev);
serio_disconnect_driver(serio);
- return 0;
}
static void serio_cleanup(struct serio *serio)
diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c
index 7de9605cac4f..b1c3198355e7 100644
--- a/drivers/ipack/ipack.c
+++ b/drivers/ipack/ipack.c
@@ -67,15 +67,13 @@ static int ipack_bus_probe(struct device *device)
return drv->ops->probe(dev);
}
-static int ipack_bus_remove(struct device *device)
+static void ipack_bus_remove(struct device *device)
{
struct ipack_device *dev = to_ipack_dev(device);
struct ipack_driver *drv = to_ipack_driver(device->driver);
if (drv->ops->remove)
drv->ops->remove(dev);
-
- return 0;
}
static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 49af60bdac92..c1fdf2896021 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -88,7 +88,7 @@ static int macio_device_probe(struct device *dev)
return error;
}
-static int macio_device_remove(struct device *dev)
+static void macio_device_remove(struct device *dev)
{
struct macio_dev * macio_dev = to_macio_device(dev);
struct macio_driver * drv = to_macio_driver(dev->driver);
@@ -96,8 +96,6 @@ static int macio_device_remove(struct device *dev)
if (dev->driver && drv->remove)
drv->remove(macio_dev);
macio_dev_put(macio_dev);
-
- return 0;
}
static void macio_device_shutdown(struct device *dev)
diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
index 38fbb3b59873..edf4ee6eff25 100644
--- a/drivers/mcb/mcb-core.c
+++ b/drivers/mcb/mcb-core.c
@@ -77,7 +77,7 @@ static int mcb_probe(struct device *dev)
return ret;
}
-static int mcb_remove(struct device *dev)
+static void mcb_remove(struct device *dev)
{
struct mcb_driver *mdrv = to_mcb_driver(dev->driver);
struct mcb_device *mdev = to_mcb_device(dev);
@@ -89,8 +89,6 @@ static int mcb_remove(struct device *dev)
module_put(carrier_mod);
put_device(&mdev->dev);
-
- return 0;
}
static void mcb_shutdown(struct device *dev)
diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c
index b730225ca887..a2b18e2bed1b 100644
--- a/drivers/media/pci/bt8xx/bttv-gpio.c
+++ b/drivers/media/pci/bt8xx/bttv-gpio.c
@@ -46,14 +46,13 @@ static int bttv_sub_probe(struct device *dev)
return sub->probe ? sub->probe(sdev) : -ENODEV;
}
-static int bttv_sub_remove(struct device *dev)
+static void bttv_sub_remove(struct device *dev)
{
struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
if (sub->remove)
sub->remove(sdev);
- return 0;
}
struct bus_type bttv_sub_bus_type = {
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
index bb1065990aeb..660df7d269fa 100644
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -91,7 +91,7 @@ static int memstick_device_probe(struct device *dev)
return rc;
}
-static int memstick_device_remove(struct device *dev)
+static void memstick_device_remove(struct device *dev)
{
struct memstick_dev *card = container_of(dev, struct memstick_dev,
dev);
@@ -105,7 +105,6 @@ static int memstick_device_remove(struct device *dev)
}
put_device(dev);
- return 0;
}
#ifdef CONFIG_PM
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index eff9423e90f5..2fa592c37c6f 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -33,13 +33,12 @@ static int mcp_bus_probe(struct device *dev)
return drv->probe(mcp);
}
-static int mcp_bus_remove(struct device *dev)
+static void mcp_bus_remove(struct device *dev)
{
struct mcp *mcp = to_mcp(dev);
struct mcp_driver *drv = to_mcp_driver(dev->driver);
drv->remove(mcp);
- return 0;
}
static struct bus_type mcp_bus_type = {
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 935acc6bbf3c..3bf2bb4fd152 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -884,7 +884,7 @@ static int mei_cl_device_probe(struct device *dev)
*
* Return: 0 on success; < 0 otherwise
*/
-static int mei_cl_device_remove(struct device *dev)
+static void mei_cl_device_remove(struct device *dev)
{
struct mei_cl_device *cldev = to_mei_cl_device(dev);
struct mei_cl_driver *cldrv = to_mei_cl_driver(dev->driver);
@@ -896,8 +896,6 @@ static int mei_cl_device_remove(struct device *dev)
mei_cl_bus_module_put(cldev);
module_put(THIS_MODULE);
-
- return 0;
}
static ssize_t name_show(struct device *dev, struct device_attribute *a,
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index 667e574a7df2..52656fc87e99 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -87,7 +87,7 @@ static void tifm_dummy_event(struct tifm_dev *sock)
return;
}
-static int tifm_device_remove(struct device *dev)
+static void tifm_device_remove(struct device *dev)
{
struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
@@ -101,7 +101,6 @@ static int tifm_device_remove(struct device *dev)
}
put_device(dev);
- return 0;
}
#ifdef CONFIG_PM
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 4383c262b3f5..f6b7a9c5bbff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -140,14 +140,12 @@ static int mmc_bus_probe(struct device *dev)
return drv->probe(card);
}
-static int mmc_bus_remove(struct device *dev)
+static void mmc_bus_remove(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
drv->remove(card);
-
- return 0;
}
static void mmc_bus_shutdown(struct device *dev)
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 3d709029e07c..fda03b35c14a 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -203,7 +203,7 @@ static int sdio_bus_probe(struct device *dev)
return ret;
}
-static int sdio_bus_remove(struct device *dev)
+static void sdio_bus_remove(struct device *dev)
{
struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev);
@@ -232,8 +232,6 @@ static int sdio_bus_remove(struct device *dev)
pm_runtime_put_sync(dev);
dev_pm_domain_detach(dev, false);
-
- return 0;
}
static const struct dev_pm_ops sdio_bus_pm_ops = {
diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
index ccec29970d5b..14b154929533 100644
--- a/drivers/net/netdevsim/bus.c
+++ b/drivers/net/netdevsim/bus.c
@@ -370,12 +370,11 @@ static int nsim_bus_probe(struct device *dev)
return nsim_dev_probe(nsim_bus_dev);
}
-static int nsim_bus_remove(struct device *dev)
+static void nsim_bus_remove(struct device *dev)
{
struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
nsim_dev_remove(nsim_bus_dev);
- return 0;
}
static int nsim_num_vf(struct device *dev)
diff --git a/drivers/ntb/core.c b/drivers/ntb/core.c
index f8f75a504a58..27dd93deff6e 100644
--- a/drivers/ntb/core.c
+++ b/drivers/ntb/core.c
@@ -271,7 +271,7 @@ static int ntb_probe(struct device *dev)
return rc;
}
-static int ntb_remove(struct device *dev)
+static void ntb_remove(struct device *dev)
{
struct ntb_dev *ntb;
struct ntb_client *client;
@@ -283,8 +283,6 @@ static int ntb_remove(struct device *dev)
client->ops.remove(client, ntb);
put_device(dev);
}
-
- return 0;
}
static void ntb_dev_release(struct device *dev)
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 4a02561cfb96..a9b97ebc71ac 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -304,7 +304,7 @@ static int ntb_transport_bus_probe(struct device *dev)
return rc;
}
-static int ntb_transport_bus_remove(struct device *dev)
+static void ntb_transport_bus_remove(struct device *dev)
{
const struct ntb_transport_client *client;
@@ -312,8 +312,6 @@ static int ntb_transport_bus_remove(struct device *dev)
client->remove(dev);
put_device(dev);
-
- return 0;
}
static struct bus_type ntb_transport_bus = {
diff --git a/drivers/nubus/bus.c b/drivers/nubus/bus.c
index ad3d17c42e23..d9d04f27f89b 100644
--- a/drivers/nubus/bus.c
+++ b/drivers/nubus/bus.c
@@ -29,14 +29,12 @@ static int nubus_device_probe(struct device *dev)
return err;
}
-static int nubus_device_remove(struct device *dev)
+static void nubus_device_remove(struct device *dev)
{
struct nubus_driver *ndrv = to_nubus_driver(dev->driver);
- int err = -ENODEV;
if (dev->driver && ndrv->remove)
- err = ndrv->remove(to_nubus_board(dev));
- return err;
+ ndrv->remove(to_nubus_board(dev));
}
struct bus_type nubus_bus_type = {
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index e6aa87043a95..9dc7f3edd42b 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -108,7 +108,7 @@ static int nvdimm_bus_probe(struct device *dev)
return rc;
}
-static int nvdimm_bus_remove(struct device *dev)
+static void nvdimm_bus_remove(struct device *dev)
{
struct nd_device_driver *nd_drv = to_nd_device_driver(dev->driver);
struct module *provider = to_bus_provider(dev);
@@ -123,7 +123,6 @@ static int nvdimm_bus_remove(struct device *dev)
dev_dbg(&nvdimm_bus->dev, "%s.remove(%s)\n", dev->driver->name,
dev_name(dev));
module_put(provider);
- return 0;
}
static void nvdimm_bus_shutdown(struct device *dev)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index 4b9ad96bf1b2..502eb79cd551 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -387,7 +387,7 @@ static int pci_epf_device_probe(struct device *dev)
return driver->probe(epf);
}
-static int pci_epf_device_remove(struct device *dev)
+static void pci_epf_device_remove(struct device *dev)
{
struct pci_epf *epf = to_pci_epf(dev);
struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
@@ -395,8 +395,6 @@ static int pci_epf_device_remove(struct device *dev)
if (driver->remove)
driver->remove(epf);
epf->driver = NULL;
-
- return 0;
}
static struct bus_type pci_epf_bus_type = {
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3a72352aa5cf..a0615395500a 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -440,7 +440,7 @@ static int pci_device_probe(struct device *dev)
return error;
}
-static int pci_device_remove(struct device *dev)
+static void pci_device_remove(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *drv = pci_dev->driver;
@@ -476,7 +476,6 @@ static int pci_device_remove(struct device *dev)
*/
pci_dev_put(pci_dev);
- return 0;
}
static void pci_device_shutdown(struct device *dev)
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index bd81aa64d011..5bd1b80424e7 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -350,7 +350,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
return;
}
-static int pcmcia_device_remove(struct device *dev)
+static void pcmcia_device_remove(struct device *dev)
{
struct pcmcia_device *p_dev;
struct pcmcia_driver *p_drv;
@@ -389,8 +389,6 @@ static int pcmcia_device_remove(struct device *dev)
/* references from pcmcia_device_probe */
pcmcia_put_dev(p_dev);
module_put(p_drv->owner);
-
- return 0;
}
diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
index 0169677c243e..0a40dd9c94ed 100644
--- a/drivers/platform/surface/aggregator/bus.c
+++ b/drivers/platform/surface/aggregator/bus.c
@@ -316,14 +316,12 @@ static int ssam_bus_probe(struct device *dev)
->probe(to_ssam_device(dev));
}
-static int ssam_bus_remove(struct device *dev)
+static void ssam_bus_remove(struct device *dev)
{
struct ssam_device_driver *sdrv = to_ssam_device_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_ssam_device(dev));
-
- return 0;
}
struct bus_type ssam_bus_type = {
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 62e0d56a3332..a76313006bdc 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -980,7 +980,7 @@ static int wmi_dev_probe(struct device *dev)
return ret;
}
-static int wmi_dev_remove(struct device *dev)
+static void wmi_dev_remove(struct device *dev)
{
struct wmi_block *wblock = dev_to_wblock(dev);
struct wmi_driver *wdriver =
@@ -997,8 +997,6 @@ static int wmi_dev_remove(struct device *dev)
if (ACPI_FAILURE(wmi_method_enable(wblock, 0)))
dev_warn(dev, "failed to disable device\n");
-
- return 0;
}
static struct class wmi_bus_class = {
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index c29d590c5e4f..cc6757dfa3f1 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -123,7 +123,7 @@ static int pnp_device_probe(struct device *dev)
return error;
}
-static int pnp_device_remove(struct device *dev)
+static void pnp_device_remove(struct device *dev)
{
struct pnp_dev *pnp_dev = to_pnp_dev(dev);
struct pnp_driver *drv = pnp_dev->driver;
@@ -139,7 +139,6 @@ static int pnp_device_remove(struct device *dev)
pnp_disable_dev(pnp_dev);
pnp_device_detach(pnp_dev);
- return 0;
}
static void pnp_device_shutdown(struct device *dev)
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 72874153972e..a72bb0a40fcf 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -112,7 +112,7 @@ static int rio_device_probe(struct device *dev)
* driver, then run the driver remove() method. Then update
* the reference count.
*/
-static int rio_device_remove(struct device *dev)
+static void rio_device_remove(struct device *dev)
{
struct rio_dev *rdev = to_rio_dev(dev);
struct rio_driver *rdrv = rdev->driver;
@@ -124,8 +124,6 @@ static int rio_device_remove(struct device *dev)
}
rio_dev_put(rdev);
-
- return 0;
}
static void rio_device_shutdown(struct device *dev)
diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c
index c1404d3dae2c..9151836190ce 100644
--- a/drivers/rpmsg/rpmsg_core.c
+++ b/drivers/rpmsg/rpmsg_core.c
@@ -530,14 +530,13 @@ static int rpmsg_dev_probe(struct device *dev)
return err;
}
-static int rpmsg_dev_remove(struct device *dev)
+static void rpmsg_dev_remove(struct device *dev)
{
struct rpmsg_device *rpdev = to_rpmsg_device(dev);
struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
- int err = 0;
if (rpdev->ops->announce_destroy)
- err = rpdev->ops->announce_destroy(rpdev);
+ rpdev->ops->announce_destroy(rpdev);
if (rpdrv->remove)
rpdrv->remove(rpdev);
@@ -546,8 +545,6 @@ static int rpmsg_dev_remove(struct device *dev)
if (rpdev->ept)
rpmsg_destroy_ept(rpdev->ept);
-
- return err;
}
static struct bus_type rpmsg_bus = {
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index a6aeab1ea0ae..382c5b5f8cd3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -439,15 +439,13 @@ module_exit(cleanup_ccwgroup);
/************************** driver stuff ******************************/
-static int ccwgroup_remove(struct device *dev)
+static void ccwgroup_remove(struct device *dev)
{
struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
if (gdrv->remove)
gdrv->remove(gdev);
-
- return 0;
}
static void ccwgroup_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 092fd1ea5799..ebc321edba51 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1371,7 +1371,7 @@ static int css_probe(struct device *dev)
return ret;
}
-static int css_remove(struct device *dev)
+static void css_remove(struct device *dev)
{
struct subchannel *sch;
@@ -1379,8 +1379,6 @@ static int css_remove(struct device *dev)
if (sch->driver->remove)
sch->driver->remove(sch);
sch->driver = NULL;
-
- return 0;
}
static void css_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index cd5d2d4d8e46..adf33b653d87 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1741,7 +1741,7 @@ ccw_device_probe (struct device *dev)
return 0;
}
-static int ccw_device_remove(struct device *dev)
+static void ccw_device_remove(struct device *dev)
{
struct ccw_device *cdev = to_ccwdev(dev);
struct ccw_driver *cdrv = cdev->drv;
@@ -1775,8 +1775,6 @@ static int ccw_device_remove(struct device *dev)
spin_unlock_irq(cdev->ccwlock);
io_subchannel_quiesce(sch);
__disable_cmf(cdev);
-
- return 0;
}
static void ccw_device_shutdown(struct device *dev)
diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c
index b31711307e5a..b6b4589c70bd 100644
--- a/drivers/s390/cio/scm.c
+++ b/drivers/s390/cio/scm.c
@@ -28,15 +28,13 @@ static int scmdev_probe(struct device *dev)
return scmdrv->probe ? scmdrv->probe(scmdev) : -ENODEV;
}
-static int scmdev_remove(struct device *dev)
+static void scmdev_remove(struct device *dev)
{
struct scm_device *scmdev = to_scm_dev(dev);
struct scm_driver *scmdrv = to_scm_drv(dev->driver);
if (scmdrv->remove)
scmdrv->remove(scmdev);
-
- return 0;
}
static int scmdev_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 8d3a1d84a757..0992edcaf1af 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -901,7 +901,7 @@ static int ap_device_probe(struct device *dev)
return rc;
}
-static int ap_device_remove(struct device *dev)
+static void ap_device_remove(struct device *dev)
{
struct ap_device *ap_dev = to_ap_dev(dev);
struct ap_driver *ap_drv = ap_dev->drv;
@@ -926,8 +926,6 @@ static int ap_device_remove(struct device *dev)
ap_dev->drv = NULL;
put_device(dev);
-
- return 0;
}
struct ap_queue *ap_get_qdev(ap_qid_t qid)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 5b3a20a140f9..58f69366bdcc 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -7674,7 +7674,7 @@ static int sdebug_driver_probe(struct device *dev)
return error;
}
-static int sdebug_driver_remove(struct device *dev)
+static void sdebug_driver_remove(struct device *dev)
{
struct sdebug_host_info *sdbg_host;
struct sdebug_dev_info *sdbg_devinfo, *tmp;
@@ -7691,7 +7691,6 @@ static int sdebug_driver_remove(struct device *dev)
}
scsi_host_put(sdbg_host->shost);
- return 0;
}
static int pseudo_lld_bus_match(struct device *dev,
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 348836b90605..c0ab904c76ec 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -150,17 +150,13 @@ static int superhyway_device_probe(struct device *dev)
return -ENODEV;
}
-static int superhyway_device_remove(struct device *dev)
+static void superhyway_device_remove(struct device *dev)
{
struct superhyway_device *shyway_dev = to_superhyway_device(dev);
struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver);
- if (shyway_drv && shyway_drv->remove) {
+ if (shyway_drv && shyway_drv->remove)
shyway_drv->remove(shyway_dev);
- return 0;
- }
-
- return -ENODEV;
}
/**
diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c
index 1794ff0106bc..7c4f32d76966 100644
--- a/drivers/siox/siox-core.c
+++ b/drivers/siox/siox-core.c
@@ -520,7 +520,7 @@ static int siox_probe(struct device *dev)
return sdriver->probe(sdevice);
}
-static int siox_remove(struct device *dev)
+static void siox_remove(struct device *dev)
{
struct siox_driver *sdriver =
container_of(dev->driver, struct siox_driver, driver);
@@ -528,8 +528,6 @@ static int siox_remove(struct device *dev)
if (sdriver->remove)
sdriver->remove(sdevice);
-
- return 0;
}
static void siox_shutdown(struct device *dev)
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index 1d2bc181da05..78480e332ab8 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -81,7 +81,7 @@ static int slim_device_probe(struct device *dev)
return ret;
}
-static int slim_device_remove(struct device *dev)
+static void slim_device_remove(struct device *dev)
{
struct slim_device *sbdev = to_slim_device(dev);
struct slim_driver *sbdrv;
@@ -91,8 +91,6 @@ static int slim_device_remove(struct device *dev)
if (sbdrv->remove)
sbdrv->remove(sbdev);
}
-
- return 0;
}
static int slim_device_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index 7abfc8c4fdc7..475a57b435b2 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -217,7 +217,7 @@ static int apr_device_probe(struct device *dev)
return adrv->probe(adev);
}
-static int apr_device_remove(struct device *dev)
+static void apr_device_remove(struct device *dev)
{
struct apr_device *adev = to_apr_device(dev);
struct apr_driver *adrv;
@@ -231,8 +231,6 @@ static int apr_device_remove(struct device *dev)
idr_remove(&apr->svcs_idr, adev->svc_id);
spin_unlock(&apr->svcs_lock);
}
-
- return 0;
}
static int apr_uevent(struct device *dev, struct kobj_uevent_env *env)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c99181165321..ad2b558dc9cb 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -405,7 +405,7 @@ static int spi_probe(struct device *dev)
return ret;
}
-static int spi_remove(struct device *dev)
+static void spi_remove(struct device *dev)
{
const struct spi_driver *sdrv = to_spi_driver(dev->driver);
@@ -420,8 +420,6 @@ static int spi_remove(struct device *dev)
}
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static void spi_shutdown(struct device *dev)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 51f5aeb65b3b..b37ead9e2fad 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -345,7 +345,7 @@ static int spmi_drv_probe(struct device *dev)
return err;
}
-static int spmi_drv_remove(struct device *dev)
+static void spmi_drv_remove(struct device *dev)
{
const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
@@ -356,7 +356,6 @@ static int spmi_drv_remove(struct device *dev)
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
- return 0;
}
static void spmi_drv_shutdown(struct device *dev)
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 3a29b5570f9f..8a93c83cb6f8 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -283,7 +283,7 @@ static void ssb_device_shutdown(struct device *dev)
ssb_drv->shutdown(ssb_dev);
}
-static int ssb_device_remove(struct device *dev)
+static void ssb_device_remove(struct device *dev)
{
struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
@@ -291,8 +291,6 @@ static int ssb_device_remove(struct device *dev)
if (ssb_drv && ssb_drv->remove)
ssb_drv->remove(ssb_dev);
ssb_device_put(ssb_dev);
-
- return 0;
}
static int ssb_device_probe(struct device *dev)
diff --git a/drivers/staging/fieldbus/anybuss/host.c b/drivers/staging/fieldbus/anybuss/host.c
index 0f730efe9a6d..8a75f6642c78 100644
--- a/drivers/staging/fieldbus/anybuss/host.c
+++ b/drivers/staging/fieldbus/anybuss/host.c
@@ -1186,15 +1186,13 @@ static int anybus_bus_probe(struct device *dev)
return adrv->probe(adev);
}
-static int anybus_bus_remove(struct device *dev)
+static void anybus_bus_remove(struct device *dev)
{
struct anybuss_client_driver *adrv =
to_anybuss_client_driver(dev->driver);
if (adrv->remove)
adrv->remove(to_anybuss_client(dev));
-
- return 0;
}
static struct bus_type anybus_bus = {
diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c
index 13d319860da5..5a5c17a4519b 100644
--- a/drivers/staging/greybus/gbphy.c
+++ b/drivers/staging/greybus/gbphy.c
@@ -169,7 +169,7 @@ static int gbphy_dev_probe(struct device *dev)
return ret;
}
-static int gbphy_dev_remove(struct device *dev)
+static void gbphy_dev_remove(struct device *dev)
{
struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
@@ -180,8 +180,6 @@ static int gbphy_dev_remove(struct device *dev)
pm_runtime_set_suspended(dev);
pm_runtime_put_noidle(dev);
pm_runtime_dont_use_autosuspend(dev);
-
- return 0;
}
static struct bus_type gbphy_bus_type = {
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 6d0b0e67e79e..cbb2118fb35e 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -81,7 +81,7 @@ static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host)
}
static int tcm_loop_driver_probe(struct device *);
-static int tcm_loop_driver_remove(struct device *);
+static void tcm_loop_driver_remove(struct device *);
static int pseudo_lld_bus_match(struct device *dev,
struct device_driver *dev_driver)
@@ -363,7 +363,7 @@ static int tcm_loop_driver_probe(struct device *dev)
return 0;
}
-static int tcm_loop_driver_remove(struct device *dev)
+static void tcm_loop_driver_remove(struct device *dev)
{
struct tcm_loop_hba *tl_hba;
struct Scsi_Host *sh;
@@ -373,7 +373,6 @@ static int tcm_loop_driver_remove(struct device *dev)
scsi_remove_host(sh);
scsi_host_put(sh);
- return 0;
}
static void tcm_loop_release_adapter(struct device *dev)
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index a062befcb3b2..7018d959f775 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -86,7 +86,7 @@ static int tb_service_probe(struct device *dev)
return driver->probe(svc, id);
}
-static int tb_service_remove(struct device *dev)
+static void tb_service_remove(struct device *dev)
{
struct tb_service *svc = tb_to_service(dev);
struct tb_service_driver *driver;
@@ -94,8 +94,6 @@ static int tb_service_remove(struct device *dev)
driver = container_of(dev->driver, struct tb_service_driver, driver);
if (driver->remove)
driver->remove(svc);
-
- return 0;
}
static void tb_service_shutdown(struct device *dev)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 9cdfcfe07e87..92498961fd92 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -421,15 +421,13 @@ static int serdev_drv_probe(struct device *dev)
return ret;
}
-static int serdev_drv_remove(struct device *dev)
+static void serdev_drv_remove(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_serdev_device(dev));
dev_pm_domain_detach(dev, true);
-
- return 0;
}
static struct bus_type serdev_bus_type = {
diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c
index 7e13b74e60e5..4169cf40a03b 100644
--- a/drivers/usb/common/ulpi.c
+++ b/drivers/usb/common/ulpi.c
@@ -78,14 +78,12 @@ static int ulpi_probe(struct device *dev)
return drv->probe(to_ulpi_dev(dev));
}
-static int ulpi_remove(struct device *dev)
+static void ulpi_remove(struct device *dev)
{
struct ulpi_driver *drv = to_ulpi_driver(dev->driver);
if (drv->remove)
drv->remove(to_ulpi_dev(dev));
-
- return 0;
}
static struct bus_type ulpi_bus = {
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 7133818a58b9..9e38142acd38 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -74,7 +74,7 @@ static int usb_serial_device_probe(struct device *dev)
return retval;
}
-static int usb_serial_device_remove(struct device *dev)
+static void usb_serial_device_remove(struct device *dev)
{
struct usb_serial_port *port = to_usb_serial_port(dev);
struct usb_serial_driver *driver;
@@ -101,8 +101,6 @@ static int usb_serial_device_remove(struct device *dev)
if (!autopm_err)
usb_autopm_put_interface(port->serial->interface);
-
- return 0;
}
static ssize_t new_id_store(struct device_driver *driver,
diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index 7f3c9a8e2bf0..78e0e78954f2 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -382,7 +382,7 @@ static int typec_probe(struct device *dev)
return ret;
}
-static int typec_remove(struct device *dev)
+static void typec_remove(struct device *dev)
{
struct typec_altmode_driver *drv = to_altmode_driver(dev->driver);
struct typec_altmode *adev = to_typec_altmode(dev);
@@ -400,8 +400,6 @@ static int typec_remove(struct device *dev)
adev->desc = NULL;
adev->ops = NULL;
-
- return 0;
}
struct bus_type typec_bus = {
diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c
index bb3f1d1f0422..3fc4525fc05c 100644
--- a/drivers/vdpa/vdpa.c
+++ b/drivers/vdpa/vdpa.c
@@ -34,15 +34,13 @@ static int vdpa_dev_probe(struct device *d)
return ret;
}
-static int vdpa_dev_remove(struct device *d)
+static void vdpa_dev_remove(struct device *d)
{
struct vdpa_device *vdev = dev_to_vdpa(d);
struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver);
if (drv && drv->remove)
drv->remove(vdev);
-
- return 0;
}
static struct bus_type vdpa_bus = {
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index c368ec824e2b..e2cb1ff56f6c 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -57,7 +57,7 @@ static int mdev_probe(struct device *dev)
return ret;
}
-static int mdev_remove(struct device *dev)
+static void mdev_remove(struct device *dev)
{
struct mdev_driver *drv =
container_of(dev->driver, struct mdev_driver, driver);
@@ -67,8 +67,6 @@ static int mdev_remove(struct device *dev)
drv->remove(mdev);
mdev_detach_iommu(mdev);
-
- return 0;
}
static int mdev_match(struct device *dev, struct device_driver *drv)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 4b15c00c0a0a..2a6055c0d4d3 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -278,7 +278,7 @@ static int virtio_dev_probe(struct device *_d)
}
-static int virtio_dev_remove(struct device *_d)
+static void virtio_dev_remove(struct device *_d)
{
struct virtio_device *dev = dev_to_virtio(_d);
struct virtio_driver *drv = drv_to_virtio(dev->dev.driver);
@@ -292,7 +292,6 @@ static int virtio_dev_remove(struct device *_d)
/* Acknowledge the device's existence again. */
virtio_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE);
- return 0;
}
static struct bus_type virtio_bus = {
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index e966981c0215..4af6615808cc 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -342,14 +342,12 @@ static int vlynq_device_probe(struct device *dev)
return result;
}
-static int vlynq_device_remove(struct device *dev)
+static void vlynq_device_remove(struct device *dev)
{
struct vlynq_driver *drv = to_vlynq_driver(dev->driver);
if (drv->remove)
drv->remove(to_vlynq_device(dev));
-
- return 0;
}
int __vlynq_register_driver(struct vlynq_driver *driver, struct module *owner)
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 1b15afea28ee..8dba20186be3 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -1990,7 +1990,7 @@ static int vme_bus_probe(struct device *dev)
return -ENODEV;
}
-static int vme_bus_remove(struct device *dev)
+static void vme_bus_remove(struct device *dev)
{
struct vme_driver *driver;
struct vme_dev *vdev = dev_to_vme_dev(dev);
@@ -1998,8 +1998,6 @@ static int vme_bus_remove(struct device *dev)
driver = dev->platform_data;
if (driver->remove)
driver->remove(vdev);
-
- return 0;
}
struct bus_type vme_bus_type = {
diff --git a/drivers/xen/xenbus/xenbus.h b/drivers/xen/xenbus/xenbus.h
index 2a93b7c9c159..2754bdfadcb8 100644
--- a/drivers/xen/xenbus/xenbus.h
+++ b/drivers/xen/xenbus/xenbus.h
@@ -106,7 +106,7 @@ void xs_request_exit(struct xb_req_data *req);
int xenbus_match(struct device *_dev, struct device_driver *_drv);
int xenbus_dev_probe(struct device *_dev);
-int xenbus_dev_remove(struct device *_dev);
+void xenbus_dev_remove(struct device *_dev);
int xenbus_register_driver_common(struct xenbus_driver *drv,
struct xen_bus_type *bus,
struct module *owner,
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 33d09b3f6211..bd003ca8acbe 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -325,7 +325,7 @@ int xenbus_dev_probe(struct device *_dev)
}
EXPORT_SYMBOL_GPL(xenbus_dev_probe);
-int xenbus_dev_remove(struct device *_dev)
+void xenbus_dev_remove(struct device *_dev)
{
struct xenbus_device *dev = to_xenbus_device(_dev);
struct xenbus_driver *drv = to_xenbus_driver(_dev->driver);
@@ -355,8 +355,6 @@ int xenbus_dev_remove(struct device *_dev)
if (!drv->allow_rebind ||
xenbus_read_driver_state(dev->nodename) == XenbusStateClosing)
xenbus_switch_state(dev, XenbusStateClosed);
-
- return 0;
}
EXPORT_SYMBOL_GPL(xenbus_dev_remove);
diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
index 0dd7cbcec2b0..c18524bb8b2a 100644
--- a/drivers/zorro/zorro-driver.c
+++ b/drivers/zorro/zorro-driver.c
@@ -62,7 +62,7 @@ static int zorro_device_probe(struct device *dev)
}
-static int zorro_device_remove(struct device *dev)
+static void zorro_device_remove(struct device *dev)
{
struct zorro_dev *z = to_zorro_dev(dev);
struct zorro_driver *drv = to_zorro_driver(dev->driver);
@@ -72,7 +72,6 @@ static int zorro_device_remove(struct device *dev)
drv->remove(z);
z->driver = NULL;
}
- return 0;
}
diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 1ea5e1d1545b..062777a45a74 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -91,7 +91,7 @@ struct bus_type {
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
void (*sync_state)(struct device *dev);
- int (*remove)(struct device *dev);
+ void (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*online)(struct device *dev);
diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c
index 6ddf646cda65..0d31a6d71468 100644
--- a/sound/ac97/bus.c
+++ b/sound/ac97/bus.c
@@ -514,7 +514,7 @@ static int ac97_bus_probe(struct device *dev)
return ret;
}
-static int ac97_bus_remove(struct device *dev)
+static void ac97_bus_remove(struct device *dev)
{
struct ac97_codec_device *adev = to_ac97_device(dev);
struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
@@ -522,7 +522,7 @@ static int ac97_bus_remove(struct device *dev)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
- return ret;
+ return;
ret = adrv->remove(adev);
pm_runtime_put_noidle(dev);
@@ -530,8 +530,6 @@ static int ac97_bus_remove(struct device *dev)
ac97_put_disable_clk(adev);
pm_runtime_disable(dev);
-
- return ret;
}
static struct bus_type ac97_bus_type = {
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 002fb5bf220b..c9579d97fbab 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -104,7 +104,7 @@ static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
return retval;
}
-static int soundbus_device_remove(struct device *dev)
+static void soundbus_device_remove(struct device *dev)
{
struct soundbus_dev * soundbus_dev = to_soundbus_device(dev);
struct soundbus_driver * drv = to_soundbus_driver(dev->driver);
@@ -112,8 +112,6 @@ static int soundbus_device_remove(struct device *dev)
if (dev->driver && drv->remove)
drv->remove(soundbus_dev);
soundbus_dev_put(soundbus_dev);
-
- return 0;
}
static void soundbus_device_shutdown(struct device *dev)
--
2.30.2
^ permalink raw reply related
* Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
From: Konrad Rzeszutek Wilk @ 2021-07-14 0:06 UTC (permalink / raw)
To: Will Deacon
Cc: Jim Quinlan, heikki.krogerus, linux-devicetree, peterz,
joonas.lahtinen, dri-devel, chris, grant.likely, paulus,
Frank Rowand, mingo, Jianxiong Gao, Stefano Stabellini,
Saravana Kannan, Rafael J . Wysocki, xypron.glpk,
Christoph Hellwig, Bartosz Golaszewski, bskeggs, linux-pci,
xen-devel, Thierry Reding, matthew.auld, Nicolas Boichat,
thomas.hellstrom, jgross, Konrad Rzeszutek Wilk, intel-gfx,
maarten.lankhorst, jani.nikula, Nathan Chancellor, Rob Herring,
rodrigo.vivi, Bjorn Helgaas, Claire Chang, Dan Williams,
Andy Shevchenko, boris.ostrovsky, airlied, linuxppc-dev,
Randy Dunlap, Qian Cai, lkml, list@263.net:IOMMU DRIVERS,
Daniel Vetter, Greg KH, Tom Lendacky, Robin Murphy, bauerman
In-Reply-To: <20210712135645.GA28881@willie-the-truck>
..snip..
> > > I think the main question I have is how would you like to see patches for
> > > 5.15? i.e. as patches on top of devel/for-linus-5.14 or something else?
> >
> > Yes that would be perfect. If there are any dependencies on the rc1, I
> > can rebase it on top of that.
>
> Yes, please, rebasing would be very helpful. The broader rework of
> 'io_tlb_default_mem' is going to conflict quite badly otherwise.
There is a devel/for-linus-5.15 (based on v5.14-rc1) now.
Thank you!
>
> Cheers,
>
> Will
^ permalink raw reply
* Re: [PATCH] powerpc/rtas_flash: fix a potential buffer overflow
From: kernel test robot @ 2021-07-14 2:49 UTC (permalink / raw)
To: Yi Zhuang, benh, paulus
Cc: kbuild-all, linux-kernel, hegdevasant, zhuangyi1, linuxppc-dev
In-Reply-To: <20210714011608.15043-1-zhuangyi1@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 4423 bytes --]
Hi Yi,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on v5.14-rc1 next-20210713]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Yi-Zhuang/powerpc-rtas_flash-fix-a-potential-buffer-overflow/20210714-090314
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/546db7a99374dedd110a01801ad4456f56170d4d
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Yi-Zhuang/powerpc-rtas_flash-fix-a-potential-buffer-overflow/20210714-090314
git checkout 546db7a99374dedd110a01801ad4456f56170d4d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
arch/powerpc/kernel/rtas_flash.c: In function 'get_validate_flash_msg':
>> arch/powerpc/kernel/rtas_flash.c:472:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
472 | if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||
| ^~
arch/powerpc/kernel/rtas_flash.c:476:4: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
476 | if (n >= msglen) {
| ^~
vim +/if +472 arch/powerpc/kernel/rtas_flash.c
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 464
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 465 static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
a94a14720eaf55 arch/powerpc/kernel/rtas_flash.c Vasant Hegde 2013-05-07 466 char *msg, int msglen)
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 467 {
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 468 int n;
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 469
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 470 if (args_buf->status >= VALIDATE_TMP_UPDATE) {
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 471 n = sprintf(msg, "%d\n", args_buf->update_results);
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 @472 if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 473 (args_buf->update_results == VALIDATE_TMP_UPDATE))
a94a14720eaf55 arch/powerpc/kernel/rtas_flash.c Vasant Hegde 2013-05-07 474 n += snprintf(msg + n, msglen - n, "%s\n",
a94a14720eaf55 arch/powerpc/kernel/rtas_flash.c Vasant Hegde 2013-05-07 475 args_buf->buf);
546db7a99374de arch/powerpc/kernel/rtas_flash.c Yi Zhuang 2021-07-14 476 if (n >= msglen) {
546db7a99374de arch/powerpc/kernel/rtas_flash.c Yi Zhuang 2021-07-14 477 n = msglen;
546db7a99374de arch/powerpc/kernel/rtas_flash.c Yi Zhuang 2021-07-14 478 printk(KERN_ERR "FLASH: msg too long.\n");
546db7a99374de arch/powerpc/kernel/rtas_flash.c Yi Zhuang 2021-07-14 479 }
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 480 } else {
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 481 n = sprintf(msg, "%d\n", args_buf->status);
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 482 }
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 483 return n;
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 484 }
^1da177e4c3f41 arch/ppc64/kernel/rtas_flash.c Linus Torvalds 2005-04-16 485
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 73240 bytes --]
^ permalink raw reply
* [PATCH] powerpc/rtas_flash: fix a potential buffer overflow
From: Yi Zhuang @ 2021-07-14 1:16 UTC (permalink / raw)
To: benh, paulus; +Cc: hegdevasant, linuxppc-dev, linux-kernel, zhuangyi1
Since snprintf() returns the possible output size instead of the
actual output size, the available flash_msg length returned by
get_validate_flash_msg may exceed the given buffer limit when
simple_read_from_buffer calls copy_to_user
Signed-off-by: Yi Zhuang <zhuangyi1@huawei.com>
---
arch/powerpc/kernel/rtas_flash.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index a99179d83538..4aa6bad28556 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -473,6 +473,10 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,
(args_buf->update_results == VALIDATE_TMP_UPDATE))
n += snprintf(msg + n, msglen - n, "%s\n",
args_buf->buf);
+ if (n >= msglen) {
+ n = msglen;
+ printk(KERN_ERR "FLASH: msg too long.\n");
+ }
} else {
n = sprintf(msg, "%d\n", args_buf->status);
}
--
2.26.0.106.g9fadedd
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox