[PATCH v3 3/3] KVM: PPC: Add KVM_CAP_PPC_AIL_MODE_3

2022-02-20 Thread Nicholas Piggin
Add KVM_CAP_PPC_AIL_MODE_3 to advertise the capability to set the AIL
resource mode to 3 with the H_SET_MODE hypercall. This capability
differs between processor types and KVM types (PR, HV, Nested HV), and
affects guest-visible behaviour.

QEMU will implement a cap-ail-mode-3 to control this behaviour[1], and
use the KVM CAP if available to determine KVM support[2].

[1] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00437.html
[2] https://lists.nongnu.org/archive/html/qemu-ppc/2022-02/msg00439.html

Signed-off-by: Nicholas Piggin 
---
 Documentation/virt/kvm/api.rst | 14 ++
 arch/powerpc/include/asm/setup.h   |  2 ++
 arch/powerpc/kvm/powerpc.c | 20 
 arch/powerpc/platforms/pseries/setup.c | 12 +++-
 include/uapi/linux/kvm.h   |  1 +
 tools/include/uapi/linux/kvm.h |  1 +
 6 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index bb8cfddbb22d..404056a9a35a 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6995,6 +6995,20 @@ indicated by the fd to the VM this is called on.
 This is intended to support intra-host migration of VMs between userspace VMMs,
 upgrading the VMM process without interrupting the guest.
 
+7.30 KVM_CAP_PPC_AIL_MODE_3
+---
+
+:Capability: KVM_CAP_PPC_AIL_MODE_3
+:Architectures: ppc
+:Type: vm
+
+This capability indicates that the kernel supports the mode 3 setting for the
+"Address Translation Mode on Interrupt" aka "Alternate Interrupt Location"
+resource that is controlled with the H_SET_MODE hypercall.
+
+This capability allows a guest kernel to use a better-performance mode for
+handling interrupts and system calls.
+
 8. Other capabilities.
 ==
 
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index d0d3dd531c7f..a555fb77258a 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -28,11 +28,13 @@ void setup_panic(void);
 #define ARCH_PANIC_TIMEOUT 180
 
 #ifdef CONFIG_PPC_PSERIES
+extern bool pseries_reloc_on_exception(void);
 extern bool pseries_enable_reloc_on_exc(void);
 extern void pseries_disable_reloc_on_exc(void);
 extern void pseries_big_endian_exceptions(void);
 void __init pseries_little_endian_exceptions(void);
 #else
+static inline bool pseries_reloc_on_exception(void) { return false; }
 static inline bool pseries_enable_reloc_on_exc(void) { return false; }
 static inline void pseries_disable_reloc_on_exc(void) {}
 static inline void pseries_big_endian_exceptions(void) {}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2ad0ccd202d5..7dc101ea778c 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -678,6 +678,26 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
 #endif
+   case KVM_CAP_PPC_AIL_MODE_3:
+   /*
+* KVM PR, POWER7, and some POWER9s don't support AIL=3 mode.
+* The POWER9s can support it if the guest runs in hash mode,
+* but QEMU doesn't necessarily query the capability in time.
+*/
+   if (hv_enabled) {
+   if (kvmhv_on_pseries()) {
+   if (pseries_reloc_on_exception())
+   r = 1;
+   } else if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
+ 
!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
+   r = 1;
+   } else {
+   r = 0;
+   }
+   } else {
+   r = 0;
+   }
+   break;
default:
r = 0;
break;
diff --git a/arch/powerpc/platforms/pseries/setup.c 
b/arch/powerpc/platforms/pseries/setup.c
index 83a04d967a59..182525c2abd5 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -353,6 +353,13 @@ static void pseries_lpar_idle(void)
pseries_idle_epilog();
 }
 
+static bool pseries_reloc_on_exception_enabled;
+
+bool pseries_reloc_on_exception(void)
+{
+   return pseries_reloc_on_exception_enabled;
+}
+
 /*
  * Enable relocation on during exceptions. This has partition wide scope and
  * may take a while to complete, if it takes longer than one second we will
@@ -377,6 +384,7 @@ bool pseries_enable_reloc_on_exc(void)
" on exceptions: %ld\n", rc);
return false;
}
+   pseries_reloc_on_exception_enabled = true;
return true;
}
 
@@ -404,7 +412,9 @@ void pseries_disable_reloc_on_exc(void)
break;

[PATCH v3 2/3] KVM: PPC: Book3S PR: Disallow AIL != 0

2022-02-20 Thread Nicholas Piggin
KVM PR does not implement address translation modes on interrupt, so it
must not allow H_SET_MODE to succeed. The behaviour change caused by
this mode is architected and not advisory (interrupts *must* behave
differently).

QEMU does not deal with differences in AIL support in the host. The
solution to that is a spapr capability and corresponding KVM CAP, but
this patch does not break things more than before (the host behaviour
already differs, this change just disallows some modes that are not
implemented properly).

By happy coincidence, this allows PR Linux guests that are using the SCV
facility to boot and run, because Linux disables the use of SCV if AIL
can not be set to 3. This does not fix the underlying problem of missing
SCV support (an OS could implement real-mode SCV vectors and try to
enable the facility). The true fix for that is for KVM PR to emulate scv
interrupts from the facility unavailable interrupt.

Reviewed-by: Fabiano Rosas 
Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kvm/book3s_pr_papr.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/powerpc/kvm/book3s_pr_papr.c 
b/arch/powerpc/kvm/book3s_pr_papr.c
index 1f10e7dfcdd0..dc4f51ac84bc 100644
--- a/arch/powerpc/kvm/book3s_pr_papr.c
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
@@ -281,6 +281,22 @@ static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu 
*vcpu)
return EMULATE_DONE;
 }
 
+static int kvmppc_h_pr_set_mode(struct kvm_vcpu *vcpu)
+{
+   unsigned long mflags = kvmppc_get_gpr(vcpu, 4);
+   unsigned long resource = kvmppc_get_gpr(vcpu, 5);
+
+   if (resource == H_SET_MODE_RESOURCE_ADDR_TRANS_MODE) {
+   /* KVM PR does not provide AIL!=0 to guests */
+   if (mflags == 0)
+   kvmppc_set_gpr(vcpu, 3, H_SUCCESS);
+   else
+   kvmppc_set_gpr(vcpu, 3, H_UNSUPPORTED_FLAG_START - 63);
+   return EMULATE_DONE;
+   }
+   return EMULATE_FAIL;
+}
+
 #ifdef CONFIG_SPAPR_TCE_IOMMU
 static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
 {
@@ -384,6 +400,8 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
return kvmppc_h_pr_logical_ci_load(vcpu);
case H_LOGICAL_CI_STORE:
return kvmppc_h_pr_logical_ci_store(vcpu);
+   case H_SET_MODE:
+   return kvmppc_h_pr_set_mode(vcpu);
case H_XIRR:
case H_CPPR:
case H_EOI:
@@ -421,6 +439,7 @@ int kvmppc_hcall_impl_pr(unsigned long cmd)
case H_CEDE:
case H_LOGICAL_CI_LOAD:
case H_LOGICAL_CI_STORE:
+   case H_SET_MODE:
 #ifdef CONFIG_KVM_XICS
case H_XIRR:
case H_CPPR:
@@ -447,6 +466,7 @@ static unsigned int default_hcall_list[] = {
H_BULK_REMOVE,
H_PUT_TCE,
H_CEDE,
+   H_SET_MODE,
 #ifdef CONFIG_KVM_XICS
H_XIRR,
H_CPPR,
-- 
2.23.0



[PATCH v3 1/3] KVM: PPC: Book3S PR: Disable SCV when AIL could be disabled

2022-02-20 Thread Nicholas Piggin
PR KVM does not support running with AIL enabled, and SCV does is not
supported with AIL disabled. Fix this by ensuring the SCV facility is
disabled with FSCR while a CPU could be running with AIL=0.

The PowerNV host supports disabling AIL on a per-CPU basis, so SCV just
needs to be disabled when a vCPU is being run.

The pSeries machine can only switch AIL on a system-wide basis, so it
must disable SCV support at boot if the configuration can potentially
run a PR KVM guest.

Also ensure a the FSCR[SCV] bit can not be enabled when emulating
mtFSCR for the guest.

SCV is not emulated for the PR guest at the moment, this just fixes the
host crashes.

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.
- System call instruction emulation for SCV facility unavailable
  instructions is too complex and old emulation code was subtly broken
  and removed.

Reviewed-by: Fabiano Rosas 
Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/kernel/exceptions-64s.S |  4 
 arch/powerpc/kernel/setup_64.c   | 28 
 arch/powerpc/kvm/Kconfig |  9 +
 arch/powerpc/kvm/book3s_pr.c | 26 +-
 4 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 55caeee37c08..b66dd6f775a4 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -809,6 +809,10 @@ __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 KVM
+ * ensures that FSCR[SCV] is disabled whenever it has to force AIL off.
+ *
  * Call convention:
  *
  * syscall register convention is in Documentation/powerpc/syscall64-abi.rst
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index be8577ac9397..d973ae7558e3 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -197,6 +197,34 @@ static void __init configure_exceptions(void)
 
/* Under a PAPR hypervisor, we need hypercalls */
if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
+   /*
+* - PR KVM does not support AIL mode interrupts in the host
+*   while a PR guest is running.
+*
+* - SCV system call interrupt vectors are only implemented for
+*   AIL mode interrupts.
+*
+* - On pseries, AIL mode can only be enabled and disabled
+*   system-wide so when a PR VM is created on a pseries host,
+*   all CPUs of the host are set to AIL=0 mode.
+*
+* - Therefore host CPUs must not execute scv while a PR VM
+*   exists.
+*
+* - SCV support can not be disabled dynamically because the
+*   feature is advertised to host userspace. Disabling the
+*   facility and emulating it would be possible but is not
+*   implemented.
+*
+* - So SCV support is blanket disabled if PR KVM could possibly
+*   run. That is, PR support compiled in, booting on pseries
+*   with hash MMU.
+*/
+   if (IS_ENABLED(CONFIG_KVM_BOOK3S_PR_POSSIBLE) && 
!radix_enabled()) {
+   init_task.thread.fscr &= ~FSCR_SCV;
+   cur_cpu_spec->cpu_user_features2 &= ~PPC_FEATURE2_SCV;
+   }
+
/* Enable AIL if possible */
if (!pseries_enable_reloc_on_exc()) {
init_task.thread.fscr &= ~FSCR_SCV;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 18e58085447c..ddd88179110a 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -112,12 +112,21 @@ config KVM_BOOK3S_64_PR
  guest in user mode (problem state) and emulating all
  privileged instructions and registers.
 
+ This is only available for hash MMU mode and only supports
+ guests that use hash MMU mode.
+
  This is not as fast as using hypervisor mode, but works on
  machines where hypervisor mode is not available or not usable,
  and can emulate processors 

[PATCH v3 0/3] KVM: PPC: Book3S PR: Fixes for AIL and SCV

2022-02-20 Thread Nicholas Piggin
The first patch in this series fixes a KVM PR host crash due to a
guest executing the scv instruction or with a pseries SMP host, the
host CPUs executing the scv instruction while a PR guest is running.

The second patch fixes unimplemented H_SET_MODE AIL modes by returning
failure from the hcall rather than succeeding but not implementing
the required behaviour. This works around missing host scv support for
scv-capable Linux guests by causing them to disable the facility.

The third patch adds a new KVM CAP to go with some QEMU work to get
the AIL differences properly represented in QEMU. The third patch will
need to allocate a KVM CAP number and merged with upstream KVM tree
before the QEMU side goes ahead.

Changes since v2:
- Fix fscr compile error in patch 1.
- Add patch 3.

Thanks,
Nick

Nicholas Piggin (3):
  KVM: PPC: Book3S PR: Disable SCV when AIL could be disabled
  KVM: PPC: Book3S PR: Disallow AIL != 0
  KVM: PPC: Add KVM_CAP_PPC_AIL_MODE_3

 Documentation/virt/kvm/api.rst | 14 +
 arch/powerpc/include/asm/setup.h   |  2 ++
 arch/powerpc/kernel/exceptions-64s.S   |  4 
 arch/powerpc/kernel/setup_64.c | 28 ++
 arch/powerpc/kvm/Kconfig   |  9 +
 arch/powerpc/kvm/book3s_pr.c   | 26 +++-
 arch/powerpc/kvm/book3s_pr_papr.c  | 20 ++
 arch/powerpc/kvm/powerpc.c | 20 ++
 arch/powerpc/platforms/pseries/setup.c | 12 ++-
 include/uapi/linux/kvm.h   |  1 +
 tools/include/uapi/linux/kvm.h |  1 +
 11 files changed, 127 insertions(+), 10 deletions(-)

-- 
2.23.0



[Bug 215621] Warning: Unable to mark rodata read only on this CPU. (PPC970MP)

2022-02-20 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215621

--- Comment #4 from Christophe Leroy (christophe.le...@csgroup.eu) ---
It is up to you to unselect CONFIG_STRICT_KERNEL_RWX.

The kernel is usually built to boot on any PPC64 processors, so we can't forbid
the selection of CONFIG_STRICT_KERNEL_RWX.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[PATCH V2 04/30] powerpc/mm: Enable ARCH_HAS_VM_GET_PAGE_PROT

2022-02-20 Thread Anshuman Khandual
This defines and exports a platform specific custom vm_get_page_prot() via
subscribing ARCH_HAS_VM_GET_PAGE_PROT. Subsequently all __SXXX and __PXXX
macros can be dropped which are no longer needed. While here, this also
localizes arch_vm_get_page_prot() as powerpc_vm_get_page_prot() and moves
it near vm_get_page_prot().

Cc: Michael Ellerman 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-ker...@vger.kernel.org
Signed-off-by: Anshuman Khandual 
---
 arch/powerpc/Kconfig   |  1 +
 arch/powerpc/include/asm/mman.h| 12 --
 arch/powerpc/include/asm/pgtable.h | 19 --
 arch/powerpc/mm/mmap.c | 59 ++
 4 files changed, 60 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b779603978e1..ddb4a3687c05 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,7 @@ config PPC
select ARCH_HAS_TICK_BROADCAST  if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE
select ARCH_HAS_UBSAN_SANITIZE_ALL
+   select ARCH_HAS_VM_GET_PAGE_PROT
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_KEEP_MEMBLOCK
select ARCH_MIGHT_HAVE_PC_PARPORT
diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h
index 7cb6d18f5cd6..1b024e64c8ec 100644
--- a/arch/powerpc/include/asm/mman.h
+++ b/arch/powerpc/include/asm/mman.h
@@ -24,18 +24,6 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned 
long prot,
 }
 #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
 
-static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
-{
-#ifdef CONFIG_PPC_MEM_KEYS
-   return (vm_flags & VM_SAO) ?
-   __pgprot(_PAGE_SAO | vmflag_to_pte_pkey_bits(vm_flags)) :
-   __pgprot(0 | vmflag_to_pte_pkey_bits(vm_flags));
-#else
-   return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
-#endif
-}
-#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags)
-
 static inline bool arch_validate_prot(unsigned long prot, unsigned long addr)
 {
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_SAO))
diff --git a/arch/powerpc/include/asm/pgtable.h 
b/arch/powerpc/include/asm/pgtable.h
index d564d0ecd4cd..3cbb6de20f9d 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -20,25 +20,6 @@ struct mm_struct;
 #include 
 #endif /* !CONFIG_PPC_BOOK3S */
 
-/* Note due to the way vm flags are laid out, the bits are XWR */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
 #ifndef __ASSEMBLY__
 
 #ifndef MAX_PTRS_PER_PGD
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index c475cf810aa8..ee275937fe19 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -254,3 +254,62 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct 
rlimit *rlim_stack)
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
}
 }
+
+static inline pgprot_t __vm_get_page_prot(unsigned long vm_flags)
+{
+   switch (vm_flags & (VM_READ | VM_WRITE | VM_EXEC | VM_SHARED)) {
+   case VM_NONE:
+   return PAGE_NONE;
+   case VM_READ:
+   return PAGE_READONLY;
+   case VM_WRITE:
+   case VM_WRITE | VM_READ:
+   return PAGE_COPY;
+   case VM_EXEC:
+   case VM_EXEC | VM_READ:
+   return PAGE_READONLY_X;
+   case VM_EXEC | VM_WRITE:
+   case VM_EXEC | VM_WRITE | VM_READ:
+   return PAGE_COPY_X;
+   case VM_SHARED:
+   return PAGE_NONE;
+   case VM_SHARED | VM_READ:
+   return PAGE_READONLY;
+   case VM_SHARED | VM_WRITE:
+   case VM_SHARED | VM_WRITE | VM_READ:
+   return PAGE_SHARED;
+   case VM_SHARED | VM_EXEC:
+   case VM_SHARED | VM_EXEC | VM_READ:
+   return PAGE_READONLY_X;
+   case VM_SHARED | VM_EXEC | VM_WRITE:
+   case VM_SHARED | VM_EXEC | VM_WRITE | VM_READ:
+   return PAGE_SHARED_X;
+   default:
+   BUILD_BUG();
+   }
+}
+
+#ifdef CONFIG_PPC64
+static pgprot_t powerpc_vm_get_page_prot(unsigned long vm_flags)
+{
+#ifdef CONFIG_PPC_MEM_KEYS
+   return (vm_flags & VM_SAO) ?
+   __pgprot(_PAGE_SAO | vmflag_to_pte_pkey_bits(vm_flags)) :
+   __pgprot(0 | vmflag_to_pte_pkey_bits(vm_flags));
+#else
+   return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
+#endif
+}
+#else
+static pgprot_t 

Re: [PATCH] platforms/83xx: Use of_device_get_match_data()

2022-02-20 Thread Christophe Leroy


Le 21/02/2022 à 03:03, cgel@gmail.com a écrit :
> From: Minghao Chi (CGEL ZTE) 
> 
> Use of_device_get_match_data() to simplify the code.
> 
> Reported-by: Zeal Robot 
> Signed-off-by: Minghao Chi (CGEL ZTE) 
> ---
>   arch/powerpc/platforms/83xx/suspend.c | 7 +--
>   1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/83xx/suspend.c 
> b/arch/powerpc/platforms/83xx/suspend.c
> index bb147d34d4a6..9ae9268b683c 100644
> --- a/arch/powerpc/platforms/83xx/suspend.c
> +++ b/arch/powerpc/platforms/83xx/suspend.c
> @@ -322,17 +322,12 @@ static const struct platform_suspend_ops 
> mpc83xx_suspend_ops = {
>   static const struct of_device_id pmc_match[];
>   static int pmc_probe(struct platform_device *ofdev)
>   {
> - const struct of_device_id *match;
>   struct device_node *np = ofdev->dev.of_node;
>   struct resource res;
>   const struct pmc_type *type;
>   int ret = 0;
>   
> - match = of_match_device(pmc_match, >dev);
> - if (!match)
> - return -EINVAL;
> -
> - type = match->data;
> + type = of_device_get_match_data(>dev);

What happens when of_device_get_match_data() returns NULL ?

>   
>   if (!of_device_is_available(np))
>   return -ENODEV;

[PATCH] platforms/83xx: Use of_device_get_match_data()

2022-02-20 Thread cgel . zte
From: Minghao Chi (CGEL ZTE) 

Use of_device_get_match_data() to simplify the code.

Reported-by: Zeal Robot 
Signed-off-by: Minghao Chi (CGEL ZTE) 
---
 arch/powerpc/platforms/83xx/suspend.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/powerpc/platforms/83xx/suspend.c 
b/arch/powerpc/platforms/83xx/suspend.c
index bb147d34d4a6..9ae9268b683c 100644
--- a/arch/powerpc/platforms/83xx/suspend.c
+++ b/arch/powerpc/platforms/83xx/suspend.c
@@ -322,17 +322,12 @@ static const struct platform_suspend_ops 
mpc83xx_suspend_ops = {
 static const struct of_device_id pmc_match[];
 static int pmc_probe(struct platform_device *ofdev)
 {
-   const struct of_device_id *match;
struct device_node *np = ofdev->dev.of_node;
struct resource res;
const struct pmc_type *type;
int ret = 0;
 
-   match = of_match_device(pmc_match, >dev);
-   if (!match)
-   return -EINVAL;
-
-   type = match->data;
+   type = of_device_get_match_data(>dev);
 
if (!of_device_is_available(np))
return -ENODEV;
-- 
2.25.1



Re: [PATCH 3/3] kprobes: Allow probing on any address belonging to ftrace

2022-02-20 Thread Masami Hiramatsu
On Thu, 17 Feb 2022 17:06:25 +0530
"Naveen N. Rao"  wrote:

> On certain architectures, ftrace can reserve multiple instructions at
> function entry. Rather than rejecting kprobe on addresses other than the
> exact ftrace call instruction, use the address returned by ftrace to
> probe at the correct address when CONFIG_KPROBES_ON_FTRACE is enabled.
> 
> Signed-off-by: Naveen N. Rao 
> ---
>  kernel/kprobes.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 94cab8c9ce56cc..0a797ede3fdf37 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1497,6 +1497,10 @@ bool within_kprobe_blacklist(unsigned long addr)
>  static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
>   const char *symbol_name, unsigned int offset)
>  {
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> + unsigned long ftrace_addr = 0;
> +#endif
> +
>   if ((symbol_name && addr) || (!symbol_name && !addr))
>   goto invalid;
>  
> @@ -1507,6 +1511,14 @@ static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t 
> *addr,
>   }
>  
>   addr = (kprobe_opcode_t *)(((char *)addr) + offset);
> +
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> + if (addr)
> + ftrace_addr = ftrace_location((unsigned long)addr);
> + if (ftrace_addr)
> + return (kprobe_opcode_t *)ftrace_addr;

As I said, this must be

if (ftrace_addr != addr)
return -EILSEQ;

This will prevent users from being confused by the results of probing
that 'func' and 'func+4' are the same. (now only 'func' is allowed to
be probed.)

Thank you,

> +#endif
> +
>   if (addr)
>   return addr;
>  
> -- 
> 2.35.1
> 


-- 
Masami Hiramatsu 


Re: [PATCH 1/3] powerpc/ftrace: Reserve instructions from function entry for ftrace

2022-02-20 Thread Masami Hiramatsu
Hi Naveen,

On Thu, 17 Feb 2022 17:06:23 +0530
"Naveen N. Rao"  wrote:

> On some architectures, enabling function tracing results in multiple
> instructions being emitted at function entry. As an example, on
> powerpc64 with -mprofile-kernel, two instructions are emitted at
> function entry:
>   mflrr0
>   bl  _mcount
> 
> It is desirable to nop out both these instructions when ftrace is not
> active. For that purpose, it is essential to mark both these
> instructions as belonging to ftrace so that other kernel subsystems
> (such as kprobes) do not modify these instructions.

Indeed, kprobes must handle this. However, to keep consistency of kprobes
usage with/without CONFIG_FUNCTION_TRACER, I think KPROBES_ON_FTRACE should
handle these instructions are virutal single instruction.
More specifically, it should allow user to put a kprobe on 'mflr r0' address
and the kprobes on 'bl _mcount' should return -EILSEQ. (because it is not an 
instruction boundary.) And the kprobe's ftrace handler temporarily modifies
the instruction pointer to the address of 'mflr'.

Thank you,

> 
> Add support for this by allowing architectures to override
> ftrace_cmp_recs() and to match against address ranges over and above a
> single MCOUNT_INSN_SIZE.
> 
> For powerpc32, we mark the two instructions preceding the call to
> _mcount() as belonging to ftrace.
> 
> For powerpc64, an additional aspect to consider is that functions can
> have a global entry point for setting up the TOC when invoked from other
> modules. If present, global entry point always involves two instructions
> (addis/lis and addi). To handle this, we provide a custom
> ftrace_init_nop() for powerpc64 where we identify functions having a
> global entry point and record this information in the LSB of
> dyn_ftrace->arch.mod. This information is used in ftrace_cmp_recs() to
> reserve instructions from the global entry point.
> 
> Suggested-by: Steven Rostedt 
> Signed-off-by: Naveen N. Rao 
> ---
>  arch/powerpc/include/asm/ftrace.h  |  15 
>  arch/powerpc/kernel/trace/ftrace.c | 110 ++---
>  kernel/trace/ftrace.c  |   2 +
>  3 files changed, 117 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/ftrace.h 
> b/arch/powerpc/include/asm/ftrace.h
> index debe8c4f706260..8eb3235831633d 100644
> --- a/arch/powerpc/include/asm/ftrace.h
> +++ b/arch/powerpc/include/asm/ftrace.h
> @@ -59,6 +59,21 @@ static inline unsigned long ftrace_call_adjust(unsigned 
> long addr)
>  struct dyn_arch_ftrace {
>   struct module *mod;
>  };
> +
> +struct dyn_ftrace;
> +struct module *ftrace_mod_addr_get(struct dyn_ftrace *rec);
> +void ftrace_mod_addr_set(struct dyn_ftrace *rec, struct module *mod);
> +
> +#ifdef CONFIG_MPROFILE_KERNEL
> +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
> +#define ftrace_init_nop ftrace_init_nop
> +#endif
> +
> +#if defined(CONFIG_MPROFILE_KERNEL) || defined(CONFIG_PPC32)
> +int ftrace_cmp_recs(const void *a, const void *b);
> +#define ftrace_cmp_recs ftrace_cmp_recs
> +#endif
> +
>  #endif /* __ASSEMBLY__ */
>  
>  #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
> diff --git a/arch/powerpc/kernel/trace/ftrace.c 
> b/arch/powerpc/kernel/trace/ftrace.c
> index 80b6285769f27c..11ce9296ce3cf2 100644
> --- a/arch/powerpc/kernel/trace/ftrace.c
> +++ b/arch/powerpc/kernel/trace/ftrace.c
> @@ -428,21 +428,21 @@ int ftrace_make_nop(struct module *mod,
>* We should either already have a pointer to the module
>* or it has been passed in.
>*/
> - if (!rec->arch.mod) {
> + if (!ftrace_mod_addr_get(rec)) {
>   if (!mod) {
>   pr_err("No module loaded addr=%lx\n", addr);
>   return -EFAULT;
>   }
> - rec->arch.mod = mod;
> + ftrace_mod_addr_set(rec, mod);
>   } else if (mod) {
> - if (mod != rec->arch.mod) {
> + if (mod != ftrace_mod_addr_get(rec)) {
>   pr_err("Record mod %p not equal to passed in mod %p\n",
> -rec->arch.mod, mod);
> +ftrace_mod_addr_get(rec), mod);
>   return -EINVAL;
>   }
>   /* nothing to do if mod == rec->arch.mod */
>   } else
> - mod = rec->arch.mod;
> + mod = ftrace_mod_addr_get(rec);
>  
>   return __ftrace_make_nop(mod, rec, addr);
>  #else
> @@ -451,6 +451,96 @@ int ftrace_make_nop(struct module *mod,
>  #endif /* CONFIG_MODULES */
>  }
>  
> +#define FUNC_MCOUNT_OFFSET_PPC32 8
> +#define FUNC_MCOUNT_OFFSET_PPC64_LEP 4
> +#define FUNC_MCOUNT_OFFSET_PPC64_GEP 12
> +
> +#ifdef CONFIG_MPROFILE_KERNEL
> +struct module *ftrace_mod_addr_get(struct dyn_ftrace *rec)
> +{
> + return (struct module *)((unsigned long)rec->arch.mod & ~0x1);
> +}
> +
> +void ftrace_mod_addr_set(struct dyn_ftrace *rec, struct module *mod)
> +{
> + rec->arch.mod = (struct 

[Bug 215621] Warning: Unable to mark rodata read only on this CPU. (PPC970MP)

2022-02-20 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215621

Erhard F. (erhar...@mailbox.org) changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--- Comment #3 from Erhard F. (erhar...@mailbox.org) ---
Erm ok, so it seems I did not check this thoroughly...

If MMU_FTRS_PPC970 doesn't provide MMU_FTR_KERNEL_RO then perhaps
CONFIG_STRICT_KERNEL_RWX can be skipped in the .config so it can't be wrongly
selected?

Anyhow you are correct that this is not a bug. Thanks for the background!

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 215621] Warning: Unable to mark rodata read only on this CPU. (PPC970MP)

2022-02-20 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=215621

Christophe Leroy (christophe.le...@csgroup.eu) changed:

   What|Removed |Added

 CC||christophe.le...@csgroup.eu

--- Comment #2 from Christophe Leroy (christophe.le...@csgroup.eu) ---
Look at
https://elixir.bootlin.com/linux/v5.17-rc4/source/arch/powerpc/kernel/cputable.c#L196
at you'll see that your processor has .mmu_features = MMU_FTRS_PPC970

Then you see at
https://elixir.bootlin.com/linux/v5.17-rc4/source/arch/powerpc/include/asm/mmu.h#L135
that MMU_FTRS_PPC970 doesn't include MMU_FTR_KERNEL_RO.

MMU_FTR_KERNEL_RO is in POWER6.

In commit 984d7a1ec67c ("powerpc/mm: Fixup kernel read only mapping") you see
that this feature appears in ISA 2.04.

Previous version of ISA only has PP bits which only provides RW for kernel
pages.

So this bug is not a bug, it's a limitation of PPC970MP, and the warning in
dmesg is there to warn you that allthough you have select
CONFIG_STRICT_KERNEL_RWX, this CPU doesn't support it.

And for the same reason, CONFIG_STRICT_MODULE_RWX doesn't work either.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [BUG] mtd: cfi_cmdset_0002: write regression since v4.17-rc1

2022-02-20 Thread Tokunori Ikegami

Hi Ahmad-san,

Could you please try the version 2 patch attached for the error case?
This version is to check the DQ true data 0xFF by chip_good().
But I am not sure if this works or not since the error is possible to be 
caused by Hi-Z 0xff on floating bus or etc.


On 2022/02/15 3:46, Tokunori Ikegami wrote:

Hi Ahmad-san,

On 2022/02/15 1:22, Ahmad Fatoum wrote:

Hello Tokunori-san,

On 13.02.22 17:47, Tokunori Ikegami wrote:

Hi Ahmad-san,

Thanks for your confirmations. Sorry for late to reply.

No worries. I appreciate you taking the time.

Could you please try the patch attached to disable the chip_good() 
change as before?
I think this should work for S29GL964N since the chip_ready() is 
used and works as mentioned.

yes, this resolves my issue:
Tested-by: Ahmad Fatoum 

Thanks for your testing. I have just sent the patch to review.



Doesn't seem to be a buffered write issue here though as the writes
did work fine before dfeae1073583. Any other ideas?
At first I thought the issue is possible to be resolved by using 
the word write instead of the buffered writes.
Now I am thinking to disable the changes dfeae1073583 partially 
with any condition if possible.

What seems to work for me is checking if chip_good or chip_ready
and map_word is equal to 0xFF. I can't justify why this is ok though.
(Worst case bus is floating at this point of time and Hi-Z is read
as 0xff on CPU data lines...)

Sorry I am not sure about this.
I thought the chip_ready() itself is correct as implemented as the 
data sheet in the past.
But it did not work correctly so changed to use chip_good() instead 
as it is also correct.
What exactly in the datasheet makes you believe chip_good is not 
appropriate?
I just mentioned about the actual issue behaviors as not worked 
chip_good() on S29GL964N and not worked chip_ready() on 
MX29GL512FHT2I-11G before etc.
Anyway let me recheck the data sheet details as just checked it again 
quickly but needed more investigation to understand.


As far as I checked still both chip_good() and chip_ready() seem correct 
but still the root cause is unknown.
If as you mentioned the issue was cased by the DQ true data 0xFF I am 
not sure why the read work without any error after the write operation.
Also if the error was caused by the Hi-Z 0xff on floating bus as 
mentioned I am not sure why the read work without any error after the 
write operation with chip_ready().
Sorry anyway the root cause is also unknown when the write operation was 
changed to use chip_good() instead of chip_ready().


Regards,
Ikegami



Regards,
Ikegami



Cheers,
Ahmad

From 2bef02bee8fa74273cfc764e288b6f92b8646bb7 Mon Sep 17 00:00:00 2001
From: Tokunori Ikegami 
Date: Sat, 19 Feb 2022 19:39:32 +0900
Subject: [PATCH v2] mtd: cfi_cmdset_0002: Change chip_good() to check DQ true
 data 0xFF

The regression issue has been caused on S29GL064N and reported it.
The change mentioned for regression is to use chip_good() for buffered write.
Also it seems that the 0xFF value is read on the error case.
It is possible to be caused by DQ true data described by S29GL064N datasheet.
So change chip_good() to check DQ true data 0xFF additionally for the error.

Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value")
Signed-off-by: Tokunori Ikegami 
Cc: linux-...@lists.infradead.org
Cc: sta...@vger.kernel.org
Link: https://lore.kernel.org/linux-mtd/cedb1604-e024-2738-5b33-15703a653...@gmail.com/
---
 drivers/mtd/chips/cfi_cmdset_0002.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a761134fd3be..079f69e5400d 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -853,7 +853,7 @@ static int __xipram chip_ready(struct map_info *map, struct flchip *chip,
  *
  */
 static int __xipram chip_good(struct map_info *map, struct flchip *chip,
-			  unsigned long addr, map_word expected)
+			  unsigned long addr, map_word *expected)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	map_word oldd, curd;
@@ -875,8 +875,13 @@ static int __xipram chip_good(struct map_info *map, struct flchip *chip,
 	oldd = map_read(map, addr);
 	curd = map_read(map, addr);
 
-	return	map_word_equal(map, oldd, curd) &&
-		map_word_equal(map, curd, expected);
+	if (!map_word_equal(map, oldd, curd))
+		return 0;
+
+	if (expected && map_word_equal(map, curd, *expected))
+		return 1;
+
+	return map_word_equal(map, oldd, map_word_ff(map));
 }
 
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
@@ -1699,7 +1704,7 @@ static int __xipram do_write_oneword_once(struct map_info *map,
 		 * "chip_good" to avoid the failure due to scheduling.
 		 */
 		if (time_after(jiffies, timeo) &&
-		!chip_good(map, chip, adr, datum)) {
+		!chip_good(map, chip, adr, )) {
 			xip_enable(map, chip, adr);
 			printk(KERN_WARNING "MTD %s():