* [PATCH v2 0/5] fsl-asoc-card: Add optional dt property for setting mclk-id
From: Ariel D'Alessandro @ 2022-01-17 13:21 UTC (permalink / raw)
To: alsa-devel, devicetree, linux-kernel, linux-omap, linuxppc-dev
Cc: ariel.dalessandro, kuninori.morimoto.gx, Xiubo.Lee, tony,
shengjiu.wang, tiwai, lgirdwood, robh+dt, perex, nicoleotsuka,
broonie, bcousson, michael, festevam
This is a follow up of patchset:
[RFC patch 0/5] Support BCLK input clock in tlv320aic31xx
Sound cards may allow using different main clock inputs. In the generic
fsl-asoc-card driver, these values are hardcoded for each specific card
configuration.
Let's make it more flexible, allowing setting mclk-id from the
device-tree node.
Changes in v2:
* Split patch adding mckl-id property.
Ariel D'Alessandro (5):
dt-bindings: sound: Rename tlv320aic31xx-micbias as tlv320aic31xx
dt-bindings: tlv320aic31xx: Define PLL clock inputs
ASoC: bindings: fsl-asoc-card: Add mclk-id optional property
ASoC: fsl-asoc-card: Add optional dt property for setting mclk-id
ASoC: fsl-asoc-card: Remove BCLK default value for tlv320aic31xx card
.../devicetree/bindings/sound/fsl-asoc-card.txt | 1 +
.../devicetree/bindings/sound/tlv320aic31xx.txt | 2 +-
arch/arm/boot/dts/am43x-epos-evm.dts | 2 +-
include/dt-bindings/sound/tlv320aic31xx-micbias.h | 9 ---------
include/dt-bindings/sound/tlv320aic31xx.h | 14 ++++++++++++++
sound/soc/codecs/tlv320aic31xx.c | 2 +-
sound/soc/fsl/fsl-asoc-card.c | 7 ++++++-
7 files changed, 24 insertions(+), 13 deletions(-)
delete mode 100644 include/dt-bindings/sound/tlv320aic31xx-micbias.h
create mode 100644 include/dt-bindings/sound/tlv320aic31xx.h
--
2.34.1
^ permalink raw reply
* [PATCH v2 3/5] ASoC: bindings: fsl-asoc-card: Add mclk-id optional property
From: Ariel D'Alessandro @ 2022-01-17 13:21 UTC (permalink / raw)
To: alsa-devel, devicetree, linux-kernel, linux-omap, linuxppc-dev
Cc: ariel.dalessandro, kuninori.morimoto.gx, Xiubo.Lee, tony,
shengjiu.wang, tiwai, lgirdwood, robh+dt, perex, nicoleotsuka,
broonie, bcousson, michael, festevam
In-Reply-To: <20220117132109.283365-1-ariel.dalessandro@collabora.com>
Support setting the sound card main clock input from the device-tree
using the mclk-id property.
Signed-off-by: Ariel D'Alessandro <ariel.dalessandro@collabora.com>
---
Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index 23d83fa7609f..b219626a5403 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -82,6 +82,7 @@ Optional properties:
- dai-format : audio format, for details see simple-card.yaml.
- frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml.
- bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml.
+ - mclk-id : main clock id, specific for each card configuration.
Optional unless SSI is selected as a CPU DAI:
--
2.34.1
^ permalink raw reply related
* [PATCH v2 4/5] ASoC: fsl-asoc-card: Add optional dt property for setting mclk-id
From: Ariel D'Alessandro @ 2022-01-17 13:21 UTC (permalink / raw)
To: alsa-devel, devicetree, linux-kernel, linux-omap, linuxppc-dev
Cc: ariel.dalessandro, kuninori.morimoto.gx, Xiubo.Lee, tony,
shengjiu.wang, tiwai, lgirdwood, robh+dt, perex, nicoleotsuka,
broonie, bcousson, michael, festevam
In-Reply-To: <20220117132109.283365-1-ariel.dalessandro@collabora.com>
Sound cards may allow using different main clock inputs. In the generic
fsl-asoc-card driver, these values are hardcoded for each specific card
configuration.
Let's make it more flexible, allowing setting mclk-id from the
device-tree node. Otherwise, the default value for each card
configuration is used.
Signed-off-by: Ariel D'Alessandro <ariel.dalessandro@collabora.com>
---
sound/soc/fsl/fsl-asoc-card.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5ee945505281..156d3c669274 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -693,6 +693,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
goto asrc_fail;
}
+ /*
+ * Allow setting mclk-id from the device-tree node. Otherwise, the
+ * default value for each card configuration is used.
+ */
+ of_property_read_u32(np, "mclk-id", &priv->codec_priv.mclk_id);
+
/* Format info from DT is optional. */
snd_soc_daifmt_parse_clock_provider_as_phandle(np, NULL, &bitclkprovider, &frameprovider);
if (bitclkprovider || frameprovider) {
--
2.34.1
^ permalink raw reply related
* [PATCH v2 5/5] ASoC: fsl-asoc-card: Remove BCLK default value for tlv320aic31xx card
From: Ariel D'Alessandro @ 2022-01-17 13:21 UTC (permalink / raw)
To: alsa-devel, devicetree, linux-kernel, linux-omap, linuxppc-dev
Cc: ariel.dalessandro, kuninori.morimoto.gx, Xiubo.Lee, tony,
shengjiu.wang, tiwai, lgirdwood, robh+dt, perex, nicoleotsuka,
broonie, bcousson, michael, festevam
In-Reply-To: <20220117132109.283365-1-ariel.dalessandro@collabora.com>
Now that fsl-asoc-card support setting mclk-id through the device-tree
mclk-id property, let's remove the default BCLK configuration for this
card.
Signed-off-by: Ariel D'Alessandro <ariel.dalessandro@collabora.com>
---
sound/soc/fsl/fsl-asoc-card.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 156d3c669274..370bc790c6ba 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -637,7 +637,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->dai_link[2].dpcm_capture = 0;
priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
- priv->codec_priv.mclk_id = AIC31XX_PLL_CLKIN_BCLK;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) {
--
2.34.1
^ permalink raw reply related
* [PATCH] powerpc/64s: Mask SRR0 before checking against the masked NIP
From: Nicholas Piggin @ 2022-01-17 13:44 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
Commit 314f6c23dd8d ("powerpc/64s: Mask NIP before checking against
SRR0") masked off the low 2 bits of the NIP value in the interrupt
stack frame in case they are non-zero and mis-compare against a SRR0
register value of a CPU which always reads back 0 from the 2 low bits
which are reserved.
This now causes the opposite problem that an implementation which does
implement those bits in SRR0 will mis-compare against the masked NIP
value in which they have been cleared. QEMU is one such implementation,
and this is allowed by the architecture.
This can be triggered by sigfuz by setting low bits of PT_NIP in the
signal context.
Fix this for now by masking the SRR0 bits as well. Cleaner is probably
to sanitise these values before putting them in registers or stack, but
this is the quick and backportable fix.
Fixes: 314f6c23dd8d ("powerpc/64s: Mask NIP before checking against SRR0")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/interrupt_64.S | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index 92088f848266..7bab2d7de372 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -30,6 +30,7 @@ COMPAT_SYS_CALL_TABLE:
.ifc \srr,srr
mfspr r11,SPRN_SRR0
ld r12,_NIP(r1)
+ clrrdi r11,r11,2
clrrdi r12,r12,2
100: tdne r11,r12
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
@@ -40,6 +41,7 @@ COMPAT_SYS_CALL_TABLE:
.else
mfspr r11,SPRN_HSRR0
ld r12,_NIP(r1)
+ clrrdi r11,r11,2
clrrdi r12,r12,2
100: tdne r11,r12
EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
--
2.23.0
^ permalink raw reply related
* Re: [PATCH net 1/4] net/fsl: xgmac_mdio: Add workaround for erratum A-009885
From: Andrew Lunn @ 2022-01-17 14:00 UTC (permalink / raw)
To: Tobias Waldekranz
Cc: devicetree, madalin.bucur, robh+dt, paulus, kuba, netdev,
linuxppc-dev, davem
In-Reply-To: <87czkqdduh.fsf@waldekranz.com>
On Mon, Jan 17, 2022 at 08:24:22AM +0100, Tobias Waldekranz wrote:
> On Sun, Jan 16, 2022 at 23:02, Andrew Lunn <andrew@lunn.ch> wrote:
> > On Sun, Jan 16, 2022 at 10:15:26PM +0100, Tobias Waldekranz wrote:
> >> Once an MDIO read transaction is initiated, we must read back the data
> >> register within 16 MDC cycles after the transaction completes. Outside
> >> of this window, reads may return corrupt data.
> >>
> >> Therefore, disable local interrupts in the critical section, to
> >> maximize the probability that we can satisfy this requirement.
> >
> > Since this is for net, a Fixes: tag would be nice. Maybe that would be
> > for the commit which added this driver, or maybe when the DTSI files
> > for the SOCs which have this errata we added?
>
> Alright, I wasn't sure how to tag WAs for errata since it is more about
> the hardware than the driver.
The tag gives the backporter an idea how far back to go. If support
for this SoC has only recently been added, there is no need to
backport a long way. If it is an old SoC, then maybe more effort
should be put into the backport?
> Should I send a v2 even if nothing else
> pops up, or is this more of a if-you're-sending-a-v2-anyway type of
> comment?
If you reply with a Fixes: patchwork will automagically append it like
it does Reviewed-by, Tested-by etc.
Andrew
^ permalink raw reply
* Re: [PATCH v3] powerpc/papr_scm: Implement initial support for injecting smart errors
From: Vaibhav Jain @ 2022-01-17 14:11 UTC (permalink / raw)
To: Aneesh Kumar K.V, nvdimm, linuxppc-dev
Cc: Dan Williams, Ira Weiny, Shivaprasad G Bhat
In-Reply-To: <871r167oi5.fsf@linux.ibm.com>
Thanks for reviewing this patch Aneesh. My responses to your comments
below:
"Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> writes:
> Vaibhav Jain <vaibhav@linux.ibm.com> writes:
>
>> Presently PAPR doesn't support injecting smart errors on an
>> NVDIMM. This makes testing the NVDIMM health reporting functionality
>> difficult as simulating NVDIMM health related events need a hacked up
>> qemu version.
>>
>> To solve this problem this patch proposes simulating certain set of
>> NVDIMM health related events in papr_scm. Specifically 'fatal' health
>> state and 'dirty' shutdown state. These error can be injected via the
>> user-space 'ndctl-inject-smart(1)' command. With the proposed patch and
>> corresponding ndctl patches following command flow is expected:
>>
>> $ sudo ndctl list -DH -d nmem0
>> ...
>> "health_state":"ok",
>> "shutdown_state":"clean",
>> ...
>> # inject unsafe shutdown and fatal health error
>> $ sudo ndctl inject-smart nmem0 -Uf
>> ...
>> "health_state":"fatal",
>> "shutdown_state":"dirty",
>> ...
>> # uninject all errors
>> $ sudo ndctl inject-smart nmem0 -N
>> ...
>> "health_state":"ok",
>> "shutdown_state":"clean",
>> ...
>>
>> The patch adds two members 'health_bitmap_mask' and
>> 'health_bitmap_override' inside struct papr_scm_priv which are then
>> bit blt'ed to the health bitmaps fetched from the hypervisor. In case
>> we are not able to fetch health information from the hypervisor we
>> service the health bitmap from these two members. These members are
>> accessible from sysfs at nmemX/papr/health_bitmap_override
>>
>> A new PDSM named 'SMART_INJECT' is proposed that accepts newly
>> introduced 'struct nd_papr_pdsm_smart_inject' as payload thats
>> exchanged between libndctl and papr_scm to indicate the requested
>> smart-error states.
>>
>> When the processing the PDSM 'SMART_INJECT', papr_pdsm_smart_inject()
>> constructs a pair or 'mask' and 'override' bitmaps from the payload
>> and bit-blt it to the 'health_bitmap_{mask, override}' members. This
>> ensures the after being fetched from the hypervisor, the health_bitmap
>> reflects requested smart-error states.
>>
>> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com>
>> Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
>> ---
>> Changelog:
>>
>> Since v2:
>> * Rebased the patch to ppc-next
>> * Added documentation for newly introduced sysfs attribute 'health_bitmap_override'
>>
>> Since v1:
>> * Updated the patch description.
>> * Removed dependency of a header movement patch.
>> * Removed '__packed' attribute for 'struct nd_papr_pdsm_smart_inject' [Aneesh]
>> ---
>> Documentation/ABI/testing/sysfs-bus-papr-pmem | 13 +++
>> arch/powerpc/include/uapi/asm/papr_pdsm.h | 18 ++++
>> arch/powerpc/platforms/pseries/papr_scm.c | 94 ++++++++++++++++++-
>> 3 files changed, 122 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
>> index 95254cec92bf..8a0b2a7f7671 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-papr-pmem
>> +++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem
>> @@ -61,3 +61,16 @@ Description:
>> * "CchRHCnt" : Cache Read Hit Count
>> * "CchWHCnt" : Cache Write Hit Count
>> * "FastWCnt" : Fast Write Count
>> +
>> +What: /sys/bus/nd/devices/nmemX/papr/health_bitmap_override
>> +Date: Jan, 2022
>> +KernelVersion: v5.17
>> +Contact: linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, nvdimm@lists.linux.dev,
>> +Description:
>> + (RO) Reports the health bitmap override/mask bitmaps that are
>> + applied to top bitmap received from PowerVM via the H_SCM_HEALTH
>> + Hcall. Together these can be used to forcibly set/reset specific
>> + bits returned from Hcall. These bitmaps are presently used to
>> + simulate various health or shutdown states for an nvdimm and are
>> + set by user-space tools like ndctl by issuing a PAPR DSM.
>> +
>> diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
>> index 82488b1e7276..17439925045c 100644
>> --- a/arch/powerpc/include/uapi/asm/papr_pdsm.h
>> +++ b/arch/powerpc/include/uapi/asm/papr_pdsm.h
>> @@ -116,6 +116,22 @@ struct nd_papr_pdsm_health {
>> };
>> };
>>
>> +/* Flags for injecting specific smart errors */
>> +#define PDSM_SMART_INJECT_HEALTH_FATAL (1 << 0)
>> +#define PDSM_SMART_INJECT_BAD_SHUTDOWN (1 << 1)
>> +
>> +struct nd_papr_pdsm_smart_inject {
>> + union {
>> + struct {
>> + /* One or more of PDSM_SMART_INJECT_ */
>> + __u32 flags;
>> + __u8 fatal_enable;
>> + __u8 unsafe_shutdown_enable;
>> + };
>> + __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
>> + };
>> +};
>> +
>> /*
>> * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
>> * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
>> @@ -123,12 +139,14 @@ struct nd_papr_pdsm_health {
>> enum papr_pdsm {
>> PAPR_PDSM_MIN = 0x0,
>> PAPR_PDSM_HEALTH,
>> + PAPR_PDSM_SMART_INJECT,
>> PAPR_PDSM_MAX,
>> };
>>
>> /* Maximal union that can hold all possible payload types */
>> union nd_pdsm_payload {
>> struct nd_papr_pdsm_health health;
>> + struct nd_papr_pdsm_smart_inject smart_inject;
>> __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
>> } __packed;
>>
>> diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
>> index f48e87ac89c9..de4cf329cfb3 100644
>> --- a/arch/powerpc/platforms/pseries/papr_scm.c
>> +++ b/arch/powerpc/platforms/pseries/papr_scm.c
>> @@ -68,6 +68,10 @@
>> #define PAPR_SCM_PERF_STATS_EYECATCHER __stringify(SCMSTATS)
>> #define PAPR_SCM_PERF_STATS_VERSION 0x1
>>
>> +/* Use bitblt method to override specific bits in the '_bitmap_' */
>> +#define BITBLT_BITMAP(_bitmap_, _mask_, _override_) \
>> + (((_bitmap_) & ~(_mask_)) | ((_mask_) & (_override_)))
>> +
>> /* Struct holding a single performance metric */
>> struct papr_scm_perf_stat {
>> u8 stat_id[8];
>> @@ -120,6 +124,12 @@ struct papr_scm_priv {
>>
>> /* length of the stat buffer as expected by phyp */
>> size_t stat_buffer_len;
>> +
>> + /* The bits which needs to be overridden */
>> + u64 health_bitmap_mask;
>> +
>> + /* The overridden values for the bits having the masks set */
>> + u64 health_bitmap_override;
>> };
>>
>> static int papr_scm_pmem_flush(struct nd_region *nd_region,
>> @@ -347,19 +357,28 @@ static ssize_t drc_pmem_query_stats(struct papr_scm_priv *p,
>> static int __drc_pmem_query_health(struct papr_scm_priv *p)
>> {
>> unsigned long ret[PLPAR_HCALL_BUFSIZE];
>> + u64 bitmap = 0;
>> long rc;
>>
>> /* issue the hcall */
>> rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
>> - if (rc != H_SUCCESS) {
>> + if (rc == H_SUCCESS)
>> + bitmap = ret[0] & ret[1];
>> + else if (rc == H_FUNCTION)
>> + dev_info_once(&p->pdev->dev,
>> + "Hcall H_SCM_HEALTH not implemented, assuming empty health bitmap");
>> + else {
>> +
>> dev_err(&p->pdev->dev,
>> "Failed to query health information, Err:%ld\n", rc);
>> return -ENXIO;
>> }
>>
>> p->lasthealth_jiffies = jiffies;
>> - p->health_bitmap = ret[0] & ret[1];
>> -
>> + /* Allow overriding specific health bits via bit blt. */
>> + bitmap = BITBLT_BITMAP(bitmap, p->health_bitmap_mask,
>> + p->health_bitmap_override);
>> + WRITE_ONCE(p->health_bitmap, bitmap);
>
> Why WRITE_ONCE ?
>
flags_show() uses READ_ONCE() to read a consistent copy of health_bitmap
to report nvdimm flags. Hence to ensure writes to health_bitmap are atomic
and consistent WRITE_ONCE is used. Though on ppc64 it may not make much
difference since loads/stores are 64bit but to be consistent across
flags_show() and __drc_pmem_query_health the store to p->health_bitmap
is replaced with a WRITE_ONCE.
>> dev_dbg(&p->pdev->dev,
>> "Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
>> ret[0], ret[1]);
>> @@ -669,6 +688,54 @@ static int papr_pdsm_health(struct papr_scm_priv *p,
>> return rc;
>> }
>>
>> +/* Inject a smart error Add the dirty-shutdown-counter value to the pdsm */
>> +static int papr_pdsm_smart_inject(struct papr_scm_priv *p,
>> + union nd_pdsm_payload *payload)
>> +{
>> + int rc;
>> + u32 supported_flags = 0;
>> + u64 mask = 0, override = 0;
>> +
>> + /* Check for individual smart error flags and update mask and override */
>> + if (payload->smart_inject.flags & PDSM_SMART_INJECT_HEALTH_FATAL) {
>> + supported_flags |= PDSM_SMART_INJECT_HEALTH_FATAL;
>> + mask |= PAPR_PMEM_HEALTH_FATAL;
>> + override |= payload->smart_inject.fatal_enable ?
>> + PAPR_PMEM_HEALTH_FATAL : 0;
>> + }
>> +
>> + if (payload->smart_inject.flags & PDSM_SMART_INJECT_BAD_SHUTDOWN) {
>> + supported_flags |= PDSM_SMART_INJECT_BAD_SHUTDOWN;
>> + mask |= PAPR_PMEM_SHUTDOWN_DIRTY;
>> + override |= payload->smart_inject.unsafe_shutdown_enable ?
>> + PAPR_PMEM_SHUTDOWN_DIRTY : 0;
>> + }
>> +
>> + dev_dbg(&p->pdev->dev, "[Smart-inject] Mask=%#llx override=%#llx\n",
>> + mask, override);
>> +
>> + /* Prevent concurrent access to dimm health bitmap related members */
>> + rc = mutex_lock_interruptible(&p->health_mutex);
>> + if (rc)
>> + return rc;
>> +
>> + /* Bitblt mask/override to corrosponding health_bitmap couterparts */
>> + p->health_bitmap_mask = BITBLT_BITMAP(p->health_bitmap_mask,
>> + mask, override);
>
> is that correct? Should we do that mask & override ? Shouldn't this be
> p->health_bitmap_mask = BITBLT_BITMAP(p->health_bitmap_mask,
> mask, ~0x0UL);
>
Just using 'mask' provides ability to only reset specific bits in the
health_bitmap. Coupled with 'override' specific bits in the bitmap can
be forced to be both set/reset since 'override' is ored to the
final bitmap.
This would be useful when adding support for injecting nvdimm restore
failure conditions which are indicated by absence of bit
PAPR_PMEM_SHUTDOWN_CLEAN in the health bitmap. That condition can be
simulated with mask == PAPR_PMEM_SHUTDOWN_CLEAN && override == 0. This
will ensure that bit PAPR_PMEM_SHUTDOWN_CLEAN is always reset in the
resulting health_bitmap.
>> + p->health_bitmap_override = BITBLT_BITMAP(p->health_bitmap_override,
>> + mask, override);
>> +
>> + /* Invalidate cached health bitmap */
>> + p->lasthealth_jiffies = 0;
>> +
>> + mutex_unlock(&p->health_mutex);
>> +
>> + /* Return the supported flags back to userspace */
>> + payload->smart_inject.flags = supported_flags;
>> +
>> + return sizeof(struct nd_papr_pdsm_health);
>> +}
>> +
>> /*
>> * 'struct pdsm_cmd_desc'
>> * Identifies supported PDSMs' expected length of in/out payloads
>> @@ -702,6 +769,12 @@ static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
>> .size_out = sizeof(struct nd_papr_pdsm_health),
>> .service = papr_pdsm_health,
>> },
>> +
>> + [PAPR_PDSM_SMART_INJECT] = {
>> + .size_in = sizeof(struct nd_papr_pdsm_smart_inject),
>> + .size_out = sizeof(struct nd_papr_pdsm_smart_inject),
>> + .service = papr_pdsm_smart_inject,
>> + },
>> /* Empty */
>> [PAPR_PDSM_MAX] = {
>> .size_in = 0,
>> @@ -838,6 +911,20 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
>> return 0;
>> }
>>
>> +static ssize_t health_bitmap_override_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct nvdimm *dimm = to_nvdimm(dev);
>> + struct papr_scm_priv *p = nvdimm_provider_data(dimm);
>> +
>> + return sprintf(buf, "mask=%#llx override=%#llx\n",
>> + READ_ONCE(p->health_bitmap_mask),
>> + READ_ONCE(p->health_bitmap_override));
>> +}
>> +
>> +static DEVICE_ATTR_ADMIN_RO(health_bitmap_override);
>> +
>> static ssize_t perf_stats_show(struct device *dev,
>> struct device_attribute *attr, char *buf)
>> {
>> @@ -952,6 +1039,7 @@ static struct attribute *papr_nd_attributes[] = {
>> &dev_attr_flags.attr,
>> &dev_attr_perf_stats.attr,
>> &dev_attr_dirty_shutdown.attr,
>> + &dev_attr_health_bitmap_override.attr,
>> NULL,
>> };
>>
>> --
>> 2.34.1
--
Cheers
~ Vaibhav
^ permalink raw reply
* [RFC PATCH 1/3] powerpc/64s: Fix system call emulation
From: Nicholas Piggin @ 2022-01-17 14:20 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
Interrupt return code expects the returned-to irq state to be reconciled
with the returned-to MSR[EE] state. That is, if local irqs are enabled
then MSR[EE] must be set, and if MSR[EE] is not set then local irqs must
be disabled.
System call emulation (both sc and scv 0) does not get this right, it
tries to return to a context with MSR[EE]=0 and local irqs enabled. This
confuses interrupt return and triggers a warning and probably worse.
Fix this by returning to the system call entry points with MSR[EE]=0 and
local irqs disabled. Add a case to deal with this kind of entry in the
system call handler. The difficulty is that the interrupt return changes
from user-mode to kernel mode, so it does not restore everything to the
way it would look when coming from userspace (e.g., CPU accounting, kuap,
the pkey regs, etc).
XXX: I don't know if this is quite the best problem. System call emulation
is much more complicated than it looks due to this return-to-kernel problem.
Even now the patch relies on SOFTE being set in the stack by the interrupt
return reading back the same way by the system call handler that creates
a new stack at the same position (this is how it determines it was an
emulated syscall). Not only that but suspect the IAMR is not being restored
correctly here and the correct user value on the stack gets clobbered.
Better option might be to have per-thread data that sets an emulated
syscall required flag and saves certain things like iamr. Or possibly just
bite the bullet and create new entry points for syscall emulation.
---
arch/powerpc/kernel/interrupt.c | 35 ++++++++++++++++++++----------
arch/powerpc/kernel/interrupt_64.S | 10 ---------
arch/powerpc/lib/sstep.c | 9 +++++---
3 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 7cd6ce3ec423..e73ad5842cb0 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -81,10 +81,31 @@ notrace long system_call_exception(long r3, long r4, long r5,
{
syscall_fn f;
- kuap_lock();
-
regs->orig_gpr3 = r3;
+ if (IS_ENABLED(CONFIG_PPC64) &&
+ unlikely(arch_irq_disabled_regs(regs))) {
+ irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
+ /*
+ * The first stack frame entry will have IRQS_ENABLED except
+ * in the case of syscall emulation, where the syscall entry
+ * code is returned-to with MSR[EE] disabled, which requires
+ * regs->softe is IRQS_DISABLED to avoid triggering the
+ * interrupt return code warning for returning to local irqs
+ * enabled but MSR[EE]=0. Not a big deal to re-set it here.
+ */
+#ifdef CONFIG_PPC_BOOK3S_64
+ set_kuap(AMR_KUAP_BLOCKED);
+#endif
+ if (trap_is_scv(regs))
+ local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+ /* XXX: pkey save? Did we save the wrong values in stack
+ * from userspace now? */
+ goto skip_user_entry;
+ }
+
+ kuap_lock();
+
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
@@ -95,7 +116,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
BUG_ON(regs_is_unrecoverable(regs));
BUG_ON(!(regs->msr & MSR_PR));
- BUG_ON(arch_irq_disabled_regs(regs));
#ifdef CONFIG_PPC_PKEY
if (mmu_has_feature(MMU_FTR_PKEY)) {
@@ -129,14 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
account_stolen_time();
- /*
- * This is not required for the syscall exit path, but makes the
- * stack frame look nicer. If this was initialised in the first stack
- * frame, or if the unwinder was taught the first stack frame always
- * returns to user with IRQS_ENABLED, this store could be avoided!
- */
- irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
-
+skip_user_entry:
/*
* If system call is called with TM active, set _TIF_RESTOREALL to
* prevent RFSCV being used to return to userspace, because POWER9
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index 7bab2d7de372..6471034c7909 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -219,16 +219,6 @@ system_call_vectored common 0x3000
*/
system_call_vectored sigill 0x7ff0
-
-/*
- * Entered via kernel return set up by kernel/sstep.c, must match entry regs
- */
- .globl system_call_vectored_emulate
-system_call_vectored_emulate:
-_ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
- li r10,IRQS_ALL_DISABLED
- stb r10,PACAIRQSOFTMASK(r13)
- b system_call_vectored_common
#endif /* CONFIG_PPC_BOOK3S */
.balign IFETCH_ALIGN_BYTES
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index a94b0cd0bdc5..62d3fd925dde 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -16,7 +16,7 @@
#include <asm/disassemble.h>
extern char system_call_common[];
-extern char system_call_vectored_emulate[];
+extern char system_call_vectored_common[];
#ifdef CONFIG_PPC64
/* Bits in SRR1 that are copied from MSR */
@@ -3667,6 +3667,8 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr)
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
+ // Return code needs regs->softe to match regs->msr & MSR_EE
+ regs->softe = IRQS_ALL_DISABLED;
regs_set_return_ip(regs, (unsigned long) &system_call_common);
regs_set_return_msr(regs, MSR_KERNEL);
return 1;
@@ -3674,11 +3676,12 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr)
#ifdef CONFIG_PPC_BOOK3S_64
case SYSCALL_VECTORED_0: /* scv 0 */
regs->gpr[9] = regs->gpr[13];
- regs->gpr[10] = MSR_KERNEL;
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
- regs_set_return_ip(regs, (unsigned long) &system_call_vectored_emulate);
+ // Return code needs regs->softe to match regs->msr & MSR_EE
+ regs->softe = IRQS_ALL_DISABLED;
+ regs_set_return_ip(regs, (unsigned long) &system_call_vectored_common);
regs_set_return_msr(regs, MSR_KERNEL);
return 1;
#endif
--
2.23.0
^ permalink raw reply related
* [RFC PATCH 1/3] powerpc/64s: Fix system call emulation
From: Nicholas Piggin @ 2022-01-17 14:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Cédric Le Goater, Nicholas Piggin
Interrupt return code expects the returned-to irq state to be reconciled
with the returned-to MSR[EE] state. That is, if local irqs are enabled
then MSR[EE] must be set, and if MSR[EE] is not set then local irqs must
be disabled.
System call emulation (both sc and scv 0) does not get this right, it
tries to return to a context with MSR[EE]=0 and local irqs enabled. This
confuses interrupt return and triggers a warning and probably worse.
Fix this by returning to the system call entry points with MSR[EE]=0 and
local irqs disabled. Add a case to deal with this kind of entry in the
system call handler. The difficulty is that the interrupt return changes
from user-mode to kernel mode, so it does not restore everything to the
way it would look when coming from userspace (e.g., CPU accounting, kuap,
the pkey regs, etc).
XXX: I don't know if this is quite the best problem. System call emulation
is much more complicated than it looks due to this return-to-kernel problem.
Even now the patch relies on SOFTE being set in the stack by the interrupt
return reading back the same way by the system call handler that creates
a new stack at the same position (this is how it determines it was an
emulated syscall). Not only that but suspect the IAMR is not being restored
correctly here and the correct user value on the stack gets clobbered.
Better option might be to have per-thread data that sets an emulated
syscall required flag and saves certain things like iamr. Or possibly just
bite the bullet and create new entry points for syscall emulation.
---
arch/powerpc/kernel/interrupt.c | 35 ++++++++++++++++++++----------
arch/powerpc/kernel/interrupt_64.S | 10 ---------
arch/powerpc/lib/sstep.c | 9 +++++---
3 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 7cd6ce3ec423..e73ad5842cb0 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -81,10 +81,31 @@ notrace long system_call_exception(long r3, long r4, long r5,
{
syscall_fn f;
- kuap_lock();
-
regs->orig_gpr3 = r3;
+ if (IS_ENABLED(CONFIG_PPC64) &&
+ unlikely(arch_irq_disabled_regs(regs))) {
+ irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
+ /*
+ * The first stack frame entry will have IRQS_ENABLED except
+ * in the case of syscall emulation, where the syscall entry
+ * code is returned-to with MSR[EE] disabled, which requires
+ * regs->softe is IRQS_DISABLED to avoid triggering the
+ * interrupt return code warning for returning to local irqs
+ * enabled but MSR[EE]=0. Not a big deal to re-set it here.
+ */
+#ifdef CONFIG_PPC_BOOK3S_64
+ set_kuap(AMR_KUAP_BLOCKED);
+#endif
+ if (trap_is_scv(regs))
+ local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+ /* XXX: pkey save? Did we save the wrong values in stack
+ * from userspace now? */
+ goto skip_user_entry;
+ }
+
+ kuap_lock();
+
if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
@@ -95,7 +116,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
BUG_ON(regs_is_unrecoverable(regs));
BUG_ON(!(regs->msr & MSR_PR));
- BUG_ON(arch_irq_disabled_regs(regs));
#ifdef CONFIG_PPC_PKEY
if (mmu_has_feature(MMU_FTR_PKEY)) {
@@ -129,14 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
account_stolen_time();
- /*
- * This is not required for the syscall exit path, but makes the
- * stack frame look nicer. If this was initialised in the first stack
- * frame, or if the unwinder was taught the first stack frame always
- * returns to user with IRQS_ENABLED, this store could be avoided!
- */
- irq_soft_mask_regs_set_state(regs, IRQS_ENABLED);
-
+skip_user_entry:
/*
* If system call is called with TM active, set _TIF_RESTOREALL to
* prevent RFSCV being used to return to userspace, because POWER9
diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
index 7bab2d7de372..6471034c7909 100644
--- a/arch/powerpc/kernel/interrupt_64.S
+++ b/arch/powerpc/kernel/interrupt_64.S
@@ -219,16 +219,6 @@ system_call_vectored common 0x3000
*/
system_call_vectored sigill 0x7ff0
-
-/*
- * Entered via kernel return set up by kernel/sstep.c, must match entry regs
- */
- .globl system_call_vectored_emulate
-system_call_vectored_emulate:
-_ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
- li r10,IRQS_ALL_DISABLED
- stb r10,PACAIRQSOFTMASK(r13)
- b system_call_vectored_common
#endif /* CONFIG_PPC_BOOK3S */
.balign IFETCH_ALIGN_BYTES
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index a94b0cd0bdc5..62d3fd925dde 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -16,7 +16,7 @@
#include <asm/disassemble.h>
extern char system_call_common[];
-extern char system_call_vectored_emulate[];
+extern char system_call_vectored_common[];
#ifdef CONFIG_PPC64
/* Bits in SRR1 that are copied from MSR */
@@ -3667,6 +3667,8 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr)
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
+ // Return code needs regs->softe to match regs->msr & MSR_EE
+ regs->softe = IRQS_ALL_DISABLED;
regs_set_return_ip(regs, (unsigned long) &system_call_common);
regs_set_return_msr(regs, MSR_KERNEL);
return 1;
@@ -3674,11 +3676,12 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr)
#ifdef CONFIG_PPC_BOOK3S_64
case SYSCALL_VECTORED_0: /* scv 0 */
regs->gpr[9] = regs->gpr[13];
- regs->gpr[10] = MSR_KERNEL;
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
- regs_set_return_ip(regs, (unsigned long) &system_call_vectored_emulate);
+ // Return code needs regs->softe to match regs->msr & MSR_EE
+ regs->softe = IRQS_ALL_DISABLED;
+ regs_set_return_ip(regs, (unsigned long) &system_call_vectored_common);
regs_set_return_msr(regs, MSR_KERNEL);
return 1;
#endif
--
2.23.0
^ permalink raw reply related
* [RFC PATCH 2/3] powerpc/64s: Emulate scv syscalls if facility unavailable and PR KVM is possible
From: Nicholas Piggin @ 2022-01-17 14:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Cédric Le Goater, Nicholas Piggin
In-Reply-To: <20220117142423.3038570-1-npiggin@gmail.com>
The SCV facility will be disabled at runtime in the host by PR KVM by
the next change, emulate it in the facility unavailable handler.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/traps.c | 45 +++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 11741703d26e..6e4eaa6bf58d 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -58,6 +58,7 @@
#include <asm/ppc-opcode.h>
#include <asm/rio.h>
#include <asm/fadump.h>
+#include <asm/sstep.h>
#include <asm/switch_to.h>
#include <asm/tm.h>
#include <asm/debug.h>
@@ -1778,6 +1779,49 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)
return;
}
+ if (status == FSCR_SCV_LG) {
+ u32 lev;
+ ppc_inst_t instr;
+
+ /* If we didn't advertise the feature to userspace, SIGILL */
+ if (!(cur_cpu_spec->cpu_user_features2 & PPC_FEATURE2_SCV))
+ goto out_msg;
+
+ /*
+ * PR KVM disables the FSCR[SCV] facility even if the rest of
+ * the kernel and userspace thought SCV was enabled. THis
+ * causes scv instructions executed by both the host and the
+ * guest to come here, in their respective kernels.
+ *
+ * If radix is enabled then PR KVM can not be in use and can
+ * not be our hypervisor, so treat this as a normal illegal
+ * instruction. If we are hash guest or host, we might need
+ * to emulate a legitimate scv interrupt here.
+ */
+ if (radix_enabled())
+ goto out_msg;
+
+ /*
+ * User is making SCV call with SCV disabled. Emulate it.
+ */
+ if (get_user_instr(instr, (void __user *)regs->nip)) {
+ pr_err("Failed to fetch the user instruction\n");
+ return;
+ }
+
+ instword = ppc_inst_val(instr);
+ if (WARN_ON_ONCE((instword & 0xfffff01f) != 0x44000001))
+ goto out;
+
+ lev = (instword >> 5) & 0x7f;
+ if (lev == 0) {
+ if (emulate_step(regs, instr) > 0)
+ return;
+ else
+ pr_err_ratelimited("Failed to emulate SCV\n");
+ }
+ }
+
if (status == FSCR_TM_LG) {
/*
* If we're here then the hardware is TM aware because it
@@ -1799,6 +1843,7 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)
return;
}
+out_msg:
pr_err_ratelimited("%sFacility '%s' unavailable (%d), exception at 0x%lx, MSR=%lx\n",
hv ? "Hypervisor " : "", facility, status, regs->nip, regs->msr);
--
2.23.0
^ permalink raw reply related
* [RFC PATCH 3/3] KVM: PPC: Book3S PR: Disable SCV when running AIL is disabled
From: Nicholas Piggin @ 2022-01-17 14:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Cédric Le Goater, Nicholas Piggin
In-Reply-To: <20220117142423.3038570-1-npiggin@gmail.com>
PR KVM does not support running with AIL enabled, and SCV does is not
supported with AIL disabled.
When PR KVM disables AIL on a system that has SCV enabled, the guest can
crash the host if it executes scv, or the host can crash itself if
another CPU executes scv while AIL is disabled (e.g., in the pseries
case).
Fix this by disabling the SCV facility when PR KVM disables AIL. The
facility unavailable handler will emulate it.
Alternatives considered and rejected:
- SCV support can not be disabled by PR KVM after boot, because it is
advertised to userspace with HWCAP.
- AIL can not be disabled on a per-CPU basis. At least when running on
pseries it is a per-LPAR setting.
- Support for real-mode SCV vectors will not be added because they are
at 0x17000 so making such a large fixed head space causes immediate
value limits to be exceeded, requiring a lot rework and more code.
- Disabling SCV for any PR KVM possible kernel will cause a slowdown
when not using PR KVM.
- A boot time option to disable SCV to use PR KVM is user-hostile.
---
This is not well tested at the moment, and PR KVM would need to emulate
scv for the guest for a complete implementation. At least it should
prevent host crashes.
arch/powerpc/kernel/exceptions-64s.S | 5 +++
arch/powerpc/kvm/book3s_hv_p9_entry.c | 14 ++++++--
arch/powerpc/kvm/book3s_pr.c | 52 ++++++++++++++++++++++-----
3 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 55caeee37c08..9985d061f9bf 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -809,6 +809,11 @@ __start_interrupts:
* - MSR_EE|MSR_RI is clear (no reentrant exceptions)
* - Standard kernel environment is set up (stack, paca, etc)
*
+ * KVM:
+ * These interrupts do not elevate HV 0->1, so HV is not involved. PR disables
+ * the FSCR[SCV] facility before running the guest so scv becomes a program
+ * interrupt and where it can be emulated by the OS.
+ *
* Call convention:
*
* syscall register convention is in Documentation/powerpc/syscall64-abi.rst
diff --git a/arch/powerpc/kvm/book3s_hv_p9_entry.c b/arch/powerpc/kvm/book3s_hv_p9_entry.c
index a28e5b3daabd..611dd34cf708 100644
--- a/arch/powerpc/kvm/book3s_hv_p9_entry.c
+++ b/arch/powerpc/kvm/book3s_hv_p9_entry.c
@@ -373,6 +373,12 @@ void save_p9_host_os_sprs(struct p9_host_os_sprs *host_os_sprs)
}
EXPORT_SYMBOL_GPL(save_p9_host_os_sprs);
+#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
+bool pr_kvm_disabled_reloc_exc(void);
+#else
+static inline bool pr_kvm_disabled_reloc_exc(void) { return false; }
+#endif
+
/* vcpu guest regs must already be saved */
void restore_p9_host_os_sprs(struct kvm_vcpu *vcpu,
struct p9_host_os_sprs *host_os_sprs)
@@ -395,8 +401,12 @@ void restore_p9_host_os_sprs(struct kvm_vcpu *vcpu,
mtspr(SPRN_UAMOR, 0);
if (host_os_sprs->amr != vcpu->arch.amr)
mtspr(SPRN_AMR, host_os_sprs->amr);
- if (current->thread.fscr != vcpu->arch.fscr)
- mtspr(SPRN_FSCR, current->thread.fscr);
+ if (current->thread.fscr != vcpu->arch.fscr) {
+ if (pr_kvm_disabled_reloc_exc())
+ mtspr(SPRN_FSCR, current->thread.fscr & ~FSCR_SCV);
+ else
+ mtspr(SPRN_FSCR, current->thread.fscr);
+ }
if (current->thread.dscr != vcpu->arch.dscr)
mtspr(SPRN_DSCR, current->thread.dscr);
if (vcpu->arch.pspb != 0)
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 6bc9425acb32..d608afb3376b 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -140,9 +140,12 @@ static void kvmppc_core_vcpu_load_pr(struct kvm_vcpu *vcpu, int cpu)
#endif
/* Disable AIL if supported */
- if (cpu_has_feature(CPU_FTR_HVMODE) &&
- cpu_has_feature(CPU_FTR_ARCH_207S))
- mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
+ if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~LPCR_AIL);
+ if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
+ mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) & ~FSCR_SCV);
+ }
vcpu->cpu = smp_processor_id();
#ifdef CONFIG_PPC_BOOK3S_32
@@ -175,9 +178,12 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
kvmppc_save_tm_pr(vcpu);
/* Enable AIL if supported */
- if (cpu_has_feature(CPU_FTR_HVMODE) &&
- cpu_has_feature(CPU_FTR_ARCH_207S))
- mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
+ if (cpu_has_feature(CPU_FTR_HVMODE)) {
+ if (cpu_has_feature(CPU_FTR_ARCH_207S))
+ mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_AIL_3);
+ if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
+ mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) | FSCR_SCV);
+ }
vcpu->cpu = -1;
}
@@ -1037,6 +1043,8 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
{
+ if (fscr & FSCR_SCV)
+ fscr &= ~FSCR_SCV; /* SCV must not be enabled */
if ((vcpu->arch.fscr & FSCR_TAR) && !(fscr & FSCR_TAR)) {
/* TAR got dropped, drop it in shadow too */
kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
@@ -1990,6 +1998,21 @@ static int kvm_vm_ioctl_get_smmu_info_pr(struct kvm *kvm,
static unsigned int kvm_global_user_count = 0;
static DEFINE_SPINLOCK(kvm_global_user_count_lock);
+bool pr_kvm_disabled_reloc_exc(void)
+{
+ return kvm_global_user_count != 0;
+}
+
+static void disable_scv(void *dummy)
+{
+ mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) & ~FSCR_SCV);
+}
+
+static void enable_scv(void *dummy)
+{
+ mtspr(SPRN_FSCR, mfspr(SPRN_FSCR) | FSCR_SCV);
+}
+
static int kvmppc_core_init_vm_pr(struct kvm *kvm)
{
mutex_init(&kvm->arch.hpt_mutex);
@@ -2001,8 +2024,17 @@ static int kvmppc_core_init_vm_pr(struct kvm *kvm)
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
spin_lock(&kvm_global_user_count_lock);
- if (++kvm_global_user_count == 1)
+ if (++kvm_global_user_count == 1) {
+ /*
+ * FSCR isn't context switched except for KVM HV
+ * entry/exit, so only have to care to keep that
+ * part up to date.
+ */
+ if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
+ smp_call_function(disable_scv, NULL, 0);
+ /* SCV must be disabled first */
pseries_disable_reloc_on_exc();
+ }
spin_unlock(&kvm_global_user_count_lock);
}
return 0;
@@ -2017,8 +2049,12 @@ static void kvmppc_core_destroy_vm_pr(struct kvm *kvm)
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
spin_lock(&kvm_global_user_count_lock);
BUG_ON(kvm_global_user_count == 0);
- if (--kvm_global_user_count == 0)
+ if (--kvm_global_user_count == 0) {
pseries_enable_reloc_on_exc();
+ /* reloc must be enabled irst */
+ if (cpu_has_feature(CPU_FTR_ARCH_300) && (current->thread.fscr & FSCR_SCV))
+ smp_call_function(enable_scv, NULL, 0);
+ }
spin_unlock(&kvm_global_user_count_lock);
}
}
--
2.23.0
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 03/52] powerpc/6xx: add missing of_node_put
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, nick.child, maz, Julia Lawall, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Julia Lawall <Julia.Lawall@lip6.fr>
[ Upstream commit f6e82647ff71d427d4148964b71f239fba9d7937 ]
for_each_compatible_node performs an of_node_get on each iteration, so
a break out of the loop requires an of_node_put.
A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):
// <smpl>
@@
expression e;
local idexpression n;
@@
@@
local idexpression n;
expression e;
@@
for_each_compatible_node(n,...) {
...
(
of_node_put(n);
|
e = n
|
+ of_node_put(n);
? break;
)
...
}
... when != n
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1448051604-25256-2-git-send-email-Julia.Lawall@lip6.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 15396333a90bd..a4b020e4b6af0 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -214,6 +214,7 @@ void hlwd_pic_probe(void)
irq_set_chained_handler(cascade_virq,
hlwd_pic_irq_cascade);
hlwd_irq_host = host;
+ of_node_put(np);
break;
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 06/52] powerpc/btext: add missing of_node_put
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Julia Lawall, linuxppc-dev, nick.child
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Julia Lawall <Julia.Lawall@lip6.fr>
[ Upstream commit a1d2b210ffa52d60acabbf7b6af3ef7e1e69cda0 ]
for_each_node_by_type performs an of_node_get on each iteration, so
a break out of the loop requires an of_node_put.
A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):
// <smpl>
@@
local idexpression n;
expression e;
@@
for_each_node_by_type(n,...) {
...
(
of_node_put(n);
|
e = n
|
+ of_node_put(n);
? break;
)
...
}
... when != n
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1448051604-25256-6-git-send-email-Julia.Lawall@lip6.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/btext.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index 803c2a45b22ac..1cffb5e7c38d6 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -241,8 +241,10 @@ int __init btext_find_display(int allow_nonstdout)
rc = btext_initialize(np);
printk("result: %d\n", rc);
}
- if (rc == 0)
+ if (rc == 0) {
+ of_node_put(np);
break;
+ }
}
return rc;
}
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 05/52] powerpc/cell: add missing of_node_put
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Julia Lawall, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Julia Lawall <Julia.Lawall@lip6.fr>
[ Upstream commit a841fd009e51c8c0a8f07c942e9ab6bb48da8858 ]
for_each_node_by_name performs an of_node_get on each iteration, so
a break out of the loop requires an of_node_put.
A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):
// <smpl>
@@
expression e,e1;
local idexpression n;
@@
for_each_node_by_name(n, e1) {
... when != of_node_put(n)
when != e = n
(
return n;
|
+ of_node_put(n);
? return ...;
)
...
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1448051604-25256-7-git-send-email-Julia.Lawall@lip6.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/cell/iommu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index fa08699aedeb8..d32f24de84798 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -977,6 +977,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
if (hbase < dbase || (hend > (dbase + dsize))) {
pr_debug("iommu: hash window doesn't fit in"
"real DMA window\n");
+ of_node_put(np);
return -1;
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 04/52] powerpc/powernv: add missing of_node_put
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, Julia Lawall, linuxppc-dev, aneesh.kumar
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Julia Lawall <Julia.Lawall@lip6.fr>
[ Upstream commit 7d405a939ca960162eb30c1475759cb2fdf38f8c ]
for_each_compatible_node performs an of_node_get on each iteration, so
a break out of the loop requires an of_node_put.
A simplified version of the semantic patch that fixes this problem is as
follows (http://coccinelle.lip6.fr):
// <smpl>
@@
local idexpression n;
expression e;
@@
for_each_compatible_node(n,...) {
...
(
of_node_put(n);
|
e = n
|
+ of_node_put(n);
? break;
)
...
}
... when != n
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1448051604-25256-4-git-send-email-Julia.Lawall@lip6.fr
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/powernv/opal-lpc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
index 1e5d51db40f84..5390c888db162 100644
--- a/arch/powerpc/platforms/powernv/opal-lpc.c
+++ b/arch/powerpc/platforms/powernv/opal-lpc.c
@@ -396,6 +396,7 @@ void __init opal_lpc_init(void)
if (!of_get_property(np, "primary", NULL))
continue;
opal_lpc_chip_id = of_get_ibm_chip_id(np);
+ of_node_put(np);
break;
}
if (opal_lpc_chip_id < 0)
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 07/52] powerpc/watchdog: Fix missed watchdog reset due to memory ordering race
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, pmladek, john.ogness, Nicholas Piggin, clg,
sudeep.holla, Laurent Dufour, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Nicholas Piggin <npiggin@gmail.com>
[ Upstream commit 5dad4ba68a2483fc80d70b9dc90bbe16e1f27263 ]
It is possible for all CPUs to miss the pending cpumask becoming clear,
and then nobody resetting it, which will cause the lockup detector to
stop working. It will eventually expire, but watchdog_smp_panic will
avoid doing anything if the pending mask is clear and it will never be
reset.
Order the cpumask clear vs the subsequent test to close this race.
Add an extra check for an empty pending mask when the watchdog fires and
finds its bit still clear, to try to catch any other possible races or
bugs here and keep the watchdog working. The extra test in
arch_touch_nmi_watchdog is required to prevent the new warning from
firing off.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Laurent Dufour <ldufour@linux.ibm.com>
Debugged-by: Laurent Dufour <ldufour@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211110025056.2084347-2-npiggin@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/watchdog.c | 41 +++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c
index 3fa6d240bade2..ad94a2c6b7337 100644
--- a/arch/powerpc/kernel/watchdog.c
+++ b/arch/powerpc/kernel/watchdog.c
@@ -135,6 +135,10 @@ static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb)
{
cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask);
cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask);
+ /*
+ * See wd_smp_clear_cpu_pending()
+ */
+ smp_mb();
if (cpumask_empty(&wd_smp_cpus_pending)) {
wd_smp_last_reset_tb = tb;
cpumask_andnot(&wd_smp_cpus_pending,
@@ -221,13 +225,44 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb)
cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck);
wd_smp_unlock(&flags);
+ } else {
+ /*
+ * The last CPU to clear pending should have reset the
+ * watchdog so we generally should not find it empty
+ * here if our CPU was clear. However it could happen
+ * due to a rare race with another CPU taking the
+ * last CPU out of the mask concurrently.
+ *
+ * We can't add a warning for it. But just in case
+ * there is a problem with the watchdog that is causing
+ * the mask to not be reset, try to kick it along here.
+ */
+ if (unlikely(cpumask_empty(&wd_smp_cpus_pending)))
+ goto none_pending;
}
return;
}
+
cpumask_clear_cpu(cpu, &wd_smp_cpus_pending);
+
+ /*
+ * Order the store to clear pending with the load(s) to check all
+ * words in the pending mask to check they are all empty. This orders
+ * with the same barrier on another CPU. This prevents two CPUs
+ * clearing the last 2 pending bits, but neither seeing the other's
+ * store when checking if the mask is empty, and missing an empty
+ * mask, which ends with a false positive.
+ */
+ smp_mb();
if (cpumask_empty(&wd_smp_cpus_pending)) {
unsigned long flags;
+none_pending:
+ /*
+ * Double check under lock because more than one CPU could see
+ * a clear mask with the lockless check after clearing their
+ * pending bits.
+ */
wd_smp_lock(&flags);
if (cpumask_empty(&wd_smp_cpus_pending)) {
wd_smp_last_reset_tb = tb;
@@ -318,8 +353,12 @@ void arch_touch_nmi_watchdog(void)
{
unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000;
int cpu = smp_processor_id();
- u64 tb = get_tb();
+ u64 tb;
+ if (!cpumask_test_cpu(cpu, &watchdog_cpumask))
+ return;
+
+ tb = get_tb();
if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) {
per_cpu(wd_timer_tb, cpu) = tb;
wd_smp_clear_cpu_pending(cpu, tb);
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 08/52] ASoC: imx-hdmi: add put_device() after of_find_device_by_node()
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, alsa-devel, Xiubo.Lee, linuxppc-dev, Zeal Robot,
tiwai, lgirdwood, perex, nicoleotsuka, Mark Brown, Ye Guojin,
shawnguo, linux-arm-kernel
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Ye Guojin <ye.guojin@zte.com.cn>
[ Upstream commit f670b274f7f6f4b2722d7f08d0fddf606a727e92 ]
This was found by coccicheck:
./sound/soc/fsl/imx-hdmi.c,209,1-7,ERROR missing put_device; call
of_find_device_by_node on line 119, but without a corresponding object
release within this function.
Reported-by: Zeal Robot <zealci@zte.com.cn>
Signed-off-by: Ye Guojin <ye.guojin@zte.com.cn>
Link: https://lore.kernel.org/r/20211110002910.134915-1-ye.guojin@zte.com.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/fsl/imx-hdmi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
index f10359a288005..929f69b758af4 100644
--- a/sound/soc/fsl/imx-hdmi.c
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -145,6 +145,8 @@ static int imx_hdmi_probe(struct platform_device *pdev)
data->dai.capture_only = false;
data->dai.init = imx_hdmi_init;
+ put_device(&cpu_pdev->dev);
+
if (of_node_name_eq(cpu_np, "sai")) {
data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 10/52] powerpc/smp: Move setup_profiling_timer() under CONFIG_PROFILING
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, parth, srikar, ego, npiggin, clg, yukuai3,
linuxppc-dev, robh, hbathini
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Michael Ellerman <mpe@ellerman.id.au>
[ Upstream commit a4ac0d249a5db80e79d573db9e4ad29354b643a8 ]
setup_profiling_timer() is only needed when CONFIG_PROFILING is enabled.
Fixes the following W=1 warning when CONFIG_PROFILING=n:
linux/arch/powerpc/kernel/smp.c:1638:5: error: no previous prototype for ‘setup_profiling_timer’
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211124093254.1054750-5-mpe@ellerman.id.au
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/smp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index c23ee842c4c33..aee3a7119f977 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -1635,10 +1635,12 @@ void start_secondary(void *unused)
BUG();
}
+#ifdef CONFIG_PROFILING
int setup_profiling_timer(unsigned int multiplier)
{
return 0;
}
+#endif
static void fixup_topology(void)
{
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 13/52] powerpc/powermac: Add missing lockdep_register_key()
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, Erhard Furtner, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Christophe Leroy <christophe.leroy@csgroup.eu>
[ Upstream commit df1f679d19edb9eeb67cc2f96b29375f21991945 ]
KeyWest i2c @0xf8001003 irq 42 /uni-n@f8000000/i2c@f8001000
BUG: key c2d00cbc has not been registered!
------------[ cut here ]------------
DEBUG_LOCKS_WARN_ON(1)
WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:4801 lockdep_init_map_type+0x4c0/0xb4c
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.15.5-gentoo-PowerMacG4 #9
NIP: c01a9428 LR: c01a9428 CTR: 00000000
REGS: e1033cf0 TRAP: 0700 Not tainted (5.15.5-gentoo-PowerMacG4)
MSR: 00029032 <EE,ME,IR,DR,RI> CR: 24002002 XER: 00000000
GPR00: c01a9428 e1033db0 c2d1cf20 00000016 00000004 00000001 c01c0630 e1033a73
GPR08: 00000000 00000000 00000000 e1033db0 24002004 00000000 f8729377 00000003
GPR16: c1829a9c 00000000 18305357 c1416fc0 c1416f80 c006ac60 c2d00ca8 c1416f00
GPR24: 00000000 c21586f0 c2160000 00000000 c2d00cbc c2170000 c216e1a0 c2160000
NIP [c01a9428] lockdep_init_map_type+0x4c0/0xb4c
LR [c01a9428] lockdep_init_map_type+0x4c0/0xb4c
Call Trace:
[e1033db0] [c01a9428] lockdep_init_map_type+0x4c0/0xb4c (unreliable)
[e1033df0] [c1c177b8] kw_i2c_add+0x334/0x424
[e1033e20] [c1c18294] pmac_i2c_init+0x9ec/0xa9c
[e1033e80] [c1c1a790] smp_core99_probe+0xbc/0x35c
[e1033eb0] [c1c03cb0] kernel_init_freeable+0x190/0x5a4
[e1033f10] [c000946c] kernel_init+0x28/0x154
[e1033f30] [c0035148] ret_from_kernel_thread+0x14/0x1c
Add missing lockdep_register_key()
Reported-by: Erhard Furtner <erhard_f@mailbox.org>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/69e4f55565bb45ebb0843977801b245af0c666fe.1638264741.git.christophe.leroy@csgroup.eu
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/powermac/low_i2c.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index f77a59b5c2e1a..de34fa34c42d8 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -582,6 +582,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
bus->close = kw_i2c_close;
bus->xfer = kw_i2c_xfer;
mutex_init(&bus->mutex);
+ lockdep_register_key(&bus->lock_key);
lockdep_set_class(&bus->mutex, &bus->lock_key);
if (controller == busnode)
bus->flags = pmac_i2c_multibus;
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 14/52] KVM: PPC: Book3S: Suppress warnings when allocating too big memory slots
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, farosas, Alexey Kardashevskiy, npiggin, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Alexey Kardashevskiy <aik@ozlabs.ru>
[ Upstream commit 511d25d6b789fffcb20a3eb71899cf974a31bd9d ]
The userspace can trigger "vmalloc size %lu allocation failure: exceeds
total pages" via the KVM_SET_USER_MEMORY_REGION ioctl.
This silences the warning by checking the limit before calling vzalloc()
and returns ENOMEM if failed.
This does not call underlying valloc helpers as __vmalloc_node() is only
exported when CONFIG_TEST_VMALLOC_MODULE and __vmalloc_node_range() is
not exported at all.
Spotted by syzkaller.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[mpe: Use 'size' for the variable rather than 'cb']
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210901084512.1658628-1-aik@ozlabs.ru
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kvm/book3s_hv.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 7b74fc0a986b8..94da0d25eb125 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -4861,8 +4861,12 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
unsigned long npages = mem->memory_size >> PAGE_SHIFT;
if (change == KVM_MR_CREATE) {
- slot->arch.rmap = vzalloc(array_size(npages,
- sizeof(*slot->arch.rmap)));
+ unsigned long size = array_size(npages, sizeof(*slot->arch.rmap));
+
+ if ((size >> PAGE_SHIFT) > totalram_pages())
+ return -ENOMEM;
+
+ slot->arch.rmap = vzalloc(size);
if (!slot->arch.rmap)
return -ENOMEM;
}
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 15/52] KVM: PPC: Book3S: Suppress failed alloc warning in H_COPY_TOFROM_GUEST
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, ravi.bangoria, Fabiano Rosas, Alexey Kardashevskiy,
nathan, npiggin, bharata, linuxppc-dev
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Alexey Kardashevskiy <aik@ozlabs.ru>
[ Upstream commit 792020907b11c6f9246c21977cab3bad985ae4b6 ]
H_COPY_TOFROM_GUEST is an hcall for an upper level VM to access its nested
VMs memory. The userspace can trigger WARN_ON_ONCE(!(gfp & __GFP_NOWARN))
in __alloc_pages() by constructing a tiny VM which only does
H_COPY_TOFROM_GUEST with a too big GPR9 (number of bytes to copy).
This silences the warning by adding __GFP_NOWARN.
Spotted by syzkaller.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210901084550.1658699-1-aik@ozlabs.ru
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kvm/book3s_hv_nested.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index ed8a2c9f56299..89295b52a97c3 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -582,7 +582,7 @@ long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu)
if (eaddr & (0xFFFUL << 52))
return H_PARAMETER;
- buf = kzalloc(n, GFP_KERNEL);
+ buf = kzalloc(n, GFP_KERNEL | __GFP_NOWARN);
if (!buf)
return H_NO_MEM;
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 27/52] powerpc/40x: Map 32Mbytes of memory at startup
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: Sasha Levin, linuxppc-dev, npiggin
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Christophe Leroy <christophe.leroy@csgroup.eu>
[ Upstream commit 06e7cbc29e97b4713b4ea6def04ae8501a7d1a59 ]
As reported by Carlo, 16Mbytes is not enough with modern kernels
that tend to be a bit big, so map another 16M page at boot.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/89b5f974a7fa5011206682cd092e2c905530ff46.1632755552.git.christophe.leroy@csgroup.eu
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/head_40x.S | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 7d72ee5ab387c..e783860bea838 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/pgtable.h>
+#include <linux/sizes.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/mmu.h>
@@ -650,7 +651,7 @@ start_here:
b . /* prevent prefetch past rfi */
/* Set up the initial MMU state so we can do the first level of
- * kernel initialization. This maps the first 16 MBytes of memory 1:1
+ * kernel initialization. This maps the first 32 MBytes of memory 1:1
* virtual to physical and more importantly sets the cache mode.
*/
initial_mmu:
@@ -687,6 +688,12 @@ initial_mmu:
tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+ li r0,62 /* TLB slot 62 */
+ addis r4,r4,SZ_16M@h
+ addis r3,r3,SZ_16M@h
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
+
isync
/* Establish the exception vector base
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 28/52] selftests/powerpc/spectre_v2: Return skip code when miss_percent is high
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, Thadeu Lima de Souza Cascardo, linuxppc-dev,
linux-kselftest, shuah
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
[ Upstream commit 3c42e9542050d49610077e083c7c3f5fd5e26820 ]
A mis-match between reported and actual mitigation is not restricted to the
Vulnerable case. The guest might also report the mitigation as "Software
count cache flush" and the host will still mitigate with branch cache
disabled.
So, instead of skipping depending on the detected mitigation, simply skip
whenever the detected miss_percent is the expected one for a fully
mitigated system, that is, above 95%.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211207130557.40566-1-cascardo@canonical.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/powerpc/security/spectre_v2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c
index adc2b7294e5fd..83647b8277e7d 100644
--- a/tools/testing/selftests/powerpc/security/spectre_v2.c
+++ b/tools/testing/selftests/powerpc/security/spectre_v2.c
@@ -193,7 +193,7 @@ int spectre_v2_test(void)
* We are not vulnerable and reporting otherwise, so
* missing such a mismatch is safe.
*/
- if (state == VULNERABLE)
+ if (miss_percent > 95)
return 4;
return 1;
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 29/52] powerpc: handle kdump appropriately with crash_kexec_post_notifiers option
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, ego, kernel test robot, nathanl, parth, npiggin, clg,
yukuai3, linuxppc-dev, robh, Hari Bathini, srikar
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Hari Bathini <hbathini@linux.ibm.com>
[ Upstream commit 219572d2fc4135b5ce65c735d881787d48b10e71 ]
Kdump can be triggered after panic_notifers since commit f06e5153f4ae2
("kernel/panic.c: add "crash_kexec_post_notifiers" option for kdump
after panic_notifers") introduced crash_kexec_post_notifiers option.
But using this option would mean smp_send_stop(), that marks all other
CPUs as offline, gets called before kdump is triggered. As a result,
kdump routines fail to save other CPUs' registers. To fix this, kdump
friendly crash_smp_send_stop() function was introduced with kernel
commit 0ee59413c967 ("x86/panic: replace smp_send_stop() with kdump
friendly version in panic path"). Override this kdump friendly weak
function to handle crash_kexec_post_notifiers option appropriately
on powerpc.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
[Fixed signature of crash_stop_this_cpu() - reported by lkp@intel.com]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211207103719.91117-1-hbathini@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/smp.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index aee3a7119f977..7201fdcf02f1c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -620,6 +620,36 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
}
#endif
+#ifdef CONFIG_NMI_IPI
+static void crash_stop_this_cpu(struct pt_regs *regs)
+#else
+static void crash_stop_this_cpu(void *dummy)
+#endif
+{
+ /*
+ * Just busy wait here and avoid marking CPU as offline to ensure
+ * register data is captured appropriately.
+ */
+ while (1)
+ cpu_relax();
+}
+
+void crash_smp_send_stop(void)
+{
+ static bool stopped = false;
+
+ if (stopped)
+ return;
+
+ stopped = true;
+
+#ifdef CONFIG_NMI_IPI
+ smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000);
+#else
+ smp_call_function(crash_stop_this_cpu, NULL, 0);
+#endif /* CONFIG_NMI_IPI */
+}
+
#ifdef CONFIG_NMI_IPI
static void nmi_stop_this_cpu(struct pt_regs *regs)
{
--
2.34.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.16 30/52] powerpc/fadump: Fix inaccurate CPU state info in vmcore generated with panic
From: Sasha Levin @ 2022-01-17 16:58 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Sasha Levin, sfr, srikar, nathanl, ego, sxwjean, npiggin, nathan,
nick.child, clg, aneesh.kumar, parth, yukuai3, linuxppc-dev, robh,
Hari Bathini
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Hari Bathini <hbathini@linux.ibm.com>
[ Upstream commit 06e629c25daa519be620a8c17359ae8fc7a2e903 ]
In panic path, fadump is triggered via a panic notifier function.
Before calling panic notifier functions, smp_send_stop() gets called,
which stops all CPUs except the panic'ing CPU. Commit 8389b37dffdc
("powerpc: stop_this_cpu: remove the cpu from the online map.") and
again commit bab26238bbd4 ("powerpc: Offline CPU in stop_this_cpu()")
started marking CPUs as offline while stopping them. So, if a kernel
has either of the above commits, vmcore captured with fadump via panic
path would not process register data for all CPUs except the panic'ing
CPU. Sample output of crash-utility with such vmcore:
# crash vmlinux vmcore
...
KERNEL: vmlinux
DUMPFILE: vmcore [PARTIAL DUMP]
CPUS: 1
DATE: Wed Nov 10 09:56:34 EST 2021
UPTIME: 00:00:42
LOAD AVERAGE: 2.27, 0.69, 0.24
TASKS: 183
NODENAME: XXXXXXXXX
RELEASE: 5.15.0+
VERSION: #974 SMP Wed Nov 10 04:18:19 CST 2021
MACHINE: ppc64le (2500 Mhz)
MEMORY: 8 GB
PANIC: "Kernel panic - not syncing: sysrq triggered crash"
PID: 3394
COMMAND: "bash"
TASK: c0000000150a5f80 [THREAD_INFO: c0000000150a5f80]
CPU: 1
STATE: TASK_RUNNING (PANIC)
crash> p -x __cpu_online_mask
__cpu_online_mask = $1 = {
bits = {0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
crash>
crash>
crash> p -x __cpu_active_mask
__cpu_active_mask = $2 = {
bits = {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
crash>
While this has been the case since fadump was introduced, the issue
was not identified for two probable reasons:
- In general, the bulk of the vmcores analyzed were from crash
due to exception.
- The above did change since commit 8341f2f222d7 ("sysrq: Use
panic() to force a crash") started using panic() instead of
deferencing NULL pointer to force a kernel crash. But then
commit de6e5d38417e ("powerpc: smp_send_stop do not offline
stopped CPUs") stopped marking CPUs as offline till kernel
commit bab26238bbd4 ("powerpc: Offline CPU in stop_this_cpu()")
reverted that change.
To ensure post processing register data of all other CPUs happens
as intended, let panic() function take the crash friendly path (read
crash_smp_send_stop()) with the help of crash_kexec_post_notifiers
option. Also, as register data for all CPUs is captured by f/w, skip
IPI callbacks here for fadump, to avoid any complications in finding
the right backtraces.
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211207103719.91117-2-hbathini@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/fadump.c | 8 ++++++++
arch/powerpc/kernel/smp.c | 10 ++++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index b7ceb041743c9..60f5fc14aa235 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -1641,6 +1641,14 @@ int __init setup_fadump(void)
else if (fw_dump.reserve_dump_area_size)
fw_dump.ops->fadump_init_mem_struct(&fw_dump);
+ /*
+ * In case of panic, fadump is triggered via ppc_panic_event()
+ * panic notifier. Setting crash_kexec_post_notifiers to 'true'
+ * lets panic() function take crash friendly path before panic
+ * notifiers are invoked.
+ */
+ crash_kexec_post_notifiers = true;
+
return 1;
}
subsys_initcall(setup_fadump);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 7201fdcf02f1c..c338f9d8ab37a 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -61,6 +61,7 @@
#include <asm/cpu_has_feature.h>
#include <asm/ftrace.h>
#include <asm/kup.h>
+#include <asm/fadump.h>
#ifdef DEBUG
#include <asm/udbg.h>
@@ -638,6 +639,15 @@ void crash_smp_send_stop(void)
{
static bool stopped = false;
+ /*
+ * In case of fadump, register data for all CPUs is captured by f/w
+ * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before
+ * this rtas call to avoid tricky post processing of those CPUs'
+ * backtraces.
+ */
+ if (should_fadump_crash())
+ return;
+
if (stopped)
return;
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox