diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 3ec48fa..a9759b7 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,43 @@
+2016-02-25  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
+
+	PR gdb/13808
+	* Makefile.in: Add i386-*-linux-ipa.o and amd64-*-linux-ipa.o.
+	* configure.srv: Ditto.
+	* linux-aarch64-ipa.c (get_ipa_tdesc): New function.
+	(initialize_low_tracepoint): Remove ipa_tdesc assignment.
+	* linux-amd64-ipa.c: Add "linux-x86-tdesc.h" include.
+	(init_registers_amd64_linux): Remove prototype.
+	(tdesc_amd64_linux): Remove declaration.
+	(get_ipa_tdesc): New function.
+	(initialize_low_tracepoint): Remove ipa_tdesc assignment,
+	initialize remaining tdescs.
+	* linux-i386-ipa.c: Add "linux-x86-tdesc.h" include.
+	(init_registers_i386_linux): Remove prototype.
+	(tdesc_i386_linux): Remove declaration.
+	(get_ipa_tdesc): New function.
+	(initialize_low_tracepoint): Remove ipa_tdesc assignment,
+	initialize remaining tdescs.
+	* linux-low.c (linux_get_ipa_tdesc_idx): New function.
+	(linux_target_ops): wire in linux_get_ipa_tdesc_idx.
+	* linux-low.h (struct linux_target_ops): Add get_ipa_tdesc_idx.
+	* linux-x86-low.c: Move tdesc declarations to linux-x86-tdesc.h.
+	(x86_get_ipa_tdesc_idx): New function.
+	(the_low_target): Wire in x86_get_ipa_tdesc_idx.
+	* linux-x86-tdesc.h: New file.
+	* target.h (struct target_ops): Add get_ipa_tdesc_idx.
+	(target_get_ipa_tdesc_idx): New macro.
+	* tracepoint.c (ipa_tdesc_idx): New macro.
+	(struct ipa_sym_addresses): Add addr_ipa_tdesc_idx.
+	(symbol_list): Add ipa_tdesc_idx.
+	(cmd_qtstart): Write ipa_tdesc_idx in the target.
+	(ipa_tdesc): Remove.
+	(ipa_tdesc_idx): New variable.
+	(get_context_regcache): Use get_ipa_tdesc.
+	(gdb_collect): Ditto.
+	(gdb_probe): Ditto.
+	* tracepoint.h (get_ipa_tdesc): New prototype.
+	(ipa_tdesc): Remove.
+
 2016-02-24  Pedro Alves  <palves@redhat.com>
 
 	* linux-low.c (check_stopped_by_breakpoint): Rename to ...
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 1e874e3..257e9bf 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -495,6 +495,18 @@ regcache-ipa.o: regcache.c
 i386-linux-ipa.o: i386-linux.c
 	$(IPAGENT_COMPILE) $<
 	$(POSTCOMPILE)
+i386-mmx-linux-ipa.o: i386-mmx-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
+i386-avx-linux-ipa.o: i386-avx-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
+i386-mpx-linux-ipa.o: i386-mpx-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
+i386-avx512-linux-ipa.o: i386-avx512-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
 linux-i386-ipa.o: linux-i386-ipa.c
 	$(IPAGENT_COMPILE) $<
 	$(POSTCOMPILE)
@@ -504,6 +516,15 @@ linux-amd64-ipa.o: linux-amd64-ipa.c
 amd64-linux-ipa.o: amd64-linux.c
 	$(IPAGENT_COMPILE) $<
 	$(POSTCOMPILE)
+amd64-avx-linux-ipa.o: amd64-avx-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
+amd64-mpx-linux-ipa.o: amd64-mpx-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
+amd64-avx512-linux-ipa.o: amd64-avx512-linux.c
+	$(IPAGENT_COMPILE) $<
+	$(POSTCOMPILE)
 linux-aarch64-ipa.o: linux-aarch64-ipa.c
 	$(IPAGENT_COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index a54b9e7..a89b1d1 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -29,8 +29,8 @@ srv_i386_linux_regobj="i386-linux.o i386-avx-linux.o i386-avx512-linux.o i386-mp
 srv_amd64_regobj="amd64.o amd64-avx.o amd64-avx512.o amd64-mpx.o x32.o x32-avx.o x32-avx512.o"
 srv_amd64_linux_regobj="amd64-linux.o amd64-avx-linux.o amd64-avx512-linux.o amd64-mpx-linux.o x32-linux.o x32-avx-linux.o x32-avx512-linux.o"
 
-ipa_i386_linux_regobj=i386-linux-ipa.o
-ipa_amd64_linux_regobj=amd64-linux-ipa.o
+ipa_i386_linux_regobj="i386-linux-ipa.o i386-avx-linux-ipa.o i386-avx512-linux-ipa.o i386-mpx-linux-ipa.o i386-mmx-linux-ipa.o"
+ipa_amd64_linux_regobj="amd64-linux-ipa.o amd64-avx-linux-ipa.o amd64-avx512-linux-ipa.o amd64-mpx-linux-ipa.o"
 
 srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml i386/32bit-avx.xml i386/32bit-avx512.xml i386/32bit-mpx.xml"
 srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-sse.xml i386/64bit-avx.xml i386/64bit-avx512.xml i386/x32-core.xml i386/64bit-mpx.xml"
diff --git a/gdb/gdbserver/linux-aarch64-ipa.c b/gdb/gdbserver/linux-aarch64-ipa.c
index 758708d..f1eaa70 100644
--- a/gdb/gdbserver/linux-aarch64-ipa.c
+++ b/gdb/gdbserver/linux-aarch64-ipa.c
@@ -143,9 +143,18 @@ gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
 			+ aarch64_ft_collect_regmap[regnum] * FT_CR_SIZE);
 }
 
+/* Return target_desc to use for IPA, given the tdesc index passed by
+   gdbserver.  Index is ignored, since we have only one tdesc
+   at the moment.  */
+
+const struct target_desc *
+get_ipa_tdesc (int idx)
+{
+  return tdesc_aarch64;
+}
+
 void
 initialize_low_tracepoint (void)
 {
   init_registers_aarch64 ();
-  ipa_tdesc = tdesc_aarch64;
 }
diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c
index 2eeedcd..2dca943 100644
--- a/gdb/gdbserver/linux-amd64-ipa.c
+++ b/gdb/gdbserver/linux-amd64-ipa.c
@@ -20,6 +20,7 @@
 
 #include "server.h"
 #include "tracepoint.h"
+#include "linux-x86-tdesc.h"
 
 /* Defined in auto-generated file amd64-linux.c.  */
 void init_registers_amd64_linux (void);
@@ -166,9 +167,34 @@ supply_static_tracepoint_registers (struct regcache *regcache,
 
 #endif /* HAVE_UST */
 
+/* Return target_desc to use for IPA, given the tdesc index passed by
+   gdbserver.  */
+
+const struct target_desc *
+get_ipa_tdesc (int idx)
+{
+  switch (idx)
+    {
+    case X86_TDESC_SSE:
+      return tdesc_amd64_linux;
+    case X86_TDESC_AVX:
+      return tdesc_amd64_avx_linux;
+    case X86_TDESC_MPX:
+      return tdesc_amd64_mpx_linux;
+    case X86_TDESC_AVX512:
+      return tdesc_amd64_avx512_linux;
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "unknown ipa tdesc index: %d", idx);
+      return tdesc_amd64_linux;
+    }
+}
+
 void
 initialize_low_tracepoint (void)
 {
   init_registers_amd64_linux ();
-  ipa_tdesc = tdesc_amd64_linux;
+  init_registers_amd64_avx_linux ();
+  init_registers_amd64_mpx_linux ();
+  init_registers_amd64_avx512_linux ();
 }
diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c
index 11dc038..4860012 100644
--- a/gdb/gdbserver/linux-i386-ipa.c
+++ b/gdb/gdbserver/linux-i386-ipa.c
@@ -21,6 +21,7 @@
 #include "server.h"
 #include <sys/mman.h>
 #include "tracepoint.h"
+#include "linux-x86-tdesc.h"
 
 /* GDB register numbers.  */
 
@@ -47,10 +48,6 @@ enum i386_gdb_regnum
 
 #define i386_num_regs 16
 
-/* Defined in auto-generated file i386-linux.c.  */
-void init_registers_i386_linux (void);
-extern const struct target_desc *tdesc_i386_linux;
-
 #define FT_CR_EAX 15
 #define FT_CR_ECX 14
 #define FT_CR_EDX 13
@@ -247,10 +244,38 @@ initialize_fast_tracepoint_trampoline_buffer (void)
     }
 }
 
+/* Return target_desc to use for IPA, given the tdesc index passed by
+   gdbserver.  */
+
+const struct target_desc *
+get_ipa_tdesc (int idx)
+{
+  switch (idx)
+    {
+    case X86_TDESC_MMX:
+      return tdesc_i386_mmx_linux;
+    case X86_TDESC_SSE:
+      return tdesc_i386_linux;
+    case X86_TDESC_AVX:
+      return tdesc_i386_avx_linux;
+    case X86_TDESC_MPX:
+      return tdesc_i386_mpx_linux;
+    case X86_TDESC_AVX512:
+      return tdesc_i386_avx512_linux;
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "unknown ipa tdesc index: %d", idx);
+      return tdesc_i386_linux;
+    }
+}
+
 void
 initialize_low_tracepoint (void)
 {
+  init_registers_i386_mmx_linux ();
   init_registers_i386_linux ();
-  ipa_tdesc = tdesc_i386_linux;
+  init_registers_i386_avx_linux ();
+  init_registers_i386_mpx_linux ();
+  init_registers_i386_avx512_linux ();
   initialize_fast_tracepoint_trampoline_buffer ();
 }
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 5e7560f..983b2d1 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -6406,6 +6406,15 @@ linux_supports_catch_syscall (void)
 }
 
 static int
+linux_get_ipa_tdesc_idx (void)
+{
+  if (the_low_target.get_ipa_tdesc_idx == NULL)
+    return 0;
+
+  return (*the_low_target.get_ipa_tdesc_idx) ();
+}
+
+static int
 linux_supports_tracepoints (void)
 {
   if (*the_low_target.supports_tracepoints == NULL)
@@ -7382,6 +7391,7 @@ static struct target_ops linux_target_ops = {
   linux_breakpoint_kind_from_current_state,
   linux_supports_software_single_step,
   linux_supports_catch_syscall,
+  linux_get_ipa_tdesc_idx,
 };
 
 #ifdef HAVE_LINUX_REGSETS
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 4ec8550..d4946c1 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -246,6 +246,9 @@ struct linux_target_ops
      due to SYSCALL_SIGTRAP.  */
   void (*get_syscall_trapinfo) (struct regcache *regcache,
 				int *sysno, int *sysret);
+
+  /* See target.h.  */
+  int (*get_ipa_tdesc_idx) (void);
 };
 
 extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 0c4954a..feaee92 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -45,57 +45,7 @@
 #include "nat/linux-nat.h"
 #include "nat/x86-linux.h"
 #include "nat/x86-linux-dregs.h"
-
-#ifdef __x86_64__
-/* Defined in auto-generated file amd64-linux.c.  */
-void init_registers_amd64_linux (void);
-extern const struct target_desc *tdesc_amd64_linux;
-
-/* Defined in auto-generated file amd64-avx-linux.c.  */
-void init_registers_amd64_avx_linux (void);
-extern const struct target_desc *tdesc_amd64_avx_linux;
-
-/* Defined in auto-generated file amd64-avx512-linux.c.  */
-void init_registers_amd64_avx512_linux (void);
-extern const struct target_desc *tdesc_amd64_avx512_linux;
-
-/* Defined in auto-generated file amd64-mpx-linux.c.  */
-void init_registers_amd64_mpx_linux (void);
-extern const struct target_desc *tdesc_amd64_mpx_linux;
-
-/* Defined in auto-generated file x32-linux.c.  */
-void init_registers_x32_linux (void);
-extern const struct target_desc *tdesc_x32_linux;
-
-/* Defined in auto-generated file x32-avx-linux.c.  */
-void init_registers_x32_avx_linux (void);
-extern const struct target_desc *tdesc_x32_avx_linux;
-
-/* Defined in auto-generated file x32-avx512-linux.c.  */
-void init_registers_x32_avx512_linux (void);
-extern const struct target_desc *tdesc_x32_avx512_linux;
-
-#endif
-
-/* Defined in auto-generated file i386-linux.c.  */
-void init_registers_i386_linux (void);
-extern const struct target_desc *tdesc_i386_linux;
-
-/* Defined in auto-generated file i386-mmx-linux.c.  */
-void init_registers_i386_mmx_linux (void);
-extern const struct target_desc *tdesc_i386_mmx_linux;
-
-/* Defined in auto-generated file i386-avx-linux.c.  */
-void init_registers_i386_avx_linux (void);
-extern const struct target_desc *tdesc_i386_avx_linux;
-
-/* Defined in auto-generated file i386-avx512-linux.c.  */
-void init_registers_i386_avx512_linux (void);
-extern const struct target_desc *tdesc_i386_avx512_linux;
-
-/* Defined in auto-generated file i386-mpx-linux.c.  */
-void init_registers_i386_mpx_linux (void);
-extern const struct target_desc *tdesc_i386_mpx_linux;
+#include "linux-x86-tdesc.h"
 
 #ifdef __x86_64__
 static struct target_desc *tdesc_amd64_linux_no_xml;
@@ -2891,6 +2841,38 @@ x86_supports_hardware_single_step (void)
   return 1;
 }
 
+static int
+x86_get_ipa_tdesc_idx (void)
+{
+  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+  const struct target_desc *tdesc = regcache->tdesc;
+
+#ifdef __x86_64__
+  if (tdesc == tdesc_amd64_linux || tdesc == tdesc_amd64_linux_no_xml
+      || tdesc == tdesc_x32_linux)
+    return X86_TDESC_SSE;
+  if (tdesc == tdesc_amd64_avx_linux || tdesc == tdesc_x32_avx_linux)
+    return X86_TDESC_AVX;
+  if (tdesc == tdesc_amd64_mpx_linux)
+    return X86_TDESC_MPX;
+  if (tdesc == tdesc_amd64_avx512_linux || tdesc == tdesc_x32_avx512_linux)
+    return X86_TDESC_AVX512;
+#endif
+
+  if (tdesc == tdesc_i386_mmx_linux)
+    return X86_TDESC_MMX;
+  if (tdesc == tdesc_i386_linux || tdesc == tdesc_i386_linux_no_xml)
+    return X86_TDESC_SSE;
+  if (tdesc == tdesc_i386_avx_linux)
+    return X86_TDESC_AVX;
+  if (tdesc == tdesc_i386_mpx_linux)
+    return X86_TDESC_MPX;
+  if (tdesc == tdesc_i386_avx512_linux)
+    return X86_TDESC_AVX512;
+
+  return 0;
+}
+
 /* This is initialized assuming an amd64 target.
    x86_arch_setup will correct it for i386 or amd64 targets.  */
 
@@ -2934,6 +2916,7 @@ struct linux_target_ops the_low_target =
   NULL, /* breakpoint_kind_from_current_state */
   x86_supports_hardware_single_step,
   x86_get_syscall_trapinfo,
+  x86_get_ipa_tdesc_idx,
 };
 
 void
diff --git a/gdb/gdbserver/linux-x86-tdesc.h b/gdb/gdbserver/linux-x86-tdesc.h
new file mode 100644
index 0000000..33fdc27
--- /dev/null
+++ b/gdb/gdbserver/linux-x86-tdesc.h
@@ -0,0 +1,89 @@
+/* Low level support for x86 (i386 and x86-64), shared between gdbserver
+   and IPA.
+
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Note: since IPA obviously knows what ABI it's running on (i386 vs x86_64
+   vs x32), it's sufficient to pass only the register set here.  This,
+   together with the ABI known at IPA compile time, maps to a tdesc.  */
+
+enum x86_linux_tdesc {
+  X86_TDESC_MMX = 0,
+  X86_TDESC_SSE = 1,
+  X86_TDESC_AVX = 2,
+  X86_TDESC_MPX = 3,
+  X86_TDESC_AVX512 = 4,
+};
+
+#ifdef __x86_64__
+
+#if defined __LP64__  || !defined IN_PROCESS_AGENT
+/* Defined in auto-generated file amd64-linux.c.  */
+void init_registers_amd64_linux (void);
+extern const struct target_desc *tdesc_amd64_linux;
+
+/* Defined in auto-generated file amd64-avx-linux.c.  */
+void init_registers_amd64_avx_linux (void);
+extern const struct target_desc *tdesc_amd64_avx_linux;
+
+/* Defined in auto-generated file amd64-avx512-linux.c.  */
+void init_registers_amd64_avx512_linux (void);
+extern const struct target_desc *tdesc_amd64_avx512_linux;
+
+/* Defined in auto-generated file amd64-mpx-linux.c.  */
+void init_registers_amd64_mpx_linux (void);
+extern const struct target_desc *tdesc_amd64_mpx_linux;
+#endif
+
+#if defined __ILP32__ || !defined IN_PROCESS_AGENT
+/* Defined in auto-generated file x32-linux.c.  */
+void init_registers_x32_linux (void);
+extern const struct target_desc *tdesc_x32_linux;
+
+/* Defined in auto-generated file x32-avx-linux.c.  */
+void init_registers_x32_avx_linux (void);
+extern const struct target_desc *tdesc_x32_avx_linux;
+
+/* Defined in auto-generated file x32-avx512-linux.c.  */
+void init_registers_x32_avx512_linux (void);
+extern const struct target_desc *tdesc_x32_avx512_linux;
+#endif
+
+#endif
+
+#if defined __i386__ || !defined IN_PROCESS_AGENT
+/* Defined in auto-generated file i386-linux.c.  */
+void init_registers_i386_linux (void);
+extern const struct target_desc *tdesc_i386_linux;
+
+/* Defined in auto-generated file i386-mmx-linux.c.  */
+void init_registers_i386_mmx_linux (void);
+extern const struct target_desc *tdesc_i386_mmx_linux;
+
+/* Defined in auto-generated file i386-avx-linux.c.  */
+void init_registers_i386_avx_linux (void);
+extern const struct target_desc *tdesc_i386_avx_linux;
+
+/* Defined in auto-generated file i386-avx512-linux.c.  */
+void init_registers_i386_avx512_linux (void);
+extern const struct target_desc *tdesc_i386_avx512_linux;
+
+/* Defined in auto-generated file i386-mpx-linux.c.  */
+void init_registers_i386_mpx_linux (void);
+extern const struct target_desc *tdesc_i386_mpx_linux;
+#endif
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 5af2051..4c14c20 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -471,6 +471,9 @@ struct target_ops
   /* Return 1 if the target supports catch syscall, 0 (or leave the
      callback NULL) otherwise.  */
   int (*supports_catch_syscall) (void);
+
+  /* Return tdesc index for IPA.  */
+  int (*get_ipa_tdesc_idx) (void);
 };
 
 extern struct target_ops *the_target;
@@ -550,6 +553,10 @@ int kill_inferior (int);
   (the_target->supports_catch_syscall ?			\
    (*the_target->supports_catch_syscall) () : 0)
 
+#define target_get_ipa_tdesc_idx()			\
+  (the_target->get_ipa_tdesc_idx			\
+   ? (*the_target->get_ipa_tdesc_idx) () : 0)
+
 #define target_supports_tracepoints()			\
   (the_target->supports_tracepoints			\
    ? (*the_target->supports_tracepoints) () : 0)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index e7c18fd..92d7f1f 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -134,6 +134,7 @@ trace_vdebug (const char *fmt, ...)
 # define ust_loaded IPA_SYM_EXPORTED_NAME (ust_loaded)
 # define helper_thread_id IPA_SYM_EXPORTED_NAME (helper_thread_id)
 # define cmd_buf IPA_SYM_EXPORTED_NAME (cmd_buf)
+# define ipa_tdesc_idx IPA_SYM_EXPORTED_NAME (ipa_tdesc_idx)
 #endif
 
 #ifndef IN_PROCESS_AGENT
@@ -171,6 +172,7 @@ struct ipa_sym_addresses
   CORE_ADDR addr_get_trace_state_variable_value;
   CORE_ADDR addr_set_trace_state_variable_value;
   CORE_ADDR addr_ust_loaded;
+  CORE_ADDR addr_ipa_tdesc_idx;
 };
 
 static struct
@@ -207,6 +209,7 @@ static struct
   IPA_SYM(get_trace_state_variable_value),
   IPA_SYM(set_trace_state_variable_value),
   IPA_SYM(ust_loaded),
+  IPA_SYM(ipa_tdesc_idx),
 };
 
 static struct ipa_sym_addresses ipa_sym_addrs;
@@ -3211,6 +3214,13 @@ cmd_qtstart (char *packet)
 
   *packet = '\0';
 
+  /* Tell IPA about the correct tdesc.  */
+  if (write_inferior_integer (ipa_sym_addrs.addr_ipa_tdesc_idx,
+			      target_get_ipa_tdesc_idx ()))
+    {
+      error ("Error setting ipa_tdesc_idx variable in lib");
+    }
+
   /* Start out empty.  */
   if (agent_loaded_p ())
     write_inferior_data_pointer (ipa_sym_addrs.addr_tracepoints, 0);
@@ -4694,19 +4704,20 @@ collect_data_at_step (struct tracepoint_hit_ctx *ctx,
 #endif
 
 #ifdef IN_PROCESS_AGENT
-/* The target description used by the IPA.  Given that the IPA library
-   is built for a specific architecture that is loaded into the
-   inferior, there only needs to be one such description per
-   build.  */
-const struct target_desc *ipa_tdesc;
+/* The target description index for IPA.  Passed from gdbserver, used
+   to select ipa_tdesc.  */
+EXTERN_C_PUSH
+IP_AGENT_EXPORT_VAR int ipa_tdesc_idx;
+EXTERN_C_POP
 #endif
 
 static struct regcache *
 get_context_regcache (struct tracepoint_hit_ctx *ctx)
 {
   struct regcache *regcache = NULL;
-
 #ifdef IN_PROCESS_AGENT
+  const struct target_desc *ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx);
+
   if (ctx->type == fast_tracepoint)
     {
       struct fast_tracepoint_ctx *fctx = (struct fast_tracepoint_ctx *) ctx;
@@ -5779,11 +5790,13 @@ IP_AGENT_EXPORT_FUNC void
 gdb_collect (struct tracepoint *tpoint, unsigned char *regs)
 {
   struct fast_tracepoint_ctx ctx;
+  const struct target_desc *ipa_tdesc;
 
   /* Don't do anything until the trace run is completely set up.  */
   if (!tracing)
     return;
 
+  ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx);
   ctx.base.type = fast_tracepoint;
   ctx.regs = regs;
   ctx.regcache_initted = 0;
@@ -6629,6 +6642,7 @@ gdb_probe (const struct marker *mdata, void *probe_private,
 {
   struct tracepoint *tpoint;
   struct static_tracepoint_ctx ctx;
+  const struct target_desc *ipa_tdesc;
 
   /* Don't do anything until the trace run is completely set up.  */
   if (!tracing)
@@ -6637,6 +6651,7 @@ gdb_probe (const struct marker *mdata, void *probe_private,
       return;
     }
 
+  ipa_tdesc = get_ipa_tdesc (ipa_tdesc_idx);
   ctx.base.type = static_tracepoint;
   ctx.regcache_initted = 0;
   ctx.regs = regs;
diff --git a/gdb/gdbserver/tracepoint.h b/gdb/gdbserver/tracepoint.h
index cab89cf..e30f4f7 100644
--- a/gdb/gdbserver/tracepoint.h
+++ b/gdb/gdbserver/tracepoint.h
@@ -124,6 +124,7 @@ int handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc);
 
 #ifdef IN_PROCESS_AGENT
 void initialize_low_tracepoint (void);
+const struct target_desc *get_ipa_tdesc (int idx);
 void supply_fast_tracepoint_registers (struct regcache *regcache,
 				       const unsigned char *regs);
 void supply_static_tracepoint_registers (struct regcache *regcache,
@@ -131,9 +132,6 @@ void supply_static_tracepoint_registers (struct regcache *regcache,
 					 CORE_ADDR pc);
 void set_trampoline_buffer_space (CORE_ADDR begin, CORE_ADDR end,
 				  char *errmsg);
-
-extern const struct target_desc *ipa_tdesc;
-
 #else
 void stop_tracing (void);
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index b3681f2..556b572 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2016-02-25  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
 
+	PR gdb/13808
+	* gdb.trace/ftrace.exp (test_fast_tracepoints): Remove kfail.
+
+2016-02-25  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
+
 	* gdb.trace/ftrace.exp: Remove unnecessary target check.
 
 2016-02-25  Marcin KoÅ›cielnicki  <koriakin@0x04.net>
diff --git a/gdb/testsuite/gdb.trace/ftrace.exp b/gdb/testsuite/gdb.trace/ftrace.exp
index 0cdbd89..a1d4771 100644
--- a/gdb/testsuite/gdb.trace/ftrace.exp
+++ b/gdb/testsuite/gdb.trace/ftrace.exp
@@ -130,7 +130,6 @@ proc test_fast_tracepoints {} {
     gdb_test "tfind pc *set_point" "Found trace frame .*" \
         "tfind set_point frame, first time"
 
-    setup_kfail "gdb/13808" "x86_64-*-linux*"
     gdb_test "print globvar" " = 1"
 
     gdb_test "tfind pc *set_point" "Found trace frame .*" \
