diff --git a/valgrind-3.18.1-ppc-hwcaps.patch b/valgrind-3.18.1-ppc-hwcaps.patch
new file mode 100644
index 0000000..09b2714
--- /dev/null
+++ b/valgrind-3.18.1-ppc-hwcaps.patch
@@ -0,0 +1,136 @@
+commit 9d1d6cd6acc612cd94261956a8a94a6403a5d528
+Author: Will Schmidt <will_schmidt@vnet.ibm.com>
+Date:   Tue Jan 4 16:41:00 2022 -0600
+
+    Subject: Assorted changes to protect from side affects from the feature checking code.
+    
+    This problem was initially reported by Tulio, he assisted me in
+    identifying the underlying issue here.
+    
+    This was discovered on a Power10, and occurs since the ISA 3.1 support
+    check uses the brh instruction via a hardcoded ".long 0x7f1401b6" asm stanza.
+    That encoding writes to r20, and since the stanza does not contain a clobber
+    the compiler did not know to save or restore that register upon entry or exit.
+    The junk value remaining in r20 subsequently caused a segfault.
+    
+    This patch adds clobber masks to the instruction stanzas, as well as
+    updates the associated comments to clarify which registers are being
+    used.
+    As part of this change I've also
+    - updated the .long for the cnttzw instruction to write to r20, and
+      zeroed the reserved bits from that instruction so it is properly
+      decoded by the disassembler.
+    - updated the .long for the dadd instruction to write to f0.
+    
+    I've inspected the current codegen with these changes in place, and
+    confirm that r20 is now saved and restored on entry and exit from the
+    machine_get_hwcaps() function.
+
+diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
+index 0b60ecc0fd44..a860ed67a334 100644
+--- a/coregrind/m_machine.c
++++ b/coregrind/m_machine.c
+@@ -1244,11 +1244,11 @@ Bool VG_(machine_get_hwcaps)( void )
+      /* Check for ISA 3.0 support. */
+      have_isa_3_0 = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_isa_3_0 = False;
+      } else {
+-        __asm__ __volatile__(".long 0x7d205434"); /* cnttzw RT, RB */
++        __asm__ __volatile__(".long 00x7f140434"::"r20"); /* cnttzw r20,r24 */
+      }
+ 
+      // ISA 3.1 not supported on 32-bit systems
+ 
+      /* determine dcbz/dcbzl sizes while we still have the signal
+@@ -1356,79 +1356,79 @@ Bool VG_(machine_get_hwcaps)( void )
+      /* Altivec insns */
+      have_V = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_V = False;
+      } else {
+-        __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
++        __asm__ __volatile__(".long 0x10000484"); /* vor v0,v0,v0 */
+      }
+ 
+      /* General-Purpose optional (fsqrt, fsqrts) */
+      have_FX = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_FX = False;
+      } else {
+-        __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/
++        __asm__ __volatile__(".long 0xFC00002C"); /* fsqrt f0,f0 */
+      }
+ 
+      /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
+      have_GX = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_GX = False;
+      } else {
+-        __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/
++        __asm__ __volatile__(".long 0xFC000034"); /* frsqrte f0,f0 */
+      }
+ 
+      /* VSX support implies Power ISA 2.06 */
+      have_VX = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_VX = False;
+      } else {
+-        __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp XT,XB */
++        __asm__ __volatile__(".long 0xf0000564"); /* xsabsdp vs0,vs0 */
+      }
+ 
+      /* Check for Decimal Floating Point (DFP) support. */
+      have_DFP = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_DFP = False;
+      } else {
+-        __asm__ __volatile__(".long 0xee4e8005"); /* dadd  FRT,FRA, FRB */
++        __asm__ __volatile__(".long 0xec0e8005"); /* dadd f0,f14,f16 */
+      }
+ 
+      /* Check for ISA 2.07 support. */
+      have_isa_2_07 = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_isa_2_07 = False;
+      } else {
+-        __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd XT,RA */
++        __asm__ __volatile__(".long 0x7c000166"); /* mtvsrd f0,r0 */
+      }
+ 
+      /* Check for ISA 3.0 support. */
+      have_isa_3_0 = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_isa_3_0 = False;
+      } else {
+-        __asm__ __volatile__(".long  0x7d205434"); /* cnttzw RT, RB */
++        __asm__ __volatile__(".long 0x7f140434":::"r20"); /* cnttzw r20,r24 */
+      }
+ 
+      /* Check for ISA 3.1 support. */
+      have_isa_3_1 = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_isa_3_1 = False;
+      } else {
+-        __asm__ __volatile__(".long 0x7f1401b6"); /* brh  RA, RS */
++        __asm__ __volatile__(".long 0x7f1401b6":::"r20"); /* brh r20,r24 */
+      }
+ 
+      /* Check if Host supports scv instruction */
+      have_scv_support = True;
+      if (VG_MINIMAL_SETJMP(env_unsup_insn)) {
+         have_scv_support = False;
+      } else {
+         /* Set r0 to 13 for the system time call.  Don't want to make a random
+            system call.  */
+-        __asm__ __volatile__(".long 0x7c000278"); /* clear r0 */
+-        __asm__ __volatile__(".long 0x6009000d"); /* set r0 to 13 */
+-        __asm__ __volatile__(".long 0x44000001"); /* scv */
++        __asm__ __volatile__(".long 0x7c000278"); /* clear r0 with xor r0,r0,r0 */
++        __asm__ __volatile__(".long 0x6009000d"); /* set r0 to 13 with ori r9,r0,13 */
++        __asm__ __volatile__(".long 0x44000001"); /* scv 0 */
+      }
+ 
+      /* determine dcbz/dcbzl sizes while we still have the signal
+       * handlers registered */
+      find_ppc_dcbz_sz(&vai);
diff --git a/valgrind.spec b/valgrind.spec
index 204c8e2..d08ec17 100644
--- a/valgrind.spec
+++ b/valgrind.spec
@@ -134,6 +134,9 @@ Patch19: valgrind-3.18.1-rseq-enosys.patch
 # KDE#444481  gdb_server test failures on s390x
 Patch20: valgrind-3.18.1-s390x-vdso.patch
 
+# KDE#447995 Valgrind segfault on power10 due to hwcap checking code
+Patch21: valgrind-3.18.1-ppc-hwcaps.patch
+
 BuildRequires: make
 BuildRequires: glibc-devel
 
@@ -286,6 +289,7 @@ Valgrind User Manual for details.
 %patch18 -p1
 %patch19 -p1
 %patch20 -p1
+%patch21 -p1
 
 %build
 # LTO triggers undefined symbols in valgrind.  Valgrind has a --enable-lto
@@ -515,6 +519,9 @@ fi
 %endif
 
 %changelog
+* Wed Jan 12 2022 Mark Wielaard <mjw@fedoraproject.org>
+- Add valgrind-3.18.1-ppc-hwcaps.patch
+
 * Sat Dec 11 2021 Mark Wielaard <mjw@fedoraproject.org> - 3.18.1-7
 -Add valgrind-3.18.1-s390x-vdso.patch