* Re: [PATCH printk v1 03/10] kgdb: delay roundup if holding printk cpulock
From: John Ogness @ 2021-08-03 15:30 UTC (permalink / raw)
To: Daniel Thompson
Cc: Gautham R. Shenoy, Douglas Anderson, Srikar Dronamraju,
Peter Zijlstra, linux-kernel, Paul Mackerras, H. Peter Anvin,
Chengyang Fan, Bhaskar Chowdhury, x86, Ingo Molnar,
kgdb-bugreport, Petr Mladek, Nicholas Piggin, Borislav Petkov,
Steven Rostedt, Thomas Gleixner, Gustavo A. R. Silva,
Sergey Senozhatsky, Jason Wessel, linuxppc-dev,
Cédric Le Goater
In-Reply-To: <20210803142558.cz7apumpgijs5y4y@maple.lan>
On 2021-08-03, Daniel Thompson <daniel.thompson@linaro.org> wrote:
> On Tue, Aug 03, 2021 at 03:18:54PM +0206, John Ogness wrote:
>> kgdb makes use of its own cpulock (@dbg_master_lock, @kgdb_active)
>> during cpu roundup. This will conflict with the printk cpulock.
>
> When the full vision is realized what will be the purpose of the printk
> cpulock?
>
> I'm asking largely because it's current role is actively unhelpful
> w.r.t. kdb. It is possible that cautious use of in_dbg_master() might
> be a better (and safer) solution. However it sounds like there is a
> larger role planned for the printk cpulock...
The printk cpulock is used as a synchronization mechanism for
implementing atomic consoles, which need to be able to safely interrupt
the console write() activity at any time and immediately continue with
their own printing. The ultimate goal is to move all console printing
into per-console dedicated kthreads, so the primary function of the
printk cpulock is really to immediately _stop_ the CPU/kthread
performing write() in order to allow write_atomic() (from any context on
any CPU) to safely and reliably take over.
Atomic consoles are actually quite similar to the kgdb_io ops. For
example, comparing:
serial8250_console_write_atomic() + serial8250_console_putchar_locked()
with
serial8250_put_poll_char()
The difference is that serial8250_console_write_atomic() is line-based
and synchronizing with serial8250_console_write() so that if the kernel
crashes while outputing to the console, write() can be interrupted by
write_atomic() and cleanly formatted crash data can be output.
Also serial8250_put_poll_char() is calling into __pm_runtime_resume(),
which includes a spinlock and possibly sleeping. This would not be
acceptable for atomic consoles. Although, as Andy pointed out [0], I
will need to figure out how to deal with suspended consoles. Or just
implement a policy that registered atomic consoles may never be
suspended.
I had not considered merging kgdb_io ops with atomic console ops. But
now that I look at it more closely, there may be some useful overlap. I
will consider this. Thank you for this idea.
>> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
>> index 3d0c933937b4..1b546e117f10 100644
>> --- a/kernel/printk/printk.c
>> +++ b/kernel/printk/printk.c
>> @@ -214,6 +215,7 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
>> #ifdef CONFIG_SMP
>> static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
>> static atomic_t printk_cpulock_nested = ATOMIC_INIT(0);
>> +static unsigned int kgdb_cpu = -1;
>
> Is this the flag to provoke retriggering? It appears to be a write-only
> variable (at least in this patch). How is it consumed?
Critical catch! Thank you. I am quite unhappy to see these hunks were
accidentally dropped when generating this series.
@@ -3673,6 +3675,9 @@ EXPORT_SYMBOL(__printk_cpu_trylock);
*/
void __printk_cpu_unlock(void)
{
+ bool trigger_kgdb = false;
+ unsigned int cpu;
+
if (atomic_read(&printk_cpulock_nested)) {
atomic_dec(&printk_cpulock_nested);
return;
@@ -3683,6 +3688,12 @@ void __printk_cpu_unlock(void)
* LMM(__printk_cpu_unlock:A)
*/
+ cpu = smp_processor_id();
+ if (kgdb_cpu == cpu) {
+ trigger_kgdb = true;
+ kgdb_cpu = -1;
+ }
+
/*
* Guarantee loads and stores from this CPU when it was the
* lock owner are visible to the next lock owner. This pairs
@@ -3703,6 +3714,21 @@ void __printk_cpu_unlock(void)
*/
atomic_set_release(&printk_cpulock_owner,
-1); /* LMM(__printk_cpu_unlock:B) */
+
+ if (trigger_kgdb) {
+ pr_warn("re-triggering kgdb roundup for CPU#%d\n", cpu);
+ kgdb_roundup_cpu(cpu);
+ }
}
EXPORT_SYMBOL(__printk_cpu_unlock);
John Ogness
[0] https://lore.kernel.org/lkml/YQlKAeXS9MPmE284@smile.fi.intel.com
^ permalink raw reply
* [PATCH] powerpc/32s: Fix napping restore in data storage interrupt (DSI)
From: Christophe Leroy @ 2021-08-03 15:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Finn Thain, userm57
Cc: linuxppc-dev, linux-kernel
When a DSI (Data Storage Interrupt) is taken while in NAP mode,
r11 doesn't survive the call to power_save_ppc32_restore().
So use r1 instead of r11 as they both contain the virtual stack
pointer at that point.
Reported-by: Finn Thain <fthain@linux-m68k.org>
Fixes: 4c0104a83fc3 ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE")
Cc: stable@vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/head_book3s_32.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S
index 764edd860ed4..68e5c0a7e99d 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -300,7 +300,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
EXCEPTION_PROLOG_1
EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
prepare_transfer_to_handler
- lwz r5, _DSISR(r11)
+ lwz r5, _DSISR(r1)
andis. r0, r5, DSISR_DABRMATCH@h
bne- 1f
bl do_page_fault
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc/kexec: fix for_each_child.cocci warning
From: Julia Lawall @ 2021-08-03 14:59 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: Sumera Priyadarsini, linuxppc-dev, kbuild-all, linux-kernel
From: kernel test robot <lkp@intel.com>
for_each_node_by_type should have of_node_put() before return.
Generated by: scripts/coccinelle/iterators/for_each_child.cocci
CC: Sumera Priyadarsini <sylphrenadin@gmail.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: kernel test robot <lkp@intel.com>
---
The code seems to have been this way since the beginning of time. Perhaps
the of_node_put is a no op for this code?
core_64.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/powerpc/kexec/core_64.c
+++ b/arch/powerpc/kexec/core_64.c
@@ -64,8 +64,10 @@ int default_machine_kexec_prepare(struct
begin = image->segment[i].mem;
end = begin + image->segment[i].memsz;
- if ((begin < high) && (end > low))
+ if ((begin < high) && (end > low)) {
+ of_node_put(node);
return -ETXTBSY;
+ }
}
}
^ permalink raw reply
* [RFC PATCH] powerpc/book3s64/radix: Upgrade va tlbie to PID tlbie if we cross PMD_SIZE
From: Aneesh Kumar K.V @ 2021-08-03 14:37 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Aneesh Kumar K.V, npiggin
With shared mapping, even though we are unmapping a large range, the kernel
will force a TLB flush with ptl lock held to avoid the race mentioned in
commit 1cf35d47712d ("mm: split 'tlb_flush_mmu()' into tlb flushing and memory freeing parts")
This results in the kernel issuing a high number of TLB flushes even for a large
range. This can be improved by making sure the kernel switch to pid based flush if the
kernel is unmapping a 2M range.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/book3s64/radix_tlb.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c
index aefc100d79a7..21d0f098e43b 100644
--- a/arch/powerpc/mm/book3s64/radix_tlb.c
+++ b/arch/powerpc/mm/book3s64/radix_tlb.c
@@ -1106,7 +1106,7 @@ EXPORT_SYMBOL(radix__flush_tlb_kernel_range);
* invalidating a full PID, so it has a far lower threshold to change from
* individual page flushes to full-pid flushes.
*/
-static unsigned long tlb_single_page_flush_ceiling __read_mostly = 33;
+static unsigned long tlb_single_page_flush_ceiling __read_mostly = 32;
static unsigned long tlb_local_single_page_flush_ceiling __read_mostly = POWER9_TLB_SETS_RADIX * 2;
static inline void __radix__flush_tlb_range(struct mm_struct *mm,
@@ -1133,7 +1133,7 @@ static inline void __radix__flush_tlb_range(struct mm_struct *mm,
if (fullmm)
flush_pid = true;
else if (type == FLUSH_TYPE_GLOBAL)
- flush_pid = nr_pages > tlb_single_page_flush_ceiling;
+ flush_pid = nr_pages >= tlb_single_page_flush_ceiling;
else
flush_pid = nr_pages > tlb_local_single_page_flush_ceiling;
/*
@@ -1335,7 +1335,7 @@ static void __radix__flush_tlb_range_psize(struct mm_struct *mm,
if (fullmm)
flush_pid = true;
else if (type == FLUSH_TYPE_GLOBAL)
- flush_pid = nr_pages > tlb_single_page_flush_ceiling;
+ flush_pid = nr_pages >= tlb_single_page_flush_ceiling;
else
flush_pid = nr_pages > tlb_local_single_page_flush_ceiling;
@@ -1505,7 +1505,7 @@ void do_h_rpt_invalidate_prt(unsigned long pid, unsigned long lpid,
continue;
nr_pages = (end - start) >> def->shift;
- flush_pid = nr_pages > tlb_single_page_flush_ceiling;
+ flush_pid = nr_pages >= tlb_single_page_flush_ceiling;
/*
* If the number of pages spanning the range is above
--
2.31.1
^ permalink raw reply related
* Re: [PATCH printk v1 03/10] kgdb: delay roundup if holding printk cpulock
From: Daniel Thompson @ 2021-08-03 14:25 UTC (permalink / raw)
To: John Ogness
Cc: Gautham R. Shenoy, Douglas Anderson, Srikar Dronamraju,
Peter Zijlstra, linux-kernel, Paul Mackerras, H. Peter Anvin,
Chengyang Fan, Bhaskar Chowdhury, x86, Ingo Molnar,
kgdb-bugreport, Petr Mladek, Nicholas Piggin, Borislav Petkov,
Steven Rostedt, Thomas Gleixner, Gustavo A. R. Silva,
Sergey Senozhatsky, Jason Wessel, linuxppc-dev,
Cédric Le Goater
In-Reply-To: <20210803131301.5588-4-john.ogness@linutronix.de>
On Tue, Aug 03, 2021 at 03:18:54PM +0206, John Ogness wrote:
> kgdb makes use of its own cpulock (@dbg_master_lock, @kgdb_active)
> during cpu roundup. This will conflict with the printk cpulock.
When the full vision is realized what will be the purpose of the printk
cpulock?
I'm asking largely because it's current role is actively unhelpful
w.r.t. kdb. It is possible that cautious use of in_dbg_master() might
be a better (and safer) solution. However it sounds like there is a
larger role planned for the printk cpulock...
> Therefore, a CPU must ensure that it is not holding the printk
> cpulock when calling kgdb_cpu_enter(). If it is, it must allow its
> printk context to complete first.
>
> A new helper function kgdb_roundup_delay() is introduced for kgdb
> to determine if it is holding the printk cpulock. If so, a flag is
> set so that when the printk cpulock is released, kgdb will be
> re-triggered for that CPU.
>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
> arch/powerpc/include/asm/smp.h | 1 +
> arch/powerpc/kernel/kgdb.c | 10 +++++++-
> arch/powerpc/kernel/smp.c | 5 ++++
> arch/x86/kernel/kgdb.c | 9 ++++---
> include/linux/kgdb.h | 3 +++
> include/linux/printk.h | 8 ++++++
> kernel/debug/debug_core.c | 45 ++++++++++++++++++++--------------
> kernel/printk/printk.c | 12 +++++++++
> 8 files changed, 70 insertions(+), 23 deletions(-)
>
> [...]
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 3d0c933937b4..1b546e117f10 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -44,6 +44,7 @@
> #include <linux/irq_work.h>
> #include <linux/ctype.h>
> #include <linux/uio.h>
> +#include <linux/kgdb.h>
> #include <linux/sched/clock.h>
> #include <linux/sched/debug.h>
> #include <linux/sched/task_stack.h>
> @@ -214,6 +215,7 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
> #ifdef CONFIG_SMP
> static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
> static atomic_t printk_cpulock_nested = ATOMIC_INIT(0);
> +static unsigned int kgdb_cpu = -1;
Is this the flag to provoke retriggering? It appears to be a write-only
variable (at least in this patch). How is it consumed?
Daniel.
> /**
> * __printk_wait_on_cpu_lock() - Busy wait until the printk cpu-reentrant
> @@ -325,6 +327,16 @@ void __printk_cpu_unlock(void)
> -1); /* LMM(__printk_cpu_unlock:B) */
> }
> EXPORT_SYMBOL(__printk_cpu_unlock);
> +
> +bool kgdb_roundup_delay(unsigned int cpu)
> +{
> + if (cpu != atomic_read(&printk_cpulock_owner))
> + return false;
> +
> + kgdb_cpu = cpu;
> + return true;
> +}
> +EXPORT_SYMBOL(kgdb_roundup_delay);
> #endif /* CONFIG_SMP */
>
> /* Number of registered extended console drivers. */
> --
> 2.20.1
>
^ permalink raw reply
* [PATCH 03/38] powerpc: Replace deprecated CPU-hotplug functions.
From: Sebastian Andrzej Siewior @ 2021-08-03 14:15 UTC (permalink / raw)
To: linux-kernel
Cc: Peter Zijlstra, Sebastian Andrzej Siewior, kvm-ppc,
Paul Mackerras, tglx, linuxppc-dev
In-Reply-To: <20210803141621.780504-1-bigeasy@linutronix.de>
The functions get_online_cpus() and put_online_cpus() have been
deprecated during the CPU hotplug rework. They map directly to
cpus_read_lock() and cpus_read_unlock().
Replace deprecated CPU-hotplug functions with the official version.
The behavior remains unchanged.
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: kvm-ppc@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
arch/powerpc/kernel/rtasd.c | 4 ++--
arch/powerpc/kvm/book3s_hv_builtin.c | 10 +++++-----
arch/powerpc/platforms/powernv/idle.c | 4 ++--
arch/powerpc/platforms/powernv/opal-imc.c | 8 ++++----
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 8561dfb33f241..32ee17753eb4a 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -429,7 +429,7 @@ static void rtas_event_scan(struct work_struct *w)
do_event_scan();
- get_online_cpus();
+ cpus_read_lock();
/* raw_ OK because just using CPU as starting point. */
cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
@@ -451,7 +451,7 @@ static void rtas_event_scan(struct work_struct *w)
schedule_delayed_work_on(cpu, &event_scan_work,
__round_jiffies_relative(event_scan_delay, cpu));
- put_online_cpus();
+ cpus_read_unlock();
}
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index be8ef1c5b1bfb..fcf4760a3a0ea 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -137,23 +137,23 @@ long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target,
* exist in the system. We use a counter of VMs to track this.
*
* One of the operations we need to block is onlining of secondaries, so we
- * protect hv_vm_count with get/put_online_cpus().
+ * protect hv_vm_count with cpus_read_lock/unlock().
*/
static atomic_t hv_vm_count;
void kvm_hv_vm_activated(void)
{
- get_online_cpus();
+ cpus_read_lock();
atomic_inc(&hv_vm_count);
- put_online_cpus();
+ cpus_read_unlock();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_activated);
void kvm_hv_vm_deactivated(void)
{
- get_online_cpus();
+ cpus_read_lock();
atomic_dec(&hv_vm_count);
- put_online_cpus();
+ cpus_read_unlock();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated);
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 528a7e0cf83aa..aa27689b832db 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -199,12 +199,12 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev,
*/
power7_fastsleep_workaround_exit = false;
- get_online_cpus();
+ cpus_read_lock();
primary_thread_mask = cpu_online_cores_map();
on_each_cpu_mask(&primary_thread_mask,
pnv_fastsleep_workaround_apply,
&err, 1);
- put_online_cpus();
+ cpus_read_unlock();
if (err) {
pr_err("fastsleep_workaround_applyonce change failed while running pnv_fastsleep_workaround_apply");
goto fail;
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c
index 7824cc364bc40..ba02a75c14102 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -186,7 +186,7 @@ static void disable_nest_pmu_counters(void)
int nid, cpu;
const struct cpumask *l_cpumask;
- get_online_cpus();
+ cpus_read_lock();
for_each_node_with_cpus(nid) {
l_cpumask = cpumask_of_node(nid);
cpu = cpumask_first_and(l_cpumask, cpu_online_mask);
@@ -195,7 +195,7 @@ static void disable_nest_pmu_counters(void)
opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
get_hard_smp_processor_id(cpu));
}
- put_online_cpus();
+ cpus_read_unlock();
}
static void disable_core_pmu_counters(void)
@@ -203,7 +203,7 @@ static void disable_core_pmu_counters(void)
cpumask_t cores_map;
int cpu, rc;
- get_online_cpus();
+ cpus_read_lock();
/* Disable the IMC Core functions */
cores_map = cpu_online_cores_map();
for_each_cpu(cpu, &cores_map) {
@@ -213,7 +213,7 @@ static void disable_core_pmu_counters(void)
pr_err("%s: Failed to stop Core (cpu = %d)\n",
__FUNCTION__, cpu);
}
- put_online_cpus();
+ cpus_read_unlock();
}
int get_max_nest_dev(void)
--
2.32.0
^ permalink raw reply related
* [PATCH printk v1 03/10] kgdb: delay roundup if holding printk cpulock
From: John Ogness @ 2021-08-03 13:12 UTC (permalink / raw)
To: Petr Mladek
Cc: Gautham R. Shenoy, Douglas Anderson, Srikar Dronamraju,
Peter Zijlstra, linux-kernel, Paul Mackerras, H. Peter Anvin,
Chengyang Fan, Daniel Thompson, Bhaskar Chowdhury, x86,
Ingo Molnar, kgdb-bugreport, Nicholas Piggin, Borislav Petkov,
Steven Rostedt, Thomas Gleixner, Gustavo A. R. Silva,
Sergey Senozhatsky, Jason Wessel, linuxppc-dev,
Cédric Le Goater
In-Reply-To: <20210803131301.5588-1-john.ogness@linutronix.de>
kgdb makes use of its own cpulock (@dbg_master_lock, @kgdb_active)
during cpu roundup. This will conflict with the printk cpulock.
Therefore, a CPU must ensure that it is not holding the printk
cpulock when calling kgdb_cpu_enter(). If it is, it must allow its
printk context to complete first.
A new helper function kgdb_roundup_delay() is introduced for kgdb
to determine if it is holding the printk cpulock. If so, a flag is
set so that when the printk cpulock is released, kgdb will be
re-triggered for that CPU.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
arch/powerpc/include/asm/smp.h | 1 +
arch/powerpc/kernel/kgdb.c | 10 +++++++-
arch/powerpc/kernel/smp.c | 5 ++++
arch/x86/kernel/kgdb.c | 9 ++++---
include/linux/kgdb.h | 3 +++
include/linux/printk.h | 8 ++++++
kernel/debug/debug_core.c | 45 ++++++++++++++++++++--------------
kernel/printk/printk.c | 12 +++++++++
8 files changed, 70 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 03b3d010cbab..eec452e647b3 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -58,6 +58,7 @@ struct smp_ops_t {
extern int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
extern int smp_send_safe_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
+extern void smp_send_debugger_break_cpu(unsigned int cpu);
extern void smp_send_debugger_break(void);
extern void start_secondary_resume(void);
extern void smp_generic_give_timebase(void);
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index bdee7262c080..d57d37497862 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -120,11 +120,19 @@ int kgdb_skipexception(int exception, struct pt_regs *regs)
static int kgdb_debugger_ipi(struct pt_regs *regs)
{
- kgdb_nmicallback(raw_smp_processor_id(), regs);
+ int cpu = raw_smp_processor_id();
+
+ if (!kgdb_roundup_delay(cpu))
+ kgdb_nmicallback(cpu, regs);
return 0;
}
#ifdef CONFIG_SMP
+void kgdb_roundup_cpu(unsigned int cpu)
+{
+ smp_send_debugger_break_cpu(cpu);
+}
+
void kgdb_roundup_cpus(void)
{
smp_send_debugger_break();
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 447b78a87c8f..816d7f09bbf9 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -582,6 +582,11 @@ static void debugger_ipi_callback(struct pt_regs *regs)
debugger_ipi(regs);
}
+void smp_send_debugger_break_cpu(unsigned int cpu)
+{
+ smp_send_nmi_ipi(cpu, debugger_ipi_callback, 1000000);
+}
+
void smp_send_debugger_break(void)
{
smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, debugger_ipi_callback, 1000000);
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 3a43a2dee658..37bd37cdf2b6 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -502,9 +502,12 @@ static int kgdb_nmi_handler(unsigned int cmd, struct pt_regs *regs)
if (atomic_read(&kgdb_active) != -1) {
/* KGDB CPU roundup */
cpu = raw_smp_processor_id();
- kgdb_nmicallback(cpu, regs);
- set_bit(cpu, was_in_debug_nmi);
- touch_nmi_watchdog();
+
+ if (!kgdb_roundup_delay(cpu)) {
+ kgdb_nmicallback(cpu, regs);
+ set_bit(cpu, was_in_debug_nmi);
+ touch_nmi_watchdog();
+ }
return NMI_HANDLED;
}
diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h
index 258cdde8d356..9bca0d98db5a 100644
--- a/include/linux/kgdb.h
+++ b/include/linux/kgdb.h
@@ -212,6 +212,8 @@ extern void kgdb_call_nmi_hook(void *ignored);
*/
extern void kgdb_roundup_cpus(void);
+extern void kgdb_roundup_cpu(unsigned int cpu);
+
/**
* kgdb_arch_set_pc - Generic call back to the program counter
* @regs: Current &struct pt_regs.
@@ -365,5 +367,6 @@ extern void kgdb_free_init_mem(void);
#define dbg_late_init()
static inline void kgdb_panic(const char *msg) {}
static inline void kgdb_free_init_mem(void) { }
+static inline void kgdb_roundup_cpu(unsigned int cpu) {}
#endif /* ! CONFIG_KGDB */
#endif /* _KGDB_H_ */
diff --git a/include/linux/printk.h b/include/linux/printk.h
index ac738d1d9934..974ea2c99749 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -280,10 +280,18 @@ static inline void dump_stack(void)
extern int __printk_cpu_trylock(void);
extern void __printk_wait_on_cpu_lock(void);
extern void __printk_cpu_unlock(void);
+extern bool kgdb_roundup_delay(unsigned int cpu);
+
#else
+
#define __printk_cpu_trylock() 1
#define __printk_wait_on_cpu_lock()
#define __printk_cpu_unlock()
+
+static inline bool kgdb_roundup_delay(unsigned int cpu)
+{
+ return false;
+}
#endif /* CONFIG_SMP */
/**
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index b4aa6bb6b2bd..9117ca86b81c 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -241,35 +241,42 @@ NOKPROBE_SYMBOL(kgdb_call_nmi_hook);
static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd) =
CSD_INIT(kgdb_call_nmi_hook, NULL);
-void __weak kgdb_roundup_cpus(void)
+void __weak kgdb_roundup_cpu(unsigned int cpu)
{
call_single_data_t *csd;
+ int ret;
+
+ csd = &per_cpu(kgdb_roundup_csd, cpu);
+
+ /*
+ * If it didn't round up last time, don't try again
+ * since smp_call_function_single_async() will block.
+ *
+ * If rounding_up is false then we know that the
+ * previous call must have at least started and that
+ * means smp_call_function_single_async() won't block.
+ */
+ if (kgdb_info[cpu].rounding_up)
+ return;
+ kgdb_info[cpu].rounding_up = true;
+
+ ret = smp_call_function_single_async(cpu, csd);
+ if (ret)
+ kgdb_info[cpu].rounding_up = false;
+}
+NOKPROBE_SYMBOL(kgdb_roundup_cpu);
+
+void __weak kgdb_roundup_cpus(void)
+{
int this_cpu = raw_smp_processor_id();
int cpu;
- int ret;
for_each_online_cpu(cpu) {
/* No need to roundup ourselves */
if (cpu == this_cpu)
continue;
- csd = &per_cpu(kgdb_roundup_csd, cpu);
-
- /*
- * If it didn't round up last time, don't try again
- * since smp_call_function_single_async() will block.
- *
- * If rounding_up is false then we know that the
- * previous call must have at least started and that
- * means smp_call_function_single_async() won't block.
- */
- if (kgdb_info[cpu].rounding_up)
- continue;
- kgdb_info[cpu].rounding_up = true;
-
- ret = smp_call_function_single_async(cpu, csd);
- if (ret)
- kgdb_info[cpu].rounding_up = false;
+ kgdb_roundup_cpu(cpu);
}
}
NOKPROBE_SYMBOL(kgdb_roundup_cpus);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 3d0c933937b4..1b546e117f10 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -44,6 +44,7 @@
#include <linux/irq_work.h>
#include <linux/ctype.h>
#include <linux/uio.h>
+#include <linux/kgdb.h>
#include <linux/sched/clock.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
@@ -214,6 +215,7 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
#ifdef CONFIG_SMP
static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
static atomic_t printk_cpulock_nested = ATOMIC_INIT(0);
+static unsigned int kgdb_cpu = -1;
/**
* __printk_wait_on_cpu_lock() - Busy wait until the printk cpu-reentrant
@@ -325,6 +327,16 @@ void __printk_cpu_unlock(void)
-1); /* LMM(__printk_cpu_unlock:B) */
}
EXPORT_SYMBOL(__printk_cpu_unlock);
+
+bool kgdb_roundup_delay(unsigned int cpu)
+{
+ if (cpu != atomic_read(&printk_cpulock_owner))
+ return false;
+
+ kgdb_cpu = cpu;
+ return true;
+}
+EXPORT_SYMBOL(kgdb_roundup_delay);
#endif /* CONFIG_SMP */
/* Number of registered extended console drivers. */
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v5 0/2] cpuidle/pseries: cleanup of the CEDE0 latency fixup code
From: Michael Ellerman @ 2021-08-03 12:50 UTC (permalink / raw)
To: Michael Ellerman, Vaidyanathan Srinivasan, Rafael J. Wysocki,
Michal Suchanek, Gautham R. Shenoy, Aneesh Kumar K.V,
Daniel Lezcano
Cc: linuxppc-dev, joedecke, linux-pm
In-Reply-To: <162798602812.163057.13114310314725073045.b4-ty@ellerman.id.au>
Michael Ellerman <patch-notifications@ellerman.id.au> writes:
> On Mon, 19 Jul 2021 12:03:17 +0530, Gautham R. Shenoy wrote:
>>
>> Hi,
>>
>> This is the v5 of the patchset to fixup CEDE0 latency only from
>> POWER10 onwards.
>>
>>
>> [...]
>
> Applied to powerpc/next.
>
> [1/2] cpuidle/pseries: Fixup CEDE0 latency only for POWER10 onwards
> https://git.kernel.org/powerpc/c/7cbd631d4decfd78f8a17196dce9abcd4e7e1e94
> [2/2] cpuidle/pseries: Do not cap the CEDE0 latency in fixup_cede0_latency()
> https://git.kernel.org/powerpc/c/4bceb03859c1a508669ce542c649c8d4f5d4bd93
First commit had a bad fixes tag, so now these are:
[1/2] cpuidle/pseries: Fixup CEDE0 latency only for POWER10 onwards
https://git.kernel.org/powerpc/c/50741b70b0cbbafbd9199f5180e66c0c53783a4a
[2/2] cpuidle/pseries: Do not cap the CEDE0 latency in fixup_cede0_latency()
https://git.kernel.org/powerpc/c/71737a6c2a8f801622d2b71567d1ec1e4c5b40b8
cheers
^ permalink raw reply
* [PATCH v4] soc: fsl: qe: convert QE interrupt controller to platform_device
From: Maxim Kochetkov @ 2021-08-03 11:35 UTC (permalink / raw)
To: linuxppc-dev
Cc: kernel test robot, saravanak, gregkh, linux-kernel, leoyang.li,
Maxim Kochetkov, Dan Carpenter, linux-arm-kernel, qiang.zhao
Since 5.13 QE's ucc nodes can't get interrupts from devicetree:
ucc@2000 {
cell-index = <1>;
reg = <0x2000 0x200>;
interrupts = <32>;
interrupt-parent = <&qeic>;
};
Now fw_devlink expects driver to create and probe a struct device
for interrupt controller.
So lets convert this driver to simple platform_device with probe().
Also use platform_get_ and devm_ family function to get/allocate
resources and drop unused .compatible = "qeic".
[1] - https://lore.kernel.org/lkml/CAGETcx9PiX==mLxB9PO8Myyk6u2vhPVwTMsA5NkD-ywH5xhusw@mail.gmail.com
Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
Fixes: ea718c699055 ("Revert "Revert "driver core: Set fw_devlink=on by default""")
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
---
drivers/soc/fsl/qe/qe_ic.c | 75 ++++++++++++++++++++++----------------
1 file changed, 44 insertions(+), 31 deletions(-)
diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c
index 3f711c1a0996..e710d554425d 100644
--- a/drivers/soc/fsl/qe/qe_ic.c
+++ b/drivers/soc/fsl/qe/qe_ic.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/device.h>
#include <linux/spinlock.h>
+#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <soc/fsl/qe/qe.h>
@@ -404,41 +405,40 @@ static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
chip->irq_eoi(&desc->irq_data);
}
-static void __init qe_ic_init(struct device_node *node)
+static int qe_ic_init(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
void (*low_handler)(struct irq_desc *desc);
void (*high_handler)(struct irq_desc *desc);
struct qe_ic *qe_ic;
- struct resource res;
- u32 ret;
+ struct resource *res;
+ struct device_node *node = pdev->dev.of_node;
- ret = of_address_to_resource(node, 0, &res);
- if (ret)
- return;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
- qe_ic = kzalloc(sizeof(*qe_ic), GFP_KERNEL);
+ qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL);
if (qe_ic == NULL)
- return;
+ return -ENOMEM;
- qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
- &qe_ic_host_ops, qe_ic);
- if (qe_ic->irqhost == NULL) {
- kfree(qe_ic);
- return;
+ qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res));
+ if (qe_ic->regs == NULL) {
+ dev_err(dev, "failed to ioremap() registers\n");
+ return -ENODEV;
}
- qe_ic->regs = ioremap(res.start, resource_size(&res));
-
qe_ic->hc_irq = qe_ic_irq_chip;
- qe_ic->virq_high = irq_of_parse_and_map(node, 0);
- qe_ic->virq_low = irq_of_parse_and_map(node, 1);
+ qe_ic->virq_high = platform_get_irq(pdev, 0);
+ qe_ic->virq_low = platform_get_irq(pdev, 1);
- if (!qe_ic->virq_low) {
- printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
- kfree(qe_ic);
- return;
+ if (qe_ic->virq_low < 0) {
+ return -ENODEV;
}
+
if (qe_ic->virq_high != qe_ic->virq_low) {
low_handler = qe_ic_cascade_low;
high_handler = qe_ic_cascade_high;
@@ -447,6 +447,13 @@ static void __init qe_ic_init(struct device_node *node)
high_handler = NULL;
}
+ qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+ &qe_ic_host_ops, qe_ic);
+ if (qe_ic->irqhost == NULL) {
+ dev_err(dev, "failed to add irq domain\n");
+ return -ENODEV;
+ }
+
qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
irq_set_handler_data(qe_ic->virq_low, qe_ic);
@@ -456,20 +463,26 @@ static void __init qe_ic_init(struct device_node *node)
irq_set_handler_data(qe_ic->virq_high, qe_ic);
irq_set_chained_handler(qe_ic->virq_high, high_handler);
}
+ return 0;
}
+static const struct of_device_id qe_ic_ids[] = {
+ { .compatible = "fsl,qe-ic"},
+ { .type = "qeic"},
+ {},
+};
-static int __init qe_ic_of_init(void)
+static struct platform_driver qe_ic_driver =
{
- struct device_node *np;
+ .driver = {
+ .name = "qe-ic",
+ .of_match_table = qe_ic_ids,
+ },
+ .probe = qe_ic_init,
+};
- np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
- if (!np) {
- np = of_find_node_by_type(NULL, "qeic");
- if (!np)
- return -ENODEV;
- }
- qe_ic_init(np);
- of_node_put(np);
+static int __init qe_ic_of_init(void)
+{
+ platform_driver_register(&qe_ic_driver);
return 0;
}
subsys_initcall(qe_ic_of_init);
--
2.31.1
^ permalink raw reply related
* [PATCH v2 5/6] PCI: Adapt all code locations to not use struct pci_dev::driver directly
From: Uwe Kleine-König @ 2021-08-03 10:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Mark Rutland, Giovanni Cabiddu, Rafał Miłecki,
Peter Zijlstra, linux-pci, Alexander Duyck, Sathya Prakash,
oss-drivers, Paul Mackerras, H. Peter Anvin, Jiri Olsa,
Boris Ostrovsky, linux-perf-users, Stefano Stabellini, Herbert Xu,
linux-scsi, Ido Schimmel, x86, qat-linux, Alexander Shishkin,
Ingo Molnar, linux-wireless, Jakub Kicinski, Mathias Nyman,
Yisen Zhuang, Fiona Trahe, Andrew Donnellan, Arnd Bergmann,
Konrad Rzeszutek Wilk, Suganath Prabu Subramani, Simon Horman,
Arnaldo Carvalho de Melo, Borislav Petkov, Michael Buesch,
Jiri Pirko, Namhyung Kim, Thomas Gleixner, Andy Shevchenko,
Juergen Gross, Salil Mehta, Sreekanth Reddy, xen-devel,
Vadym Kochan, MPT-FusionLinux.pdl, Greg Kroah-Hartman, linux-usb,
Wojciech Ziemba, linux-kernel, Taras Chornyi, Zhou Wang,
linux-crypto, kernel, netdev, Frederic Barrat,
Oliver O'Halloran, linuxppc-dev, David S. Miller
In-Reply-To: <20210803100150.1543597-1-u.kleine-koenig@pengutronix.de>
This prepares removing the driver member of struct pci_dev which holds the
same information than struct pci_dev::dev->driver.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
arch/powerpc/include/asm/ppc-pci.h | 3 +-
arch/powerpc/kernel/eeh_driver.c | 12 ++++---
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/kernel/probe_roms.c | 2 +-
drivers/bcma/host_pci.c | 6 ++--
drivers/crypto/hisilicon/qm.c | 2 +-
drivers/crypto/qat/qat_common/adf_aer.c | 2 +-
drivers/message/fusion/mptbase.c | 4 +--
drivers/misc/cxl/guest.c | 21 +++++------
drivers/misc/cxl/pci.c | 25 +++++++------
.../ethernet/hisilicon/hns3/hns3_ethtool.c | 2 +-
.../ethernet/marvell/prestera/prestera_pci.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/pci.c | 2 +-
.../ethernet/netronome/nfp/nfp_net_ethtool.c | 2 +-
drivers/pci/iov.c | 23 +++++++-----
drivers/pci/pci-driver.c | 28 ++++++++-------
drivers/pci/pci.c | 10 +++---
drivers/pci/pcie/err.c | 35 ++++++++++---------
drivers/pci/xen-pcifront.c | 3 +-
drivers/ssb/pcihost_wrapper.c | 7 ++--
drivers/usb/host/xhci-pci.c | 3 +-
21 files changed, 112 insertions(+), 84 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 2b9edbf6e929..63938c156c57 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -57,7 +57,8 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev);
static inline const char *eeh_driver_name(struct pci_dev *pdev)
{
- return (pdev && pdev->driver) ? pdev->driver->name : "<null>";
+ struct pci_driver *pdrv;
+ return (pdev && (pdrv = pci_driver_of_dev(pdev))) ? pdrv->name : "<null>";
}
#endif /* CONFIG_EEH */
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 3eff6a4888e7..0fc712a8775e 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -104,13 +104,14 @@ static bool eeh_edev_actionable(struct eeh_dev *edev)
*/
static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
{
- if (!pdev || !pdev->driver)
+ struct pci_driver *pdrv;
+ if (!pdev || !(pdrv = pci_driver_of_dev(pdev)))
return NULL;
- if (!try_module_get(pdev->driver->driver.owner))
+ if (!try_module_get(pdrv->driver.owner))
return NULL;
- return pdev->driver;
+ return pdrv;
}
/**
@@ -122,10 +123,11 @@ static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev)
*/
static inline void eeh_pcid_put(struct pci_dev *pdev)
{
- if (!pdev || !pdev->driver)
+ struct pci_driver *pdrv;
+ if (!pdev || !(pdrv = pci_driver_of_dev(pdev)))
return;
- module_put(pdev->driver->driver.owner);
+ module_put(pdrv->driver.owner);
}
/**
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 9bf4dbbc26e2..14eb141b6cf2 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1176,7 +1176,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
* PCI slot and func to indicate the uncore box.
*/
if (id->driver_data & ~0xffff) {
- struct pci_driver *pci_drv = pdev->driver;
+ struct pci_driver *pci_drv = pci_driver_of_dev(pdev);
pmu = uncore_pci_find_dev_pmu(pdev, pci_drv->id_table);
if (pmu == NULL)
diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c
index 9e1def3744f2..55bfafec9684 100644
--- a/arch/x86/kernel/probe_roms.c
+++ b/arch/x86/kernel/probe_roms.c
@@ -80,7 +80,7 @@ static struct resource video_rom_resource = {
*/
static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device)
{
- struct pci_driver *drv = pdev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pdev);
const struct pci_device_id *id;
if (pdev->vendor == vendor && pdev->device == device)
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 69c10a7b7c61..f9bfae87ebd9 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -161,6 +161,7 @@ static int bcma_host_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct bcma_bus *bus;
+ struct pci_driver *pdrv;
int err = -ENOMEM;
const char *name;
u32 val;
@@ -176,8 +177,9 @@ static int bcma_host_pci_probe(struct pci_dev *dev,
goto err_kfree_bus;
name = dev_name(&dev->dev);
- if (dev->driver && dev->driver->name)
- name = dev->driver->name;
+ pdrv = pci_driver_of_dev(dev);
+ if (pdrv && pdrv->name)
+ name = pdrv->name;
err = pci_request_regions(dev, name);
if (err)
goto err_pci_disable;
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 1d67f94a1d56..303cc546f466 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3003,7 +3003,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
};
int ret;
- ret = strscpy(interface.name, pdev->driver->name,
+ ret = strscpy(interface.name, pci_driver_of_dev(pdev)->name,
sizeof(interface.name));
if (ret < 0)
return -ENAMETOOLONG;
diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
index d2ae293d0df6..162c2b9ef93d 100644
--- a/drivers/crypto/qat/qat_common/adf_aer.c
+++ b/drivers/crypto/qat/qat_common/adf_aer.c
@@ -185,7 +185,7 @@ static const struct pci_error_handlers adf_err_handler = {
int adf_enable_aer(struct adf_accel_dev *accel_dev)
{
struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
- struct pci_driver *pdrv = pdev->driver;
+ struct pci_driver *pdrv = pci_driver_of_dev(pdev);
pdrv->err_handler = &adf_err_handler;
pci_enable_pcie_error_reporting(pdev);
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 7f7abc9069f7..b93e160560d4 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -838,8 +838,8 @@ mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
/* call per pci device probe entry point */
list_for_each_entry(ioc, &ioc_list, list) {
- id = ioc->pcidev->driver ?
- ioc->pcidev->driver->id_table : NULL;
+ struct pci_driver *pdrv = pci_driver_of_dev(ioc->pcidev);
+ id = pdrv ? pdrv->id_table : NULL;
if (dd_cbfunc->probe)
dd_cbfunc->probe(ioc->pcidev, id);
}
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
index 186308f1f8eb..99b969b182b5 100644
--- a/drivers/misc/cxl/guest.c
+++ b/drivers/misc/cxl/guest.c
@@ -25,28 +25,29 @@ static void pci_error_handlers(struct cxl_afu *afu,
return;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (!afu_dev->driver)
+ struct pci_driver *afu_drv = pci_driver_of_dev(afu_dev);
+ if (!afu_drv)
continue;
switch (bus_error_event) {
case CXL_ERROR_DETECTED_EVENT:
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->error_detected)
- afu_dev->driver->err_handler->error_detected(afu_dev, state);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->error_detected)
+ afu_drv->err_handler->error_detected(afu_dev, state);
break;
case CXL_SLOT_RESET_EVENT:
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->slot_reset)
- afu_dev->driver->err_handler->slot_reset(afu_dev);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->slot_reset)
+ afu_drv->err_handler->slot_reset(afu_dev);
break;
case CXL_RESUME_EVENT:
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->resume)
- afu_dev->driver->err_handler->resume(afu_dev);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->resume)
+ afu_drv->err_handler->resume(afu_dev);
break;
}
}
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index 2ba899f5659f..1cf39275029f 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1805,13 +1805,14 @@ static pci_ers_result_t cxl_vphb_error_detected(struct cxl_afu *afu,
return result;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (!afu_dev->driver)
+ struct pci_driver *afu_drv = pci_driver_of_dev(afu_dev);
+ if (!afu_drv)
continue;
afu_dev->error_state = state;
- if (afu_dev->driver->err_handler)
- afu_result = afu_dev->driver->err_handler->error_detected(afu_dev,
+ if (afu_drv->err_handler)
+ afu_result = afu_drv->err_handler->error_detected(afu_dev,
state);
/* Disconnect trumps all, NONE trumps NEED_RESET */
if (afu_result == PCI_ERS_RESULT_DISCONNECT)
@@ -2003,6 +2004,8 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
continue;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
+ struct pci_driver *afu_drv;
+
/* Reset the device context.
* TODO: make this less disruptive
*/
@@ -2028,12 +2031,13 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
* shouldn't start new work until we call
* their resume function.
*/
- if (!afu_dev->driver)
+ afu_drv = pci_driver_of_dev(afu_dev);
+ if (!afu_drv)
continue;
- if (afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->slot_reset)
- afu_result = afu_dev->driver->err_handler->slot_reset(afu_dev);
+ if (afu_drv->err_handler &&
+ afu_drv->err_handler->slot_reset)
+ afu_result = afu_drv->err_handler->slot_reset(afu_dev);
if (afu_result == PCI_ERS_RESULT_DISCONNECT)
result = PCI_ERS_RESULT_DISCONNECT;
@@ -2074,9 +2078,10 @@ static void cxl_pci_resume(struct pci_dev *pdev)
continue;
list_for_each_entry(afu_dev, &afu->phb->bus->devices, bus_list) {
- if (afu_dev->driver && afu_dev->driver->err_handler &&
- afu_dev->driver->err_handler->resume)
- afu_dev->driver->err_handler->resume(afu_dev);
+ struct pci_driver *afu_drv = pci_driver_of_dev(afu_dev);
+ if (afu_drv && afu_drv->err_handler &&
+ afu_drv->err_handler->resume)
+ afu_drv->err_handler->resume(afu_dev);
}
}
spin_unlock(&adapter->afu_list_lock);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 82061ab6930f..e085454c8b84 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -593,7 +593,7 @@ static void hns3_get_drvinfo(struct net_device *netdev,
return;
}
- strncpy(drvinfo->driver, h->pdev->driver->name,
+ strncpy(drvinfo->driver, pci_driver_of_dev(h->pdev)->name,
sizeof(drvinfo->driver));
drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_pci.c b/drivers/net/ethernet/marvell/prestera/prestera_pci.c
index a250d394da38..180999c2165e 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_pci.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_pci.c
@@ -720,7 +720,7 @@ static int prestera_fw_load(struct prestera_fw *fw)
static int prestera_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
- const char *driver_name = pdev->driver->name;
+ const char *driver_name = pci_driver_of_dev(pdev)->name;
struct prestera_fw *fw;
int err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 13b0259f7ea6..d3c1ca840fa7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1876,7 +1876,7 @@ static void mlxsw_pci_cmd_fini(struct mlxsw_pci *mlxsw_pci)
static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- const char *driver_name = pdev->driver->name;
+ const char *driver_name = pci_driver_of_dev(pdev)->name;
struct mlxsw_pci *mlxsw_pci;
int err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 1b482446536d..5c25f6af3f62 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -202,7 +202,7 @@ nfp_get_drvinfo(struct nfp_app *app, struct pci_dev *pdev,
{
char nsp_version[ETHTOOL_FWVERS_LEN] = {};
- strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->driver, pci_driver_of_dev(pdev)->name, sizeof(drvinfo->driver));
nfp_net_get_nspinfo(app, nsp_version);
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
"%s %s %s %s", vnic_version, nsp_version,
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index dafdc652fcd0..7c6f0c466df8 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -164,13 +164,14 @@ static ssize_t sriov_vf_total_msix_show(struct device *dev,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_driver *pdrv = pci_driver_of_dev(pdev);
u32 vf_total_msix = 0;
device_lock(dev);
- if (!pdev->driver || !pdev->driver->sriov_get_vf_total_msix)
+ if (!pdrv || !pdrv->sriov_get_vf_total_msix)
goto unlock;
- vf_total_msix = pdev->driver->sriov_get_vf_total_msix(pdev);
+ vf_total_msix = pdrv->sriov_get_vf_total_msix(pdev);
unlock:
device_unlock(dev);
return sysfs_emit(buf, "%u\n", vf_total_msix);
@@ -183,6 +184,7 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
{
struct pci_dev *vf_dev = to_pci_dev(dev);
struct pci_dev *pdev = pci_physfn(vf_dev);
+ struct pci_driver *pdrv;
int val, ret;
ret = kstrtoint(buf, 0, &val);
@@ -193,13 +195,14 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
return -EINVAL;
device_lock(&pdev->dev);
- if (!pdev->driver || !pdev->driver->sriov_set_msix_vec_count) {
+ pdrv = pci_driver_of_dev(pdev);
+ if (!pdrv || !pdrv->sriov_set_msix_vec_count) {
ret = -EOPNOTSUPP;
goto err_pdev;
}
device_lock(&vf_dev->dev);
- if (vf_dev->driver) {
+ if (pci_driver_of_dev(vf_dev)) {
/*
* A driver is already attached to this VF and has configured
* itself based on the current MSI-X vector count. Changing
@@ -209,7 +212,7 @@ static ssize_t sriov_vf_msix_count_store(struct device *dev,
goto err_dev;
}
- ret = pdev->driver->sriov_set_msix_vec_count(vf_dev, val);
+ ret = pdrv->sriov_set_msix_vec_count(vf_dev, val);
err_dev:
device_unlock(&vf_dev->dev);
@@ -376,6 +379,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_driver *pdrv;
int ret;
u16 num_vfs;
@@ -392,14 +396,15 @@ static ssize_t sriov_numvfs_store(struct device *dev,
goto exit;
/* is PF driver loaded */
- if (!pdev->driver) {
+ pdrv = pci_driver_of_dev(pdev);
+ if (!pdrv) {
pci_info(pdev, "no driver bound to device; cannot configure SR-IOV\n");
ret = -ENOENT;
goto exit;
}
/* is PF driver loaded w/callback */
- if (!pdev->driver->sriov_configure) {
+ if (!pdrv->sriov_configure) {
pci_info(pdev, "driver does not support SR-IOV configuration via sysfs\n");
ret = -ENOENT;
goto exit;
@@ -407,7 +412,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
if (num_vfs == 0) {
/* disable VFs */
- ret = pdev->driver->sriov_configure(pdev, 0);
+ ret = pdrv->sriov_configure(pdev, 0);
goto exit;
}
@@ -419,7 +424,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
goto exit;
}
- ret = pdev->driver->sriov_configure(pdev, num_vfs);
+ ret = pdrv->sriov_configure(pdev, num_vfs);
if (ret < 0)
goto exit;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 7dff574bb2fa..740d5bf5d411 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -443,7 +443,7 @@ static int pci_device_probe(struct device *dev)
static int pci_device_remove(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pci_dev);
if (drv->remove) {
pm_runtime_get_sync(dev);
@@ -480,7 +480,7 @@ static int pci_device_remove(struct device *dev)
static void pci_device_shutdown(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pci_dev);
pm_runtime_resume(dev);
@@ -576,7 +576,7 @@ static int pci_pm_reenable_device(struct pci_dev *pci_dev)
static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pci_dev);
if (drv && drv->suspend) {
pci_power_t prev = pci_dev->current_state;
@@ -617,7 +617,7 @@ static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
static int pci_legacy_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pci_dev);
pci_fixup_device(pci_fixup_resume, pci_dev);
@@ -636,7 +636,7 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
{
- struct pci_driver *drv = pci_dev->driver;
+ struct pci_driver *drv = pci_driver_of_dev(pci_dev);
bool ret = drv && (drv->suspend || drv->resume);
/*
@@ -1224,16 +1224,17 @@ static int pci_pm_restore(struct device *dev)
static int pci_pm_runtime_suspend(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *pdrv = pci_driver_of_dev(pci_dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
pci_power_t prev = pci_dev->current_state;
int error;
/*
- * If pci_dev->driver is not set (unbound), we leave the device in D0,
+ * If pdrv is not set (unbound), we leave the device in D0,
* but it may go to D3cold when the bridge above it runtime suspends.
* Save its config space in case that happens.
*/
- if (!pci_dev->driver) {
+ if (!pdrv) {
pci_save_state(pci_dev);
return 0;
}
@@ -1279,6 +1280,7 @@ static int pci_pm_runtime_suspend(struct device *dev)
static int pci_pm_runtime_resume(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *pdrv = pci_driver_of_dev(pci_dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
pci_power_t prev_state = pci_dev->current_state;
int error = 0;
@@ -1290,7 +1292,7 @@ static int pci_pm_runtime_resume(struct device *dev)
*/
pci_restore_standard_config(pci_dev);
- if (!pci_dev->driver)
+ if (!pdrv)
return 0;
pci_fixup_device(pci_fixup_resume_early, pci_dev);
@@ -1310,13 +1312,14 @@ static int pci_pm_runtime_resume(struct device *dev)
static int pci_pm_runtime_idle(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct pci_driver *pdrv = pci_driver_of_dev(pci_dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
/*
- * If pci_dev->driver is not set (unbound), the device should
+ * If pdrv is not set (unbound), the device should
* always remain in D0 regardless of the runtime PM status
*/
- if (!pci_dev->driver)
+ if (!pdrv)
return 0;
if (!pm)
@@ -1423,8 +1426,9 @@ static struct pci_driver pci_compat_driver = {
*/
struct pci_driver *pci_dev_driver(const struct pci_dev *dev)
{
- if (dev->driver)
- return dev->driver;
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
+ if (pdrv)
+ return pdrv;
else {
int i;
for (i = 0; i <= PCI_ROM_RESOURCE; i++)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index aacf575c15cf..9565f6c1bd4f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5069,11 +5069,12 @@ EXPORT_SYMBOL_GPL(pci_dev_unlock);
static void pci_dev_save_and_disable(struct pci_dev *dev)
{
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
const struct pci_error_handlers *err_handler =
- dev->driver ? dev->driver->err_handler : NULL;
+ pdrv ? pdrv->err_handler : NULL;
/*
- * dev->driver->err_handler->reset_prepare() is protected against
+ * pdrv->err_handler->reset_prepare() is protected against
* races with ->remove() by the device lock, which must be held by
* the caller.
*/
@@ -5100,13 +5101,14 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
static void pci_dev_restore(struct pci_dev *dev)
{
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
const struct pci_error_handlers *err_handler =
- dev->driver ? dev->driver->err_handler : NULL;
+ pdrv ? pdrv->err_handler : NULL;
pci_restore_state(dev);
/*
- * dev->driver->err_handler->reset_done() is protected against
+ * err_handler->reset_done() is protected against
* races with ->remove() by the device lock, which must be held by
* the caller.
*/
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index b576aa890c76..5b2b7b2972dd 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -51,12 +51,12 @@ static int report_error_detected(struct pci_dev *dev,
{
pci_ers_result_t vote;
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
device_lock(&dev->dev);
if (!pci_dev_set_io_state(dev, state) ||
- !dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->error_detected) {
+ !pdrv || !pdrv->err_handler ||
+ !pdrv->err_handler->error_detected) {
/*
* If any device in the subtree does not have an error_detected
* callback, PCI_ERS_RESULT_NO_AER_DRIVER prevents subsequent
@@ -70,7 +70,7 @@ static int report_error_detected(struct pci_dev *dev,
vote = PCI_ERS_RESULT_NONE;
}
} else {
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->error_detected(dev, state);
}
pci_uevent_ers(dev, vote);
@@ -93,14 +93,15 @@ static int report_mmio_enabled(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
device_lock(&dev->dev);
- if (!dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->mmio_enabled)
+ if (!pdrv ||
+ !pdrv->err_handler ||
+ !pdrv->err_handler->mmio_enabled)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->mmio_enabled(dev);
*result = merge_result(*result, vote);
out:
@@ -112,14 +113,15 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
{
pci_ers_result_t vote, *result = data;
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
device_lock(&dev->dev);
- if (!dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->slot_reset)
+ if (!pdrv ||
+ !pdrv->err_handler ||
+ !pdrv->err_handler->slot_reset)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
vote = err_handler->slot_reset(dev);
*result = merge_result(*result, vote);
out:
@@ -130,15 +132,16 @@ static int report_slot_reset(struct pci_dev *dev, void *data)
static int report_resume(struct pci_dev *dev, void *data)
{
const struct pci_error_handlers *err_handler;
+ struct pci_driver *pdrv = pci_driver_of_dev(dev);
device_lock(&dev->dev);
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
- !dev->driver ||
- !dev->driver->err_handler ||
- !dev->driver->err_handler->resume)
+ !pdrv ||
+ !pdrv->err_handler ||
+ !pdrv->err_handler->resume)
goto out;
- err_handler = dev->driver->err_handler;
+ err_handler = pdrv->err_handler;
err_handler->resume(dev);
out:
pci_uevent_ers(dev, PCI_ERS_RESULT_RECOVERED);
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 3c648e6cb8f8..fc3ffb6a8689 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -598,12 +598,11 @@ static pci_ers_result_t pcifront_common_process(int cmd,
result = PCI_ERS_RESULT_NONE;
pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
- if (!pcidev || !pcidev->driver) {
+ if (!pcidev || !(pdrv = pci_driver_of_dev(pcidev))) {
dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
pci_dev_put(pcidev);
return result;
}
- pdrv = pcidev->driver;
if (pdrv->err_handler && pdrv->err_handler->error_detected) {
pci_dbg(pcidev, "trying to call AER service\n");
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index 410215c16920..9cd3633498d3 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -68,6 +68,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct ssb_bus *ssb;
+ struct pci_driver *pdrv;
int err = -ENOMEM;
const char *name;
u32 val;
@@ -79,8 +80,10 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
if (err)
goto err_kfree_ssb;
name = dev_name(&dev->dev);
- if (dev->driver && dev->driver->name)
- name = dev->driver->name;
+
+ pdrv = pci_driver_of_dev(dev);
+ if (pdrv && pdrv->name)
+ name = pdrv->name;
err = pci_request_regions(dev, name);
if (err)
goto err_pci_disable;
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 18c2bbddf080..d8a6ef602a46 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -100,10 +100,11 @@ static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev)
static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_driver *pdrv = pci_driver_of_dev(pdev);
struct xhci_driver_data *driver_data;
const struct pci_device_id *id;
- id = pci_match_id(pdev->driver->id_table, pdev);
+ id = pci_match_id(pdrv->id_table, pdev);
if (id && id->driver_data) {
driver_data = (struct xhci_driver_data *)id->driver_data;
--
2.30.2
^ permalink raw reply related
* [PATCH v2 0/6] PCI: Drop duplicated tracking of a pci_dev's bound driver
From: Uwe Kleine-König @ 2021-08-03 10:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Mark Rutland, Giovanni Cabiddu, Rafał Miłecki,
Peter Zijlstra, linux-pci, Alexander Duyck, Sathya Prakash,
oss-drivers, Paul Mackerras, H. Peter Anvin, Jiri Olsa,
Boris Ostrovsky, linux-perf-users, Stefano Stabellini, Herbert Xu,
linux-scsi, Ido Schimmel, x86, qat-linux, Alexander Shishkin,
Ingo Molnar, linux-wireless, Jakub Kicinski, Mathias Nyman,
Yisen Zhuang, Fiona Trahe, Andrew Donnellan, Arnd Bergmann,
Konrad Rzeszutek Wilk, Suganath Prabu Subramani, Simon Horman,
Arnaldo Carvalho de Melo, Borislav Petkov, Michael Buesch,
Jiri Pirko, Namhyung Kim, Thomas Gleixner, Andy Shevchenko,
Juergen Gross, Salil Mehta, Sreekanth Reddy, xen-devel,
Vadym Kochan, MPT-FusionLinux.pdl, Greg Kroah-Hartman, linux-usb,
Wojciech Ziemba, linux-kernel, Taras Chornyi, Zhou Wang,
linux-crypto, kernel, netdev, Frederic Barrat,
Oliver O'Halloran, linuxppc-dev, David S. Miller
Hello,
changes since v1 (https://lore.kernel.org/linux-pci/20210729203740.1377045-1-u.kleine-koenig@pengutronix.de):
- New patch to simplify drivers/pci/xen-pcifront.c, spotted and
suggested by Boris Ostrovsky
- Fix a possible NULL pointer dereference I introduced in xen-pcifront.c
- A few whitespace improvements
- Add a commit log to patch #6 (formerly #5)
I also expanded the audience for patches #4 and #6 to allow affected
people to actually see the changes to their drivers.
Interdiff can be found below.
The idea is still the same: After a few cleanups (#1 - #3) a new macro
is introduced abstracting access to struct pci_dev->driver. All users
are then converted to use this and in the last patch the macro is
changed to make use of struct pci_dev::dev->driver to get rid of the
duplicated tracking.
Best regards
Uwe
Uwe Kleine-König (6):
PCI: Simplify pci_device_remove()
PCI: Drop useless check from pci_device_probe()
xen/pci: Drop some checks that are always true
PCI: Provide wrapper to access a pci_dev's bound driver
PCI: Adapt all code locations to not use struct pci_dev::driver
directly
PCI: Drop duplicated tracking of a pci_dev's bound driver
arch/powerpc/include/asm/ppc-pci.h | 3 +-
arch/powerpc/kernel/eeh_driver.c | 12 ++--
arch/x86/events/intel/uncore.c | 2 +-
arch/x86/kernel/probe_roms.c | 2 +-
drivers/bcma/host_pci.c | 6 +-
drivers/crypto/hisilicon/qm.c | 2 +-
drivers/crypto/qat/qat_common/adf_aer.c | 2 +-
drivers/message/fusion/mptbase.c | 4 +-
drivers/misc/cxl/guest.c | 21 +++----
drivers/misc/cxl/pci.c | 25 ++++----
.../ethernet/hisilicon/hns3/hns3_ethtool.c | 2 +-
.../ethernet/marvell/prestera/prestera_pci.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/pci.c | 2 +-
.../ethernet/netronome/nfp/nfp_net_ethtool.c | 2 +-
drivers/pci/iov.c | 23 ++++---
drivers/pci/pci-driver.c | 48 +++++++--------
drivers/pci/pci.c | 10 ++--
drivers/pci/pcie/err.c | 35 ++++++-----
drivers/pci/xen-pcifront.c | 60 ++++++++-----------
drivers/ssb/pcihost_wrapper.c | 7 ++-
drivers/usb/host/xhci-pci.c | 3 +-
include/linux/pci.h | 2 +-
22 files changed, 145 insertions(+), 130 deletions(-)
Range-diff against v1:
1: 7d97605df363 = 1: 8ba6e9faa18c PCI: Simplify pci_device_remove()
2: aec84c688d0f = 2: d8a7dc52091f PCI: Drop useless check from pci_device_probe()
-: ------------ > 3: f4b78aa41776 xen/pci: Drop some checks that are always true
3: e6f933f532c9 = 4: 50f3daa64170 PCI: Provide wrapper to access a pci_dev's bound driver
4: d678a2924143 ! 5: 21cbd3f180a1 PCI: Adapt all code locations to not use struct pci_dev::driver directly
@@ drivers/message/fusion/mptbase.c: mpt_device_driver_register(struct mpt_pci_driv
- id = ioc->pcidev->driver ?
- ioc->pcidev->driver->id_table : NULL;
+ struct pci_driver *pdrv = pci_driver_of_dev(ioc->pcidev);
-+ id = pdrv ? pdrv->id_table : NULL;
++ id = pdrv ? pdrv->id_table : NULL;
if (dd_cbfunc->probe)
dd_cbfunc->probe(ioc->pcidev, id);
}
@@ drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c: static void hns3_get_drvinfo
}
- strncpy(drvinfo->driver, h->pdev->driver->name,
-- sizeof(drvinfo->driver));
-+ strncpy(drvinfo->driver, pci_driver_of_dev(h->pdev)->name, sizeof(drvinfo->driver));
++ strncpy(drvinfo->driver, pci_driver_of_dev(h->pdev)->name,
+ sizeof(drvinfo->driver));
drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
- strncpy(drvinfo->bus_info, pci_name(h->pdev),
## drivers/net/ethernet/marvell/prestera/prestera_pci.c ##
@@ drivers/net/ethernet/marvell/prestera/prestera_pci.c: static int prestera_fw_load(struct prestera_fw *fw)
@@ drivers/pci/xen-pcifront.c: static pci_ers_result_t pcifront_common_process(int
pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
- if (!pcidev || !pcidev->driver) {
-+ pdrv = pci_driver_of_dev(pcidev);
-+ if (!pcidev || !pdrv) {
++ if (!pcidev || !(pdrv = pci_driver_of_dev(pcidev))) {
dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
pci_dev_put(pcidev);
return result;
}
- pdrv = pcidev->driver;
- if (pdrv) {
- if (pdrv->err_handler && pdrv->err_handler->error_detected) {
+ if (pdrv->err_handler && pdrv->err_handler->error_detected) {
+ pci_dbg(pcidev, "trying to call AER service\n");
## drivers/ssb/pcihost_wrapper.c ##
@@ drivers/ssb/pcihost_wrapper.c: static int ssb_pcihost_probe(struct pci_dev *dev,
@@ drivers/ssb/pcihost_wrapper.c: static int ssb_pcihost_probe(struct pci_dev *dev,
name = dev_name(&dev->dev);
- if (dev->driver && dev->driver->name)
- name = dev->driver->name;
-+
++
+ pdrv = pci_driver_of_dev(dev);
+ if (pdrv && pdrv->name)
+ name = pdrv->name;
5: 8c70ffd24380 ! 6: 02e6da6e5919 PCI: Drop duplicated tracking of a pci_dev's bound driver
@@ Metadata
## Commit message ##
PCI: Drop duplicated tracking of a pci_dev's bound driver
+ Currently it's tracked twice which driver is bound to a given pci
+ device. Now that all users of the pci specific one (struct
+ pci_dev::driver) are updated to use an access macro
+ (pci_driver_of_dev()), change the macro to use the information from the
+ driver core and remove the driver member from struct pci_dev.
+
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
## drivers/pci/pci-driver.c ##
base-commit: 2734d6c1b1a089fb593ef6a23d4b70903526fe0c
--
2.30.2
^ permalink raw reply
* [PATCH v2 4/6] PCI: Provide wrapper to access a pci_dev's bound driver
From: Uwe Kleine-König @ 2021-08-03 10:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Mark Rutland, Giovanni Cabiddu, Rafał Miłecki,
Peter Zijlstra, linux-pci, Alexander Duyck, Sathya Prakash,
oss-drivers, Paul Mackerras, H. Peter Anvin, Jiri Olsa,
Boris Ostrovsky, linux-perf-users, Stefano Stabellini, Herbert Xu,
linux-scsi, Ido Schimmel, x86, qat-linux, Alexander Shishkin,
Ingo Molnar, linux-wireless, Jakub Kicinski, Mathias Nyman,
Yisen Zhuang, Fiona Trahe, Andrew Donnellan, Arnd Bergmann,
Konrad Rzeszutek Wilk, Suganath Prabu Subramani, Simon Horman,
Arnaldo Carvalho de Melo, Borislav Petkov, Michael Buesch,
Jiri Pirko, Namhyung Kim, Thomas Gleixner, Andy Shevchenko,
Juergen Gross, Salil Mehta, Sreekanth Reddy, xen-devel,
Vadym Kochan, MPT-FusionLinux.pdl, Greg Kroah-Hartman, linux-usb,
Wojciech Ziemba, linux-kernel, Taras Chornyi, Zhou Wang,
linux-crypto, kernel, netdev, Frederic Barrat,
Oliver O'Halloran, linuxppc-dev, David S. Miller
In-Reply-To: <20210803100150.1543597-1-u.kleine-koenig@pengutronix.de>
Which driver a device is bound to is available twice: In struct
pci_dev::dev->driver and in struct pci_dev::driver. To get rid of the
duplication introduce a wrapper to access struct pci_dev's driver
member. Once all users are converted the wrapper can be changed to
calculate the driver using pci_dev::dev->driver.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
include/linux/pci.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 540b377ca8f6..778f3b5e6f23 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -887,6 +887,7 @@ struct pci_driver {
};
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
+#define pci_driver_of_dev(pdev) ((pdev)->driver)
/**
* PCI_DEVICE - macro used to describe a specific PCI device
--
2.30.2
^ permalink raw reply related
* [PATCH v2 6/6] PCI: Drop duplicated tracking of a pci_dev's bound driver
From: Uwe Kleine-König @ 2021-08-03 10:01 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Mark Rutland, Giovanni Cabiddu, Rafał Miłecki,
Peter Zijlstra, linux-pci, Alexander Duyck, Sathya Prakash,
oss-drivers, Paul Mackerras, H. Peter Anvin, Jiri Olsa,
Boris Ostrovsky, linux-perf-users, Stefano Stabellini, Herbert Xu,
linux-scsi, Ido Schimmel, x86, qat-linux, Alexander Shishkin,
Ingo Molnar, linux-wireless, Jakub Kicinski, Mathias Nyman,
Yisen Zhuang, Fiona Trahe, Andrew Donnellan, Arnd Bergmann,
Konrad Rzeszutek Wilk, Suganath Prabu Subramani, Simon Horman,
Arnaldo Carvalho de Melo, Borislav Petkov, Michael Buesch,
Jiri Pirko, Namhyung Kim, Thomas Gleixner, Andy Shevchenko,
Juergen Gross, Salil Mehta, Sreekanth Reddy, xen-devel,
Vadym Kochan, MPT-FusionLinux.pdl, Greg Kroah-Hartman, linux-usb,
Wojciech Ziemba, linux-kernel, Taras Chornyi, Zhou Wang,
linux-crypto, kernel, netdev, Frederic Barrat,
Oliver O'Halloran, linuxppc-dev, David S. Miller
In-Reply-To: <20210803100150.1543597-1-u.kleine-koenig@pengutronix.de>
Currently it's tracked twice which driver is bound to a given pci
device. Now that all users of the pci specific one (struct
pci_dev::driver) are updated to use an access macro
(pci_driver_of_dev()), change the macro to use the information from the
driver core and remove the driver member from struct pci_dev.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
drivers/pci/pci-driver.c | 4 ----
include/linux/pci.h | 3 +--
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 740d5bf5d411..5d950eb476e2 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -305,12 +305,10 @@ static long local_pci_probe(void *_ddi)
* its remove routine.
*/
pm_runtime_get_sync(dev);
- pci_dev->driver = pci_drv;
rc = pci_drv->probe(pci_dev, ddi->id);
if (!rc)
return rc;
if (rc < 0) {
- pci_dev->driver = NULL;
pm_runtime_put_sync(dev);
return rc;
}
@@ -376,7 +374,6 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
* @pci_dev: PCI device being probed
*
* returns 0 on success, else error.
- * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
*/
static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
@@ -451,7 +448,6 @@ static int pci_device_remove(struct device *dev)
pm_runtime_put_noidle(dev);
}
pcibios_free_irq(pci_dev);
- pci_dev->driver = NULL;
pci_iov_remove(pci_dev);
/* Undo the runtime PM settings in local_pci_probe() */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 778f3b5e6f23..f44ab76e216f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -342,7 +342,6 @@ struct pci_dev {
u16 pcie_flags_reg; /* Cached PCIe Capabilities Register */
unsigned long *dma_alias_mask;/* Mask of enabled devfn aliases */
- struct pci_driver *driver; /* Driver bound to this device */
u64 dma_mask; /* Mask of the bits of bus address this
device implements. Normally this is
0xffffffff. You only need to change
@@ -887,7 +886,7 @@ struct pci_driver {
};
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
-#define pci_driver_of_dev(pdev) ((pdev)->driver)
+#define pci_driver_of_dev(pdev) ((pdev)->dev.driver ? to_pci_driver((pdev)->dev.driver) : NULL)
/**
* PCI_DEVICE - macro used to describe a specific PCI device
--
2.30.2
^ permalink raw reply related
* Re: [PATCH 2/3] selftests/powerpc: Add test for real address error handling
From: Michael Ellerman @ 2021-08-03 10:53 UTC (permalink / raw)
To: Ganesh Goudar, linuxppc-dev; +Cc: mikey, Ganesh Goudar, mahesh, npiggin
In-Reply-To: <20210730182349.625819-2-ganeshgr@linux.ibm.com>
Ganesh Goudar <ganeshgr@linux.ibm.com> writes:
> Add test for real address or control memory address access
> error handling, using NX-GZIP engine.
>
> The error is injected by accessing the control memory address
> using illegal instruction, on successful handling the process
> attempting to access control memory address using illegal
> instruction receives SIGBUS.
>
> Signed-off-by: Ganesh Goudar <ganeshgr@linux.ibm.com>
> ---
> tools/testing/selftests/powerpc/Makefile | 3 +-
> tools/testing/selftests/powerpc/mce/Makefile | 6 +++
> .../selftests/powerpc/mce/inject-ra-err.c | 42 +++++++++++++++++++
> .../selftests/powerpc/mce/inject-ra-err.sh | 19 +++++++++
> 4 files changed, 69 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/powerpc/mce/Makefile
> create mode 100644 tools/testing/selftests/powerpc/mce/inject-ra-err.c
> create mode 100755 tools/testing/selftests/powerpc/mce/inject-ra-err.sh
This breaks the selftests build:
https://github.com/ruscur/linux-ci/runs/3204665920?check_suite_focus=true
make[2]: Entering directory '/linux/tools/testing/selftests/powerpc/mce'
powerpc-linux-gnu-gcc -std=gnu99 -O2 -Wall -Werror -DGIT_VERSION='"77349a6"' -I/linux/tools/testing/selftests/powerpc/include inject-ra-err.c -o /output/kselftest/powerpc/mce/inject-ra-err
Error: inject-ra-err.c:11:25: fatal error: asm/vas-api.h: No such file or directory
cheers
^ permalink raw reply
* Re: [PATCH v5 0/2] cpuidle/pseries: cleanup of the CEDE0 latency fixup code
From: Michael Ellerman @ 2021-08-03 10:20 UTC (permalink / raw)
To: Vaidyanathan Srinivasan, Rafael J. Wysocki, Michael Ellerman,
Michal Suchanek, Gautham R. Shenoy, Aneesh Kumar K.V,
Daniel Lezcano
Cc: linuxppc-dev, joedecke, linux-pm
In-Reply-To: <1626676399-15975-1-git-send-email-ego@linux.vnet.ibm.com>
On Mon, 19 Jul 2021 12:03:17 +0530, Gautham R. Shenoy wrote:
>
> Hi,
>
> This is the v5 of the patchset to fixup CEDE0 latency only from
> POWER10 onwards.
>
>
> [...]
Applied to powerpc/next.
[1/2] cpuidle/pseries: Fixup CEDE0 latency only for POWER10 onwards
https://git.kernel.org/powerpc/c/7cbd631d4decfd78f8a17196dce9abcd4e7e1e94
[2/2] cpuidle/pseries: Do not cap the CEDE0 latency in fixup_cede0_latency()
https://git.kernel.org/powerpc/c/4bceb03859c1a508669ce542c649c8d4f5d4bd93
cheers
^ permalink raw reply
* Re: [PATCH] powerpc/stacktrace: Include linux/delay.h
From: Michael Ellerman @ 2021-08-03 10:20 UTC (permalink / raw)
To: Michal Suchanek, linuxppc-dev
In-Reply-To: <20210729180103.15578-1-msuchanek@suse.de>
On Thu, 29 Jul 2021 20:01:03 +0200, Michal Suchanek wrote:
> commit 7c6986ade69e ("powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()")
> introduces udelay() call without including the linux/delay.h header.
> This may happen to work on master but the header that declares the
> functionshould be included nonetheless.
Applied to powerpc/next.
[1/1] powerpc/stacktrace: Include linux/delay.h
https://git.kernel.org/powerpc/c/135462ae7692a824e5b63299178684fca3a366e6
cheers
^ permalink raw reply
* Re: [PATCH] powerpc/kexec: blacklist functions called in real mode for kprobe
From: Michael Ellerman @ 2021-08-03 10:20 UTC (permalink / raw)
To: Michael Ellerman, Hari Bathini
Cc: Naveen N. Rao, linuxppc-dev, Mahesh J Salgaonkar, Sourabh Jain
In-Reply-To: <162626687834.155313.4692863392927831843.stgit@hbathini-workstation.ibm.com>
On Wed, 14 Jul 2021 18:17:58 +0530, Hari Bathini wrote:
> As kprobe does not handle events happening in real mode, blacklist the
> functions that only get called in real mode or in kexec sequence with
> MMU turned off.
Applied to powerpc/next.
[1/1] powerpc/kexec: blacklist functions called in real mode for kprobe
https://git.kernel.org/powerpc/c/8119cefd9a29b71997e62b762932d23499ba4896
cheers
^ permalink raw reply
* Re: Debian SID kernel doesn't boot on PowerBook 3400c
From: Christophe Leroy @ 2021-08-03 10:08 UTC (permalink / raw)
To: Stan Johnson; +Cc: Debian PowerPC, linuxppc-dev, Finn Thain
In-Reply-To: <b84bb7ff-2dfb-0ae6-6eee-dd3c40661982@yahoo.com>
Le 02/08/2021 à 19:32, Stan Johnson a écrit :
> On 8/2/21 8:41 AM, Christophe Leroy wrote:
>>
>>
>> Le 31/07/2021 à 20:24, Stan Johnson a écrit :
>>> Hi Christophe,
>>>
>>> On 7/31/21 9:58 AM, Christophe Leroy wrote:
>>>> Stan Johnson <userm57@yahoo.com> a écrit :
>>>>
>>>>> Hello,
>>>>>
>>>>> The current Debian SID kernel will not boot on a PowerBook 3400c
>>>>> running
>>>>> the latest version of Debian SID. If booted using the BootX extension,
>>>>> the kernel hangs immediately:
>>>>>
>>>>> "Welcome to Linux, kernel 5.10.0-8-powerpc"
>>>>>
>>>>> If booted from Mac OS, the Mac OS screen hangs.
>>>>>
>>>>> Booting also hangs if the "No video driver" option is selected in
>>>>> BootX,
>>>>> "No video driver" causes "video=ofonly" to be passed to the kernel.
>>>>>
>>>>> This is the current command line that I'm using in BootX:
>>>>> root=/dev/sda13 video=chips65550:vmode:14,cmode:16
>>>>>
>>>>> Kernel v5.9 works as expected.
>>>>>
>>>>> The config file I'm using is attached.
>>>>>
>>>>> Here are the results of a git bisect, marking v5.9 as "good" and the
>>>>> most current kernel as "bad":
>>>>>
>>>>> $ cd linux
>>>>> $ git remote update
>>>>> $ git bisect reset
>>>>> $ git bisect start
>>>>> $ git bisect bad
>>>>> $ git bisect good v5.9
>>>>>
>>>>> Note: "bad" -> hangs at boot; "good" -> boots to login prompt
>>>>>
>>>>> 1) 5.11.0-rc5-pmac-00034-g684da7628d9 (bad)
>>>>> 2) 5.10.0-rc3-pmac-00383-gbb9dd3ce617 (good)
>>>>> 3) 5.10.0-pmac-06637-g2911ed9f47b (good)
>>>>> Note: I had to disable SMP to build this kernel.
>>>>> 4) 5.10.0-pmac-10584-g9805529ec54 (good)
>>>>> Note: I had to disable SMP to build this kernel.
>>>>> 5) 5.10.0-pmac-12577-g8552d28e140 (bad)
>>>>> 6) 5.10.0-pmac-11576-g8a5be36b930 (bad)
>>>>> 7) 5.10.0-pmac-11044-gbe695ee29e8 (good)
>>>>> Note: I had to disable SMP to build this kernel.
>>>>> 8) 5.10.0-rc2-pmac-00288-g59d512e4374 (bad)
>>>>> 9) 5.10.0-rc2-pmac-00155-gc3d35ddd1ec (good)
>>>>> 10) 5.10.0-rc2-pmac-00221-g7049b288ea8 (good)
>>>>> 11) 5.10.0-rc2-pmac-00254-g4b74a35fc7e (bad)
>>>>> 12) 5.10.0-rc2-pmac-00237-ged22bb8d39f (good)
>>>>> 13) 5.10.0-rc2-pmac-00245-g87b57ea7e10 (good)
>>>>> 14) 5.10.0-rc2-pmac-00249-gf10881a46f8 (bad)
>>>>> 15) 5.10.0-rc2-pmac-00247-gf8a4b277c3c (good)
>>>>> 16) 5.10.0-rc2-pmac-00248-gdb972a3787d (bad)
>>>>>
>>>>> db972a3787d12b1ce9ba7a31ec376d8a79e04c47 is the first bad commit
>>>>
>>>> Not sure this is really the root of the problem.
>>>>
>>>> Can you try again without CONFIG_VMAP_STACK ?
>>>>
>>>> Thanks
>>>> Christophe
>>>> ...
>>>
>>>
>>> With CONFIG_VMAP_STACK=y, 5.11.0-rc5-pmac-00034-g684da7628d9 hangs at
>>> boot on the PB 3400c.
>>>
>>> Without CONFIG_VMAP_STACK, 5.11.0-rc5-pmac-00034-g684da7628d9 boots as
>>> expected.
>>>
>>> I didn't re-build the Debian SID kernel, though I confirmed that the
>>> Debian config file for 5.10.0-8-powerpc includes CONFIG_VMAP_STACK=y.
>>> It's not clear whether removing CONFIG_VMAP_STACK would be appropriate
>>> for other powerpc systems.
>>>
>>> Please let me know why removing CONFIG_VMAP_STACK fixed the problem on
>>> the PB 3400c. Should CONFIG_HAVE_ARCH_VMAP_STACK also be removed?
>>>
>>
>> When CONFIG_HAVE_ARCH_VMAP_STACK is selected by the architecture,
>> CONFIG_VMAP_STACK is selected by default.
>>
>> The point is that your config has CONFIG_ADB_PMU.
>>
>> A bug with VMAP stack was detected during 5.9 release cycle for
>> platforms selecting CONFIG_ADB_PMU. Because fixing the bug was an heavy
>> change, we prefered at that time to disable VMAP stack, so VMAP stack
>> was deselected for CONFIG_ADB_PMU by commit
>> 4a133eb351ccc275683ad49305d0b04dde903733.
>>
>> Then as a second step, the proper fix was implemented and then VMAP
>> stack was enabled again by the commit you bisected.
>>
>> Taking into account that the problem disappears for you when you
>> manually deselect VMAP stacks, it means the problem is not the fix
>> itself, but the fact that VMAP stacks are now enable by default.
>>
>> We need to understand why VMAP stack doesn't work on your platform, more
>> than that why it doesn't boot at all with VMAP stack.
>>
>> Could you send me the dmesg output of your system when it properly boots ?
>>
>> Did you check with kernel 5.13 ?
>>
>> Thanks
>> Christophe
>>
>
> Christophe,
>
> Thanks for your response. It looks like I never tested v5.13 (I was
> originally just reporting that the default Debian SID kernel,
> 5.10.0-8-powerpc, hangs at boot on the PB 3400c).
>
> So I rebuilt the stock v5.13 from kernel.org using Finn's
> dot-config-powermac-5.13, which got changed slightly at compilation (see
> dot-config-v5.13-pmac, attached). It has CONFIG_VMAP_STACK and
> CONFIG_ADB_PMU set, and it booted, but there were multiple memory
> errors. So it looks like the hang-at-boot problem was fixed sometime
> after v5.11, but there are now memory errors (similar to Wallstreet).
>
> With CONFIG_VMAP_STACK not set (CONFIG_ADB_PMU is still set), the
> .config file turns into the attached dot-config-v5.13-pmac_NO_VMAP. And
> there were still memory errors (dmesg output attached).
>
> The memory errors may be a completely unrelated issue, since they occur
> regardless of the CONFIG_VMAP_STACK setting.
>
> To help rule out a hardware issue, I confirmed that memory errors don't
> occur with v5.8.2 (dmesg output attached).
>
> A useful git bisect might be possible if CONFIG_VMAP_STACK is disabled
> for each build. I would need to determine where the memory errors
> started (v5.9, v5.10, v5.11, or v5.12). There is the complication that
> (at least) several v5.10 kernels won't compile if SMP is set, so I might
> need to disable that everywhere as well, assuming the SMP fix didn't
> cause the memory errors.
>
Thanks a lot for the information.
Looks like the memory errors are linked to KUAP (Kernel Userspace Access Protection). Based on the
places the problems happen, I don't think there are any invalid access, so there must be something
wrong in the KUAP logic, probably linked to some interrupts happenning in kernel mode while the KUAP
window is opened. And because is not selected by default on book3s/32 until 5.14, probably nobody
ever tested it in a real environment before you.
I think the issue may be linked to commit https://github.com/linuxppc/linux/commit/c16728835 which
happened between 5.12 and 5.13. Would be nice if you could confirm that 5.12 doesn't have the
problem (At the same time maybe you can see if 5.12 also boots OK with CONFIG_VMAP_STACK)
Note that the error detected in the other thread which is being discussed with Finn might also be an
issue to be checked while we are here.
Thanks
Christophe
^ permalink raw reply
* Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
From: Finn Thain @ 2021-08-03 0:43 UTC (permalink / raw)
To: Stan Johnson, LEROY Christophe
Cc: linux-kernel, Nick Piggin, Paul Mackerras, linuxppc-dev
In-Reply-To: <9b64dde3-6ebd-b446-41d9-61e8cb0d8c39@csgroup.eu>
[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]
On Mon, 2 Aug 2021, LEROY Christophe wrote:
> Le 01/08/2021 à 03:21, Finn Thain a écrit :
> > On Sat, 31 Jul 2021, Christophe Leroy wrote:
> >
> > > >
> > > > Stan Johnson contacted me about a regression in mainline that he
> > > > observed on his G3 Powerbooks. Using 'git bisect' we determined that
> > > > this patch was the cause of the regression, i.e. commit 4c0104a83fc3
> > > > ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE").
> > > >
> > > > When testing 4c0104a83fc and all subsequent builds, various user
> > > > processes were liable to segfault. Here is the console log that Stan
> > > > provided:
> > >
> > > Hi, i will be able to look at that more in details next week, however I
> > > have a few preliminary qurstions.
> > >
> > > Can you reliabily reproduce the problem with the said commit, and can
> > > you reliabily run without problem with the parent commit ?
> >
> > Yes and yes. (I already asked Stan to establish those things before I
> > contacted the list.)
>
> I think I found the problem with that commit. Can you retry with the following
> change:
>
> diff --git a/arch/powerpc/kernel/head_book3s_32.S
> b/arch/powerpc/kernel/head_book3s_32.S
> index 0a3d7d4a9ec4..a294103a91a1 100644
> --- a/arch/powerpc/kernel/head_book3s_32.S
> +++ b/arch/powerpc/kernel/head_book3s_32.S
> @@ -299,7 +299,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
> EXCEPTION_PROLOG_1
> EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
> prepare_transfer_to_handler
> - lwz r5, _DSISR(r11)
> + lwz r5, _DSISR(r1)
> andis. r0, r5, DSISR_DABRMATCH@h
> bne- 1f
> bl do_page_fault
That patch doesn't apply to mainline. This version might help.
diff --git a/arch/powerpc/kernel/head_book3s_32.S b/arch/powerpc/kernel/head_book3s_32.S
index 764edd860ed4..68e5c0a7e99d 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -300,7 +300,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
EXCEPTION_PROLOG_1
EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
prepare_transfer_to_handler
- lwz r5, _DSISR(r11)
+ lwz r5, _DSISR(r1)
andis. r0, r5, DSISR_DABRMATCH@h
bne- 1f
bl do_page_fault
^ permalink raw reply related
* [PATCH] KVM: PPC: Book3S HV: Fix kvmhv_copy_tofrom_guest_radix
From: Fabiano Rosas @ 2021-08-02 23:49 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, christophe.leroy, npiggin
This function was introduced along with nested HV guest support. It
uses the platform's Radix MMU quadrants[1] to provide a nested
hypervisor with fast access to its nested guests memory
(H_COPY_TOFROM_GUEST hypercall). It has also since been added as a
fast path for the kvmppc_ld/st routines which are used during
instruction emulation.
The commit def0bfdbd603 ("powerpc: use probe_user_read() and
probe_user_write()") changed the low level copy function from
raw_copy_from_user to probe_user_read, which adds a check to
access_ok. In powerpc that is:
static inline bool __access_ok(unsigned long addr, unsigned long size)
{
return addr < TASK_SIZE_MAX && size <= TASK_SIZE_MAX - addr;
}
and TASK_SIZE_MAX is 0x0010000000000000UL for 64-bit, which means that
setting the two MSBs of the effective address (which correspond to the
quadrant) now cause access_ok to reject the access.
This was not caught earlier because the most common code path via
kvmppc_ld/st contains a fallback (kvm_read_guest) that is likely to
succeed for L1 guests. For nested guests there is no fallback.
Another issue is that probe_user_read (now __copy_from_user_nofault)
does not return the number of not copied bytes in case of failure, so
the destination memory is not being cleared anymore in
kvmhv_copy_from_guest_radix:
ret = kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, to, NULL, n);
if (ret > 0) <-- always false!
memset(to + (n - ret), 0, ret);
This patch fixes both issues by introducing two new functions that set
the quadrant bit of the effective address only after checking
access_ok and moving the memset closer to __copy_to_user_inatomic.
1 - for more on quadrants see commit d7b456152230 ("KVM: PPC: Book3S
HV: Implement functions to access quadrants 1 & 2")
Fixes: def0bfdbd603 ("powerpc: use probe_user_read() and probe_user_write()")
Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
---
arch/powerpc/kvm/book3s_64_mmu_radix.c | 63 ++++++++++++++++++++------
1 file changed, 49 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index b5905ae4377c..076a8e4a9135 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -30,12 +30,57 @@
*/
static int p9_supported_radix_bits[4] = { 5, 9, 9, 13 };
+/* LPIDR and PIDR must have already been set */
+static long __copy_from_guest_quadrant(void *dst, void __user *src, size_t size,
+ unsigned long quadrant)
+{
+ long ret = size;
+ mm_segment_t old_fs = force_uaccess_begin();
+
+ if (access_ok(src, size)) {
+ src += (quadrant << 62);
+
+ pagefault_disable();
+ ret = __copy_from_user_inatomic((void __user *)dst, src, size);
+ pagefault_enable();
+ }
+ force_uaccess_end(old_fs);
+
+ if (!ret)
+ return ret;
+
+ memset(dst + (size - ret), 0, ret);
+
+ return -EFAULT;
+}
+
+/* LPIDR and PIDR must have already been set */
+static long __copy_to_guest_quadrant(void __user *dst, void *src, size_t size,
+ unsigned long quadrant)
+{
+ long ret = -EFAULT;
+ mm_segment_t old_fs = force_uaccess_begin();
+
+ if (access_ok(dst, size)) {
+ dst += (quadrant << 62);
+
+ pagefault_disable();
+ ret = __copy_to_user_inatomic(dst, (void __user *)src, size);
+ pagefault_enable();
+ }
+ force_uaccess_end(old_fs);
+
+ if (ret)
+ return -EFAULT;
+ return 0;
+}
+
unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
gva_t eaddr, void *to, void *from,
unsigned long n)
{
int old_pid, old_lpid;
- unsigned long quadrant, ret = n;
+ unsigned long quadrant, ret;
bool is_load = !!to;
/* Can't access quadrants 1 or 2 in non-HV mode, call the HV to do it */
@@ -47,10 +92,6 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
quadrant = 1;
if (!pid)
quadrant = 2;
- if (is_load)
- from = (void *) (eaddr | (quadrant << 62));
- else
- to = (void *) (eaddr | (quadrant << 62));
preempt_disable();
@@ -66,9 +107,9 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
isync();
if (is_load)
- ret = copy_from_user_nofault(to, (const void __user *)from, n);
+ ret = __copy_from_guest_quadrant(to, (void __user *)eaddr, n, quadrant);
else
- ret = copy_to_user_nofault((void __user *)to, from, n);
+ ret = __copy_to_guest_quadrant((void __user *)eaddr, from, n, quadrant);
/* switch the pid first to avoid running host with unallocated pid */
if (quadrant == 1 && pid != old_pid)
@@ -109,13 +150,7 @@ static long kvmhv_copy_tofrom_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
long kvmhv_copy_from_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, void *to,
unsigned long n)
{
- long ret;
-
- ret = kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, to, NULL, n);
- if (ret > 0)
- memset(to + (n - ret), 0, ret);
-
- return ret;
+ return kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, to, NULL, n);
}
EXPORT_SYMBOL_GPL(kvmhv_copy_from_guest_radix);
--
2.29.2
^ permalink raw reply related
* Re: Possible regression by ab037dd87a2f (powerpc/vdso: Switch VDSO to generic C implementation.)
From: Lynn Boger @ 2021-08-02 18:14 UTC (permalink / raw)
To: Michael Ellerman, Paul Murphy, pmenzel
Cc: parkerderek86, xaionaro, paulus, murphyp, linuxppc-dev
In-Reply-To: <87czqwl67h.fsf@mpe.ellerman.id.au>
Fixes will be in Go 1.16.7 and 1.15.15. Backports are no longer being
done for Go 1.14.
On 8/2/21 1:18 AM, Michael Ellerman wrote:
> "Paul Murphy" <murp@ibm.com> writes:
>>
>> (My apologies for however IBM's email client munges this)
>>
>>> I heard it is going to be in Go 1.16.7, but I do not know much about Go.
>>> Maybe the folks in Cc can chime in.
>>
>>
>> We have backports primed and ready for the next point release. They
>> are waiting on the release manager to cherrypick them.
> OK good, that is still the correct fix in the long run.
>
>> I think we were aware that our VDSO usage may have exploited some
>> peculiarities in how the ppc64 version was constructed (i.e hand
>> written assembly which just didn't happen to clobber R30).
> Yeah I was "somewhat surprised" that Go thought it could use r30 like
> that across a VDSO call :D
>
> But to be fair the ABI of the VDSO has always been a little fishy,
> because the entry points pretend to be a transparent wrapper around
> system calls, but then in a case like this are not.
>
>> Go up to this point has only used the vdso function __kernel_clock_gettime; it
>> is the only entry point which would need to explicitly avoid R30 for
>> Go's sake.
> I thought about limiting the workaround to just that code, but it seemed
> silly and likely to come back to bite us. Once the compilers decides to
> spill a non-volatile there are plenty of other ones to choose from.
>
> cheers
^ permalink raw reply
* Re: [PATCH 2/3] trace: refactor TRACE_IRQFLAGS_SUPPORT in Kconfig
From: Max Filippov @ 2021-08-02 18:03 UTC (permalink / raw)
To: Masahiro Yamada
Cc: Mark Rutland, Rich Felker, open list:SUPERH, Peter Zijlstra,
Catalin Marinas, Linus Walleij, Viresh Kumar, LKML,
James E.J. Bottomley, Guo Ren, linux-csky, H. Peter Anvin,
open list:SPARC + UltraSPAR..., linux-riscv, Vincent Chen,
Will Deacon, Ard Biesheuvel, Paul Mackerras, Anton Ivanov,
Jonas Bonn, linux-s390, Vasily Gorbik, Yoshinori Sato,
Krzysztof Kozlowski, YiFei Zhu, Richard Weinberger, Helge Deller,
maintainer:X86 ARCHITECTURE..., Russell King, Ley Foon Tan,
Christian Borntraeger, Ingo Molnar, Geert Uytterhoeven,
open list:PARISC ARCHITECTURE, Sami Tolvanen,
Uwe Kleine-König, Stafford Horne, linux-snps-arc, Jeff Dike,
open list:TENSILICA XTENSA PORT (xtensa), Albert Ou, Kees Cook,
Arnd Bergmann, Anshuman Khandual, Heiko Carstens, linux-um,
Steven Rostedt, Stefan Kristiansson, openrisc, Borislav Petkov,
Greentime Hu, Paul Walmsley, Thomas Gleixner, linux-arm-kernel,
Andrey Konovalov, Chris Zankel, Michal Simek, Thomas Bogendoerfer,
Brian Cain, Nick Hu, Vineet Gupta, Nicholas Piggin, linux-mips,
Frederic Weisbecker, Palmer Dabbelt,
open list:QUALCOMM HEXAGON..., Colin Ian King, Andrew Morton,
linuxppc-dev, David S. Miller, Mike Rapoport
In-Reply-To: <20210731052233.4703-2-masahiroy@kernel.org>
On Fri, Jul 30, 2021 at 10:24 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> Make architectures select TRACE_IRQFLAGS_SUPPORT instead of
> having many defines.
>
> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
> ---
> arch/xtensa/Kconfig | 4 +---
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
--
Thanks.
-- Max
^ permalink raw reply
* Re: [PATCH 2/3] trace: refactor TRACE_IRQFLAGS_SUPPORT in Kconfig
From: Catalin Marinas @ 2021-08-02 15:55 UTC (permalink / raw)
To: Masahiro Yamada
Cc: Mark Rutland, Rich Felker, linux-sh, Peter Zijlstra,
Linus Walleij, Viresh Kumar, linux-kernel, James E.J. Bottomley,
Max Filippov, Guo Ren, linux-csky, H. Peter Anvin, sparclinux,
linux-riscv, Vincent Chen, Will Deacon, Ard Biesheuvel,
Paul Mackerras, Anton Ivanov, Jonas Bonn, linux-s390,
Vasily Gorbik, Yoshinori Sato, Krzysztof Kozlowski, YiFei Zhu,
Richard Weinberger, Helge Deller, x86, Russell King, Ley Foon Tan,
Christian Borntraeger, Ingo Molnar, Geert Uytterhoeven,
linux-parisc, Sami Tolvanen, Uwe Kleine-König,
Stafford Horne, linux-snps-arc, Jeff Dike, linux-xtensa,
Albert Ou, Kees Cook, Arnd Bergmann, Anshuman Khandual,
Heiko Carstens, linux-um, Steven Rostedt, Stefan Kristiansson,
openrisc, Borislav Petkov, Greentime Hu, Paul Walmsley,
Thomas Gleixner, linux-arm-kernel, Andrey Konovalov, Chris Zankel,
Michal Simek, Thomas Bogendoerfer, Brian Cain, Nick Hu,
Vineet Gupta, Nicholas Piggin, linux-mips, Frederic Weisbecker,
Palmer Dabbelt, linux-hexagon, Colin Ian King, Andrew Morton,
linuxppc-dev, David S. Miller, Mike Rapoport
In-Reply-To: <20210731052233.4703-2-masahiroy@kernel.org>
On Sat, Jul 31, 2021 at 02:22:32PM +0900, Masahiro Yamada wrote:
> Make architectures select TRACE_IRQFLAGS_SUPPORT instead of
> having many defines.
>
> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
For arm64:
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* Re: [PATCH v1 4/5] PCI: Adapt all code locations to not use struct pci_dev::driver directly
From: Boris Ostrovsky @ 2021-08-02 13:06 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Mark Rutland, Giovanni Cabiddu, Rafał Miłecki,
Peter Zijlstra, linux-pci, Alexander Duyck, x86, oss-drivers,
netdev, Oliver O'Halloran, H. Peter Anvin, Jiri Olsa,
Paul Mackerras, Taras Chornyi, Stefano Stabellini, Herbert Xu,
linux-scsi, Sathya Prakash, qat-linux, Alexander Shishkin,
Ingo Molnar, Geert Uytterhoeven, Jakub Kicinski, Yisen Zhuang,
Suganath Prabu Subramani, Fiona Trahe, Andrew Donnellan,
Mathias Nyman, Konrad Rzeszutek Wilk, Ido Schimmel,
Arnaldo Carvalho de Melo, Frederic Barrat, Borislav Petkov,
Michael Buesch, Jiri Pirko, Bjorn Helgaas, Namhyung Kim,
Thomas Gleixner, Andy Shevchenko, Juergen Gross, Salil Mehta,
Sreekanth Reddy, xen-devel, Vadym Kochan, MPT-FusionLinux.pdl,
linux-usb, linux-wireless, linux-kernel, linux-perf-users,
Zhou Wang, Arnd Bergmann, linux-crypto, kernel,
Greg Kroah-Hartman, Simon Horman, Wojciech Ziemba, linuxppc-dev,
David S. Miller
In-Reply-To: <20210731120836.vegno6voijvlflws@pengutronix.de>
On 7/31/21 8:08 AM, Uwe Kleine-König wrote:
> Hello Boris,
>
> On Fri, Jul 30, 2021 at 04:37:31PM -0400, Boris Ostrovsky wrote:
>> On 7/29/21 4:37 PM, Uwe Kleine-König wrote:
>>> --- a/drivers/pci/xen-pcifront.c
>>> +++ b/drivers/pci/xen-pcifront.c
>>> @@ -599,12 +599,12 @@ static pci_ers_result_t pcifront_common_process(int cmd,
>>> result = PCI_ERS_RESULT_NONE;
>>>
>>> pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
>>> - if (!pcidev || !pcidev->driver) {
>>> + pdrv = pci_driver_of_dev(pcidev);
>>> + if (!pcidev || !pdrv) {
>> If pcidev is NULL we are dead by the time we reach 'if' statement.
> Oh, you're right. So this needs something like:
>
> if (!pcidev || !(pdrv = pci_driver_of_dev(pcidev)))
Sure, that's fine. And while at it please also drop 'if (pdrv)' check below (it's not directly related to your change but is more noticeable now so since you are in that function anyway I'd appreciate if you could do that).
Thanks.
-boris
>
> or repeating the call to pci_driver_of_dev for each previous usage of
> pdev->driver.
>
> If there are no other preferences I'd got with the first approach for
> v2.
>
> Best regards and thanks for catching,
> Uwe
>
^ permalink raw reply
* Re: [PATCH 2/2] virtio-console: remove unnecessary kmemdup()
From: Xianting Tian @ 2021-08-02 8:32 UTC (permalink / raw)
To: Jiri Slaby, gregkh, amit, arnd
Cc: osandov, linuxppc-dev, linux-kernel, virtualization
In-Reply-To: <b5554967-a683-96ae-deb9-2d4980d33b41@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 2454 bytes --]
在 2021/8/2 下午3:25, Jiri Slaby 写道:
> Hi,
>
> why is this 2/2? I seem (Lore neither) to find 1/2.
You didn't receive 1/2?
[PATCH 1/2] tty: hvc: pass DMA capable memory to put_chars()
https://lkml.org/lkml/2021/8/1/8 <https://lkml.org/lkml/2021/8/1/8>
>
> On 01. 08. 21, 7:16, Xianting Tian wrote:
>> hvc framework will never pass stack memory to the put_chars() function,
>
> Am I blind or missing something?
>
> hvc_console_print(...)
> {
> char c[N_OUTBUF]
> ...
> cons_ops[index]->put_chars(vtermnos[index], c, i);
>
> The same here:
>
> hvc_poll_put_char(..., char ch)
> {
> ...
> n = hp->ops->put_chars(hp->vtermno, &ch, 1);
>
> AFAICS both of them *pass* a pointer to stack variable.
yes, I discussed the issue with Arnd before in below thread, you can
get the history, thanks
https://lkml.org/lkml/2021/7/27/494 <https://lkml.org/lkml/2021/7/27/494>
>
>> So the calling of kmemdup() is unnecessary, remove it.
>>
>> Fixes: c4baad5029 ("virtio-console: avoid DMA from stack")
>
> This patch doesn't "Fix" -- it reverts the commit. You should've CCed
> the author too.
yes, we discussed ther issue in above thread, which we CCed the author.
>
>> Signed-off-by: Xianting Tian <xianting.tian@linux.alibaba.com>
>> ---
>> drivers/char/virtio_console.c | 12 ++----------
>> 1 file changed, 2 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/char/virtio_console.c
>> b/drivers/char/virtio_console.c
>> index 7eaf303a7..4ed3ffb1d 100644
>> --- a/drivers/char/virtio_console.c
>> +++ b/drivers/char/virtio_console.c
>> @@ -1117,8 +1117,6 @@ static int put_chars(u32 vtermno, const char
>> *buf, int count)
>> {
>> struct port *port;
>> struct scatterlist sg[1];
>> - void *data;
>> - int ret;
>> if (unlikely(early_put_chars))
>> return early_put_chars(vtermno, buf, count);
>> @@ -1127,14 +1125,8 @@ static int put_chars(u32 vtermno, const char
>> *buf, int count)
>> if (!port)
>> return -EPIPE;
>> - data = kmemdup(buf, count, GFP_ATOMIC);
>> - if (!data)
>> - return -ENOMEM;
>> -
>> - sg_init_one(sg, data, count);
>> - ret = __send_to_port(port, sg, 1, count, data, false);
>> - kfree(data);
>> - return ret;
>> + sg_init_one(sg, buf, count);
>> + return __send_to_port(port, sg, 1, count, (void *)buf, false);
>> }
>> /*
>>
>
>
[-- Attachment #2: Type: text/html, Size: 4975 bytes --]
^ permalink raw reply
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