diff --git a/valgrind-3.13.0-arm64-ptrace.patch b/valgrind-3.13.0-arm64-ptrace.patch
new file mode 100644
index 0000000..6ac1a44
--- /dev/null
+++ b/valgrind-3.13.0-arm64-ptrace.patch
@@ -0,0 +1,235 @@
+commit 122225d7ed260f6bd9de4472e5260ec768ce972d
+Author: Mark Wielaard <mark@klomp.org>
+Date:   Tue Jun 19 18:26:43 2018 +0200
+
+    Implement ptrace syscall wrapper for arm64-linux.
+    
+    With this valgrind is able to run gdb on arm64.
+    Also fixes the memcheck/tests/linux/getregset testcase.
+    
+    https://bugs.kde.org/show_bug.cgi?id=368913
+
+diff --git a/coregrind/m_syswrap/syswrap-arm64-linux.c b/coregrind/m_syswrap/syswrap-arm64-linux.c
+index 32b87bf..24a6493 100644
+--- a/coregrind/m_syswrap/syswrap-arm64-linux.c
++++ b/coregrind/m_syswrap/syswrap-arm64-linux.c
+@@ -265,7 +265,7 @@ DECL_TEMPLATE(arm64_linux, sys_rt_sigreturn);
+ //ZZ DECL_TEMPLATE(arm_linux, sys_sigsuspend);
+ //ZZ DECL_TEMPLATE(arm_linux, sys_set_tls);
+ //ZZ DECL_TEMPLATE(arm_linux, sys_cacheflush);
+-//ZZ DECL_TEMPLATE(arm_linux, sys_ptrace);
++DECL_TEMPLATE(arm64_linux, sys_ptrace);
+ 
+ //ZZ PRE(sys_mmap2)
+ //ZZ {
+@@ -459,137 +459,70 @@ PRE(sys_rt_sigreturn)
+ //ZZ                               "PRE(sys_cacheflush)" );
+ //ZZ    SET_STATUS_Success(0);
+ //ZZ }
+-//ZZ 
+-//ZZ // ARG3 is only used for pointers into the traced process's address
+-//ZZ // space and for offsets into the traced process's struct
+-//ZZ // user_regs_struct. It is never a pointer into this process's memory
+-//ZZ // space, and we should therefore not check anything it points to.
+-//ZZ PRE(sys_ptrace)
+-//ZZ {
+-//ZZ    PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
+-//ZZ    PRE_REG_READ4(int, "ptrace", 
+-//ZZ                  long, request, long, pid, long, addr, long, data);
+-//ZZ    switch (ARG1) {
+-//ZZ    case VKI_PTRACE_PEEKTEXT:
+-//ZZ    case VKI_PTRACE_PEEKDATA:
+-//ZZ    case VKI_PTRACE_PEEKUSR:
+-//ZZ       PRE_MEM_WRITE( "ptrace(peek)", ARG4, 
+-//ZZ 		     sizeof (long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getregs)", ARG4, 
+-//ZZ 		     sizeof (struct vki_user_regs_struct));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETFPREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getfpregs)", ARG4, 
+-//ZZ 		     sizeof (struct vki_user_fp));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETWMMXREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getwmmxregs)", ARG4, 
+-//ZZ 		     VKI_IWMMXT_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETCRUNCHREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getcrunchregs)", ARG4, 
+-//ZZ 		     VKI_CRUNCH_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETVFPREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getvfpregs)", ARG4, 
+-//ZZ                      sizeof (struct vki_user_vfp) );
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETHBPREGS:
+-//ZZ       PRE_MEM_WRITE( "ptrace(gethbpregs)", ARG4, 
+-//ZZ                      sizeof (unsigned long) );
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(setregs)", ARG4, 
+-//ZZ 		     sizeof (struct vki_user_regs_struct));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETFPREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(setfpregs)", ARG4, 
+-//ZZ 		     sizeof (struct vki_user_fp));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETWMMXREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(setwmmxregs)", ARG4, 
+-//ZZ 		     VKI_IWMMXT_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETCRUNCHREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(setcrunchregs)", ARG4, 
+-//ZZ 		     VKI_CRUNCH_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETVFPREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(setvfpregs)", ARG4, 
+-//ZZ                      sizeof (struct vki_user_vfp));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETHBPREGS:
+-//ZZ       PRE_MEM_READ( "ptrace(sethbpregs)", ARG4, sizeof(unsigned long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GET_THREAD_AREA:
+-//ZZ       PRE_MEM_WRITE( "ptrace(get_thread_area)", ARG4, sizeof(unsigned long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETEVENTMSG:
+-//ZZ       PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETSIGINFO:
+-//ZZ       PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETSIGINFO:
+-//ZZ       PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETREGSET:
+-//ZZ       ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_SETREGSET:
+-//ZZ       ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
+-//ZZ       break;
+-//ZZ    default:
+-//ZZ       break;
+-//ZZ    }
+-//ZZ }
+-//ZZ 
+-//ZZ POST(sys_ptrace)
+-//ZZ {
+-//ZZ    switch (ARG1) {
+-//ZZ    case VKI_PTRACE_PEEKTEXT:
+-//ZZ    case VKI_PTRACE_PEEKDATA:
+-//ZZ    case VKI_PTRACE_PEEKUSR:
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof (long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETREGS:
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_regs_struct));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETFPREGS:
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof (struct vki_user_fp));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETWMMXREGS:
+-//ZZ       POST_MEM_WRITE( ARG4, VKI_IWMMXT_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETCRUNCHREGS:
+-//ZZ       POST_MEM_WRITE( ARG4, VKI_CRUNCH_SIZE);
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETVFPREGS:
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof(struct vki_user_vfp));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GET_THREAD_AREA:
+-//ZZ    case VKI_PTRACE_GETHBPREGS:
+-//ZZ    case VKI_PTRACE_GETEVENTMSG:
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof(unsigned long));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETSIGINFO:
+-//ZZ       /* XXX: This is a simplification. Different parts of the
+-//ZZ        * siginfo_t are valid depending on the type of signal.
+-//ZZ        */
+-//ZZ       POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
+-//ZZ       break;
+-//ZZ    case VKI_PTRACE_GETREGSET:
+-//ZZ       ML_(linux_POST_getregset)(tid, ARG3, ARG4);
+-//ZZ       break;
+-//ZZ    default:
+-//ZZ       break;
+-//ZZ    }
+-//ZZ }
+-//ZZ 
+-//ZZ #undef PRE
+-//ZZ #undef POST
++
++// ARG3 is only used for pointers into the traced process's address
++// space and for offsets into the traced process's struct
++// user_regs_struct. It is never a pointer into this process's memory
++// space, and we should therefore not check anything it points to.
++PRE(sys_ptrace)
++{
++   PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4);
++   PRE_REG_READ4(int, "ptrace",
++                 long, request, long, pid, long, addr, long, data);
++   switch (ARG1) {
++   case VKI_PTRACE_PEEKTEXT:
++   case VKI_PTRACE_PEEKDATA:
++   case VKI_PTRACE_PEEKUSR:
++      PRE_MEM_WRITE( "ptrace(peek)", ARG4,
++		     sizeof (long));
++      break;
++   case VKI_PTRACE_GETEVENTMSG:
++      PRE_MEM_WRITE( "ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
++      break;
++   case VKI_PTRACE_GETSIGINFO:
++      PRE_MEM_WRITE( "ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
++      break;
++   case VKI_PTRACE_SETSIGINFO:
++      PRE_MEM_READ( "ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
++      break;
++   case VKI_PTRACE_GETREGSET:
++      ML_(linux_PRE_getregset)(tid, ARG3, ARG4);
++      break;
++   case VKI_PTRACE_SETREGSET:
++      ML_(linux_PRE_setregset)(tid, ARG3, ARG4);
++      break;
++   default:
++      break;
++   }
++}
++
++POST(sys_ptrace)
++{
++   switch (ARG1) {
++   case VKI_PTRACE_PEEKTEXT:
++   case VKI_PTRACE_PEEKDATA:
++   case VKI_PTRACE_PEEKUSR:
++      POST_MEM_WRITE( ARG4, sizeof (long));
++      break;
++   case VKI_PTRACE_GETEVENTMSG:
++      POST_MEM_WRITE( ARG4, sizeof(unsigned long));
++      break;
++   case VKI_PTRACE_GETSIGINFO:
++      /* XXX: This is a simplification. Different parts of the
++       * siginfo_t are valid depending on the type of signal.
++       */
++      POST_MEM_WRITE( ARG4, sizeof(vki_siginfo_t));
++      break;
++   case VKI_PTRACE_GETREGSET:
++      ML_(linux_POST_getregset)(tid, ARG3, ARG4);
++      break;
++   default:
++      break;
++   }
++}
++
++#undef PRE
++#undef POST
+ 
+ /* ---------------------------------------------------------------------
+    The arm64/Linux syscall table
+@@ -730,7 +663,7 @@ static SyscallTableEntry syscall_main_table[] = {
+    LINXY(__NR_clock_getres,      sys_clock_getres),      // 114
+    LINXY(__NR_clock_nanosleep,   sys_clock_nanosleep),   // 115
+    LINXY(__NR_syslog,            sys_syslog),            // 116
+-   //   (__NR_ptrace,            sys_ptrace),            // 117
++   PLAXY(__NR_ptrace,            sys_ptrace),            // 117
+    LINXY(__NR_sched_setparam,    sys_sched_setparam),    // 118
+    LINX_(__NR_sched_setscheduler,sys_sched_setscheduler),// 119
+    LINX_(__NR_sched_getscheduler,sys_sched_getscheduler),// 120
diff --git a/valgrind.spec b/valgrind.spec
index 28f9280..d2a3ce3 100644
--- a/valgrind.spec
+++ b/valgrind.spec
@@ -172,6 +172,9 @@ Patch20: valgrind-3.13.0-ppc64-mtfprwa-constraint.patch
 # KDE#393062 Reading build-id ELF note "debuginfo reader: ensure_valid failed"
 Patch21: valgrind-3.13.0-build-id-phdrs.patch
 
+# KDE#368913 WARNING: unhandled arm64-linux syscall: 117 (ptrace)
+Patch22: valgrind-3.13.0-arm64-ptrace.patch
+
 %if %{build_multilib}
 # Ensure glibc{,-devel} is installed for both multilib arches
 BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so
@@ -316,6 +319,7 @@ Valgrind User Manual for details.
 %patch19 -p1
 %patch20 -p1
 %patch21 -p1
+%patch22 -p1
 
 %build
 # We need to use the software collection compiler and binutils if available.
@@ -548,6 +552,7 @@ echo ===============END TESTING===============
 %changelog
 * Thu Apr 12 2018 Mark Wielaard <mjw@fedoraproject.org> - 3.13.0-19
 - Improved valgrind-3.13.0-arm64-hwcap.patch
+- Add valgrind-3.13.0-arm64-ptrace.patch
 
 * Thu Apr 12 2018 Mark Wielaard <mjw@fedoraproject.org> - 3.13.0-18
 - Add valgrind-3.13.0-build-id-phdrs.patch (#1566639)