* [PATCH v6 4/8] powerpc/pseries: Define MCE error event section.
From: Mahesh J Salgaonkar @ 2018-07-04 17:57 UTC (permalink / raw)
To: linuxppc-dev
Cc: Nicholas Piggin, Aneesh Kumar K.V, Laurent Dufour,
Michal Suchanek, Michael Ellerman
In-Reply-To: <153072695700.29016.8614312307132803349.stgit@jupiter.in.ibm.com>
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
On pseries, the machine check error details are part of RTAS extended
event log passed under Machine check exception section. This patch adds
the definition of rtas MCE event section and related helper
functions.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/rtas.h | 111 +++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index ec9dd79398ee..ceeed2dd489b 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -185,6 +185,13 @@ static inline uint8_t rtas_error_disposition(const struct rtas_error_log *elog)
return (elog->byte1 & 0x18) >> 3;
}
+static inline
+void rtas_set_disposition_recovered(struct rtas_error_log *elog)
+{
+ elog->byte1 &= ~0x18;
+ elog->byte1 |= (RTAS_DISP_FULLY_RECOVERED << 3);
+}
+
static inline uint8_t rtas_error_extended(const struct rtas_error_log *elog)
{
return (elog->byte1 & 0x04) >> 2;
@@ -275,6 +282,7 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
#define PSERIES_ELOG_SECT_ID_CALL_HOME (('C' << 8) | 'H')
#define PSERIES_ELOG_SECT_ID_USER_DEF (('U' << 8) | 'D')
#define PSERIES_ELOG_SECT_ID_HOTPLUG (('H' << 8) | 'P')
+#define PSERIES_ELOG_SECT_ID_MCE (('M' << 8) | 'C')
/* Vendor specific Platform Event Log Format, Version 6, section header */
struct pseries_errorlog {
@@ -326,6 +334,109 @@ struct pseries_hp_errorlog {
#define PSERIES_HP_ELOG_ID_DRC_COUNT 3
#define PSERIES_HP_ELOG_ID_DRC_IC 4
+/* RTAS pseries MCE errorlog section */
+#pragma pack(push, 1)
+struct pseries_mc_errorlog {
+ __be32 fru_id;
+ __be32 proc_id;
+ uint8_t error_type;
+ union {
+ struct {
+ uint8_t ue_err_type;
+ /* XXXXXXXX
+ * X 1: Permanent or Transient UE.
+ * X 1: Effective address provided.
+ * X 1: Logical address provided.
+ * XX 2: Reserved.
+ * XXX 3: Type of UE error.
+ */
+ uint8_t reserved_1[6];
+ __be64 effective_address;
+ __be64 logical_address;
+ } ue_error;
+ struct {
+ uint8_t soft_err_type;
+ /* XXXXXXXX
+ * X 1: Effective address provided.
+ * XXXXX 5: Reserved.
+ * XX 2: Type of SLB/ERAT/TLB error.
+ */
+ uint8_t reserved_1[6];
+ __be64 effective_address;
+ uint8_t reserved_2[8];
+ } soft_error;
+ } u;
+};
+#pragma pack(pop)
+
+/* RTAS pseries MCE error types */
+#define PSERIES_MC_ERROR_TYPE_UE 0x00
+#define PSERIES_MC_ERROR_TYPE_SLB 0x01
+#define PSERIES_MC_ERROR_TYPE_ERAT 0x02
+#define PSERIES_MC_ERROR_TYPE_TLB 0x04
+#define PSERIES_MC_ERROR_TYPE_D_CACHE 0x05
+#define PSERIES_MC_ERROR_TYPE_I_CACHE 0x07
+
+/* RTAS pseries MCE error sub types */
+#define PSERIES_MC_ERROR_UE_INDETERMINATE 0
+#define PSERIES_MC_ERROR_UE_IFETCH 1
+#define PSERIES_MC_ERROR_UE_PAGE_TABLE_WALK_IFETCH 2
+#define PSERIES_MC_ERROR_UE_LOAD_STORE 3
+#define PSERIES_MC_ERROR_UE_PAGE_TABLE_WALK_LOAD_STORE 4
+
+#define PSERIES_MC_ERROR_SLB_PARITY 0
+#define PSERIES_MC_ERROR_SLB_MULTIHIT 1
+#define PSERIES_MC_ERROR_SLB_INDETERMINATE 2
+
+#define PSERIES_MC_ERROR_ERAT_PARITY 1
+#define PSERIES_MC_ERROR_ERAT_MULTIHIT 2
+#define PSERIES_MC_ERROR_ERAT_INDETERMINATE 3
+
+#define PSERIES_MC_ERROR_TLB_PARITY 1
+#define PSERIES_MC_ERROR_TLB_MULTIHIT 2
+#define PSERIES_MC_ERROR_TLB_INDETERMINATE 3
+
+static inline uint8_t rtas_mc_error_type(const struct pseries_mc_errorlog *mlog)
+{
+ return mlog->error_type;
+}
+
+static inline uint8_t rtas_mc_error_sub_type(
+ const struct pseries_mc_errorlog *mlog)
+{
+ switch (mlog->error_type) {
+ case PSERIES_MC_ERROR_TYPE_UE:
+ return (mlog->u.ue_error.ue_err_type & 0x07);
+ case PSERIES_MC_ERROR_TYPE_SLB:
+ case PSERIES_MC_ERROR_TYPE_ERAT:
+ case PSERIES_MC_ERROR_TYPE_TLB:
+ return (mlog->u.soft_error.soft_err_type & 0x03);
+ default:
+ return 0;
+ }
+}
+
+static inline uint64_t rtas_mc_get_effective_addr(
+ const struct pseries_mc_errorlog *mlog)
+{
+ uint64_t addr = 0;
+
+ switch (mlog->error_type) {
+ case PSERIES_MC_ERROR_TYPE_UE:
+ if (mlog->u.ue_error.ue_err_type & 0x40)
+ addr = mlog->u.ue_error.effective_address;
+ break;
+ case PSERIES_MC_ERROR_TYPE_SLB:
+ case PSERIES_MC_ERROR_TYPE_ERAT:
+ case PSERIES_MC_ERROR_TYPE_TLB:
+ if (mlog->u.soft_error.soft_err_type & 0x80)
+ addr = mlog->u.soft_error.effective_address;
+ default:
+ break;
+ }
+ return be64_to_cpu(addr);
+}
+
struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
uint16_t section_id);
^ permalink raw reply related
* [PATCH v6 3/8] powerpc/pseries: Fix endainness while restoring of r3 in MCE handler.
From: Mahesh J Salgaonkar @ 2018-07-04 17:57 UTC (permalink / raw)
To: linuxppc-dev
Cc: stable, Nicholas Piggin, Nicholas Piggin, Aneesh Kumar K.V,
Laurent Dufour, Michal Suchanek, Michael Ellerman
In-Reply-To: <153072695700.29016.8614312307132803349.stgit@jupiter.in.ibm.com>
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
During Machine Check interrupt on pseries platform, register r3 points
RTAS extended event log passed by hypervisor. Since hypervisor uses r3
to pass pointer to rtas log, it stores the original r3 value at the
start of the memory (first 8 bytes) pointed by r3. Since hypervisor
stores this info and rtas log is in BE format, linux should make
sure to restore r3 value in correct endian format.
Without this patch when MCE handler, after recovery, returns to code that
that caused the MCE may end up with Data SLB access interrupt for invalid
address followed by kernel panic or hang.
[ 62.878965] Severe Machine check interrupt [Recovered]
[ 62.878968] NIP [d00000000ca301b8]: init_module+0x1b8/0x338 [bork_kernel]
[ 62.878969] Initiator: CPU
[ 62.878970] Error type: SLB [Multihit]
[ 62.878971] Effective address: d00000000ca70000
cpu 0xa: Vector: 380 (Data SLB Access) at [c0000000fc7775b0]
pc: c0000000009694c0: vsnprintf+0x80/0x480
lr: c0000000009698e0: vscnprintf+0x20/0x60
sp: c0000000fc777830
msr: 8000000002009033
dar: a803a30c000000d0
current = 0xc00000000bc9ef00
paca = 0xc00000001eca5c00 softe: 3 irq_happened: 0x01
pid = 8860, comm = insmod
[c0000000fc7778b0] c0000000009698e0 vscnprintf+0x20/0x60
[c0000000fc7778e0] c00000000016b6c4 vprintk_emit+0xb4/0x4b0
[c0000000fc777960] c00000000016d40c vprintk_func+0x5c/0xd0
[c0000000fc777980] c00000000016cbb4 printk+0x38/0x4c
[c0000000fc7779a0] d00000000ca301c0 init_module+0x1c0/0x338 [bork_kernel]
[c0000000fc777a40] c00000000000d9c4 do_one_initcall+0x54/0x230
[c0000000fc777b00] c0000000001b3b74 do_init_module+0x8c/0x248
[c0000000fc777b90] c0000000001b2478 load_module+0x12b8/0x15b0
[c0000000fc777d30] c0000000001b29e8 sys_finit_module+0xa8/0x110
[c0000000fc777e30] c00000000000b204 system_call+0x58/0x6c
--- Exception: c00 (System Call) at 00007fff8bda0644
SP (7fffdfbfe980) is in userspace
This patch fixes this issue.
Fixes: a08a53ea4c97 ("powerpc/le: Enable RTAS events support")
Cc: stable@vger.kernel.org
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/ras.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 14a46b07ab2f..851ce326874a 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -367,7 +367,7 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
}
savep = __va(regs->gpr[3]);
- regs->gpr[3] = savep[0]; /* restore original r3 */
+ regs->gpr[3] = be64_to_cpu(savep[0]); /* restore original r3 */
h = (struct rtas_error_log *)&savep[1];
/* Use the per cpu buffer from paca to store rtas error log */
^ permalink raw reply related
* [PATCH v6 2/8] powerpc/pseries: Defer the logging of rtas error to irq work queue.
From: Mahesh J Salgaonkar @ 2018-07-04 17:57 UTC (permalink / raw)
To: linuxppc-dev
Cc: stable, Nicholas Piggin, Nicholas Piggin, Aneesh Kumar K.V,
Laurent Dufour, Michal Suchanek, Michael Ellerman
In-Reply-To: <153072695700.29016.8614312307132803349.stgit@jupiter.in.ibm.com>
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
rtas_log_buf is a buffer to hold RTAS event data that are communicated
to kernel by hypervisor. This buffer is then used to pass RTAS event
data to user through proc fs. This buffer is allocated from vmalloc
(non-linear mapping) area.
On Machine check interrupt, register r3 points to RTAS extended event
log passed by hypervisor that contains the MCE event. The pseries
machine check handler then logs this error into rtas_log_buf. The
rtas_log_buf is a vmalloc-ed (non-linear) buffer we end up taking up a
page fault (vector 0x300) while accessing it. Since machine check
interrupt handler runs in NMI context we can not afford to take any
page fault. Page faults are not honored in NMI context and causes
kernel panic. Apart from that, as Nick pointed out, pSeries_log_error()
also takes a spin_lock while logging error which is not safe in NMI
context. It may endup in deadlock if we get another MCE before releasing
the lock. Fix this by deferring the logging of rtas error to irq work queue.
Current implementation uses two different buffers to hold rtas error log
depending on whether extended log is provided or not. This makes bit
difficult to identify which buffer has valid data that needs to logged
later in irq work. Simplify this using single buffer, one per paca, and
copy rtas log to it irrespective of whether extended log is provided or
not. Allocate this buffer below RMA region so that it can be accessed
in real mode mce handler.
Fixes: b96672dd840f ("powerpc: Machine check interrupt is a non-maskable interrupt")
Cc: stable@vger.kernel.org
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/paca.h | 3 ++
arch/powerpc/platforms/pseries/ras.c | 47 ++++++++++++++++++++++----------
arch/powerpc/platforms/pseries/setup.c | 16 +++++++++++
3 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 3f109a3e3edb..b441fef53077 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -251,6 +251,9 @@ struct paca_struct {
void *rfi_flush_fallback_area;
u64 l1d_flush_size;
#endif
+#ifdef CONFIG_PPC_PSERIES
+ u8 *mce_data_buf; /* buffer to hold per cpu rtas errlog */
+#endif /* CONFIG_PPC_PSERIES */
} ____cacheline_aligned;
extern void copy_mm_to_paca(struct mm_struct *mm);
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index ef104144d4bc..14a46b07ab2f 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -22,6 +22,7 @@
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/reboot.h>
+#include <linux/irq_work.h>
#include <asm/machdep.h>
#include <asm/rtas.h>
@@ -32,11 +33,13 @@
static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
static DEFINE_SPINLOCK(ras_log_buf_lock);
-static char global_mce_data_buf[RTAS_ERROR_LOG_MAX];
-static DEFINE_PER_CPU(__u64, mce_data_buf);
-
static int ras_check_exception_token;
+static void mce_process_errlog_event(struct irq_work *work);
+static struct irq_work mce_errlog_process_work = {
+ .func = mce_process_errlog_event,
+};
+
#define EPOW_SENSOR_TOKEN 9
#define EPOW_SENSOR_INDEX 0
@@ -330,16 +333,20 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
((((A) >= 0x7000) && ((A) < 0x7ff0)) || \
(((A) >= rtas.base) && ((A) < (rtas.base + rtas.size - 16))))
+static inline struct rtas_error_log *fwnmi_get_errlog(void)
+{
+ return (struct rtas_error_log *)local_paca->mce_data_buf;
+}
+
/*
* Get the error information for errors coming through the
* FWNMI vectors. The pt_regs' r3 will be updated to reflect
* the actual r3 if possible, and a ptr to the error log entry
* will be returned if found.
*
- * If the RTAS error is not of the extended type, then we put it in a per
- * cpu 64bit buffer. If it is the extended type we use global_mce_data_buf.
+ * Use one buffer mce_data_buf per cpu to store RTAS error.
*
- * The global_mce_data_buf does not have any locks or protection around it,
+ * The mce_data_buf does not have any locks or protection around it,
* if a second machine check comes in, or a system reset is done
* before we have logged the error, then we will get corruption in the
* error log. This is preferable over holding off on calling
@@ -349,7 +356,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
{
unsigned long *savep;
- struct rtas_error_log *h, *errhdr = NULL;
+ struct rtas_error_log *h;
/* Mask top two bits */
regs->gpr[3] &= ~(0x3UL << 62);
@@ -362,22 +369,20 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
savep = __va(regs->gpr[3]);
regs->gpr[3] = savep[0]; /* restore original r3 */
- /* If it isn't an extended log we can use the per cpu 64bit buffer */
h = (struct rtas_error_log *)&savep[1];
+ /* Use the per cpu buffer from paca to store rtas error log */
+ memset(local_paca->mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
if (!rtas_error_extended(h)) {
- memcpy(this_cpu_ptr(&mce_data_buf), h, sizeof(__u64));
- errhdr = (struct rtas_error_log *)this_cpu_ptr(&mce_data_buf);
+ memcpy(local_paca->mce_data_buf, h, sizeof(__u64));
} else {
int len, error_log_length;
error_log_length = 8 + rtas_error_extended_log_length(h);
len = min_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
- memset(global_mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
- memcpy(global_mce_data_buf, h, len);
- errhdr = (struct rtas_error_log *)global_mce_data_buf;
+ memcpy(local_paca->mce_data_buf, h, len);
}
- return errhdr;
+ return (struct rtas_error_log *)local_paca->mce_data_buf;
}
/* Call this when done with the data returned by FWNMI_get_errinfo.
@@ -422,6 +427,17 @@ int pSeries_system_reset_exception(struct pt_regs *regs)
return 0; /* need to perform reset */
}
+/*
+ * Process MCE rtas errlog event.
+ */
+static void mce_process_errlog_event(struct irq_work *work)
+{
+ struct rtas_error_log *err;
+
+ err = fwnmi_get_errlog();
+ log_error((char *)err, ERR_TYPE_RTAS_LOG, 0);
+}
+
/*
* See if we can recover from a machine check exception.
* This is only called on power4 (or above) and only via
@@ -466,7 +482,8 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log *err)
recovered = 1;
}
- log_error((char *)err, ERR_TYPE_RTAS_LOG, 0);
+ /* Queue irq work to log this rtas event later. */
+ irq_work_queue(&mce_errlog_process_work);
return recovered;
}
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index fdb32e056ef4..60a067a6e743 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -41,6 +41,7 @@
#include <linux/root_dev.h>
#include <linux/of.h>
#include <linux/of_pci.h>
+#include <linux/memblock.h>
#include <asm/mmu.h>
#include <asm/processor.h>
@@ -101,6 +102,9 @@ static void pSeries_show_cpuinfo(struct seq_file *m)
static void __init fwnmi_init(void)
{
unsigned long system_reset_addr, machine_check_addr;
+ u8 *mce_data_buf;
+ unsigned int i;
+ int nr_cpus = num_possible_cpus();
int ibm_nmi_register = rtas_token("ibm,nmi-register");
if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
@@ -114,6 +118,18 @@ static void __init fwnmi_init(void)
if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr,
machine_check_addr))
fwnmi_active = 1;
+
+ /*
+ * Allocate a chunk for per cpu buffer to hold rtas errorlog.
+ * It will be used in real mode mce handler, hence it needs to be
+ * below RMA.
+ */
+ mce_data_buf = __va(memblock_alloc_base(RTAS_ERROR_LOG_MAX * nr_cpus,
+ RTAS_ERROR_LOG_MAX, ppc64_rma_size));
+ for_each_possible_cpu(i) {
+ paca_ptrs[i]->mce_data_buf = mce_data_buf +
+ (RTAS_ERROR_LOG_MAX * i);
+ }
}
static void pseries_8259_cascade(struct irq_desc *desc)
^ permalink raw reply related
* [PATCH v6 1/8] powerpc/pseries: Avoid using the size greater than RTAS_ERROR_LOG_MAX.
From: Mahesh J Salgaonkar @ 2018-07-04 17:57 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michal Suchanek, Nicholas Piggin, Aneesh Kumar K.V,
Laurent Dufour, Michal Suchanek, Michael Ellerman
In-Reply-To: <153072695700.29016.8614312307132803349.stgit@jupiter.in.ibm.com>
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
The global mce data buffer that used to copy rtas error log is of 2048
(RTAS_ERROR_LOG_MAX) bytes in size. Before the copy we read
extended_log_length from rtas error log header, then use max of
extended_log_length and RTAS_ERROR_LOG_MAX as a size of data to be copied.
Ideally the platform (phyp) will never send extended error log with
size > 2048. But if that happens, then we have a risk of buffer overrun
and corruption. Fix this by using min_t instead.
Fixes: d368514c3097 ("powerpc: Fix corruption when grabbing FWNMI data")
Reported-by: Michal Suchanek <msuchanek@suse.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/ras.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 5e1ef9150182..ef104144d4bc 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -371,7 +371,7 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
int len, error_log_length;
error_log_length = 8 + rtas_error_extended_log_length(h);
- len = max_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
+ len = min_t(int, error_log_length, RTAS_ERROR_LOG_MAX);
memset(global_mce_data_buf, 0, RTAS_ERROR_LOG_MAX);
memcpy(global_mce_data_buf, h, len);
errhdr = (struct rtas_error_log *)global_mce_data_buf;
^ permalink raw reply related
* [PATCH v6 0/8] powerpc/pseries: Machine check handler improvements.
From: Mahesh J Salgaonkar @ 2018-07-04 17:56 UTC (permalink / raw)
To: linuxppc-dev
Cc: Nicholas Piggin, Michal Suchanek, Michael Ellerman, stable,
Aneesh Kumar K.V, Nicholas Piggin, Aneesh Kumar K.V,
Laurent Dufour, Michal Suchanek, Michael Ellerman
This patch series includes some improvement to Machine check handler
for pSeries. Patch 1 fixes a buffer overrun issue if rtas extended error
log size is greater than RTAS_ERROR_LOG_MAX.
Patch 2 fixes an issue where machine check handler crashes
kernel while accessing vmalloc-ed buffer while in nmi context.
Patch 3 fixes endain bug while restoring of r3 in MCE handler.
Patch 5 implements a real mode mce handler and flushes the SLBs on SLB error.
Patch 6 display's the MCE error details on console.
Patch 7 saves and dumps the SLB contents on SLB MCE errors to improve the
debugability.
Patch 8 consolidates mce early real mode handling code.
Change in V6:
- Introduce patch 8 to consolidate early real mode handling code.
- Address Nick's comment on erroneous hunk.
Change in V5:
- Use min_t instead of max_t.
- Fix an issue reported by kbuild test robot and address review comments.
Change in V4:
- Flush the SLBs in real mode mce handler to handle SLB errors for entry 0.
- Allocate buffers per cpu to hold rtas error log and old slb contents.
- Defer the logging of rtas error log to irq work queue.
Change in V3:
- Moved patch 5 to patch 2
Change in V2:
- patch 3: Display additional info (NIP and task info) in MCE error details.
- patch 5: Fix endain bug while restoring of r3 in MCE handler.
---
Mahesh Salgaonkar (8):
powerpc/pseries: Avoid using the size greater than RTAS_ERROR_LOG_MAX.
powerpc/pseries: Defer the logging of rtas error to irq work queue.
powerpc/pseries: Fix endainness while restoring of r3 in MCE handler.
powerpc/pseries: Define MCE error event section.
powerpc/pseries: flush SLB contents on SLB MCE errors.
powerpc/pseries: Display machine check error details.
powerpc/pseries: Dump the SLB contents on SLB MCE errors.
powernv/pseries: consolidate code for mce early handling.
arch/powerpc/include/asm/book3s/64/mmu-hash.h | 8 +
arch/powerpc/include/asm/machdep.h | 1
arch/powerpc/include/asm/paca.h | 4
arch/powerpc/include/asm/rtas.h | 116 ++++++++++++
arch/powerpc/kernel/exceptions-64s.S | 18 +-
arch/powerpc/kernel/mce.c | 16 +-
arch/powerpc/mm/slb.c | 63 +++++++
arch/powerpc/platforms/pseries/pseries.h | 1
arch/powerpc/platforms/pseries/ras.c | 242 +++++++++++++++++++++++--
arch/powerpc/platforms/pseries/setup.c | 27 +++
10 files changed, 471 insertions(+), 25 deletions(-)
--
Signature
^ permalink raw reply
* [RFC PATCH 2/2] dma-mapping: Clean up dma_get_required_mask() hooks
From: Robin Murphy @ 2018-07-04 17:50 UTC (permalink / raw)
To: hch, m.szyprowski; +Cc: iommu, linux-arm-kernel, linux-ia64, linuxppc-dev
In-Reply-To: <55ac9550c311f056dcfeed9b2c8265375f17b155.1530726467.git.robin.murphy@arm.com>
As for the other mask-related hooks, standardise the arch override into
a Kconfig option, and also pull the generic implementation into the DMA
mapping code rather than having it hide away in the platform bus code.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
arch/ia64/Kconfig | 1 +
arch/ia64/include/asm/dma-mapping.h | 2 --
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/device.h | 2 --
drivers/base/platform.c | 23 -----------------------
drivers/pci/controller/vmd.c | 4 ++--
include/linux/dma-mapping.h | 2 +-
kernel/dma/Kconfig | 3 +++
kernel/dma/mapping.c | 23 +++++++++++++++++++++++
9 files changed, 31 insertions(+), 30 deletions(-)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index ff861420b8f5..a6274e79b155 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -12,6 +12,7 @@ menu "Processor type and features"
config IA64
bool
+ select ARCH_HAS_DMA_GET_REQUIRED_MASK
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select PCI if (!IA64_HP_SIM)
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 76e4d6632d68..522745ae67bb 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -10,8 +10,6 @@
#include <linux/scatterlist.h>
#include <linux/dma-debug.h>
-#define ARCH_HAS_DMA_GET_REQUIRED_MASK
-
extern const struct dma_map_ops *dma_ops;
extern struct ia64_machine_vector ia64_mv;
extern void set_iommu_machvec(void);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 08d85412d783..3581c576c762 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -126,6 +126,7 @@ config PPC
# Please keep this list sorted alphabetically.
#
select ARCH_HAS_DEVMEM_IS_ALLOWED
+ select ARCH_HAS_DMA_GET_REQUIRED_MASK
select ARCH_HAS_DMA_SET_MASK
select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 0245bfcaac32..17cceab5ccf9 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -54,6 +54,4 @@ struct pdev_archdata {
u64 dma_mask;
};
-#define ARCH_HAS_DMA_GET_REQUIRED_MASK
-
#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index dff82a3c2caa..dae427a77b0a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
-#include <linux/bootmem.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
@@ -1179,28 +1178,6 @@ int __init platform_bus_init(void)
return error;
}
-#ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK
-u64 dma_get_required_mask(struct device *dev)
-{
- u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
- u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
- u64 mask;
-
- if (!high_totalram) {
- /* convert to mask just covering totalram */
- low_totalram = (1 << (fls(low_totalram) - 1));
- low_totalram += low_totalram - 1;
- mask = low_totalram;
- } else {
- high_totalram = (1 << (fls(high_totalram) - 1));
- high_totalram += high_totalram - 1;
- mask = (((u64)high_totalram) << 32) + 0xffffffff;
- }
- return mask;
-}
-EXPORT_SYMBOL_GPL(dma_get_required_mask);
-#endif
-
static __initdata LIST_HEAD(early_platform_driver_list);
static __initdata LIST_HEAD(early_platform_device_list);
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 942b64fc7f1f..9dd721d36783 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -393,7 +393,7 @@ static int vmd_dma_supported(struct device *dev, u64 mask)
return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);
}
-#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+#ifdef CONFIG_ARCH_HAS_DMA_GET_REQUIRED_MASK
static u64 vmd_get_required_mask(struct device *dev)
{
return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));
@@ -439,7 +439,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)
ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);
ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);
ASSIGN_VMD_DMA_OPS(source, dest, dma_supported);
-#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+#ifdef CONFIG_ARCH_HAS_DMA_GET_REQUIRED_MASK
ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask);
#endif
add_dma_domain(domain);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 30fe0c900420..788d7a609dd8 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -130,7 +130,7 @@ struct dma_map_ops {
enum dma_data_direction direction);
int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
int (*dma_supported)(struct device *dev, u64 mask);
-#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK
+#ifdef CONFIG_ARCH_HAS_DMA_GET_REQUIRED_MASK
u64 (*get_required_mask)(struct device *dev);
#endif
};
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 01001371d892..cb12bb2d270a 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -16,6 +16,9 @@ config ARCH_DMA_ADDR_T_64BIT
config HAVE_GENERIC_DMA_COHERENT
bool
+config ARCH_HAS_DMA_GET_REQUIRED_MASK
+ bool
+
config ARCH_HAS_DMA_SET_MASK
bool
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index d2a92ddaac4d..fdadc9524cb2 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -7,6 +7,7 @@
*/
#include <linux/acpi.h>
+#include <linux/bootmem.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/gfp.h>
@@ -198,6 +199,28 @@ EXPORT_SYMBOL(dmam_release_declared_memory);
#endif
+#ifndef CONFIG_ARCH_HAS_DMA_GET_REQUIRED_MASK
+u64 dma_get_required_mask(struct device *dev)
+{
+ u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
+ u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
+ u64 mask;
+
+ if (!high_totalram) {
+ /* convert to mask just covering totalram */
+ low_totalram = (1 << (fls(low_totalram) - 1));
+ low_totalram += low_totalram - 1;
+ mask = low_totalram;
+ } else {
+ high_totalram = (1 << (fls(high_totalram) - 1));
+ high_totalram += high_totalram - 1;
+ mask = (((u64)high_totalram) << 32) + 0xffffffff;
+ }
+ return mask;
+}
+EXPORT_SYMBOL_GPL(dma_get_required_mask);
+#endif
+
/*
* Create scatter-list for the already allocated DMA buffer.
*/
--
2.17.1.dirty
^ permalink raw reply related
* [RFC PATCH 1/2] dma-mapping: Clean up dma_set_*mask() hooks
From: Robin Murphy @ 2018-07-04 17:50 UTC (permalink / raw)
To: hch, m.szyprowski; +Cc: iommu, linux-arm-kernel, linux-ia64, linuxppc-dev
Arch-specific implementions for dma_set_{coherent_,}mask() currently
rely on an inconsistent mix of arch-defined Kconfig symbols and macro
overrides. Now that we have a nice centralised home for DMA API gubbins,
let's consolidate these loose ends under consistent config options.
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
Here's hoping the buildbot comes by to point out what I've inevitably
missed, although I did check a cursory cross-compile of ppc64_defconfig
to iron out the obvious howlers.
The motivation here is that I'm looking at adding set_mask overrides
for arm64, and having discovered a bit of a mess it seemed prudent to
clean up before ingraining it any more.
Robin.
arch/arm/Kconfig | 3 ---
arch/powerpc/Kconfig | 4 +---
arch/powerpc/include/asm/dma-mapping.h | 3 ---
include/linux/dma-mapping.h | 4 +++-
kernel/dma/Kconfig | 6 ++++++
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 843edfd000be..ab0c081b6ec2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -227,9 +227,6 @@ config ZONE_DMA
config ARCH_SUPPORTS_UPROBES
def_bool y
-config ARCH_HAS_DMA_SET_COHERENT_MASK
- bool
-
config GENERIC_ISA_DMA
bool
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9f2b75fe2c2d..08d85412d783 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -119,9 +119,6 @@ config GENERIC_HWEIGHT
bool
default y
-config ARCH_HAS_DMA_SET_COHERENT_MASK
- bool
-
config PPC
bool
default y
@@ -129,6 +126,7 @@ config PPC
# Please keep this list sorted alphabetically.
#
select ARCH_HAS_DEVMEM_IS_ALLOWED
+ select ARCH_HAS_DMA_SET_MASK
select ARCH_HAS_DMA_SET_COHERENT_MASK
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 8fa394520af6..fe912c4367f2 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -107,9 +107,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
dev->archdata.dma_offset = off;
}
-#define HAVE_ARCH_DMA_SET_MASK 1
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-
extern u64 __dma_get_required_mask(struct device *dev);
#define ARCH_HAS_DMA_MMAP_COHERENT
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index ffeca3ab59c0..30fe0c900420 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -596,7 +596,9 @@ static inline int dma_supported(struct device *dev, u64 mask)
return ops->dma_supported(dev, mask);
}
-#ifndef HAVE_ARCH_DMA_SET_MASK
+#ifdef CONFIG_ARCH_HAS_DMA_SET_MASK
+int dma_set_mask(struct device *dev, u64 mask);
+#else
static inline int dma_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask || !dma_supported(dev, mask))
diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig
index 9bd54304446f..01001371d892 100644
--- a/kernel/dma/Kconfig
+++ b/kernel/dma/Kconfig
@@ -16,6 +16,12 @@ config ARCH_DMA_ADDR_T_64BIT
config HAVE_GENERIC_DMA_COHERENT
bool
+config ARCH_HAS_DMA_SET_MASK
+ bool
+
+config ARCH_HAS_DMA_SET_COHERENT_MASK
+ bool
+
config ARCH_HAS_SYNC_DMA_FOR_DEVICE
bool
--
2.17.1.dirty
^ permalink raw reply related
* Re: [v2 PATCH 2/2] powerpc: Enable CPU_FTR_ASYM_SMT for interleaved big-cores
From: Murilo Opsfelder Araujo @ 2018-07-04 17:36 UTC (permalink / raw)
To: Gautham R Shenoy
Cc: Michael Neuling, linux-kernel, Nicholas Piggin,
Oliver O'Halloran, Shilpasri G Bhat, linuxppc-dev,
Akshay Adiga
In-Reply-To: <20180704081505.GB1007@in.ibm.com>
On Wed, Jul 04, 2018 at 01:45:05PM +0530, Gautham R Shenoy wrote:
> Hi Murilo,
>
> Thanks for the review.
>
> On Tue, Jul 03, 2018 at 02:53:46PM -0300, Murilo Opsfelder Araujo wrote:
> [..snip..]
>
> > > - /* Initialize CPU <=> thread mapping/
> > > + if (has_interleaved_big_core) {
> > > + int key = __builtin_ctzl(CPU_FTR_ASYM_SMT);
> > > +
> > > + cur_cpu_spec->cpu_features |= CPU_FTR_ASYM_SMT;
> > > + static_branch_enable(&cpu_feature_keys[key]);
> > > + pr_info("Detected interleaved big-cores\n");
> > > + }
> >
> > Shouldn't we use cpu_has_feature(CPU_FTR_ASYM_SMT) before setting
> > > it?
>
>
> Are you suggesting that we do the following?
>
> if (has_interleaved_big_core &&
> !cpu_has_feature(CPU_FTR_ASYM_SMT)) {
> ...
> }
>
> Currently CPU_FTR_ASYM_SMT is set at compile time for only POWER7
> where running the tasks on lower numbered threads give us the benefit
> of SMT thread folding. Interleaved big core is a feature introduced
> only on POWER9. Thus, we know that CPU_FTR_ASYM_SMT is not set in
> cpu_features at this point.
Since we're setting CPU_FTR_ASYM_SMT, it doesn't make sense to use
cpu_has_feature(CPU_FTR_ASYM_SMT). I thought cpu_has_feature() held all
available features (not necessarily enabled) that we could check before
setting or enabling such feature. I think I misread it. Sorry.
>
> >
> > > +
> > > + /* Initialize CPU <=> thread mapping/
> > > *
> > > * WARNING: We assume that the number of threads is the same for
> > > * every CPU in the system. If that is not the case, then some code
> > > --
> > > 1.9.4
> > >
> >
> > --
> > Murilo
>
> --
> Thanks and Regards
> gautham.
>
--
Murilo
^ permalink raw reply
* Re: [PATCHv5 4/4] arm64: Add build salt to the vDSO
From: Will Deacon @ 2018-07-04 17:36 UTC (permalink / raw)
To: Laura Abbott
Cc: mjw, H . J . Lu, Masahiro Yamada, Catalin Marinas,
Andy Lutomirski, Linus Torvalds, X86 ML, linux-kernel,
Nick Clifton, Cary Coutant, linux-kbuild, linuxppc-dev,
Michael Ellerman, linux-arm-kernel
In-Reply-To: <20180703233430.14416-5-labbott@redhat.com>
On Tue, Jul 03, 2018 at 04:34:30PM -0700, Laura Abbott wrote:
>
> The vDSO needs to have a unique build id in a similar manner
> to the kernel and modules. Use the build salt macro.
>
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---
> v5: I was previously focused on x86 only but since powerpc gave a patch,
> I figured I would do arm64 since the changes were also fairly simple.
> ---
> arch/arm64/kernel/vdso/note.S | 3 +++
> 1 file changed, 3 insertions(+)
If you drop the trailing semicolon, then:
Acked-by: Will Deacon <will.deacon@arm.com>
Will
> diff --git a/arch/arm64/kernel/vdso/note.S b/arch/arm64/kernel/vdso/note.S
> index b82c85e5d972..2c429dfd3f45 100644
> --- a/arch/arm64/kernel/vdso/note.S
> +++ b/arch/arm64/kernel/vdso/note.S
> @@ -22,7 +22,10 @@
> #include <linux/uts.h>
> #include <linux/version.h>
> #include <linux/elfnote.h>
> +#include <linux/build-salt.h>
>
> ELFNOTE_START(Linux, 0, "a")
> .long LINUX_VERSION_CODE
> ELFNOTE_END
> +
> +BUILD_SALT;
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCHv3 2/4] drivers/base: utilize device tree info to shutdown devices
From: kbuild test robot @ 2018-07-04 17:04 UTC (permalink / raw)
To: Pingfan Liu
Cc: kbuild-all, linux-kernel, Pingfan Liu, Greg Kroah-Hartman,
Rafael J . Wysocki, Grygorii Strashko, Christoph Hellwig,
Bjorn Helgaas, Dave Young, linux-pci, linuxppc-dev
In-Reply-To: <1530600642-25090-3-git-send-email-kernelfans@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 11686 bytes --]
Hi Pingfan,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on driver-core/driver-core-testing]
[also build test WARNING on v4.18-rc3 next-20180704]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Pingfan-Liu/drivers-base-bugfix-for-supplier-consumer-ordering-in-device_kset/20180703-184317
reproduce: make htmldocs
All warnings (new ones prefixed by >>):
WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org)
mm/mempool.c:228: warning: Function parameter or member 'pool' not described in 'mempool_init'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.ibss' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.connect' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.keys' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.ie' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.ie_len' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.bssid' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.ssid' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.default_key' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.default_mgmt_key' not described in 'wireless_dev'
include/net/cfg80211.h:4279: warning: Function parameter or member 'wext.prev_bssid_valid' not described in 'wireless_dev'
include/net/mac80211.h:2282: warning: Function parameter or member 'radiotap_timestamp.units_pos' not described in 'ieee80211_hw'
include/net/mac80211.h:2282: warning: Function parameter or member 'radiotap_timestamp.accuracy' not described in 'ieee80211_hw'
include/net/mac80211.h:955: warning: Function parameter or member 'control.rates' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.rts_cts_rate_idx' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.use_rts' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.use_cts_prot' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.short_preamble' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.skip_table' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.jiffies' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.vif' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.hw_key' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.flags' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'control.enqueue_time' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'ack' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'ack.cookie' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.rates' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.ack_signal' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.ampdu_ack_len' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.ampdu_len' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.antenna' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.tx_time' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.is_valid_ack_signal' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'status.status_driver_data' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'driver_rates' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'pad' not described in 'ieee80211_tx_info'
include/net/mac80211.h:955: warning: Function parameter or member 'rate_driver_data' not described in 'ieee80211_tx_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'rx_stats_avg' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'rx_stats_avg.signal' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'rx_stats_avg.chain_signal' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.filtered' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.retry_failed' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.retry_count' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.lost_packets' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.last_tdls_pkt_time' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.msdu_retries' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.msdu_failed' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.last_ack' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.last_ack_signal' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.ack_signal_filled' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'status_stats.avg_ack_signal' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'tx_stats.packets' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'tx_stats.bytes' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'tx_stats.last_rate' not described in 'sta_info'
net/mac80211/sta_info.h:588: warning: Function parameter or member 'tx_stats.msdu' not described in 'sta_info'
kernel/sched/fair.c:3760: warning: Function parameter or member 'flags' not described in 'attach_entity_load_avg'
include/linux/device.h:93: warning: bad line: this bus.
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.cb' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.poll' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_excl.active' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.cb' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.poll' not described in 'dma_buf'
include/linux/dma-buf.h:307: warning: Function parameter or member 'cb_shared.active' not described in 'dma_buf'
include/linux/dma-fence-array.h:54: warning: Function parameter or member 'work' not described in 'dma_fence_array'
include/linux/gpio/driver.h:142: warning: Function parameter or member 'request_key' not described in 'gpio_irq_chip'
include/linux/iio/hw-consumer.h:1: warning: no structured comments found
include/linux/device.h:94: warning: bad line: this bus.
>> include/linux/device.h:1008: warning: Function parameter or member 'shutdown' not described in 'device'
include/linux/input/sparse-keymap.h:46: warning: Function parameter or member 'sw' not described in 'key_entry'
include/linux/regulator/driver.h:227: warning: Function parameter or member 'resume_early' not described in 'regulator_ops'
drivers/regulator/core.c:4465: warning: Excess function parameter 'state' description in 'regulator_suspend_late'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw0' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw1' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw2' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.esw3' not described in 'irb'
arch/s390/include/asm/cio.h:245: warning: Function parameter or member 'esw.eadm' not described in 'irb'
drivers/usb/dwc3/gadget.c:510: warning: Excess function parameter 'dwc' description in 'dwc3_gadget_start_config'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_pin' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_unpin' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_res_obj' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_get_sg_table' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_import_sg_table' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_vmap' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_vunmap' not described in 'drm_driver'
include/drm/drm_drv.h:610: warning: Function parameter or member 'gem_prime_mmap' not described in 'drm_driver'
drivers/gpu/drm/i915/i915_vma.h:48: warning: cannot understand function prototype: 'struct i915_vma '
drivers/gpu/drm/i915/i915_vma.h:1: warning: no structured comments found
include/drm/tinydrm/tinydrm.h:34: warning: Function parameter or member 'fb_dirty' not described in 'tinydrm_device'
drivers/gpu/drm/tinydrm/mipi-dbi.c:272: warning: Function parameter or member 'crtc_state' not described in 'mipi_dbi_enable_flush'
drivers/gpu/drm/tinydrm/mipi-dbi.c:272: warning: Function parameter or member 'plane_state' not described in 'mipi_dbi_enable_flush'
vim +1008 include/linux/device.h
^1da177e Linus Torvalds 2005-04-16 @1008
:::::: The code at line 1008 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6443 bytes --]
^ permalink raw reply
* Re: [PATCH v6 2/4] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-07-04 17:00 UTC (permalink / raw)
To: Baoquan He
Cc: kbuild-all, linux-kernel, akpm, robh+dt, dan.j.williams,
nicolas.pitre, josh, fengguang.wu, bp, andy.shevchenko,
brijesh.singh, devicetree, airlied, linux-pci, richard.weiyang,
keith.busch, jcmvbkbc, baiyaowei, frowand.list, lorenzo.pieralisi,
sthemmin, Baoquan He, linux-nvdimm, patrik.r.jakobsson,
linux-input, gustavo, dyoung, vgoyal, thomas.lendacky, haiyangz,
maarten.lankhorst, jglisse, seanpaul, bhelgaas, tglx, yinghai,
jonathan.derrick, chris, monstr, linux-parisc, gregkh,
dmitry.torokhov, kexec, ebiederm, devel, linuxppc-dev, davem
In-Reply-To: <20180704041038.8190-3-bhe@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2540 bytes --]
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.18-rc3 next-20180704]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180704-121402
config: mips-rb532_defconfig (attached as .config)
compiler: mipsel-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=mips
All error/warnings (new ones prefixed by >>):
>> arch/mips/pci/pci-rc32434.c:57:11: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.child = &rc32434_res_pci_mem2
^
arch/mips/pci/pci-rc32434.c:57:11: note: (near initialization for 'rc32434_res_pci_mem1.child.next')
>> arch/mips/pci/pci-rc32434.c:51:47: warning: missing braces around initializer [-Wmissing-braces]
static struct resource rc32434_res_pci_mem1 = {
^
arch/mips/pci/pci-rc32434.c:60:47: warning: missing braces around initializer [-Wmissing-braces]
static struct resource rc32434_res_pci_mem2 = {
^
cc1: some warnings being treated as errors
vim +57 arch/mips/pci/pci-rc32434.c
73b4390f Ralf Baechle 2008-07-16 50
73b4390f Ralf Baechle 2008-07-16 @51 static struct resource rc32434_res_pci_mem1 = {
73b4390f Ralf Baechle 2008-07-16 52 .name = "PCI MEM1",
73b4390f Ralf Baechle 2008-07-16 53 .start = 0x50000000,
73b4390f Ralf Baechle 2008-07-16 54 .end = 0x5FFFFFFF,
73b4390f Ralf Baechle 2008-07-16 55 .flags = IORESOURCE_MEM,
73b4390f Ralf Baechle 2008-07-16 56 .sibling = NULL,
73b4390f Ralf Baechle 2008-07-16 @57 .child = &rc32434_res_pci_mem2
73b4390f Ralf Baechle 2008-07-16 58 };
73b4390f Ralf Baechle 2008-07-16 59
:::::: The code at line 57 was first introduced by commit
:::::: 73b4390fb23456964201abda79f1210fe337d01a [MIPS] Routerboard 532: Support for base system
:::::: TO: Ralf Baechle <ralf@linux-mips.org>
:::::: CC: Ralf Baechle <ralf@linux-mips.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 14130 bytes --]
^ permalink raw reply
* Re: [PATCH v6 2/4] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-07-04 17:00 UTC (permalink / raw)
To: Baoquan He
Cc: kbuild-all, linux-kernel, akpm, robh+dt, dan.j.williams,
nicolas.pitre, josh, fengguang.wu, bp, andy.shevchenko,
brijesh.singh, devicetree, airlied, linux-pci, richard.weiyang,
keith.busch, jcmvbkbc, baiyaowei, frowand.list, lorenzo.pieralisi,
sthemmin, Baoquan He, linux-nvdimm, patrik.r.jakobsson,
linux-input, gustavo, dyoung, vgoyal, thomas.lendacky, haiyangz,
maarten.lankhorst, jglisse, seanpaul, bhelgaas, tglx, yinghai,
jonathan.derrick, chris, monstr, linux-parisc, gregkh,
dmitry.torokhov, kexec, ebiederm, devel, linuxppc-dev, davem
In-Reply-To: <20180704041038.8190-3-bhe@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 6506 bytes --]
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.18-rc3 next-20180704]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180704-121402
config: ia64-allnoconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=ia64
All errors (new ones prefixed by >>):
arch/ia64/sn/kernel/io_init.c: In function 'sn_io_slot_fixup':
>> arch/ia64/sn/kernel/io_init.c:195:19: error: invalid operands to binary && (have 'int' and 'struct list_head')
if (res->parent && res->parent->child)
~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~~~
vim +195 arch/ia64/sn/kernel/io_init.c
^1da177e Linus Torvalds 2005-04-16 142
3ec829b6 John Keller 2005-11-29 143 /*
6f09a925 John Keller 2007-01-30 144 * sn_io_slot_fixup() - We are not running with an ACPI capable PROM,
8ea6091f John Keller 2006-10-04 145 * and need to convert the pci_dev->resource
8ea6091f John Keller 2006-10-04 146 * 'start' and 'end' addresses to mapped addresses,
8ea6091f John Keller 2006-10-04 147 * and setup the pci_controller->window array entries.
^1da177e Linus Torvalds 2005-04-16 148 */
8ea6091f John Keller 2006-10-04 149 void
6f09a925 John Keller 2007-01-30 150 sn_io_slot_fixup(struct pci_dev *dev)
^1da177e Linus Torvalds 2005-04-16 151 {
^1da177e Linus Torvalds 2005-04-16 152 int idx;
ab97b8cc Bjorn Helgaas 2016-03-02 153 struct resource *res;
18c25526 Matt Fleming 2016-05-04 154 unsigned long size;
6f09a925 John Keller 2007-01-30 155 struct pcidev_info *pcidev_info;
6f09a925 John Keller 2007-01-30 156 struct sn_irq_info *sn_irq_info;
6f09a925 John Keller 2007-01-30 157 int status;
6f09a925 John Keller 2007-01-30 158
6f09a925 John Keller 2007-01-30 159 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
6f09a925 John Keller 2007-01-30 160 if (!pcidev_info)
d4ed8084 Harvey Harrison 2008-03-04 161 panic("%s: Unable to alloc memory for pcidev_info", __func__);
6f09a925 John Keller 2007-01-30 162
6f09a925 John Keller 2007-01-30 163 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
6f09a925 John Keller 2007-01-30 164 if (!sn_irq_info)
d4ed8084 Harvey Harrison 2008-03-04 165 panic("%s: Unable to alloc memory for sn_irq_info", __func__);
6f09a925 John Keller 2007-01-30 166
6f09a925 John Keller 2007-01-30 167 /* Call to retrieve pci device information needed by kernel. */
6f09a925 John Keller 2007-01-30 168 status = sal_get_pcidev_info((u64) pci_domain_nr(dev),
6f09a925 John Keller 2007-01-30 169 (u64) dev->bus->number,
6f09a925 John Keller 2007-01-30 170 dev->devfn,
6f09a925 John Keller 2007-01-30 171 (u64) __pa(pcidev_info),
6f09a925 John Keller 2007-01-30 172 (u64) __pa(sn_irq_info));
6f09a925 John Keller 2007-01-30 173
80a03e29 Stoyan Gaydarov 2009-03-10 174 BUG_ON(status); /* Cannot get platform pci device information */
6f09a925 John Keller 2007-01-30 175
3ec829b6 John Keller 2005-11-29 176
^1da177e Linus Torvalds 2005-04-16 177 /* Copy over PIO Mapped Addresses */
^1da177e Linus Torvalds 2005-04-16 178 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
ab97b8cc Bjorn Helgaas 2016-03-02 179 if (!pcidev_info->pdi_pio_mapped_addr[idx])
^1da177e Linus Torvalds 2005-04-16 180 continue;
^1da177e Linus Torvalds 2005-04-16 181
ab97b8cc Bjorn Helgaas 2016-03-02 182 res = &dev->resource[idx];
ab97b8cc Bjorn Helgaas 2016-03-02 183
ab97b8cc Bjorn Helgaas 2016-03-02 184 size = res->end - res->start;
ab97b8cc Bjorn Helgaas 2016-03-02 185 if (size == 0)
3ec829b6 John Keller 2005-11-29 186 continue;
ab97b8cc Bjorn Helgaas 2016-03-02 187
240504ad Bjorn Helgaas 2016-03-02 188 res->start = pcidev_info->pdi_pio_mapped_addr[idx];
18c25526 Matt Fleming 2016-05-04 189 res->end = res->start + size;
64715725 Bernhard Walle 2007-03-18 190
64715725 Bernhard Walle 2007-03-18 191 /*
64715725 Bernhard Walle 2007-03-18 192 * if it's already in the device structure, remove it before
64715725 Bernhard Walle 2007-03-18 193 * inserting
64715725 Bernhard Walle 2007-03-18 194 */
ab97b8cc Bjorn Helgaas 2016-03-02 @195 if (res->parent && res->parent->child)
ab97b8cc Bjorn Helgaas 2016-03-02 196 release_resource(res);
64715725 Bernhard Walle 2007-03-18 197
ab97b8cc Bjorn Helgaas 2016-03-02 198 if (res->flags & IORESOURCE_IO)
ab97b8cc Bjorn Helgaas 2016-03-02 199 insert_resource(&ioport_resource, res);
^1da177e Linus Torvalds 2005-04-16 200 else
ab97b8cc Bjorn Helgaas 2016-03-02 201 insert_resource(&iomem_resource, res);
d7ad2254 John Keller 2007-07-09 202 /*
240504ad Bjorn Helgaas 2016-03-02 203 * If ROM, mark as shadowed in PROM.
d7ad2254 John Keller 2007-07-09 204 */
d7ad2254 John Keller 2007-07-09 205 if (idx == PCI_ROM_RESOURCE) {
240504ad Bjorn Helgaas 2016-03-02 206 pci_disable_rom(dev);
240504ad Bjorn Helgaas 2016-03-02 207 res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
240504ad Bjorn Helgaas 2016-03-02 208 IORESOURCE_PCI_FIXED;
d7ad2254 John Keller 2007-07-09 209 }
^1da177e Linus Torvalds 2005-04-16 210 }
6f09a925 John Keller 2007-01-30 211
6f09a925 John Keller 2007-01-30 212 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
^1da177e Linus Torvalds 2005-04-16 213 }
6f09a925 John Keller 2007-01-30 214 EXPORT_SYMBOL(sn_io_slot_fixup);
6f09a925 John Keller 2007-01-30 215
:::::: The code at line 195 was first introduced by commit
:::::: ab97b8cc560eabfd8139dd97924a09e46a3c9632 ia64/PCI: Use temporary struct resource * to avoid repetition
:::::: TO: Bjorn Helgaas <bhelgaas@google.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 5528 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] hwmon: ibmpowernv: Add attributes to enable/disable sensor groups
From: Shilpasri G Bhat @ 2018-07-04 16:53 UTC (permalink / raw)
To: Guenter Roeck, mpe; +Cc: linuxppc-dev, linux-hwmon, linux-kernel, ego
In-Reply-To: <e3a013fb-eaf0-8d45-2f23-3be8b3e5640b@roeck-us.net>
Hi Guenter,
Thanks for reviewing the patch.
On 07/04/2018 08:16 PM, Guenter Roeck wrote:
>> + /* Disable if last sensor in the group */
>> + send_command = true;
>> + for (i = 0; i < sg->nr_sensor; i++) {
>> + struct sensor_data *sd = sg->sensors[i];
>> +
>> + if (sd->enable) {
>> + send_command = false;
>> + break;
>> + }
>
> This is weird. So there are situations where a request to disable
> a sensor is accepted, but effectively ignored ? Shouldn't that
> return, say, -EBUSY ?
This is because we do not support per-sensor enable/disable. We can only
enable/disable at a sensor-group level.
This patch follows the semantic to disable a sensor group iff all the sensors
belonging to that group have been disabled. Otherwise the sensor alone is marked
to be disabled and returns -ENODATA on reading it.
And a sensor group will be enabled if any of the sensor in that group is enabled.
I will make changes to the remaining code according to your suggestion.
Thanks and Regards,
Shilpa
^ permalink raw reply
* Re: [PATCH v6 1/4] resource: Move reparent_resources() to kernel/resource.c and make it public
From: Andy Shevchenko @ 2018-07-04 16:46 UTC (permalink / raw)
To: Baoquan He
Cc: Linux Kernel Mailing List, Andrew Morton, Rob Herring,
Dan Williams, Nicolas Pitre, Josh Triplett, kbuild test robot,
Borislav Petkov, Patrik Jakobsson, David Airlie, KY Srinivasan,
Haiyang Zhang, Stephen Hemminger, Dmitry Torokhov, Frank Rowand,
Keith Busch, Jon Derrick, Lorenzo Pieralisi, Bjorn Helgaas,
Thomas Gleixner, brijesh.singh, Jérôme Glisse,
Tom Lendacky, Greg Kroah-Hartman, baiyaowei, richard.weiyang,
devel, linux-input, linux-nvdimm, devicetree, linux-pci,
Eric Biederman, Vivek Goyal, Dave Young, Yinghai Lu, kexec,
Michal Simek, David S. Miller, Chris Zankel, Max Filippov,
Gustavo Padovan, Maarten Lankhorst, Sean Paul, linux-parisc,
open list:LINUX FOR POWERPC PA SEMI PWRFICIENT
In-Reply-To: <20180704041038.8190-2-bhe@redhat.com>
On Wed, Jul 4, 2018 at 7:10 AM, Baoquan He <bhe@redhat.com> wrote:
> reparent_resources() is duplicated in arch/microblaze/pci/pci-common.c
> and arch/powerpc/kernel/pci-common.c, so move it to kernel/resource.c
> so that it's shared.
With couple of comments below,
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
P.S. In some commit message in this series you used 'likt' instead of 'like'.
>
> Signed-off-by: Baoquan He <bhe@redhat.com>
> ---
> arch/microblaze/pci/pci-common.c | 37 -------------------------------------
> arch/powerpc/kernel/pci-common.c | 35 -----------------------------------
> include/linux/ioport.h | 1 +
> kernel/resource.c | 39 +++++++++++++++++++++++++++++++++++++++
> 4 files changed, 40 insertions(+), 72 deletions(-)
>
> diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
> index f34346d56095..7899bafab064 100644
> --- a/arch/microblaze/pci/pci-common.c
> +++ b/arch/microblaze/pci/pci-common.c
> @@ -619,43 +619,6 @@ int pcibios_add_device(struct pci_dev *dev)
> EXPORT_SYMBOL(pcibios_add_device);
>
> /*
> - * Reparent resource children of pr that conflict with res
> - * under res, and make res replace those children.
> - */
> -static int __init reparent_resources(struct resource *parent,
> - struct resource *res)
> -{
> - struct resource *p, **pp;
> - struct resource **firstpp = NULL;
> -
> - for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
> - if (p->end < res->start)
> - continue;
> - if (res->end < p->start)
> - break;
> - if (p->start < res->start || p->end > res->end)
> - return -1; /* not completely contained */
> - if (firstpp == NULL)
> - firstpp = pp;
> - }
> - if (firstpp == NULL)
> - return -1; /* didn't find any conflicting entries? */
> - res->parent = parent;
> - res->child = *firstpp;
> - res->sibling = *pp;
> - *firstpp = res;
> - *pp = NULL;
> - for (p = res->child; p != NULL; p = p->sibling) {
> - p->parent = res;
> - pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
> - p->name,
> - (unsigned long long)p->start,
> - (unsigned long long)p->end, res->name);
> - }
> - return 0;
> -}
> -
> -/*
> * Handle resources of PCI devices. If the world were perfect, we could
> * just allocate all the resource regions and do nothing more. It isn't.
> * On the other hand, we cannot just re-allocate all devices, as it would
> diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
> index fe9733ffffaa..926035bb378d 100644
> --- a/arch/powerpc/kernel/pci-common.c
> +++ b/arch/powerpc/kernel/pci-common.c
> @@ -1088,41 +1088,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> EXPORT_SYMBOL(pcibios_align_resource);
>
> /*
> - * Reparent resource children of pr that conflict with res
> - * under res, and make res replace those children.
> - */
> -static int reparent_resources(struct resource *parent,
> - struct resource *res)
> -{
> - struct resource *p, **pp;
> - struct resource **firstpp = NULL;
> -
> - for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
> - if (p->end < res->start)
> - continue;
> - if (res->end < p->start)
> - break;
> - if (p->start < res->start || p->end > res->end)
> - return -1; /* not completely contained */
> - if (firstpp == NULL)
> - firstpp = pp;
> - }
> - if (firstpp == NULL)
> - return -1; /* didn't find any conflicting entries? */
> - res->parent = parent;
> - res->child = *firstpp;
> - res->sibling = *pp;
> - *firstpp = res;
> - *pp = NULL;
> - for (p = res->child; p != NULL; p = p->sibling) {
> - p->parent = res;
> - pr_debug("PCI: Reparented %s %pR under %s\n",
> - p->name, p, res->name);
> - }
> - return 0;
> -}
> -
> -/*
> * Handle resources of PCI devices. If the world were perfect, we could
> * just allocate all the resource regions and do nothing more. It isn't.
> * On the other hand, we cannot just re-allocate all devices, as it would
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index da0ebaec25f0..dfdcd0bfe54e 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -192,6 +192,7 @@ extern int allocate_resource(struct resource *root, struct resource *new,
> struct resource *lookup_resource(struct resource *root, resource_size_t start);
> int adjust_resource(struct resource *res, resource_size_t start,
> resource_size_t size);
> +int reparent_resources(struct resource *parent, struct resource *res);
> resource_size_t resource_alignment(struct resource *res);
> static inline resource_size_t resource_size(const struct resource *res)
> {
> diff --git a/kernel/resource.c b/kernel/resource.c
> index 30e1bc68503b..d1cbf4b50e17 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -983,6 +983,45 @@ int adjust_resource(struct resource *res, resource_size_t start,
> }
> EXPORT_SYMBOL(adjust_resource);
>
> +/*
/** ?
> + * reparent_resources - reparent resource children of parent that res covers
> + * @parent: parent resource descriptor
> + * @res: resource descriptor desired by caller
> + *
> + * Reparent resource children of 'parent' that conflict with 'res'
> + * under 'res', and make 'res' replace those children.
Describe error codes, please.
> + */
> +int reparent_resources(struct resource *parent, struct resource *res)
> +{
> + struct resource *p, **pp;
> + struct resource **firstpp = NULL;
> +
> + for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
> + if (p->end < res->start)
> + continue;
> + if (res->end < p->start)
> + break;
> + if (p->start < res->start || p->end > res->end)
> + return -ENOTSUPP; /* not completely contained */
> + if (firstpp == NULL)
> + firstpp = pp;
> + }
> + if (firstpp == NULL)
> + return -ECANCELED; /* didn't find any conflicting entries? */
> + res->parent = parent;
> + res->child = *firstpp;
> + res->sibling = *pp;
> + *firstpp = res;
> + *pp = NULL;
> + for (p = res->child; p != NULL; p = p->sibling) {
> + p->parent = res;
> + pr_debug("PCI: Reparented %s %pR under %s\n",
> + p->name, p, res->name);
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL(reparent_resources);
> +
> static void __init __reserve_region_with_split(struct resource *root,
> resource_size_t start, resource_size_t end,
> const char *name)
> --
> 2.13.6
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH v2 2/2] hwmon: ibmpowernv: Add attributes to enable/disable sensor groups
From: Guenter Roeck @ 2018-07-04 14:46 UTC (permalink / raw)
To: Shilpasri G Bhat, mpe; +Cc: linuxppc-dev, linux-hwmon, linux-kernel, ego
In-Reply-To: <1530695793-4584-3-git-send-email-shilpa.bhat@linux.vnet.ibm.com>
On 07/04/2018 02:16 AM, Shilpasri G Bhat wrote:
> On-Chip-Controller(OCC) is an embedded micro-processor in POWER9 chip
> which measures various system and chip level sensors. These sensors
> comprises of environmental sensors (like power, temperature, current
> and voltage) and performance sensors (like utilization, frequency).
> All these sensors are copied to main memory at a regular interval of
> 100ms. OCC provides a way to select a group of sensors that is copied
> to the main memory to increase the update frequency of selected sensor
> groups. When a sensor-group is disabled, OCC will not copy it to main
> memory and those sensors read 0 values.
>
> This patch provides support for enabling/disabling the sensor groups
> like power, temperature, current and voltage. This patch adds new
> per-senor sysfs attribute to disable and enable them.
>
> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
> ---
> Changes from v1:
> - Add per-sensor 'enable' attribute
> - Return -ENODATA when sensor is disabled
>
> Documentation/hwmon/sysfs-interface | 22 +++
> drivers/hwmon/ibmpowernv.c | 281 +++++++++++++++++++++++++++++++-----
> 2 files changed, 264 insertions(+), 39 deletions(-)
>
> diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
> index fc337c3..38ab05c 100644
> --- a/Documentation/hwmon/sysfs-interface
> +++ b/Documentation/hwmon/sysfs-interface
Separate patch please.
> @@ -184,6 +184,11 @@ vrm Voltage Regulator Module version number.
> Affects the way the driver calculates the CPU core reference
> voltage from the vid pins.
>
> +in[0-*]_enable Enable or disable the sensor
> + 1 : Enable
> + 0 : Disable
> + RW
> +
> Also see the Alarms section for status flags associated with voltages.
>
>
> @@ -409,6 +414,12 @@ temp_reset_history
> Reset temp_lowest and temp_highest for all sensors
> WO
>
> +temp[1-*]_enable
> + Enable or disable the sensor
> + 1 : Enable
> + 0 : Disable > + RW
> +
> Some chips measure temperature using external thermistors and an ADC, and
> report the temperature measurement as a voltage. Converting this voltage
> back to a temperature (or the other way around for limits) requires
> @@ -468,6 +479,12 @@ curr_reset_history
> Reset currX_lowest and currX_highest for all sensors
> WO
>
> +curr[1-*]_enable
> + Enable or disable the sensor
> + 1 : Enable
> + 0 : Disable
> + RW
> +
> Also see the Alarms section for status flags associated with currents.
>
> *********
> @@ -566,6 +583,11 @@ power[1-*]_crit Critical maximum power.
> Unit: microWatt
> RW
>
> +power[1-*]_enable Enable or disable the sensor
> + 1 : Enable
> + 0 : Disable
> + RW
> +
> Also see the Alarms section for status flags associated with power readings.
>
Any reason for excluding fan, energy, humidity ?
> **********
> diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
> index f829dad..61e04cf 100644
> --- a/drivers/hwmon/ibmpowernv.c
> +++ b/drivers/hwmon/ibmpowernv.c
> @@ -90,8 +90,28 @@ struct sensor_data {
> char label[MAX_LABEL_LEN];
> char name[MAX_ATTR_LEN];
> struct device_attribute dev_attr;
> + struct sensor_group_data *sgdata;
> + struct sensor_data *sdata[3];
> + bool enable;
> };
>
> +static struct sensor_group_data {
> + u32 gid;
> + u32 nr_phandle;
> + u32 nr_sensor;
> + enum sensors type;
> + const __be32 *phandles;
> + struct sensor_data **sensors;
> + bool enable;
> +} *sg_data;
> +
> +/*
> + * To synchronise writes to struct sensor_data.enable and
> + * struct sensor_group_data.enable
> + */
> +DEFINE_MUTEX(sensor_groups_mutex);
Not as global variable, please.
> +static int nr_sensor_groups;
> +
Do those have to be static variables ? Why not in struct platform_data ?
> struct platform_data {
> const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
> u32 sensors_count; /* Total count of sensors from each group */
> @@ -105,6 +125,9 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
> ssize_t ret;
> u64 x;
>
> + if (sdata->sgdata && !sdata->enable)
> + return -ENODATA;
> +
This return code should be documented in the ABI.
> ret = opal_get_sensor_data_u64(sdata->id, &x);
>
> if (ret)
> @@ -120,6 +143,74 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
> return sprintf(buf, "%llu\n", x);
> }
>
> +static ssize_t show_enable(struct device *dev,
> + struct device_attribute *devattr, char *buf)
> +{
> + struct sensor_data *sdata = container_of(devattr, struct sensor_data,
> + dev_attr);
> +
> + return sprintf(buf, "%u\n", sdata->enable);
> +}
> +
> +static ssize_t store_enable(struct device *dev,
> + struct device_attribute *devattr,
> + const char *buf, size_t count)
> +{
> + struct sensor_data *sdata = container_of(devattr, struct sensor_data,
> + dev_attr);
> + struct sensor_group_data *sg = sdata->sgdata;
> + u32 data;
> + int ret, i;
> + bool send_command;
> +
> + ret = kstrtoint(buf, 0, &data);
Use kstrtobool(), please. Then you won't need the additional range check below.
> + if (ret)
> + return ret;
> +
> + if (data != 0 && data != 1)
> + return -EIO;
This is not an IO error.
> +
> + ret = mutex_lock_interruptible(&sensor_groups_mutex);
> + if (ret)
> + return ret;
> +
> + sdata->enable = data;
> + if ((data && sg->enable) || (!data && !sg->enable)) {
> + send_command = false;
If data is bool you can use a simple comparison.
> + } else if (data && !sg->enable) {
!sg->enable is unnecessary.
> + /* Enable if first sensor in the group */
> + send_command = true; > + } else if (!data && sg->enable) {
This if statement is always true and thus unnecessary.
Overall, you could use
send_command = data != sg->enable;
if (send_command && !data) {
for (...) {
> + /* Disable if last sensor in the group */
> + send_command = true;
> + for (i = 0; i < sg->nr_sensor; i++) {
> + struct sensor_data *sd = sg->sensors[i];
> +
> + if (sd->enable) {
> + send_command = false;
> + break;
> + }
This is weird. So there are situations where a request to disable
a sensor is accepted, but effectively ignored ? Shouldn't that
return, say, -EBUSY ?
> + }
> + }
> +
> + if (send_command) {
> + ret = sensor_group_enable(sg->gid, data);
> + if (!ret)
> + sg->enable = data;
> + }
> +
> + if (!ret) {
> + for (i = 0; i < ARRAY_SIZE(sdata->sdata); i++)
> + sdata->sdata[i]->enable = data;
> + ret = count;
> + } else {
> + ret = -EIO;
No overriding error codes, please.
> + }
> +
> + mutex_unlock(&sensor_groups_mutex);
> + return ret;
> +}
> +
> static ssize_t show_label(struct device *dev, struct device_attribute *devattr,
> char *buf)
> {
> @@ -292,6 +383,90 @@ static u32 get_sensor_hwmon_index(struct sensor_data *sdata,
> return ++sensor_groups[sdata->type].hwmon_index;
> }
>
> +static int init_sensor_group_data(struct platform_device *pdev)
> +{
> + struct device_node *sensor_groups, *sg;
> + enum sensors type;
> + int count = 0, ret = 0;
> +
> + sensor_groups = of_find_node_by_path("/ibm,opal/sensor-groups");
> + if (!sensor_groups)
> + return ret;
> +
> + for_each_child_of_node(sensor_groups, sg) {
> + type = get_sensor_type(sg);
> + if (type != MAX_SENSOR_TYPE)
> + nr_sensor_groups++;
> + }
> +
> + if (!nr_sensor_groups)
> + goto out;
> +
> + sg_data = devm_kzalloc(&pdev->dev, nr_sensor_groups * sizeof(*sg_data),
> + GFP_KERNEL);
> + if (!sg_data) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + for_each_child_of_node(sensor_groups, sg) {
> + const __be32 *phandles;
> + int len, gid;
> +
> + type = get_sensor_type(sg);
> + if (type == MAX_SENSOR_TYPE)
> + continue;
> +
> + if (of_property_read_u32(sg, "sensor-group-id", &gid))
> + continue;
> +
> + phandles = of_get_property(sg, "sensors", &len);
> + if (!phandles)
> + continue;
> +
> + len /= sizeof(u32);
> + if (!len)
> + continue;
> +
> + sg_data[count].sensors = devm_kzalloc(&pdev->dev,
> + len * sizeof(struct sensor_data *),
> + GFP_KERNEL);
> + if (!sg_data[count].sensors) {
> + ret = -ENOMEM;
> + break;
Doesn't this result in a missing of_node_put() on sg ?
> + }
> +
> + sg_data[count].nr_sensor = 0;
> + sg_data[count].gid = gid;
> + sg_data[count].type = type;
> + sg_data[count].nr_phandle = len;
> + sg_data[count].phandles = phandles;
> + sg_data[count++].enable = true;
> + }
> +out:
> + of_node_put(sensor_groups);
> + return ret;
> +}
> +
> +static struct sensor_group_data *get_sensor_group(struct device_node *np,
> + enum sensors type)
> +{
> + int i, j;
> +
> + for (i = 0; i < nr_sensor_groups; i++) {
> + const __be32 *phandles = sg_data[i].phandles;
> +
> + if (type != sg_data[i].type)
> + continue;
> +
> + for (j = 0; j < sg_data[i].nr_phandle; j++)
> + if (be32_to_cpu(phandles[j]) == np->phandle)
> + return &sg_data[i];
> + }
> +
> + return NULL;
> +}
> +
> static int populate_attr_groups(struct platform_device *pdev)
> {
> struct platform_data *pdata = platform_get_drvdata(pdev);
> @@ -299,6 +474,9 @@ static int populate_attr_groups(struct platform_device *pdev)
> struct device_node *opal, *np;
> enum sensors type;
>
> + if (init_sensor_group_data(pdev))
> + return -ENOMEM;
> +
init_sensor_group_data() returns an error code which you should pass on.
> opal = of_find_node_by_path("/ibm,opal/sensors");
> for_each_child_of_node(opal, np) {
> const char *label;
> @@ -313,7 +491,7 @@ static int populate_attr_groups(struct platform_device *pdev)
> sensor_groups[type].attr_count++;
>
> /*
> - * add attributes for labels, min and max
> + * add attributes for labels, min, max and enable
> */
> if (!of_property_read_string(np, "label", &label))
> sensor_groups[type].attr_count++;
> @@ -321,6 +499,8 @@ static int populate_attr_groups(struct platform_device *pdev)
> sensor_groups[type].attr_count++;
> if (of_find_property(np, "sensor-data-max", NULL))
> sensor_groups[type].attr_count++;
> + if (get_sensor_group(np, type))
> + sensor_groups[type].attr_count++;
> }
>
> of_node_put(opal);
> @@ -344,7 +524,10 @@ static int populate_attr_groups(struct platform_device *pdev)
> static void create_hwmon_attr(struct sensor_data *sdata, const char *attr_name,
> ssize_t (*show)(struct device *dev,
> struct device_attribute *attr,
> - char *buf))
> + char *buf),
> + ssize_t (*store)(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count))
> {
> snprintf(sdata->name, MAX_ATTR_LEN, "%s%d_%s",
> sensor_groups[sdata->type].name, sdata->hwmon_index,
> @@ -352,23 +535,34 @@ static void create_hwmon_attr(struct sensor_data *sdata, const char *attr_name,
>
> sysfs_attr_init(&sdata->dev_attr.attr);
> sdata->dev_attr.attr.name = sdata->name;
> - sdata->dev_attr.attr.mode = S_IRUGO;
> sdata->dev_attr.show = show;
> + if (store) {
> + sdata->dev_attr.store = store;
> + sdata->dev_attr.attr.mode = 0664;
> + } else {
> + sdata->dev_attr.attr.mode = 0444;
> + }
> }
>
> static void populate_sensor(struct sensor_data *sdata, int od, int hd, int sid,
> const char *attr_name, enum sensors type,
> const struct attribute_group *pgroup,
> + struct sensor_group_data *sgdata,
> ssize_t (*show)(struct device *dev,
> struct device_attribute *attr,
> - char *buf))
> + char *buf),
> + ssize_t (*store)(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count))
> {
> sdata->id = sid;
> sdata->type = type;
> sdata->opal_index = od;
> sdata->hwmon_index = hd;
> - create_hwmon_attr(sdata, attr_name, show);
> + create_hwmon_attr(sdata, attr_name, show, store);
> pgroup->attrs[sensor_groups[type].attr_count++] = &sdata->dev_attr.attr;
> + sdata->enable = true;
> + sdata->sgdata = sgdata;
> }
>
> static char *get_max_attr(enum sensors type)
> @@ -408,18 +602,17 @@ static int create_device_attrs(struct platform_device *pdev)
> u32 count = 0;
> int err = 0;
>
> - opal = of_find_node_by_path("/ibm,opal/sensors");
> sdata = devm_kcalloc(&pdev->dev,
> pdata->sensors_count, sizeof(*sdata),
> GFP_KERNEL);
> - if (!sdata) {
> - err = -ENOMEM;
> - goto exit_put_node;
> - }
> + if (!sdata)
> + return -ENOMEM;
>
> + opal = of_find_node_by_path("/ibm,opal/sensors");
> for_each_child_of_node(opal, np) {
> + struct sensor_group_data *sgdata;
> const char *attr_name;
> - u32 opal_index;
> + u32 opal_index, hw_id;
> const char *label;
>
> if (np->name == NULL)
> @@ -456,14 +649,43 @@ static int create_device_attrs(struct platform_device *pdev)
> opal_index = INVALID_INDEX;
> }
>
> - sdata[count].opal_index = opal_index;
> - sdata[count].hwmon_index =
> - get_sensor_hwmon_index(&sdata[count], sdata, count);
> + hw_id = get_sensor_hwmon_index(&sdata[count], sdata, count);
> + sgdata = get_sensor_group(np, type);
> + populate_sensor(&sdata[count], opal_index, hw_id, sensor_id,
> + attr_name, type, pgroups[type], sgdata,
> + show_sensor, NULL);
> + count++;
> +
> + if (!of_property_read_u32(np, "sensor-data-max", &sensor_id)) {
> + attr_name = get_max_attr(type);
> + populate_sensor(&sdata[count], opal_index, hw_id,
> + sensor_id, attr_name, type,
> + pgroups[type], sgdata, show_sensor,
> + NULL);
> + count++;
> + }
> +
> + if (!of_property_read_u32(np, "sensor-data-min", &sensor_id)) {
> + attr_name = get_min_attr(type);
> + populate_sensor(&sdata[count], opal_index, hw_id,
> + sensor_id, attr_name, type,
> + pgroups[type], sgdata, show_sensor,
> + NULL);
> + count++;
> + }
>
> - create_hwmon_attr(&sdata[count], attr_name, show_sensor);
> + if (sgdata) {
> + int i;
>
> - pgroups[type]->attrs[sensor_groups[type].attr_count++] =
> - &sdata[count++].dev_attr.attr;
> + sgdata->sensors[sgdata->nr_sensor++] = &sdata[count];
> + populate_sensor(&sdata[count], opal_index, hw_id,
> + sgdata->gid, "enable", type,
> + pgroups[type], sgdata, show_enable,
> + store_enable);
> + for (i = 0; i < ARRAY_SIZE(sdata[count].sdata); i++)
> + sdata[count].sdata[i] = &sdata[count - i - 1];
> + count++;
> + }
>
> if (!of_property_read_string(np, "label", &label)) {
> /*
> @@ -474,34 +696,15 @@ static int create_device_attrs(struct platform_device *pdev)
> */
>
> make_sensor_label(np, &sdata[count], label);
> - populate_sensor(&sdata[count], opal_index,
> - sdata[count - 1].hwmon_index,
> + populate_sensor(&sdata[count], opal_index, hw_id,
> sensor_id, "label", type, pgroups[type],
> - show_label);
> - count++;
> - }
> -
> - if (!of_property_read_u32(np, "sensor-data-max", &sensor_id)) {
> - attr_name = get_max_attr(type);
> - populate_sensor(&sdata[count], opal_index,
> - sdata[count - 1].hwmon_index,
> - sensor_id, attr_name, type,
> - pgroups[type], show_sensor);
> - count++;
> - }
> -
> - if (!of_property_read_u32(np, "sensor-data-min", &sensor_id)) {
> - attr_name = get_min_attr(type);
> - populate_sensor(&sdata[count], opal_index,
> - sdata[count - 1].hwmon_index,
> - sensor_id, attr_name, type,
> - pgroups[type], show_sensor);
> + NULL, show_label, NULL);
> count++;
> }
> }
>
> -exit_put_node:
> of_node_put(opal);
> +
> return err;
> }
>
>
^ permalink raw reply
* Re: [bug report] cxl: Prevent adapter reset if an active context exists
From: Vaibhav Jain @ 2018-07-04 15:31 UTC (permalink / raw)
To: Dan Carpenter; +Cc: linuxppc-dev
In-Reply-To: <20180704144050.mjex2gg7hsarhc6x@kili.mountain>
Dan Carpenter <dan.carpenter@oracle.com> writes:
> The patch 70b565bbdb91: "cxl: Prevent adapter reset if an active
> context exists" from Oct 14, 2016, leads to the following static
> checker warning:
>
> drivers/misc/cxl/main.c:290 cxl_adapter_context_get()
> warn: 'atomic_inc_unless_negative(&adapter->contexts_num)' is unsigned
>
Thanks for reporting this. I have sent out a patch to fix this at
http://patchwork.ozlabs.org/patch/939426/
--
Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
Linux Technology Center, IBM India Pvt. Ltd.
^ permalink raw reply
* [PATCH] cxl: Fix wrong comparison in cxl_adapter_context_get()
From: Vaibhav Jain @ 2018-07-04 15:28 UTC (permalink / raw)
To: linuxppc-dev, Frederic Barrat, Andrew Donnellan, Dan Carpenter
Cc: Vaibhav Jain, Christophe Lombard, Philippe Bergheaud,
Alastair D'Silva, stable
Function atomic_inc_unless_negative() returns a bool to indicate
success/failure. However cxl_adapter_context_get() wrongly compares
the return value against '>=0' which will always be true. The patch
fixes this comparison to '==0' there by also fixing this compile time
warning:
drivers/misc/cxl/main.c:290 cxl_adapter_context_get()
warn: 'atomic_inc_unless_negative(&adapter->contexts_num)' is unsigned
Cc: stable@vger.kernel.org
Fixes: 70b565bbdb91 ("cxl: Prevent adapter reset if an active context exists")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
---
drivers/misc/cxl/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index c1ba0d42cbc8..e0f29b8a872d 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -287,7 +287,7 @@ int cxl_adapter_context_get(struct cxl *adapter)
int rc;
rc = atomic_inc_unless_negative(&adapter->contexts_num);
- return rc >= 0 ? 0 : -EBUSY;
+ return rc ? 0 : -EBUSY;
}
void cxl_adapter_context_put(struct cxl *adapter)
--
2.17.1
^ permalink raw reply related
* [bug report] cxl: Prevent adapter reset if an active context exists
From: Dan Carpenter @ 2018-07-04 14:40 UTC (permalink / raw)
To: vaibhav; +Cc: linuxppc-dev
Hello Vaibhav Jain,
The patch 70b565bbdb91: "cxl: Prevent adapter reset if an active
context exists" from Oct 14, 2016, leads to the following static
checker warning:
drivers/misc/cxl/main.c:290 cxl_adapter_context_get()
warn: 'atomic_inc_unless_negative(&adapter->contexts_num)' is unsigned
drivers/misc/cxl/main.c
285 int cxl_adapter_context_get(struct cxl *adapter)
286 {
287 int rc;
288
289 rc = atomic_inc_unless_negative(&adapter->contexts_num);
290 return rc >= 0 ? 0 : -EBUSY;
atomic_inc_unless_negative() returns bool so it's always >= 0.
291 }
regards,
dan carpenter
^ permalink raw reply
* [PATCH] ASoC: fsl_spdif: Use 64-bit arithmetic instead of 32-bit
From: Gustavo A. R. Silva @ 2018-07-04 14:18 UTC (permalink / raw)
To: Timur Tabi, Nicolin Chen, Xiubo Li, Fabio Estevam, Liam Girdwood,
Mark Brown, Jaroslav Kysela, Takashi Iwai
Cc: alsa-devel, linuxppc-dev, linux-kernel, Gustavo A. R. Silva
Add suffix ULL to constant 64 in order to give the compiler complete
information about the proper arithmetic to use.
Notice that such constant is used in a context that expects an
expression of type u64 (64 bits, unsigned) and the following
expression is currently being evaluated using 32-bit arithmetic:
rate[index] * txclk_df * 64
Addresses-Coverity-ID: 1222129 ("Unintentional integer overflow")
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
---
sound/soc/fsl/fsl_spdif.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 9b59d87..740b90d 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1118,7 +1118,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
for (sysclk_df = sysclk_dfmin; sysclk_df <= sysclk_dfmax; sysclk_df++) {
for (txclk_df = 1; txclk_df <= 128; txclk_df++) {
- rate_ideal = rate[index] * txclk_df * 64;
+ rate_ideal = rate[index] * txclk_df * 64ULL;
if (round)
rate_actual = clk_round_rate(clk, rate_ideal);
else
--
2.7.4
^ permalink raw reply related
* Re: How is this possible - Register r30 contains 0xc2236400 instead of 0xc6236400
From: Christophe LEROY @ 2018-07-04 13:59 UTC (permalink / raw)
To: Segher Boessenkool, Michael Ellerman
Cc: linuxppc-dev@lists.ozlabs.org, Benjamin Herrenschmidt,
Paul Mackerras
In-Reply-To: <20180704134515.GI16221@gate.crashing.org>
Le 04/07/2018 à 15:45, Segher Boessenkool a écrit :
> On Wed, Jul 04, 2018 at 11:11:59PM +1000, Michael Ellerman wrote:
>> Christophe LEROY <christophe.leroy@c-s.fr> writes:
>>
>>> Kernel Oops at 0xc0334d5c for reading at address 0xc2236450 which
>>> corresponds to r30 + 80
>>>
>>> But r30 should contain what's at r3 + 16 that is at 0xc619ec10 so r30
>>> should be c6236400 as shown below (print_hex_dump(regs->gpr[3]) added at
>>> end of __die() )
>>>
>>> So how can r30 contain 0xc2236400 instead ?
>>
>> The simplest answer is that memory was modified between the time we
>> loaded it into r30 and when you print it.
>>
>> So it did contain 0xc2236400 but has since been modified to now contain
>> 0xc6236400.
>>
>> The thing that makes me less certain, is that c6 would be the correct
>> value (I think?), so it's been modified back to the correct value, which
>> seems lucky.
>>
>> Mysterious.
>
> That depends. Is this reproducible at all? It is a single bit flip.
Yes it is reproductible.
It isn't reproduced if I modify the function in such a way that there is
an additional (unrelated) instruction before that read.
It isn't reproduced if I move the kernel base address to 0xd0000000 or
0xb0000000 instead of 0xc0000000
If I force a second read of this address in the function, I get the same
value (in another register).
If I add a dcbi before the second read I get the correct address.
So it still looks mysterious to me ...
Christophe
>
>
> Segher
>
^ permalink raw reply
* Re: How is this possible - Register r30 contains 0xc2236400 instead of 0xc6236400
From: Segher Boessenkool @ 2018-07-04 13:45 UTC (permalink / raw)
To: Michael Ellerman
Cc: Christophe LEROY, linuxppc-dev@lists.ozlabs.org,
Benjamin Herrenschmidt, Paul Mackerras
In-Reply-To: <87k1qbkuw0.fsf@concordia.ellerman.id.au>
On Wed, Jul 04, 2018 at 11:11:59PM +1000, Michael Ellerman wrote:
> Christophe LEROY <christophe.leroy@c-s.fr> writes:
>
> > Kernel Oops at 0xc0334d5c for reading at address 0xc2236450 which
> > corresponds to r30 + 80
> >
> > But r30 should contain what's at r3 + 16 that is at 0xc619ec10 so r30
> > should be c6236400 as shown below (print_hex_dump(regs->gpr[3]) added at
> > end of __die() )
> >
> > So how can r30 contain 0xc2236400 instead ?
>
> The simplest answer is that memory was modified between the time we
> loaded it into r30 and when you print it.
>
> So it did contain 0xc2236400 but has since been modified to now contain
> 0xc6236400.
>
> The thing that makes me less certain, is that c6 would be the correct
> value (I think?), so it's been modified back to the correct value, which
> seems lucky.
>
> Mysterious.
That depends. Is this reproducible at all? It is a single bit flip.
Segher
^ permalink raw reply
* Re: [PATCH] powerpc/mpic: Cleanup irq vector accounting
From: Michael Ellerman @ 2018-07-04 13:27 UTC (permalink / raw)
To: Bharat Bhushan, benh, paulus, robh, geoff, tyreld, linuxppc-dev,
linux-kernel
Cc: Bharat Bhushan
In-Reply-To: <1530267872-31244-1-git-send-email-Bharat.Bhushan@nxp.com>
Bharat Bhushan <Bharat.Bhushan@nxp.com> writes:
> Available vector space accounts ipis and timer interrupts
> while spurious vector was not accounted.
OK. What is the symptom of that? Nothing? Total system crash?
Looks like this can be tagged:
Fixes: 0a4081641d72 ("powerpc/mpic: FSL MPIC error interrupt support.")
Which added the code that uses "12".
> Also later
> mpic_setup_error_int() escape one more vector, seemingly it
> assumes one spurious vector.
Ah right, I get it now.
So there is no bug. It's just a disagreement about whether the "intvec"
argument to mpic_setup_error_int() indicates the first number that's
free to use or the last number that has been allocated.
Right?
cheers
> Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
> ---
> arch/powerpc/sysdev/fsl_mpic_err.c | 2 +-
> arch/powerpc/sysdev/mpic.c | 6 +++---
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c
> index 488ec45..2a98837 100644
> --- a/arch/powerpc/sysdev/fsl_mpic_err.c
> +++ b/arch/powerpc/sysdev/fsl_mpic_err.c
> @@ -76,7 +76,7 @@ int mpic_setup_error_int(struct mpic *mpic, int intvec)
> mpic->flags |= MPIC_FSL_HAS_EIMR;
> /* allocate interrupt vectors for error interrupts */
> for (i = MPIC_MAX_ERR - 1; i >= 0; i--)
> - mpic->err_int_vecs[i] = --intvec;
> + mpic->err_int_vecs[i] = intvec--;
>
> return 0;
> }
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index 1d4e0ef6..e098d1e 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -1380,12 +1380,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
> * global vector number space, as in case of ipis
> * and timer interrupts.
> *
> - * Available vector space = intvec_top - 12, where 12
> + * Available vector space = intvec_top - 13, where 13
> * is the number of vectors which have been consumed by
> - * ipis and timer interrupts.
> + * ipis, timer interrupts and spurious.
> */
> if (fsl_version >= 0x401) {
> - ret = mpic_setup_error_int(mpic, intvec_top - 12);
> + ret = mpic_setup_error_int(mpic, intvec_top - 13);
> if (ret)
> return NULL;
> }
> --
> 1.9.3
^ permalink raw reply
* Re: [PATCH v5 5/7] powerpc/pseries: flush SLB contents on SLB MCE errors.
From: Michael Ellerman @ 2018-07-04 13:15 UTC (permalink / raw)
To: Michal Suchánek, Nicholas Piggin
Cc: Mahesh J Salgaonkar, Laurent Dufour, Michal Suchanek,
Aneesh Kumar K.V, linuxppc-dev
In-Reply-To: <20180703123758.7705260b@naga.suse.cz>
Michal Such=C3=A1nek <msuchanek@suse.de> writes:
> On Tue, 3 Jul 2018 08:08:14 +1000
> Nicholas Piggin <npiggin@gmail.com> wrote:
>> On Mon, 02 Jul 2018 11:17:06 +0530
>> Mahesh J Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>> > From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>> >=20
>> > On pseries, as of today system crashes if we get a machine check
>> > exceptions due to SLB errors. These are soft errors and can be
>> > fixed by flushing the SLBs so the kernel can continue to function
>> > instead of system crash. We do this in real mode before turning on
>> > MMU. Otherwise we would run into nested machine checks. This patch
>> > now fetches the rtas error log in real mode and flushes the SLBs on
>> > SLB errors.
>> >=20
>> > Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>> > ---
>> > arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1=20
>> > arch/powerpc/include/asm/machdep.h | 1=20
>> > arch/powerpc/kernel/exceptions-64s.S | 42
>> > +++++++++++++++++++++ arch/powerpc/kernel/mce.c
>> > | 16 +++++++- arch/powerpc/mm/slb.c |
>> > 6 +++ arch/powerpc/platforms/powernv/opal.c | 1=20
>> > arch/powerpc/platforms/pseries/pseries.h | 1=20
>> > arch/powerpc/platforms/pseries/ras.c | 51
>> > +++++++++++++++++++++++++
>> > arch/powerpc/platforms/pseries/setup.c | 1 9 files
>> > changed, 116 insertions(+), 4 deletions(-)=20
>>=20
>>=20
>> > +TRAMP_REAL_BEGIN(machine_check_pSeries_early)
>> > +BEGIN_FTR_SECTION
>> > + EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200)
>> > + mr r10,r1 /* Save r1 */
>> > + ld r1,PACAMCEMERGSP(r13) /* Use MC emergency
>> > stack */
>> > + subi r1,r1,INT_FRAME_SIZE /* alloc stack
>> > frame */
>> > + mfspr r11,SPRN_SRR0 /* Save SRR0 */
>> > + mfspr r12,SPRN_SRR1 /* Save SRR1 */
>> > + EXCEPTION_PROLOG_COMMON_1()
>> > + EXCEPTION_PROLOG_COMMON_2(PACA_EXMC)
>> > + EXCEPTION_PROLOG_COMMON_3(0x200)
>> > + addi r3,r1,STACK_FRAME_OVERHEAD
>> > + BRANCH_LINK_TO_FAR(machine_check_early) /* Function call
>> > ABI */=20=20
>>=20
>> Is there any reason you can't use the existing
>> machine_check_powernv_early code to do all this?
>
> Code sharing is nice but if we envision this going to stable kernels
> butchering the existing handler is going to be a nightmare. The code is
> quite a bit different between kernel versions.
I'm not sure if we'll send it to stable kernels. But we obviously will
back port it to some distros :)
So if sharing the code is a significant impediment to that, then I'm
happy if we don't share code initially. That could be done as a
follow-up to this series.
cheers
^ permalink raw reply
* Re: How is this possible - Register r30 contains 0xc2236400 instead of 0xc6236400
From: Michael Ellerman @ 2018-07-04 13:11 UTC (permalink / raw)
To: Christophe LEROY, linuxppc-dev@lists.ozlabs.org,
Segher Boessenkool, Benjamin Herrenschmidt, Paul Mackerras
In-Reply-To: <09ae0460-11e7-c893-5a5f-55e55a3ef372@c-s.fr>
Christophe LEROY <christophe.leroy@c-s.fr> writes:
> Kernel Oops at 0xc0334d5c for reading at address 0xc2236450 which=20
> corresponds to r30 + 80
>
> But r30 should contain what's at r3 + 16 that is at 0xc619ec10 so r30=20
> should be c6236400 as shown below (print_hex_dump(regs->gpr[3]) added at=
=20
> end of __die() )
>
> So how can r30 contain 0xc2236400 instead ?
The simplest answer is that memory was modified between the time we
loaded it into r30 and when you print it.
So it did contain 0xc2236400 but has since been modified to now contain
0xc6236400.
The thing that makes me less certain, is that c6 would be the correct
value (I think?), so it's been modified back to the correct value, which
seems lucky.
Mysterious.
cheers
> And this is not random, it happens at most if not every startup.
>
> c0334d44 <sock_wfree>:
> c0334d44:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 7c 08 02 a6=C2=A0=C2=A0=C2=
=A0=C2=A0 mflr=C2=A0=C2=A0=C2=A0 r0
> c0334d48:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 94 21 ff f0=C2=A0=C2=A0=C2=
=A0=C2=A0 stwu=C2=A0=C2=A0=C2=A0 r1,-16(r1)
> c0334d4c:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 bf c1 00 08=C2=A0=C2=A0=C2=
=A0=C2=A0 stmw=C2=A0=C2=A0=C2=A0 r30,8(r1)
> c0334d50:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 90 01 00 14=C2=A0=C2=A0=C2=
=A0=C2=A0 stw=C2=A0=C2=A0=C2=A0=C2=A0 r0,20(r1)
> c0334d54:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 83 c3 00 10=C2=A0=C2=A0=C2=
=A0=C2=A0 lwz=C2=A0=C2=A0=C2=A0=C2=A0 r30,16(r3)
> c0334d58:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 81 23 00 a8=C2=A0=C2=A0=C2=
=A0=C2=A0 lwz=C2=A0=C2=A0=C2=A0=C2=A0 r9,168(r3)
> c0334d5c:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 81 5e 00 50=C2=A0=C2=A0=C2=
=A0=C2=A0 lwz=C2=A0=C2=A0=C2=A0=C2=A0 r10,80(r30)
>
>
> [=C2=A0 152.288237] Unable to handle kernel paging request for data at=20
> address 0xc2236450
> [=C2=A0 152.295444] Faulting instruction address: 0xc0334d5c
> [=C2=A0 152.300369] Oops: Kernel access of bad area, sig: 11 [#1]
> [=C2=A0 152.305665] BE PREEMPT DEBUG_PAGEALLOC CMPC885
> [=C2=A0 152.313630] CPU: 0 PID: 269 Comm: in:imuxsock Not tainted=20
> 4.14.52-00025-g5bada429cf-dirty #36
> [=C2=A0 152.322729] task: c623e100 task.stack: c650c000
> [=C2=A0 152.327202] NIP:=C2=A0 c0334d5c LR: c043602c CTR: c0435fb8
> [=C2=A0 152.332200] REGS: c650dc00 TRAP: 0300=C2=A0=C2=A0 Not tainted=20
> (4.14.52-00025-g5bada429cf-dirty)
> [=C2=A0 152.340699] MSR:=C2=A0 00009032 <EE,ME,IR,DR,RI>=C2=A0 CR: 280028=
22 XER: 20000000
> [=C2=A0 152.347333] DAR: c2236450 DSISR: c0000000
> [=C2=A0 152.347333] GPR00: c043602c c650dcb0 c623e100 c619ec00 c642c060=20
> 00000008 00000018 c650dd4c
> [=C2=A0 152.347333] GPR08: c0435fb8 000002b0 c068d830 00000004 28004822=20
> 100d4208 00000000 7780c848
> [=C2=A0 152.347333] GPR16: 0ff58398 777674b0 1024b050 1024b0a8 1005ddbc=20
> 0ff5a7bc 000003e8 00000000
> [=C2=A0 152.347333] GPR24: 0000008e c5011650 c650deb8 0000008e c619ec00=20
> 00000040 c2236400 c619ec00
> [=C2=A0 152.385015] NIP [c0334d5c] sock_wfree+0x18/0xa4
> [=C2=A0 152.389458] LR [c043602c] unix_destruct_scm+0x74/0x88
> [=C2=A0 152.394399] Call Trace:
> [=C2=A0 152.396868] [c650dcb0] [c006348c] ns_to_timeval+0x4c/0x7c (unreli=
able)
> [=C2=A0 152.403305] [c650dcc0] [c043602c] unix_destruct_scm+0x74/0x88
> [=C2=A0 152.408999] [c650dcf0] [c033a10c] skb_release_head_state+0x8c/0x1=
10
> [=C2=A0 152.415184] [c650dd00] [c033a3c4] skb_release_all+0x18/0x50
> [=C2=A0 152.420690] [c650dd10] [c033a7cc] consume_skb+0x38/0xec
> [=C2=A0 152.425869] [c650dd20] [c0342d7c] skb_free_datagram+0x1c/0x68
> [=C2=A0 152.431535] [c650dd30] [c0435c8c] unix_dgram_recvmsg+0x19c/0x4ac
> [=C2=A0 152.437476] [c650ddb0] [c0331370] ___sys_recvmsg+0x98/0x138
> [=C2=A0 152.442984] [c650deb0] [c0333280] __sys_recvmsg+0x40/0x84
> [=C2=A0 152.448321] [c650df10] [c0333680] SyS_socketcall+0xb8/0x1d4
> [=C2=A0 152.453832] [c650df40] [c000d1ac] ret_from_syscall+0x0/0x38
> [=C2=A0 152.459286] Instruction dump:
> [=C2=A0 152.462225] 41beffac 4bffff58 38800003 4bffffa0 38800001 4bffff98=
=20
> 7c0802a6 9421fff0
> [=C2=A0 152.469881] bfc10008 90010014 83c30010 812300a8 <815e0050> 3bfe00=
e0=20
> 71480200 4082003c
> [=C2=A0 152.477739] c619ec00: 00 00 00 00 00 00 00 00 00 00 00 23 6f d9 b=
1 65
> [=C2=A0 152.484100] c619ec10: c6 23 64 00 00 00 00 00 c6 42 c0 60 00 00 0=
3 e8
> [=C2=A0 152.490471] c619ec20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0=
0 00
> [=C2=A0 152.496837] c619ec30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0=
0 00
> [=C2=A0 152.503205] c619ec40: 00 00 00 00 00 00 00 00 00 00 00 00 c0 43 5=
f b8
> [=C2=A0 152.509575] c619ec50: 00 00 00 00 00 00 00 00 00 00 00 8e 00 00 0=
0 00
> [=C2=A0 152.515943] c619ec60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0=
0 00
> [=C2=A0 152.522311] c619ec70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0=
0 00
> [=C2=A0 152.528680] c619ec80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0=
0 00
> [=C2=A0 152.535048] c619ec90: 00 00 ff ff 00 00 ff ff c6 42 30 8e c6 42 3=
1 50
> [=C2=A0 152.541417] c619eca0: c6 42 30 00 c6 42 30 00 00 00 02 b0 00 00 0=
0 01
> [=C2=A0 152.547781] ---[ end trace 0710a9d231876a27 ]---
>
> Christophe
^ permalink raw reply
* Re: [PATCH v3 0/2] powernv/cpuidle Device-tree parsing cleanup
From: Rafael J. Wysocki @ 2018-07-04 10:54 UTC (permalink / raw)
To: Akshay Adiga
Cc: linux-kernel, linuxppc-dev, linux-pm, stewart, benh, svaidy, ego,
npiggin, mpe
In-Reply-To: <1530609656-13301-1-git-send-email-akshay.adiga@linux.vnet.ibm.com>
On Tuesday, July 3, 2018 11:20:54 AM CEST Akshay Adiga wrote:
>
> Device-tree parsed multiple time in powernv cpuidle and powernv
> hotplug code.
>
> First to identify supported flags. Second time, to identify deepest_state
> and first deep state. Third time, during cpuidle init to find the available
> idle states. Any change in device-tree format will lead to make changes in
> these 3 places. Errors in device-tree can be handled in a better manner.
>
> This series adds code to parse device tree once and save in global structure.
>
> Changes from v2 :
> - Fix build error (moved a hunk from patch 1 to patch 2)
> Changes from v1 :
> - fold first 2 patches into 1
> - rename pm_ctrl_reg_* as psscr_*
> - added comment stating removal of pmicr parsing code
> - removed parsing code for pmicr
> - add member valid in pnv_idle_states_t to indicate if the psscr-mask/val
> are valid combination,
> - Change function description of pnv_parse_cpuidle_dt
> - Added error handling code.
>
>
> Akshay Adiga (2):
> powernv/cpuidle: Parse dt idle properties into global structure
> powernv/cpuidle: Use parsed device tree values for cpuidle_init
>
> arch/powerpc/include/asm/cpuidle.h | 13 ++
> arch/powerpc/platforms/powernv/idle.c | 216 ++++++++++++++++----------
> drivers/cpuidle/cpuidle-powernv.c | 154 ++++--------------
> 3 files changed, 177 insertions(+), 206 deletions(-)
>
>
I am assuming that this series will go in via the powerpc tree.
Thanks,
Rafael
^ 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