select HAVE_PERF_USER_STACK_DUMP
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RSEQ
+       select HAVE_SAMPLE_FTRACE_DIRECT
+       select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
        select HAVE_SETUP_PER_CPU_AREA if NUMA
        select HAVE_STACKPROTECTOR
        select HAVE_SYSCALL_TRACEPOINTS
 
 
 #endif /* CONFIG_S390 */
 
+#ifdef CONFIG_LOONGARCH
+
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp1, @function\n"
+"      .globl          my_tramp1\n"
+"   my_tramp1:\n"
+"      addi.d  $sp, $sp, -16\n"
+"      st.d    $t0, $sp, 0\n"
+"      st.d    $ra, $sp, 8\n"
+"      bl      my_direct_func1\n"
+"      ld.d    $t0, $sp, 0\n"
+"      ld.d    $ra, $sp, 8\n"
+"      addi.d  $sp, $sp, 16\n"
+"      jr      $t0\n"
+"      .size           my_tramp1, .-my_tramp1\n"
+
+"      .type           my_tramp2, @function\n"
+"      .globl          my_tramp2\n"
+"   my_tramp2:\n"
+"      addi.d  $sp, $sp, -16\n"
+"      st.d    $t0, $sp, 0\n"
+"      st.d    $ra, $sp, 8\n"
+"      bl      my_direct_func2\n"
+"      ld.d    $t0, $sp, 0\n"
+"      ld.d    $ra, $sp, 8\n"
+"      addi.d  $sp, $sp, 16\n"
+"      jr      $t0\n"
+"      .size           my_tramp2, .-my_tramp2\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_LOONGARCH */
+
 static unsigned long my_tramp = (unsigned long)my_tramp1;
 static unsigned long tramps[2] = {
        (unsigned long)my_tramp1,
 
 
 #endif /* CONFIG_S390 */
 
+#ifdef CONFIG_LOONGARCH
+#include <asm/asm.h>
+
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp1, @function\n"
+"      .globl          my_tramp1\n"
+"   my_tramp1:\n"
+"      addi.d  $sp, $sp, -32\n"
+"      st.d    $a0, $sp, 0\n"
+"      st.d    $t0, $sp, 8\n"
+"      st.d    $ra, $sp, 16\n"
+"      move    $a0, $t0\n"
+"      bl      my_direct_func1\n"
+"      ld.d    $a0, $sp, 0\n"
+"      ld.d    $t0, $sp, 8\n"
+"      ld.d    $ra, $sp, 16\n"
+"      addi.d  $sp, $sp, 32\n"
+"      jr      $t0\n"
+"      .size           my_tramp1, .-my_tramp1\n"
+
+"      .type           my_tramp2, @function\n"
+"      .globl          my_tramp2\n"
+"   my_tramp2:\n"
+"      addi.d  $sp, $sp, -32\n"
+"      st.d    $a0, $sp, 0\n"
+"      st.d    $t0, $sp, 8\n"
+"      st.d    $ra, $sp, 16\n"
+"      move    $a0, $t0\n"
+"      bl      my_direct_func2\n"
+"      ld.d    $a0, $sp, 0\n"
+"      ld.d    $t0, $sp, 8\n"
+"      ld.d    $ra, $sp, 16\n"
+"      addi.d  $sp, $sp, 32\n"
+"      jr      $t0\n"
+"      .size           my_tramp2, .-my_tramp2\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_LOONGARCH */
+
 static unsigned long my_tramp = (unsigned long)my_tramp1;
 static unsigned long tramps[2] = {
        (unsigned long)my_tramp1,
 
 
 #endif /* CONFIG_S390 */
 
+#ifdef CONFIG_LOONGARCH
+
+#include <asm/asm.h>
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp, @function\n"
+"      .globl          my_tramp\n"
+"   my_tramp:\n"
+"      addi.d  $sp, $sp, -32\n"
+"      st.d    $a0, $sp, 0\n"
+"      st.d    $t0, $sp, 8\n"
+"      st.d    $ra, $sp, 16\n"
+"      move    $a0, $t0\n"
+"      bl      my_direct_func\n"
+"      ld.d    $a0, $sp, 0\n"
+"      ld.d    $t0, $sp, 8\n"
+"      ld.d    $ra, $sp, 16\n"
+"      addi.d  $sp, $sp, 32\n"
+"      jr      $t0\n"
+"      .size           my_tramp, .-my_tramp\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_LOONGARCH */
+
 static struct ftrace_ops direct;
 
 static int __init ftrace_direct_multi_init(void)
 
 
 #endif /* CONFIG_S390 */
 
+#ifdef CONFIG_LOONGARCH
+
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp, @function\n"
+"      .globl          my_tramp\n"
+"   my_tramp:\n"
+"      addi.d  $sp, $sp, -48\n"
+"      st.d    $a0, $sp, 0\n"
+"      st.d    $a1, $sp, 8\n"
+"      st.d    $a2, $sp, 16\n"
+"      st.d    $t0, $sp, 24\n"
+"      st.d    $ra, $sp, 32\n"
+"      bl      my_direct_func\n"
+"      ld.d    $a0, $sp, 0\n"
+"      ld.d    $a1, $sp, 8\n"
+"      ld.d    $a2, $sp, 16\n"
+"      ld.d    $t0, $sp, 24\n"
+"      ld.d    $ra, $sp, 32\n"
+"      addi.d  $sp, $sp, 48\n"
+"      jr      $t0\n"
+"      .size           my_tramp, .-my_tramp\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_LOONGARCH */
+
 static int __init ftrace_direct_init(void)
 {
        return register_ftrace_direct((unsigned long)handle_mm_fault,
 
 
 #endif /* CONFIG_S390 */
 
+#ifdef CONFIG_LOONGARCH
+
+asm (
+"      .pushsection    .text, \"ax\", @progbits\n"
+"      .type           my_tramp, @function\n"
+"      .globl          my_tramp\n"
+"   my_tramp:\n"
+"      addi.d  $sp, $sp, -32\n"
+"      st.d    $a0, $sp, 0\n"
+"      st.d    $t0, $sp, 8\n"
+"      st.d    $ra, $sp, 16\n"
+"      bl      my_direct_func\n"
+"      ld.d    $a0, $sp, 0\n"
+"      ld.d    $t0, $sp, 8\n"
+"      ld.d    $ra, $sp, 16\n"
+"      addi.d  $sp, $sp, 32\n"
+"      jr      $t0\n"
+"      .size           my_tramp, .-my_tramp\n"
+"      .popsection\n"
+);
+
+#endif /* CONFIG_LOONGARCH */
+
 static int __init ftrace_direct_init(void)
 {
        return register_ftrace_direct((unsigned long)wake_up_process,