* [PATCH 1/2] crypto: talitos - Work around SEC6 ERRATA (AES-CTR mode data size error)
From: Christophe Leroy @ 2021-01-20 18:57 UTC (permalink / raw)
To: Herbert Xu, David S. Miller; +Cc: linuxppc-dev, linux-crypto, linux-kernel
Talitos Security Engine AESU considers any input
data size that is not a multiple of 16 bytes to be an error.
This is not a problem in general, except for Counter mode
that is a stream cipher and can have an input of any size.
Test Manager for ctr(aes) fails on 4th test vector which has
a length of 499 while all previous vectors which have a 16 bytes
multiple length succeed.
As suggested by Freescale, round up the input data length to the
nearest 16 bytes.
Fixes: 5e75ae1b3cef ("crypto: talitos - add new crypto modes")
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
drivers/crypto/talitos.c | 28 ++++++++++++++++------------
drivers/crypto/talitos.h | 1 +
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 4fd85f31630a..b656983c1ef4 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1093,11 +1093,12 @@ static void ipsec_esp_decrypt_hwauth_done(struct device *dev,
*/
static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
unsigned int offset, int datalen, int elen,
- struct talitos_ptr *link_tbl_ptr)
+ struct talitos_ptr *link_tbl_ptr, int align)
{
int n_sg = elen ? sg_count + 1 : sg_count;
int count = 0;
int cryptlen = datalen + elen;
+ int padding = ALIGN(cryptlen, align) - cryptlen;
while (cryptlen && sg && n_sg--) {
unsigned int len = sg_dma_len(sg);
@@ -1121,7 +1122,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count,
offset += datalen;
}
to_talitos_ptr(link_tbl_ptr + count,
- sg_dma_address(sg) + offset, len, 0);
+ sg_dma_address(sg) + offset, sg_next(sg) ? len : len + padding, 0);
to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
@@ -1144,10 +1145,11 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
unsigned int len, struct talitos_edesc *edesc,
struct talitos_ptr *ptr, int sg_count,
unsigned int offset, int tbl_off, int elen,
- bool force)
+ bool force, int align)
{
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
+ int aligned_len = ALIGN(len, align);
if (!src) {
to_talitos_ptr(ptr, 0, 0, is_sec1);
@@ -1155,22 +1157,22 @@ static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
}
to_talitos_ptr_ext_set(ptr, elen, is_sec1);
if (sg_count == 1 && !force) {
- to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
+ to_talitos_ptr(ptr, sg_dma_address(src) + offset, aligned_len, is_sec1);
return sg_count;
}
if (is_sec1) {
- to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
+ to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, aligned_len, is_sec1);
return sg_count;
}
sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, elen,
- &edesc->link_tbl[tbl_off]);
+ &edesc->link_tbl[tbl_off], align);
if (sg_count == 1 && !force) {
/* Only one segment now, so no link tbl needed*/
copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1);
return sg_count;
}
to_talitos_ptr(ptr, edesc->dma_link_tbl +
- tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
+ tbl_off * sizeof(struct talitos_ptr), aligned_len, is_sec1);
to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
return sg_count;
@@ -1182,7 +1184,7 @@ static int talitos_sg_map(struct device *dev, struct scatterlist *src,
unsigned int offset, int tbl_off)
{
return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
- tbl_off, 0, false);
+ tbl_off, 0, false, 1);
}
/*
@@ -1251,7 +1253,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4],
sg_count, areq->assoclen, tbl_off, elen,
- false);
+ false, 1);
if (ret > 1) {
tbl_off += ret;
@@ -1271,7 +1273,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
elen = 0;
ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5],
sg_count, areq->assoclen, tbl_off, elen,
- is_ipsec_esp && !encrypt);
+ is_ipsec_esp && !encrypt, 1);
tbl_off += ret;
if (!encrypt && is_ipsec_esp) {
@@ -1577,6 +1579,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
+ bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU &&
+ (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR;
/* first DWORD empty */
@@ -1597,8 +1601,8 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
/*
* cipher in
*/
- sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
- &desc->ptr[3], sg_count, 0, 0);
+ sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3],
+ sg_count, 0, 0, 0, false, is_ctr ? 16 : 1);
if (sg_count > 1)
sync_needed = true;
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 1469b956948a..32825119e880 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -344,6 +344,7 @@ static inline bool has_ftr_sec1(struct talitos_private *priv)
/* primary execution unit mode (MODE0) and derivatives */
#define DESC_HDR_MODE0_ENCRYPT cpu_to_be32(0x00100000)
+#define DESC_HDR_MODE0_AESU_MASK cpu_to_be32(0x00600000)
#define DESC_HDR_MODE0_AESU_CBC cpu_to_be32(0x00200000)
#define DESC_HDR_MODE0_AESU_CTR cpu_to_be32(0x00600000)
#define DESC_HDR_MODE0_DEU_CBC cpu_to_be32(0x00400000)
--
2.25.0
^ permalink raw reply related
* [PATCH 2/2] crypto: talitos - Fix ctr(aes) on SEC1
From: Christophe Leroy @ 2021-01-20 18:57 UTC (permalink / raw)
To: Herbert Xu, David S. Miller; +Cc: linuxppc-dev, linux-crypto, linux-kernel
In-Reply-To: <4b7a870573f485b9fea496b13c9b02d86dd97314.1611169001.git.christophe.leroy@csgroup.eu>
While ctr(aes) requires the use of a special descriptor on SEC2 (see
commit 70d355ccea89 ("crypto: talitos - fix ctr-aes-talitos")), that
special descriptor doesn't work on SEC1, see commit e738c5f15562
("powerpc/8xx: Add DT node for using the SEC engine of the MPC885").
However, the common nonsnoop descriptor works properly on SEC1 for
ctr(aes).
Add a second template for ctr(aes) that will be registered
only on SEC1.
Fixes: 70d355ccea89 ("crypto: talitos - fix ctr-aes-talitos")
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
drivers/crypto/talitos.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b656983c1ef4..25c9f825b8b5 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2765,6 +2765,22 @@ static struct talitos_alg_template driver_algs[] = {
DESC_HDR_SEL0_AESU |
DESC_HDR_MODE0_AESU_CTR,
},
+ { .type = CRYPTO_ALG_TYPE_SKCIPHER,
+ .alg.skcipher = {
+ .base.cra_name = "ctr(aes)",
+ .base.cra_driver_name = "ctr-aes-talitos",
+ .base.cra_blocksize = 1,
+ .base.cra_flags = CRYPTO_ALG_ASYNC |
+ CRYPTO_ALG_ALLOCATES_MEMORY,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = skcipher_aes_setkey,
+ },
+ .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+ DESC_HDR_SEL0_AESU |
+ DESC_HDR_MODE0_AESU_CTR,
+ },
{ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(des)",
@@ -3182,6 +3198,12 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.skcipher.setkey ?: skcipher_setkey;
t_alg->algt.alg.skcipher.encrypt = skcipher_encrypt;
t_alg->algt.alg.skcipher.decrypt = skcipher_decrypt;
+ if (!strcmp(alg->cra_name, "ctr(aes)") && !has_ftr_sec1(priv) &&
+ DESC_TYPE(t_alg->algt.desc_hdr_template) !=
+ DESC_TYPE(DESC_HDR_TYPE_AESU_CTR_NONSNOOP)) {
+ devm_kfree(dev, t_alg);
+ return ERR_PTR(-ENOTSUPP);
+ }
break;
case CRYPTO_ALG_TYPE_AEAD:
alg = &t_alg->algt.alg.aead.base;
--
2.25.0
^ permalink raw reply related
* [PATCH] powerpc: Fix debug print in smp_setup_cpu_maps
From: Fabiano Rosas @ 2021-01-20 18:18 UTC (permalink / raw)
To: linuxppc-dev
When figuring out the number of threads, the debug message prints "1
thread" for the first iteration of the loop, instead of the actual
number of threads calculated from the length of the
"ibm,ppc-interrupt-server#s" property.
* /cpus/PowerPC,POWER8@20...
ibm,ppc-interrupt-server#s -> 1 threads <--- WRONG
thread 0 -> cpu 0 (hard id 32)
thread 1 -> cpu 1 (hard id 33)
thread 2 -> cpu 2 (hard id 34)
thread 3 -> cpu 3 (hard id 35)
thread 4 -> cpu 4 (hard id 36)
thread 5 -> cpu 5 (hard id 37)
thread 6 -> cpu 6 (hard id 38)
thread 7 -> cpu 7 (hard id 39)
* /cpus/PowerPC,POWER8@28...
ibm,ppc-interrupt-server#s -> 8 threads
thread 0 -> cpu 8 (hard id 40)
thread 1 -> cpu 9 (hard id 41)
thread 2 -> cpu 10 (hard id 42)
thread 3 -> cpu 11 (hard id 43)
thread 4 -> cpu 12 (hard id 44)
thread 5 -> cpu 13 (hard id 45)
thread 6 -> cpu 14 (hard id 46)
thread 7 -> cpu 15 (hard id 47)
(...)
Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
---
arch/powerpc/kernel/setup-common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 71f38e9248be..46481ea96c88 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -462,8 +462,8 @@ void __init smp_setup_cpu_maps(void)
intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
&len);
if (intserv) {
- DBG(" ibm,ppc-interrupt-server#s -> %d threads\n",
- nthreads);
+ DBG(" ibm,ppc-interrupt-server#s -> %lu threads\n",
+ (len / sizeof(int)));
} else {
DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n");
intserv = of_get_property(dn, "reg", &len);
--
2.29.2
^ permalink raw reply related
* Re: [PATCH] arch: powerpc: mm: book3s64: Fixed spelling architectue -> architecture in line number 1061
From: Randy Dunlap @ 2021-01-20 17:51 UTC (permalink / raw)
To: Bhaskar Chowdhury, mpe, benh, paulus, akpm, rppt, linuxppc-dev,
linux-kernel
In-Reply-To: <20210120142020.2623355-1-unixbhaskar@gmail.com>
On 1/20/21 6:20 AM, Bhaskar Chowdhury wrote:
> s/architectue/architecture/
>
> Signed-off-by: Bhaskar Chowdhury <unixbhaskar@gmail.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Thanks.
Line number in $Subject is just too much.
> ---
> arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index 98f0b243c1ab..8b8f1451e944 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -1058,7 +1058,7 @@ void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
> * Book3S does not require a TLB flush when relaxing access
> * restrictions when the address space is not attached to a
> * NMMU, because the core MMU will reload the pte after taking
> - * an access fault, which is defined by the architectue.
> + * an access fault, which is defined by the architecture.
> */
> }
> /* See ptesync comment in radix__set_pte_at */
> --
> 2.30.0
>
--
~Randy
"He closes his eyes and drops the goggles. You can't get hurt
by looking at a bitmap. Or can you?"
(Neal Stephenson: Snow Crash)
^ permalink raw reply
* Re: [RFC PATCH v3 5/6] dt-bindings: of: Add restricted DMA pool
From: Robin Murphy @ 2021-01-20 17:30 UTC (permalink / raw)
To: Rob Herring, Claire Chang
Cc: heikki.krogerus, peterz, linux-kernel, grant.likely, paulus, will,
mingo, m.szyprowski, sstabellini, saravanak, joro,
rafael.j.wysocki, hch, bgolaszewski, xen-devel, treding,
devicetree, konrad.wilk, dan.j.williams, drinkcat,
boris.ostrovsky, andriy.shevchenko, jgross, gregkh, rdunlap,
frowand.list, tfiga, iommu, xypron.glpk, linuxppc-dev, bauerman
In-Reply-To: <20210120165348.GA220770@robh.at.kernel.org>
On 2021-01-20 16:53, Rob Herring wrote:
> On Wed, Jan 06, 2021 at 11:41:23AM +0800, Claire Chang wrote:
>> Introduce the new compatible string, restricted-dma-pool, for restricted
>> DMA. One can specify the address and length of the restricted DMA memory
>> region by restricted-dma-pool in the device tree.
>
> If this goes into DT, I think we should be able to use dma-ranges for
> this purpose instead. Normally, 'dma-ranges' is for physical bus
> restrictions, but there's no reason it can't be used for policy or to
> express restrictions the firmware has enabled.
There would still need to be some way to tell SWIOTLB to pick up the
corresponding chunk of memory and to prevent the kernel from using it
for anything else, though.
>> Signed-off-by: Claire Chang <tientzu@chromium.org>
>> ---
>> .../reserved-memory/reserved-memory.txt | 24 +++++++++++++++++++
>> 1 file changed, 24 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
>> index e8d3096d922c..44975e2a1fd2 100644
>> --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
>> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
>> @@ -51,6 +51,20 @@ compatible (optional) - standard definition
>> used as a shared pool of DMA buffers for a set of devices. It can
>> be used by an operating system to instantiate the necessary pool
>> management subsystem if necessary.
>> + - restricted-dma-pool: This indicates a region of memory meant to be
>> + used as a pool of restricted DMA buffers for a set of devices. The
>> + memory region would be the only region accessible to those devices.
>> + When using this, the no-map and reusable properties must not be set,
>> + so the operating system can create a virtual mapping that will be used
>> + for synchronization. The main purpose for restricted DMA is to
>> + mitigate the lack of DMA access control on systems without an IOMMU,
>> + which could result in the DMA accessing the system memory at
>> + unexpected times and/or unexpected addresses, possibly leading to data
>> + leakage or corruption. The feature on its own provides a basic level
>> + of protection against the DMA overwriting buffer contents at
>> + unexpected times. However, to protect against general data leakage and
>> + system memory corruption, the system needs to provide way to restrict
>> + the DMA to a predefined memory region.
>> - vendor specific string in the form <vendor>,[<device>-]<usage>
>> no-map (optional) - empty property
>> - Indicates the operating system must not create a virtual mapping
>> @@ -120,6 +134,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
>> compatible = "acme,multimedia-memory";
>> reg = <0x77000000 0x4000000>;
>> };
>> +
>> + restricted_dma_mem_reserved: restricted_dma_mem_reserved {
>> + compatible = "restricted-dma-pool";
>> + reg = <0x50000000 0x400000>;
>> + };
>> };
>>
>> /* ... */
>> @@ -138,4 +157,9 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
>> memory-region = <&multimedia_reserved>;
>> /* ... */
>> };
>> +
>> + pcie_device: pcie_device@0,0 {
>> + memory-region = <&restricted_dma_mem_reserved>;
>
> PCI hosts often have inbound window configurations that limit the
> address range and translate PCI to bus addresses. Those windows happen
> to be configured by dma-ranges. In any case, wouldn't you want to put
> the configuration in the PCI host node? Is there a usecase of
> restricting one PCIe device and not another?
The general design seems to accommodate devices having their own pools
such that they can't even snoop on each others' transient DMA data. If
the interconnect had a way of wiring up, say, PCI RIDs to AMBA NSAIDs,
then in principle you could certainly apply that to PCI endpoints too
(presumably you'd also disallow them from peer-to-peer transactions at
the PCI level too).
Robin.
^ permalink raw reply
* Re: [PATCH 1/3] tty: hvcs: Drop unnecessary if block
From: Tyrel Datwyler @ 2021-01-20 17:16 UTC (permalink / raw)
To: Uwe Kleine-König, Greg Kroah-Hartman, Jiri Slaby
Cc: sparclinux, linuxppc-dev, David S . Miller, linux-kernel
In-Reply-To: <20210114175718.137483-2-u.kleine-koenig@pengutronix.de>
On 1/14/21 9:57 AM, Uwe Kleine-König wrote:
> If hvcs_probe() succeeded dev_set_drvdata() is called with a non-NULL
> value, and if hvcs_probe() failed hvcs_remove() isn't called.
>
> So there is no way dev_get_drvdata() can return NULL in hvcs_remove() and
> the check can just go away.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Reviewed-by: Tyrel Datwyler <tyreld@linux.ibm.com>
> ---
> drivers/tty/hvc/hvcs.c | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
> index 509d1042825a..3e0461285c34 100644
> --- a/drivers/tty/hvc/hvcs.c
> +++ b/drivers/tty/hvc/hvcs.c
> @@ -825,9 +825,6 @@ static int hvcs_remove(struct vio_dev *dev)
> unsigned long flags;
> struct tty_struct *tty;
>
> - if (!hvcsd)
> - return -ENODEV;
> -
> /* By this time the vty-server won't be getting any more interrupts */
>
> spin_lock_irqsave(&hvcsd->lock, flags);
>
^ permalink raw reply
* Re: [RFC PATCH v3 5/6] dt-bindings: of: Add restricted DMA pool
From: Rob Herring @ 2021-01-20 16:53 UTC (permalink / raw)
To: Claire Chang
Cc: heikki.krogerus, peterz, linux-kernel, grant.likely, paulus, will,
mingo, m.szyprowski, sstabellini, saravanak, joro,
rafael.j.wysocki, hch, bgolaszewski, xen-devel, treding,
devicetree, konrad.wilk, dan.j.williams, linuxppc-dev, drinkcat,
boris.ostrovsky, andriy.shevchenko, jgross, gregkh, rdunlap,
frowand.list, tfiga, iommu, xypron.glpk, robin.murphy, bauerman
In-Reply-To: <20210106034124.30560-6-tientzu@chromium.org>
On Wed, Jan 06, 2021 at 11:41:23AM +0800, Claire Chang wrote:
> Introduce the new compatible string, restricted-dma-pool, for restricted
> DMA. One can specify the address and length of the restricted DMA memory
> region by restricted-dma-pool in the device tree.
If this goes into DT, I think we should be able to use dma-ranges for
this purpose instead. Normally, 'dma-ranges' is for physical bus
restrictions, but there's no reason it can't be used for policy or to
express restrictions the firmware has enabled.
> Signed-off-by: Claire Chang <tientzu@chromium.org>
> ---
> .../reserved-memory/reserved-memory.txt | 24 +++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> index e8d3096d922c..44975e2a1fd2 100644
> --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
> @@ -51,6 +51,20 @@ compatible (optional) - standard definition
> used as a shared pool of DMA buffers for a set of devices. It can
> be used by an operating system to instantiate the necessary pool
> management subsystem if necessary.
> + - restricted-dma-pool: This indicates a region of memory meant to be
> + used as a pool of restricted DMA buffers for a set of devices. The
> + memory region would be the only region accessible to those devices.
> + When using this, the no-map and reusable properties must not be set,
> + so the operating system can create a virtual mapping that will be used
> + for synchronization. The main purpose for restricted DMA is to
> + mitigate the lack of DMA access control on systems without an IOMMU,
> + which could result in the DMA accessing the system memory at
> + unexpected times and/or unexpected addresses, possibly leading to data
> + leakage or corruption. The feature on its own provides a basic level
> + of protection against the DMA overwriting buffer contents at
> + unexpected times. However, to protect against general data leakage and
> + system memory corruption, the system needs to provide way to restrict
> + the DMA to a predefined memory region.
> - vendor specific string in the form <vendor>,[<device>-]<usage>
> no-map (optional) - empty property
> - Indicates the operating system must not create a virtual mapping
> @@ -120,6 +134,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
> compatible = "acme,multimedia-memory";
> reg = <0x77000000 0x4000000>;
> };
> +
> + restricted_dma_mem_reserved: restricted_dma_mem_reserved {
> + compatible = "restricted-dma-pool";
> + reg = <0x50000000 0x400000>;
> + };
> };
>
> /* ... */
> @@ -138,4 +157,9 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB).
> memory-region = <&multimedia_reserved>;
> /* ... */
> };
> +
> + pcie_device: pcie_device@0,0 {
> + memory-region = <&restricted_dma_mem_reserved>;
PCI hosts often have inbound window configurations that limit the
address range and translate PCI to bus addresses. Those windows happen
to be configured by dma-ranges. In any case, wouldn't you want to put
the configuration in the PCI host node? Is there a usecase of
restricting one PCIe device and not another?
Rob
^ permalink raw reply
* Re: [PATCH v3] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Michal Suchánek @ 2021-01-20 16:09 UTC (permalink / raw)
To: Ananth N Mavinakayanahalli; +Cc: naveen.n.rao, ravi.bangoria, linuxppc-dev, dja
In-Reply-To: <161114113785.214433.12934683302522893921.stgit@thinktux.local>
On Wed, Jan 20, 2021 at 04:43:14PM +0530, Ananth N Mavinakayanahalli wrote:
> We currently unconditionally try to emulate newer instructions on older
> Power versions that could cause issues. Gate it.
Fixes: 350779a29f11 ("powerpc: Handle most loads and stores in instruction emulation code")
There are more that would apply but most of the checks land in code
added by the above.
Thanks
Michal
>
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
> ---
>
> [v3] Addressed Naveen's comments on scv and addpcis
> [v2] Fixed description
>
> arch/powerpc/lib/sstep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index bf7a7d62ae8b..5a425a4a1d88 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1304,9 +1304,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> if ((word & 0xfe2) == 2)
> op->type = SYSCALL;
> else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) &&
> - (word & 0xfe3) == 1)
> + (word & 0xfe3) == 1) { /* scv */
> op->type = SYSCALL_VECTORED_0;
> - else
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> + } else
> op->type = UNKNOWN;
> return 0;
> #endif
> @@ -1530,6 +1532,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> case 19:
> if (((word >> 1) & 0x1f) == 2) {
> /* addpcis */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> imm = (short) (word & 0xffc1); /* d0 + d2 fields */
> imm |= (word >> 15) & 0x3e; /* d1 field */
> op->val = regs->nip + (imm << 16) + 4;
> @@ -2439,6 +2443,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 268: /* lxvx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 16);
> op->element_size = 16;
> @@ -2448,6 +2454,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> case 269: /* lxvl */
> case 301: { /* lxvll */
> int nb;
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->ea = ra ? regs->gpr[ra] : 0;
> nb = regs->gpr[rb] & 0xff;
> @@ -2475,6 +2483,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 364: /* lxvwsx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 4);
> op->element_size = 4;
> @@ -2482,6 +2492,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 396: /* stxvx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(STORE_VSX, 0, 16);
> op->element_size = 16;
> @@ -2491,6 +2503,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> case 397: /* stxvl */
> case 429: { /* stxvll */
> int nb;
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->ea = ra ? regs->gpr[ra] : 0;
> nb = regs->gpr[rb] & 0xff;
> @@ -2542,6 +2556,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 781: /* lxsibzx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 1);
> op->element_size = 8;
> @@ -2549,6 +2565,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 812: /* lxvh8x */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 16);
> op->element_size = 2;
> @@ -2556,6 +2574,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 813: /* lxsihzx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 2);
> op->element_size = 8;
> @@ -2569,6 +2589,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 876: /* lxvb16x */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(LOAD_VSX, 0, 16);
> op->element_size = 1;
> @@ -2582,6 +2604,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 909: /* stxsibx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(STORE_VSX, 0, 1);
> op->element_size = 8;
> @@ -2589,6 +2613,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 940: /* stxvh8x */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(STORE_VSX, 0, 16);
> op->element_size = 2;
> @@ -2596,6 +2622,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 941: /* stxsihx */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(STORE_VSX, 0, 2);
> op->element_size = 8;
> @@ -2609,6 +2637,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 1004: /* stxvb16x */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd | ((word & 1) << 5);
> op->type = MKOP(STORE_VSX, 0, 16);
> op->element_size = 1;
> @@ -2717,12 +2747,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> op->type = MKOP(LOAD_FP, 0, 16);
> break;
> case 2: /* lxsd */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd + 32;
> op->type = MKOP(LOAD_VSX, 0, 8);
> op->element_size = 8;
> op->vsx_flags = VSX_CHECK_VEC;
> break;
> case 3: /* lxssp */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->reg = rd + 32;
> op->type = MKOP(LOAD_VSX, 0, 4);
> op->element_size = 8;
> @@ -2775,6 +2809,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 1: /* lxv */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->ea = dqform_ea(word, regs);
> if (word & 8)
> op->reg = rd + 32;
> @@ -2785,6 +2821,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
>
> case 2: /* stxsd with LSB of DS field = 0 */
> case 6: /* stxsd with LSB of DS field = 1 */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->ea = dsform_ea(word, regs);
> op->reg = rd + 32;
> op->type = MKOP(STORE_VSX, 0, 8);
> @@ -2794,6 +2832,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
>
> case 3: /* stxssp with LSB of DS field = 0 */
> case 7: /* stxssp with LSB of DS field = 1 */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->ea = dsform_ea(word, regs);
> op->reg = rd + 32;
> op->type = MKOP(STORE_VSX, 0, 4);
> @@ -2802,6 +2842,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> break;
>
> case 5: /* stxv */
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> op->ea = dqform_ea(word, regs);
> if (word & 8)
> op->reg = rd + 32;
>
>
^ permalink raw reply
* Re: [PATCH] PCI: dwc: layerscape: convert to builtin_platform_driver()
From: Greg Kroah-Hartman @ 2021-01-20 15:50 UTC (permalink / raw)
To: Rob Herring
Cc: Roy Zang, Lorenzo Pieralisi, Saravana Kannan, PCI,
linux-kernel@vger.kernel.org, Minghuan Lian, Michael Walle,
Mingkai Hu, Bjorn Helgaas, linuxppc-dev, linux-arm-kernel
In-Reply-To: <CAL_JsqLSJCLtgPyAdKSqsy=JoHSLYef_0s-stTbiJ+VCq2qaSA@mail.gmail.com>
On Wed, Jan 20, 2021 at 08:23:59AM -0600, Rob Herring wrote:
> On Wed, Jan 20, 2021 at 4:53 AM Michael Walle <michael@walle.cc> wrote:
> >
> > fw_devlink will defer the probe until all suppliers are ready. We can't
> > use builtin_platform_driver_probe() because it doesn't retry after probe
> > deferral. Convert it to builtin_platform_driver().
>
> If builtin_platform_driver_probe() doesn't work with fw_devlink, then
> shouldn't it be fixed or removed? Then we're not fixing drivers later
> when folks start caring about deferred probe and devlink.
>
> I'd really prefer if we convert this to a module instead. (And all the
> other PCI host drivers.)
>
> > Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
>
> This happened!?
It's in linux-next in my tree, but is looking like it might be reverted
soon. But finding these issues is good.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] PCI: dwc: layerscape: convert to builtin_platform_driver()
From: Michael Walle @ 2021-01-20 14:34 UTC (permalink / raw)
To: Rob Herring
Cc: Roy Zang, Lorenzo Pieralisi, Saravana Kannan, PCI, linux-kernel,
Minghuan Lian, linux-arm-kernel, Greg Kroah-Hartman,
Bjorn Helgaas, linuxppc-dev, Mingkai Hu
In-Reply-To: <CAL_JsqLSJCLtgPyAdKSqsy=JoHSLYef_0s-stTbiJ+VCq2qaSA@mail.gmail.com>
Am 2021-01-20 15:23, schrieb Rob Herring:
> On Wed, Jan 20, 2021 at 4:53 AM Michael Walle <michael@walle.cc> wrote:
>>
>> fw_devlink will defer the probe until all suppliers are ready. We
>> can't
>> use builtin_platform_driver_probe() because it doesn't retry after
>> probe
>> deferral. Convert it to builtin_platform_driver().
>
> If builtin_platform_driver_probe() doesn't work with fw_devlink, then
> shouldn't it be fixed or removed? Then we're not fixing drivers later
> when folks start caring about deferred probe and devlink.
>
> I'd really prefer if we convert this to a module instead. (And all the
> other PCI host drivers.)
I briefly looked into adding a remove() op. But I don't know what will
have to be undo of the ls_pcie_host_init(). That would be up to the
maintainers of this driver.
_But_ I'd really like to see PCI working on my board again ;) At
least until the end of this development cycle.
-michael
>> Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
>
> This happened!?
>
>> Signed-off-by: Michael Walle <michael@walle.cc>
>> ---
>> drivers/pci/controller/dwc/pci-layerscape.c | 5 +++--
>> 1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/pci/controller/dwc/pci-layerscape.c
>> b/drivers/pci/controller/dwc/pci-layerscape.c
>> index 44ad34cdc3bc..5b9c625df7b8 100644
>> --- a/drivers/pci/controller/dwc/pci-layerscape.c
>> +++ b/drivers/pci/controller/dwc/pci-layerscape.c
>> @@ -232,7 +232,7 @@ static const struct of_device_id
>> ls_pcie_of_match[] = {
>> { },
>> };
>>
>> -static int __init ls_pcie_probe(struct platform_device *pdev)
>> +static int ls_pcie_probe(struct platform_device *pdev)
>> {
>> struct device *dev = &pdev->dev;
>> struct dw_pcie *pci;
>> @@ -271,10 +271,11 @@ static int __init ls_pcie_probe(struct
>> platform_device *pdev)
>> }
>>
>> static struct platform_driver ls_pcie_driver = {
>> + .probe = ls_pcie_probe,
>> .driver = {
>> .name = "layerscape-pcie",
>> .of_match_table = ls_pcie_of_match,
>> .suppress_bind_attrs = true,
>> },
>> };
>> -builtin_platform_driver_probe(ls_pcie_driver, ls_pcie_probe);
>> +builtin_platform_driver(ls_pcie_driver);
>> --
>> 2.20.1
>>
^ permalink raw reply
* Re: [PATCH 1/4] KVM: PPC: Book3S HV: Remove support for running HPT guest on RPT host without mixed mode support
From: Fabiano Rosas @ 2021-01-20 14:27 UTC (permalink / raw)
To: Nicholas Piggin, kvm-ppc; +Cc: linuxppc-dev
In-Reply-To: <1611099866.a9bsenxeey.astroid@bobo.none>
Nicholas Piggin <npiggin@gmail.com> writes:
> Excerpts from Fabiano Rosas's message of January 20, 2021 7:07 am:
>> Nicholas Piggin <npiggin@gmail.com> writes:
>>
>>> Excerpts from Fabiano Rosas's message of January 19, 2021 11:46 am:
>>>> Resending because the previous got spam-filtered:
>>>>
>>>> Nicholas Piggin <npiggin@gmail.com> writes:
>>>>
>>>>> This reverts much of commit c01015091a770 ("KVM: PPC: Book3S HV: Run HPT
>>>>> guests on POWER9 radix hosts"), which was required to run HPT guests on
>>>>> RPT hosts on early POWER9 CPUs without support for "mixed mode", which
>>>>> meant the host could not run with MMU on while guests were running.
>>>>>
>>>>> This code has some corner case bugs, e.g., when the guest hits a machine
>>>>> check or HMI the primary locks up waiting for secondaries to switch LPCR
>>>>> to host, which they never do. This could all be fixed in software, but
>>>>> most CPUs in production have mixed mode support, and those that don't
>>>>> are believed to be all in installations that don't use this capability.
>>>>> So simplify things and remove support.
>>>>
>>>> With this patch in a DD2.1 machine + indep_threads_mode=N +
>>>> disable_radix, QEMU aborts and dumps registers, is that intended?
>>>
>>> Yes. That configuration is hanging handling MCEs in the guest with some
>>> threads waiting forever to synchronize. Paul suggested it was never a
>>> supported configuration so we might just remove it.
>>>
>>
>> OK, so:
>>
>> Tested-by: Fabiano Rosas <farosas@linux.ibm.com>
>>
>>>> Could we use the 'no_mixing_hpt_and_radix' logic in check_extension to
>>>> advertise only KVM_CAP_PPC_MMU_RADIX to the guest via OV5 so it doesn't
>>>> try to run hash?
>>>>
>>>> For instance, if I hack QEMU's 'spapr_dt_ov5_platform_support' from
>>>> OV5_MMU_BOTH to OV5_MMU_RADIX_300 then it boots succesfuly, but the
>>>> guest turns into radix, due to this code in prom_init:
>>>>
>>>> prom_parse_mmu_model:
>>>>
>>>> case OV5_FEAT(OV5_MMU_RADIX): /* Only Radix */
>>>> prom_debug("MMU - radix only\n");
>>>> if (prom_radix_disable) {
>>>> /*
>>>> * If we __have__ to do radix, we're better off ignoring
>>>> * the command line rather than not booting.
>>>> */
>>>> prom_printf("WARNING: Ignoring cmdline option disable_radix\n");
>>>> }
>>>> support->radix_mmu = true;
>>>> break;
>>>>
>>>> It seems we could explicitly say that the host does not support hash and
>>>> that would align with the above code.
>>>
>>> I'm not sure, sounds like you could, on the other hand these aborts seem
>>> like the prefered failure mode for these kinds of configuration issues,
>>> I don't know what the policy is, is reverting back to radix acceptable?
>>>
>>
>> Yeah, I couldn't find documentation about why we're reverting back to
>> radix. I personally dislike it, but there is already a precedent so I'm
>> not sure. A radix guest on a hash host does the same transparent
>> conversion AFAICT.
>>
>> But despite that, this patch removes support for hash MMU in this
>> particular scenario. I don't see why continuing to tell the guest we
>> support hash.
>>
>> Anyway, here's a patch if you decide to go that way (tested w/ DD2.1 &
>> 2.3 machines):
>
> Thanks, I don't mind it, have to see if the maintainer will take it :)
>
> You could add a small changelog / SOB and I could putit after my patch?
>
Sure, I'll reply to this thread with a proper patch.
>>
>> ---
>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
>> index 0a056c64c317b..53743555676d6 100644
>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>> @@ -314,6 +314,7 @@ struct kvmppc_ops {
>> int size);
>> int (*enable_svm)(struct kvm *kvm);
>> int (*svm_off)(struct kvm *kvm);
>> + bool (*hash_possible)(void);
>> };
>>
>> extern struct kvmppc_ops *kvmppc_hv_ops;
>> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
>> index 6f612d240392f..2d1e8aba22b85 100644
>> --- a/arch/powerpc/kvm/book3s_hv.c
>> +++ b/arch/powerpc/kvm/book3s_hv.c
>> @@ -5599,6 +5599,15 @@ static int kvmhv_svm_off(struct kvm *kvm)
>> return ret;
>> }
>>
>> +static bool kvmppc_hash_possible(void)
>> +{
>> + if (radix_enabled() && no_mixing_hpt_and_radix)
>> + return false;
>> +
>> + return cpu_has_feature(CPU_FTR_ARCH_300) &&
>> + cpu_has_feature(CPU_FTR_HVMODE);
>> +}
>
> Just be careful, it's hash_v3 specifically. Either make this return true
> for arch < 300 add the ARCH_300 check in the ioctl, or rename to include
> v3.
>
>> +
>> static struct kvmppc_ops kvm_ops_hv = {
>> .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv,
>> .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv,
>> @@ -5642,6 +5651,7 @@ static struct kvmppc_ops kvm_ops_hv = {
>> .store_to_eaddr = kvmhv_store_to_eaddr,
>> .enable_svm = kvmhv_enable_svm,
>> .svm_off = kvmhv_svm_off,
>> + .hash_possible = kvmppc_hash_possible,
>> };
>>
>
> How about adding an op which can check extensions? It could return false
> if it wasn't checked and so default to the generic checks in
> kvm_vm_ioctl_check_extension, and take a pointer to 'r' to set.
>
I'm not sure I get the part about "return false if it wasn't
checked". Do you mean like this?
static bool kvmhv_check_extension(long ext, int *r)
{
switch (ext) {
case KVM_CAP_PPC_MMU_HASH_V3:
r = kvmppc_hash_v3_possible();
break;
default:
return false;
}
return true;
}
And then we could move all of the #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
cases into it and early in kvm_vm_ioctl_check_extension have something
like:
if (hv_enabled && kvmppc_hv_ops->check_extension(ext, &r))
return r;
>> static int kvm_init_subcore_bitmap(void)
>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
>> index cf52d26f49cd7..99ced6c570e74 100644
>> --- a/arch/powerpc/kvm/powerpc.c
>> +++ b/arch/powerpc/kvm/powerpc.c
>> @@ -611,8 +611,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>> r = !!(hv_enabled && radix_enabled());
>> break;
>> case KVM_CAP_PPC_MMU_HASH_V3:
>> - r = !!(hv_enabled && cpu_has_feature(CPU_FTR_ARCH_300) &&
>> - cpu_has_feature(CPU_FTR_HVMODE));
>> + r = !!(hv_enabled && kvmppc_hv_ops->hash_possible());
>> break;
>> case KVM_CAP_PPC_NESTED_HV:
>> r = !!(hv_enabled && kvmppc_hv_ops->enable_nested &&
>
> Thanks,
> Nick
^ permalink raw reply
* Re: [PATCH] PCI: dwc: layerscape: convert to builtin_platform_driver()
From: Rob Herring @ 2021-01-20 14:23 UTC (permalink / raw)
To: Michael Walle
Cc: Roy Zang, Lorenzo Pieralisi, Saravana Kannan, PCI,
linux-kernel@vger.kernel.org, Minghuan Lian, linux-arm-kernel,
Greg Kroah-Hartman, Bjorn Helgaas, linuxppc-dev, Mingkai Hu
In-Reply-To: <20210120105246.23218-1-michael@walle.cc>
On Wed, Jan 20, 2021 at 4:53 AM Michael Walle <michael@walle.cc> wrote:
>
> fw_devlink will defer the probe until all suppliers are ready. We can't
> use builtin_platform_driver_probe() because it doesn't retry after probe
> deferral. Convert it to builtin_platform_driver().
If builtin_platform_driver_probe() doesn't work with fw_devlink, then
shouldn't it be fixed or removed? Then we're not fixing drivers later
when folks start caring about deferred probe and devlink.
I'd really prefer if we convert this to a module instead. (And all the
other PCI host drivers.)
> Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
This happened!?
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
> drivers/pci/controller/dwc/pci-layerscape.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
> index 44ad34cdc3bc..5b9c625df7b8 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> @@ -232,7 +232,7 @@ static const struct of_device_id ls_pcie_of_match[] = {
> { },
> };
>
> -static int __init ls_pcie_probe(struct platform_device *pdev)
> +static int ls_pcie_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> struct dw_pcie *pci;
> @@ -271,10 +271,11 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
> }
>
> static struct platform_driver ls_pcie_driver = {
> + .probe = ls_pcie_probe,
> .driver = {
> .name = "layerscape-pcie",
> .of_match_table = ls_pcie_of_match,
> .suppress_bind_attrs = true,
> },
> };
> -builtin_platform_driver_probe(ls_pcie_driver, ls_pcie_probe);
> +builtin_platform_driver(ls_pcie_driver);
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v3] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Naveen N. Rao @ 2021-01-20 13:50 UTC (permalink / raw)
To: Ananth N Mavinakayanahalli; +Cc: naveen.n.rao, linuxppc-dev, ravi.bangoria, dja
In-Reply-To: <161114113785.214433.12934683302522893921.stgit@thinktux.local>
On 2021/01/20 04:43PM, Ananth N Mavinakayanahalli wrote:
> We currently unconditionally try to emulate newer instructions on older
> Power versions that could cause issues. Gate it.
>
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
> ---
>
> [v3] Addressed Naveen's comments on scv and addpcis
> [v2] Fixed description
>
> arch/powerpc/lib/sstep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
- Naveen
^ permalink raw reply
* [PATCH] powerpc: Fix build error in paravirt.h
From: Michal Suchanek @ 2021-01-20 13:28 UTC (permalink / raw)
To: linuxppc-dev
Cc: Juergen Gross, Srikar Dronamraju, Deep Shah, VMware, Inc.,
linux-kernel, virtualization, Paul Mackerras, Waiman Long,
Michal Suchanek
./arch/powerpc/include/asm/paravirt.h:83:44: error: implicit declaration
of function 'smp_processor_id'; did you mean 'raw_smp_processor_id'?
smp_processor_id is defined in linux/smp.h but it is not included.
The build error happens only when the patch is applied to 5.3 kernel but
it only works by chance in mainline.
Fixes: ca3f969dcb11 ("powerpc/paravirt: Use is_kvm_guest() in vcpu_is_preempted()")
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
arch/powerpc/include/asm/paravirt.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h
index edc08f04aef7..5d1726bb28e7 100644
--- a/arch/powerpc/include/asm/paravirt.h
+++ b/arch/powerpc/include/asm/paravirt.h
@@ -10,6 +10,7 @@
#endif
#ifdef CONFIG_PPC_SPLPAR
+#include <linux/smp.h>
#include <asm/kvm_guest.h>
#include <asm/cputhreads.h>
--
2.26.2
^ permalink raw reply related
* Re: [PATCH 6/6] powerpc/rtas: constrain user region allocation to RMA
From: Michael Ellerman @ 2021-01-20 12:13 UTC (permalink / raw)
To: Nathan Lynch, linuxppc-dev; +Cc: aik, tyreld, brking, ajd, aneesh.kumar
In-Reply-To: <874kjcy73z.fsf@linux.ibm.com>
Nathan Lynch <nathanl@linux.ibm.com> writes:
> Michael Ellerman <mpe@ellerman.id.au> writes:
>> Nathan Lynch <nathanl@linux.ibm.com> writes:
>>> Memory locations passed as arguments from the OS to RTAS usually need
>>> to be addressable in 32-bit mode and must reside in the Real Mode
>>> Area. On PAPR guests, the RMA starts at logical address 0 and is the
>>> first logical memory block reported in the LPAR’s device tree.
>>>
>>> On powerpc targets with RTAS, Linux makes available to user space a
>>> region of memory suitable for arguments to be passed to RTAS via
>>> sys_rtas(). This region (rtas_rmo_buf) is allocated via the memblock
>>> API during boot in order to ensure that it satisfies the requirements
>>> described above.
>>>
>>> With radix MMU, the upper limit supplied to the memblock allocation
>>> can exceed the bounds of the first logical memory block, since
>>> ppc64_rma_size is ULONG_MAX and RTAS_INSTANTIATE_MAX is 1GB.
>>
>> Why does the size of the first memory block matter for radix?
>
> Here is my understanding: in the platform architecture, the size of the
> first memory block equals the RMA, regardless of the MMU mode. It just
> so happens that when using radix, Linux can pass ibm,configure-connector
> a work area address outside of the RMA because the allocation
> constraints for the work area are computed differently. It would be
> wrong of the OS to pass RTAS arguments outside of this region with hash
> MMU as well.
If that's the requirement then shouldn't we be adjusting ppc64_rma_size?
Otherwise aren't other uses of ppc64_rma_size going to run into similar
problems.
Or does the RMA only apply for RTAS calls when using radix?
cheers
^ permalink raw reply
* Re: [PATCH 6/6] powerpc/rtas: constrain user region allocation to RMA
From: Michael Ellerman @ 2021-01-20 12:06 UTC (permalink / raw)
To: Nathan Lynch, Alexey Kardashevskiy, linuxppc-dev
Cc: tyreld, brking, ajd, aneesh.kumar
In-Reply-To: <871regxwzh.fsf@linux.ibm.com>
Nathan Lynch <nathanl@linux.ibm.com> writes:
> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
>> On 16/01/2021 02:38, Nathan Lynch wrote:
>>> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
>>>> On 15/01/2021 09:00, Nathan Lynch wrote:
>>>>> Memory locations passed as arguments from the OS to RTAS usually need
>>>>> to be addressable in 32-bit mode and must reside in the Real Mode
>>>>> Area. On PAPR guests, the RMA starts at logical address 0 and is the
>>>>> first logical memory block reported in the LPAR’s device tree.
>>>>>
>>>>> On powerpc targets with RTAS, Linux makes available to user space a
>>>>> region of memory suitable for arguments to be passed to RTAS via
>>>>> sys_rtas(). This region (rtas_rmo_buf) is allocated via the memblock
>>>>> API during boot in order to ensure that it satisfies the requirements
>>>>> described above.
>>>>>
>>>>> With radix MMU, the upper limit supplied to the memblock allocation
>>>>> can exceed the bounds of the first logical memory block, since
>>>>> ppc64_rma_size is ULONG_MAX and RTAS_INSTANTIATE_MAX is 1GB. (512MB is
>>>>> a common size of the first memory block according to a small sample of
>>>>> LPARs I have checked.) This leads to failures when user space invokes
>>>>> an RTAS function that uses a work area, such as
>>>>> ibm,configure-connector.
>>>>>
>>>>> Alter the determination of the upper limit for rtas_rmo_buf's
>>>>> allocation to consult the device tree directly, ensuring placement
>>>>> within the RMA regardless of the MMU in use.
>>>>
>>>> Can we tie this with RTAS (which also needs to be in RMA) and simply add
>>>> extra 64K in prom_instantiate_rtas() and advertise this address
>>>> (ALIGH_UP(rtas-base + rtas-size, PAGE_SIZE)) to the user space? We do
>>>> not need this RMO area before that point.
>>>
>>> Can you explain more about what advantage that would bring? I'm not
>>> seeing it. It's a more significant change than what I've written
>>> here.
>>
>>
>> We already allocate space for RTAS and (like RMO) it needs to be in RMA,
>> and RMO is useless without RTAS. We can reuse RTAS allocation code for
>> RMO like this:
>
> When you say RMO I assume you are referring to rtas_rmo_buf? (I don't
> think it is well-named.)
...
RMO (Real mode offset) is the old term we used to use to refer to what
is now called the RMA (Real mode area). There are still many references
to RMO in Linux, but they almost certainly all refer to what we now call
the RMA.
>> May be store in the FDT as "linux,rmo-base" next to "linux,rtas-base",
>> for clarity, as sharing symbols between prom and main kernel is a bit
>> tricky.
>>
>> The benefit is that we do not do the same thing (== find 64K in RMA)
>> in 2 different ways and if the RMO allocated my way is broken - we'll
>> know it much sooner as RTAS itself will break too.
>
> Implementation details aside... I'll grant that combining the
> allocations into one in prom_init reduces some duplication in the sense
> that both are subject to the same constraints (mostly - the RTAS data
> area must not cross a 256MB boundary, while the user region may). But
> they really are distinct concerns. The RTAS private data area is
> specified in the platform architecture, the OS is obligated to allocate
> it and pass it to instantiate-rtas, etc etc. However the user region
> (rtas_rmo_buf) is purely a Linux construct which is there to support
> sys_rtas.
>
> Now, there are multiple sites in the kernel proper that must allocate
> memory suitable for passing to RTAS. Obviously there is value in
> consolidating the logic for that purpose in one place, so I'll work on
> adding that in v2. OK?
I don't think we want to move any allocations into prom_init.c unless we
have to.
It's best thought of as a trampoline, that runs before the kernel
proper, to transition from live OF to a flat DT environment. One thing
that must be done as part of that is instantiating RTAS, because it's
basically a runtime copy of the live OF. But any other allocs are for
Linux to handle later, IMHO.
cheers
^ permalink raw reply
* Re: [PATCH v6 25/39] powerpc: convert interrupt handlers to use wrappers
From: kernel test robot @ 2021-01-20 11:45 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev
Cc: clang-built-linux, kbuild-all, Nicholas Piggin
In-Reply-To: <20210115165012.1260253-26-npiggin@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4556 bytes --]
Hi Nicholas,
I love your patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on v5.11-rc4 next-20210120]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20210116-023244
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-randconfig-r035-20210120 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 22b68440e1647e16b5ee24b924986207173c02d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# https://github.com/0day-ci/linux/commit/04d5131f1545e1e992962a5339135b605eb421a5
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20210116-023244
git checkout 04d5131f1545e1e992962a5339135b605eb421a5
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> arch/powerpc/mm/book3s64/hash_utils.c:1516:30: warning: no previous prototype for function '__do_hash_fault' [-Wmissing-prototypes]
DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
^
arch/powerpc/mm/book3s64/hash_utils.c:1516:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
^
arch/powerpc/include/asm/interrupt.h:150:19: note: expanded from macro 'DEFINE_INTERRUPT_HANDLER_RET'
__visible noinstr long func(struct pt_regs *regs) \
^
arch/powerpc/mm/book3s64/hash_utils.c:1905:6: warning: no previous prototype for function 'hpte_insert_repeating' [-Wmissing-prototypes]
long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
^
arch/powerpc/mm/book3s64/hash_utils.c:1905:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
^
static
2 warnings generated.
vim +/__do_hash_fault +1516 arch/powerpc/mm/book3s64/hash_utils.c
1515
> 1516 DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
1517 {
1518 unsigned long ea = regs->dar;
1519 unsigned long dsisr = regs->dsisr;
1520 unsigned long access = _PAGE_PRESENT | _PAGE_READ;
1521 unsigned long flags = 0;
1522 struct mm_struct *mm;
1523 unsigned int region_id;
1524 long err;
1525
1526 region_id = get_region_id(ea);
1527 if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
1528 mm = &init_mm;
1529 else
1530 mm = current->mm;
1531
1532 if (dsisr & DSISR_NOHPTE)
1533 flags |= HPTE_NOHPTE_UPDATE;
1534
1535 if (dsisr & DSISR_ISSTORE)
1536 access |= _PAGE_WRITE;
1537 /*
1538 * We set _PAGE_PRIVILEGED only when
1539 * kernel mode access kernel space.
1540 *
1541 * _PAGE_PRIVILEGED is NOT set
1542 * 1) when kernel mode access user space
1543 * 2) user space access kernel space.
1544 */
1545 access |= _PAGE_PRIVILEGED;
1546 if (user_mode(regs) || (region_id == USER_REGION_ID))
1547 access &= ~_PAGE_PRIVILEGED;
1548
1549 if (regs->trap == 0x400)
1550 access |= _PAGE_EXEC;
1551
1552 err = hash_page_mm(mm, ea, access, regs->trap, flags);
1553 if (unlikely(err < 0)) {
1554 // failed to instert a hash PTE due to an hypervisor error
1555 if (user_mode(regs)) {
1556 if (IS_ENABLED(CONFIG_PPC_SUBPAGE_PROT) && err == -2)
1557 _exception(SIGSEGV, regs, SEGV_ACCERR, ea);
1558 else
1559 _exception(SIGBUS, regs, BUS_ADRERR, ea);
1560 } else {
1561 bad_page_fault(regs, SIGBUS);
1562 }
1563 err = 0;
1564 }
1565
1566 return err;
1567 }
1568
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33697 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc/uprobes: Don't allow probe on suffix of prefixed instruction
From: Ravi Bangoria @ 2021-01-20 11:18 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Ravi Bangoria, linux-kernel, rostedt, paulus, sandipan, jniethe5,
naveen.n.rao, linuxppc-dev
In-Reply-To: <20210119172603.GA16696@redhat.com>
On 1/19/21 10:56 PM, Oleg Nesterov wrote:
> On 01/19, Ravi Bangoria wrote:
>>
>> Probe on 2nd word of a prefixed instruction is invalid scenario and
>> should be restricted.
>
> I don't understand this ppc-specific problem, but...
So far (upto Power9), instruction size was fixed - 4 bytes. But Power10
introduced a prefixed instruction which consist of 8 bytes, where first
4 bytes is prefix and remaining is suffix.
This patch checks whether the Uprobe is on the 2nd word (suffix) of a
prefixed instruction. If so, consider it as invalid Uprobe.
>
>> +#ifdef CONFIG_PPC64
>> +int arch_uprobe_verify_opcode(struct page *page, unsigned long vaddr,
>> + uprobe_opcode_t opcode)
>> +{
>> + uprobe_opcode_t prefix;
>> + void *kaddr;
>> + struct ppc_inst inst;
>> +
>> + /* Don't check if vaddr is pointing to the beginning of page */
>> + if (!(vaddr & ~PAGE_MASK))
>> + return 0;
>
> So the fix is incomplete? Or insn at the start of page can't be prefixed?
Prefixed instruction can not cross 64 byte boundary. If it does, kernel
generates SIGBUS. Considering all powerpc supported page sizes to be
multiple of 64 bytes, there will never be a scenario where prefix and
suffix will be on different pages. i.e. a beginning of the page should
never be a suffix.
>
>> +int __weak arch_uprobe_verify_opcode(struct page *page, unsigned long vaddr,
>> + uprobe_opcode_t opcode)
>> +{
>> + return 0;
>> +}
>> +
>> static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t *new_opcode)
>> {
>> uprobe_opcode_t old_opcode;
>> @@ -275,6 +281,8 @@ static int verify_opcode(struct page *page, unsigned long vaddr, uprobe_opcode_t
>> if (is_swbp_insn(new_opcode)) {
>> if (is_swbp) /* register: already installed? */
>> return 0;
>> + if (arch_uprobe_verify_opcode(page, vaddr, old_opcode))
>> + return -EINVAL;
>
> Well, this doesn't look good...
>
> To me it would be better to change the prepare_uprobe() path to copy
> the potential prefix into uprobe->arch and check ppc_inst_prefixed()
> in arch_uprobe_analyze_insn(). What do you think?
Agreed. The only reason I was checking via verify_opcode() is to make the
code more simpler. If I need to check via prepare_uprobe(), I'll need to
abuse uprobe->offset by setting it to uprobe->offset - 4 to read previous
4 bytes of current instruction. Which, IMHO, is not that straightforward
with current implementation of prepare_uprobe().
But while replying here, I'm thinking... I should be able to grab a page
using mm and vaddr, which are already available in arch_uprobe_analyze_insn().
With that, I should be able to do all this inside arch_uprobe_analyze_insn()
only. I'll try this and send v2 if that works.
Thanks for the review.
Ravi
^ permalink raw reply
* [PATCH v3] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Ananth N Mavinakayanahalli @ 2021-01-20 11:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: naveen.n.rao, ravi.bangoria, dja
We currently unconditionally try to emulate newer instructions on older
Power versions that could cause issues. Gate it.
Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
---
[v3] Addressed Naveen's comments on scv and addpcis
[v2] Fixed description
arch/powerpc/lib/sstep.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index bf7a7d62ae8b..5a425a4a1d88 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1304,9 +1304,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
if ((word & 0xfe2) == 2)
op->type = SYSCALL;
else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) &&
- (word & 0xfe3) == 1)
+ (word & 0xfe3) == 1) { /* scv */
op->type = SYSCALL_VECTORED_0;
- else
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
+ } else
op->type = UNKNOWN;
return 0;
#endif
@@ -1530,6 +1532,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 19:
if (((word >> 1) & 0x1f) == 2) {
/* addpcis */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
imm = (short) (word & 0xffc1); /* d0 + d2 fields */
imm |= (word >> 15) & 0x3e; /* d1 field */
op->val = regs->nip + (imm << 16) + 4;
@@ -2439,6 +2443,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 268: /* lxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 16;
@@ -2448,6 +2454,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 269: /* lxvl */
case 301: { /* lxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2475,6 +2483,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 364: /* lxvwsx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 4;
@@ -2482,6 +2492,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 396: /* stxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 16;
@@ -2491,6 +2503,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 397: /* stxvl */
case 429: { /* stxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2542,6 +2556,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 781: /* lxsibzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 1);
op->element_size = 8;
@@ -2549,6 +2565,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 812: /* lxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 2;
@@ -2556,6 +2574,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 813: /* lxsihzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 2);
op->element_size = 8;
@@ -2569,6 +2589,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 876: /* lxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 1;
@@ -2582,6 +2604,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 909: /* stxsibx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 1);
op->element_size = 8;
@@ -2589,6 +2613,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 940: /* stxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 2;
@@ -2596,6 +2622,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 941: /* stxsihx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 2);
op->element_size = 8;
@@ -2609,6 +2637,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1004: /* stxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 1;
@@ -2717,12 +2747,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(LOAD_FP, 0, 16);
break;
case 2: /* lxsd */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 8);
op->element_size = 8;
op->vsx_flags = VSX_CHECK_VEC;
break;
case 3: /* lxssp */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 8;
@@ -2775,6 +2809,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1: /* lxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
@@ -2785,6 +2821,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 2: /* stxsd with LSB of DS field = 0 */
case 6: /* stxsd with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 8);
@@ -2794,6 +2832,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 3: /* stxssp with LSB of DS field = 0 */
case 7: /* stxssp with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 4);
@@ -2802,6 +2842,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 5: /* stxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
^ permalink raw reply related
* [PATCH] PCI: dwc: layerscape: convert to builtin_platform_driver()
From: Michael Walle @ 2021-01-20 10:52 UTC (permalink / raw)
To: linuxppc-dev, linux-pci, linux-arm-kernel, linux-kernel
Cc: Rob Herring, Lorenzo Pieralisi, Saravana Kannan, Roy Zang,
Greg Kroah-Hartman, Minghuan Lian, Michael Walle, Bjorn Helgaas,
Mingkai Hu
fw_devlink will defer the probe until all suppliers are ready. We can't
use builtin_platform_driver_probe() because it doesn't retry after probe
deferral. Convert it to builtin_platform_driver().
Fixes: e590474768f1 ("driver core: Set fw_devlink=on by default")
Signed-off-by: Michael Walle <michael@walle.cc>
---
drivers/pci/controller/dwc/pci-layerscape.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index 44ad34cdc3bc..5b9c625df7b8 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -232,7 +232,7 @@ static const struct of_device_id ls_pcie_of_match[] = {
{ },
};
-static int __init ls_pcie_probe(struct platform_device *pdev)
+static int ls_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
@@ -271,10 +271,11 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
}
static struct platform_driver ls_pcie_driver = {
+ .probe = ls_pcie_probe,
.driver = {
.name = "layerscape-pcie",
.of_match_table = ls_pcie_of_match,
.suppress_bind_attrs = true,
},
};
-builtin_platform_driver_probe(ls_pcie_driver, ls_pcie_probe);
+builtin_platform_driver(ls_pcie_driver);
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v6 25/39] powerpc: convert interrupt handlers to use wrappers
From: kernel test robot @ 2021-01-20 10:48 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: kbuild-all, Nicholas Piggin
In-Reply-To: <20210115165012.1260253-26-npiggin@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4075 bytes --]
Hi Nicholas,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.11-rc4 next-20210120]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20210116-023244
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-skiroot_defconfig (attached as .config)
compiler: powerpc64le-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/04d5131f1545e1e992962a5339135b605eb421a5
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20210116-023244
git checkout 04d5131f1545e1e992962a5339135b605eb421a5
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from arch/powerpc/mm/book3s64/hash_utils.c:41:
>> arch/powerpc/mm/book3s64/hash_utils.c:1516:30: error: no previous prototype for '__do_hash_fault' [-Werror=missing-prototypes]
1516 | DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
| ^~~~~~~~~~~~~~~
arch/powerpc/include/asm/interrupt.h:150:24: note: in definition of macro 'DEFINE_INTERRUPT_HANDLER_RET'
150 | __visible noinstr long func(struct pt_regs *regs) \
| ^~~~
arch/powerpc/mm/book3s64/hash_utils.c:1905:6: error: no previous prototype for 'hpte_insert_repeating' [-Werror=missing-prototypes]
1905 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
| ^~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
vim +/__do_hash_fault +1516 arch/powerpc/mm/book3s64/hash_utils.c
1515
> 1516 DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
1517 {
1518 unsigned long ea = regs->dar;
1519 unsigned long dsisr = regs->dsisr;
1520 unsigned long access = _PAGE_PRESENT | _PAGE_READ;
1521 unsigned long flags = 0;
1522 struct mm_struct *mm;
1523 unsigned int region_id;
1524 long err;
1525
1526 region_id = get_region_id(ea);
1527 if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
1528 mm = &init_mm;
1529 else
1530 mm = current->mm;
1531
1532 if (dsisr & DSISR_NOHPTE)
1533 flags |= HPTE_NOHPTE_UPDATE;
1534
1535 if (dsisr & DSISR_ISSTORE)
1536 access |= _PAGE_WRITE;
1537 /*
1538 * We set _PAGE_PRIVILEGED only when
1539 * kernel mode access kernel space.
1540 *
1541 * _PAGE_PRIVILEGED is NOT set
1542 * 1) when kernel mode access user space
1543 * 2) user space access kernel space.
1544 */
1545 access |= _PAGE_PRIVILEGED;
1546 if (user_mode(regs) || (region_id == USER_REGION_ID))
1547 access &= ~_PAGE_PRIVILEGED;
1548
1549 if (regs->trap == 0x400)
1550 access |= _PAGE_EXEC;
1551
1552 err = hash_page_mm(mm, ea, access, regs->trap, flags);
1553 if (unlikely(err < 0)) {
1554 // failed to instert a hash PTE due to an hypervisor error
1555 if (user_mode(regs)) {
1556 if (IS_ENABLED(CONFIG_PPC_SUBPAGE_PROT) && err == -2)
1557 _exception(SIGSEGV, regs, SEGV_ACCERR, ea);
1558 else
1559 _exception(SIGBUS, regs, BUS_ADRERR, ea);
1560 } else {
1561 bad_page_fault(regs, SIGBUS);
1562 }
1563 err = 0;
1564 }
1565
1566 return err;
1567 }
1568
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 21496 bytes --]
^ permalink raw reply
* Re: [PATCH] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Ananth N Mavinakayanahalli @ 2021-01-20 10:40 UTC (permalink / raw)
To: Naveen N. Rao; +Cc: linuxppc-dev, ravi.bangoria, dja
In-Reply-To: <20210120101445.GA80@DESKTOP-TDPLP67.localdomain>
On 1/20/21 3:44 PM, Naveen N. Rao wrote:
> On 2021/01/20 03:16PM, Ananth N Mavinakayanahalli wrote:
...
>> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
>> index bf7a7d62ae8b..ed119858e5e9 100644
>> --- a/arch/powerpc/lib/sstep.c
>> +++ b/arch/powerpc/lib/sstep.c
>> @@ -1528,6 +1528,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
>> goto compute_done;
>>
>> case 19:
>> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
>> + return -1;
>> if (((word >> 1) & 0x1f) == 2) {
>> /* addpcis */
>> imm = (short) (word & 0xffc1); /* d0 + d2 fields */
>
> The cpu feature check should be within the if condition above since
> there are other instructions under opcode 19. This is not an issue right
> now as we don't emulate any of the others after this point, but it would
> be good to restrict the change to specific instructions.
>
> Rest of the changes below look good to me. The only other v3.0
> instruction we need to gate is the 'scv' instruction. It would be good
> to handle that too.
I missed this in v2.. will send a v3. There is a bigger change needed to
accommodate scv since we currently don't check for it in analyze_insn().
--
Ananth
^ permalink raw reply
* [PATCH] [PATCH V2] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Ananth N Mavinakayanahalli @ 2021-01-20 10:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: naveen.n.rao, ravi.bangoria, dja
We currently unconditionally try to emulate newer instructions on older
Power versions that could cause issues. Gate it.
Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
---
arch/powerpc/lib/sstep.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index bf7a7d62ae8b..ed119858e5e9 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1528,6 +1528,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
goto compute_done;
case 19:
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
if (((word >> 1) & 0x1f) == 2) {
/* addpcis */
imm = (short) (word & 0xffc1); /* d0 + d2 fields */
@@ -2439,6 +2441,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 268: /* lxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 16;
@@ -2448,6 +2452,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 269: /* lxvl */
case 301: { /* lxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2475,6 +2481,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 364: /* lxvwsx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 4;
@@ -2482,6 +2490,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 396: /* stxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 16;
@@ -2491,6 +2501,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 397: /* stxvl */
case 429: { /* stxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2542,6 +2554,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 781: /* lxsibzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 1);
op->element_size = 8;
@@ -2549,6 +2563,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 812: /* lxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 2;
@@ -2556,6 +2572,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 813: /* lxsihzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 2);
op->element_size = 8;
@@ -2569,6 +2587,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 876: /* lxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 1;
@@ -2582,6 +2602,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 909: /* stxsibx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 1);
op->element_size = 8;
@@ -2589,6 +2611,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 940: /* stxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 2;
@@ -2596,6 +2620,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 941: /* stxsihx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 2);
op->element_size = 8;
@@ -2609,6 +2635,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1004: /* stxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 1;
@@ -2717,12 +2745,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(LOAD_FP, 0, 16);
break;
case 2: /* lxsd */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 8);
op->element_size = 8;
op->vsx_flags = VSX_CHECK_VEC;
break;
case 3: /* lxssp */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 8;
@@ -2775,6 +2807,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1: /* lxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
@@ -2785,6 +2819,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 2: /* stxsd with LSB of DS field = 0 */
case 6: /* stxsd with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 8);
@@ -2794,6 +2830,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 3: /* stxssp with LSB of DS field = 0 */
case 7: /* stxssp with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 4);
@@ -2802,6 +2840,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 5: /* stxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
^ permalink raw reply related
* Re: [PATCH] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Naveen N. Rao @ 2021-01-20 10:14 UTC (permalink / raw)
To: Ananth N Mavinakayanahalli; +Cc: naveen.n.rao, linuxppc-dev, ravi.bangoria, dja
In-Reply-To: <161113596420.206556.5023431229030762544.stgit@thinktux.local>
On 2021/01/20 03:16PM, Ananth N Mavinakayanahalli wrote:
> We currently unconditionally try to newer emulate instructions on older
^^^^^ never?
Or: "emulate newer"?
> Power versions that could cause issues. Gate it.
>
> Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
> ---
> arch/powerpc/lib/sstep.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
Thanks!
>
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index bf7a7d62ae8b..ed119858e5e9 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1528,6 +1528,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
> goto compute_done;
>
> case 19:
> + if (!cpu_has_feature(CPU_FTR_ARCH_300))
> + return -1;
> if (((word >> 1) & 0x1f) == 2) {
> /* addpcis */
> imm = (short) (word & 0xffc1); /* d0 + d2 fields */
The cpu feature check should be within the if condition above since
there are other instructions under opcode 19. This is not an issue right
now as we don't emulate any of the others after this point, but it would
be good to restrict the change to specific instructions.
Rest of the changes below look good to me. The only other v3.0
instruction we need to gate is the 'scv' instruction. It would be good
to handle that too.
- Naveen
^ permalink raw reply
* [PATCH] [PATCH] powerpc/sstep: Check ISA 3.0 instruction validity before emulation
From: Ananth N Mavinakayanahalli @ 2021-01-20 9:46 UTC (permalink / raw)
To: linuxppc-dev; +Cc: naveen.n.rao, ravi.bangoria, dja
We currently unconditionally try to newer emulate instructions on older
Power versions that could cause issues. Gate it.
Signed-off-by: Ananth N Mavinakayanahalli <ananth@linux.ibm.com>
---
arch/powerpc/lib/sstep.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index bf7a7d62ae8b..ed119858e5e9 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1528,6 +1528,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
goto compute_done;
case 19:
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
if (((word >> 1) & 0x1f) == 2) {
/* addpcis */
imm = (short) (word & 0xffc1); /* d0 + d2 fields */
@@ -2439,6 +2441,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 268: /* lxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 16;
@@ -2448,6 +2452,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 269: /* lxvl */
case 301: { /* lxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2475,6 +2481,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 364: /* lxvwsx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 4;
@@ -2482,6 +2490,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 396: /* stxvx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 16;
@@ -2491,6 +2501,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 397: /* stxvl */
case 429: { /* stxvll */
int nb;
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->ea = ra ? regs->gpr[ra] : 0;
nb = regs->gpr[rb] & 0xff;
@@ -2542,6 +2554,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 781: /* lxsibzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 1);
op->element_size = 8;
@@ -2549,6 +2563,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 812: /* lxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 2;
@@ -2556,6 +2572,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 813: /* lxsihzx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 2);
op->element_size = 8;
@@ -2569,6 +2587,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 876: /* lxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(LOAD_VSX, 0, 16);
op->element_size = 1;
@@ -2582,6 +2602,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 909: /* stxsibx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 1);
op->element_size = 8;
@@ -2589,6 +2611,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 940: /* stxvh8x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 2;
@@ -2596,6 +2620,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 941: /* stxsihx */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 2);
op->element_size = 8;
@@ -2609,6 +2635,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1004: /* stxvb16x */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd | ((word & 1) << 5);
op->type = MKOP(STORE_VSX, 0, 16);
op->element_size = 1;
@@ -2717,12 +2745,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
op->type = MKOP(LOAD_FP, 0, 16);
break;
case 2: /* lxsd */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 8);
op->element_size = 8;
op->vsx_flags = VSX_CHECK_VEC;
break;
case 3: /* lxssp */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->reg = rd + 32;
op->type = MKOP(LOAD_VSX, 0, 4);
op->element_size = 8;
@@ -2775,6 +2807,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 1: /* lxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
@@ -2785,6 +2819,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 2: /* stxsd with LSB of DS field = 0 */
case 6: /* stxsd with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 8);
@@ -2794,6 +2830,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
case 3: /* stxssp with LSB of DS field = 0 */
case 7: /* stxssp with LSB of DS field = 1 */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dsform_ea(word, regs);
op->reg = rd + 32;
op->type = MKOP(STORE_VSX, 0, 4);
@@ -2802,6 +2840,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
break;
case 5: /* stxv */
+ if (!cpu_has_feature(CPU_FTR_ARCH_300))
+ return -1;
op->ea = dqform_ea(word, regs);
if (word & 8)
op->reg = rd + 32;
^ 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