diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h
index f0e4a4221f..50e9e064d0 100644
--- a/gdb/arch/ppc-linux-common.h
+++ b/gdb/arch/ppc-linux-common.h
@@ -33,6 +33,8 @@ struct target_desc;
 #define PPC_LINUX_SIZEOF_PPRREGSET 8
 #define PPC_LINUX_SIZEOF_DSCRREGSET 8
 #define PPC_LINUX_SIZEOF_TARREGSET 8
+#define PPC_LINUX_SIZEOF_EBBREGSET (3*8)
+#define PPC_LINUX_SIZEOF_PMUREGSET (5*8)
 
 /* Check if the hwcap auxv entry indicates that isa205 is supported.  */
 bool ppc_linux_has_isa205 (CORE_ADDR hwcap);
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 97b3308648..f30a459e9e 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -42791,6 +42791,15 @@ contain the 64-bit register @samp{dscr}.
 The @samp{org.gnu.gdb.power.tar} feature is optional.  It should
 contain the 64-bit register @samp{tar}.
 
+The @samp{org.gnu.gdb.power.ebb} feature is optional.  It should
+contain registers @samp{bescr}, @samp{ebbhr} and @samp{ebbrr}, all
+64-bit wide.
+
+The @samp{org.gnu.gdb.power.linux.pmu} feature is optional.  It should
+contain registers @samp{mmcr0}, @samp{mmcr2}, @samp{siar}, @samp{sdar}
+and @samp{sier}, all 64-bit wide.  This is the subset of the isa 2.07
+server PMU registers provided by @sc{gnu}/Linux.
+
 @node S/390 and System z Features
 @subsection S/390 and System z Features
 @cindex target descriptions, S/390 features
diff --git a/gdb/features/rs6000/power-ebb.xml b/gdb/features/rs6000/power-ebb.xml
new file mode 100644
index 0000000000..7bec21f916
--- /dev/null
+++ b/gdb/features/rs6000/power-ebb.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- POWER8 Event-based Branching Registers.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.ebb">
+  <reg name="bescr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="ebbhr" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="ebbrr" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/power-linux-pmu.xml b/gdb/features/rs6000/power-linux-pmu.xml
new file mode 100644
index 0000000000..c60b44462d
--- /dev/null
+++ b/gdb/features/rs6000/power-linux-pmu.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2018 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- Subset of the POWER8 ISA 2.07 Performance Monitor Registers
+     provided by Linux.  -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.linux.pmu">
+  <reg name="mmcr0" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="mmcr2" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="siar" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="sdar" bitsize="64" type="uint64" save-restore="no"/>
+  <reg name="sier" bitsize="64" type="uint64" save-restore="no"/>
+</feature>
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.c b/gdb/features/rs6000/powerpc-isa207-vsx32l.c
index 73c7a01077..8fe0f5e438 100644
--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.c
+++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.c
@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx32l (void)
   feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
   tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
 
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
   tdesc_powerpc_isa207_vsx32l = result;
 }
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
index 599e6a24a2..635eef52ee 100644
--- a/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
+++ b/gdb/features/rs6000/powerpc-isa207-vsx32l.xml
@@ -16,4 +16,6 @@
   <xi:include href="power-ppr.xml"/>
   <xi:include href="power-dscr.xml"/>
   <xi:include href="power-tar.xml"/>
+  <xi:include href="power-ebb.xml"/>
+  <xi:include href="power-linux-pmu.xml"/>
 </target>
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.c b/gdb/features/rs6000/powerpc-isa207-vsx64l.c
index 9c735522d2..0af1879e10 100644
--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.c
+++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.c
@@ -199,5 +199,17 @@ initialize_tdesc_powerpc_isa207_vsx64l (void)
   feature = tdesc_create_feature (result, "org.gnu.gdb.power.tar");
   tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
 
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.ebb");
+  tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.power.linux.pmu");
+  tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+  tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
   tdesc_powerpc_isa207_vsx64l = result;
 }
diff --git a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
index 42a23cc001..67dff71fe2 100644
--- a/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
+++ b/gdb/features/rs6000/powerpc-isa207-vsx64l.xml
@@ -16,4 +16,6 @@
   <xi:include href="power-ppr.xml"/>
   <xi:include href="power-dscr.xml"/>
   <xi:include href="power-tar.xml"/>
+  <xi:include href="power-ebb.xml"/>
+  <xi:include href="power-linux-pmu.xml"/>
 </target>
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 0cb50627aa..a18d7b6357 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -249,6 +249,8 @@ case "${target}" in
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-dscr.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml"
+			srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml"
+			srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-e500l.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/power-spe.xml"
 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-64l.xml"
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
index c86bfd5577..261247861c 100644
--- a/gdb/gdbserver/linux-ppc-low.c
+++ b/gdb/gdbserver/linux-ppc-low.c
@@ -526,6 +526,44 @@ ppc_store_tarregset (struct regcache *regcache, const void *buf)
 }
 
 static void
+ppc_store_ebbregset (struct regcache *regcache, const void *buf)
+{
+  const char *regset = (const char *) buf;
+
+  /* The order in the kernel regset is: EBBRR, EBBHR, BESCR.  In the
+     .dat file is BESCR, EBBHR, EBBRR.  */
+  supply_register_by_name (regcache, "ebbrr", &regset[0]);
+  supply_register_by_name (regcache, "ebbhr", &regset[8]);
+  supply_register_by_name (regcache, "bescr", &regset[16]);
+}
+
+static void
+ppc_fill_pmuregset (struct regcache *regcache, void *buf)
+{
+  char *regset = (char *) buf;
+
+  /* The order in the kernel regset is SIAR, SDAR, SIER, MMCR2, MMCR0.
+     In the .dat file is MMCR0, MMCR2, SIAR, SDAR, SIER.  */
+  collect_register_by_name (regcache, "siar", &regset[0]);
+  collect_register_by_name (regcache, "sdar", &regset[8]);
+  collect_register_by_name (regcache, "sier", &regset[16]);
+  collect_register_by_name (regcache, "mmcr2", &regset[24]);
+  collect_register_by_name (regcache, "mmcr0", &regset[32]);
+}
+
+static void
+ppc_store_pmuregset (struct regcache *regcache, const void *buf)
+{
+  const char *regset = (const char *) buf;
+
+  supply_register_by_name (regcache, "siar", &regset[0]);
+  supply_register_by_name (regcache, "sdar", &regset[8]);
+  supply_register_by_name (regcache, "sier", &regset[16]);
+  supply_register_by_name (regcache, "mmcr2", &regset[24]);
+  supply_register_by_name (regcache, "mmcr0", &regset[32]);
+}
+
+static void
 ppc_fill_vsxregset (struct regcache *regcache, void *buf)
 {
   int i, base;
@@ -634,6 +672,10 @@ static struct regset_info ppc_regsets[] = {
      fetch them every time, but still fall back to PTRACE_PEEKUSER for the
      general registers.  Some kernels support these, but not the newer
      PPC_PTRACE_GETREGS.  */
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_EBB, 0, EXTENDED_REGS,
+    NULL, ppc_store_ebbregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS,
+    ppc_fill_pmuregset, ppc_store_pmuregset },
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS,
     ppc_fill_tarregset, ppc_store_tarregset },
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS,
@@ -714,8 +756,13 @@ ppc_arch_setup (void)
       features.ppr_dscr = true;
       if ((ppc_hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	  && (ppc_hwcap2 & PPC_FEATURE2_TAR)
+	  && (ppc_hwcap2 & PPC_FEATURE2_EBB)
 	  && ppc_check_regset (tid, NT_PPC_TAR,
-			       PPC_LINUX_SIZEOF_TARREGSET))
+			       PPC_LINUX_SIZEOF_TARREGSET)
+	  && ppc_check_regset (tid, NT_PPC_EBB,
+			       PPC_LINUX_SIZEOF_EBBREGSET)
+	  && ppc_check_regset (tid, NT_PPC_PMU,
+			       PPC_LINUX_SIZEOF_PMUREGSET))
 	features.isa207 = true;
     }
 
@@ -778,6 +825,14 @@ ppc_arch_setup (void)
 	    regset->size = (features.isa207 ?
 			    PPC_LINUX_SIZEOF_TARREGSET : 0);
 	    break;
+	  case NT_PPC_EBB:
+	    regset->size = (features.isa207 ?
+			    PPC_LINUX_SIZEOF_EBBREGSET : 0);
+	    break;
+	  case NT_PPC_PMU:
+	    regset->size = (features.isa207 ?
+			    PPC_LINUX_SIZEOF_PMUREGSET : 0);
+	    break;
 	  default:
 	    break;
 	  }
diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h
index 913a9e0bd8..c965030d91 100644
--- a/gdb/nat/ppc-linux.h
+++ b/gdb/nat/ppc-linux.h
@@ -60,6 +60,9 @@
 #ifndef PPC_FEATURE2_TAR
 #define PPC_FEATURE2_TAR 0x04000000
 #endif
+#ifndef PPC_FEATURE2_EBB
+#define PPC_FEATURE2_EBB 0x10000000
+#endif
 
 /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
    configure time check.  Some older glibc's (for instance 2.2.1)
@@ -106,6 +109,16 @@
 #define NT_PPC_DSCR 0x105
 #endif
 
+/* Event Based Branch Registers.  */
+#ifndef NT_PPC_EBB
+#define NT_PPC_EBB 0x106
+#endif
+
+/* Performance Monitor Registers.  */
+#ifndef NT_PPC_PMU
+#define NT_PPC_PMU 0x107
+#endif
+
 /* Return the wordsize of the target, either 4 or 8 bytes.  */
 int ppc_linux_target_wordsize (int tid);
 
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index ffe1f813d2..3466f4dc7f 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -666,6 +666,24 @@ fetch_register (struct regcache *regcache, int tid, int regno)
 		    &ppc32_linux_tarregset);
       return;
     }
+  else if (PPC_IS_EBB_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_ebb);
+
+      fetch_regset (regcache, tid, NT_PPC_EBB,
+		    PPC_LINUX_SIZEOF_EBBREGSET,
+		    &ppc32_linux_ebbregset);
+      return;
+    }
+  else if (PPC_IS_PMU_REGNUM (regno))
+    {
+      gdb_assert (tdep->ppc_mmcr0_regnum != -1);
+
+      fetch_regset (regcache, tid, NT_PPC_PMU,
+		    PPC_LINUX_SIZEOF_PMUREGSET,
+		    &ppc32_linux_pmuregset);
+      return;
+    }
 
   if (regaddr == -1)
     {
@@ -871,6 +889,14 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
     fetch_regset (regcache, tid, NT_PPC_TAR,
 		  PPC_LINUX_SIZEOF_TARREGSET,
 		  &ppc32_linux_tarregset);
+  if (tdep->have_ebb)
+    fetch_regset (regcache, tid, NT_PPC_EBB,
+		  PPC_LINUX_SIZEOF_EBBREGSET,
+		  &ppc32_linux_ebbregset);
+  if (tdep->ppc_mmcr0_regnum != -1)
+    fetch_regset (regcache, tid, NT_PPC_PMU,
+		  PPC_LINUX_SIZEOF_PMUREGSET,
+		  &ppc32_linux_pmuregset);
 }
 
 /* Fetch registers from the child process.  Fetch all registers if
@@ -1078,6 +1104,24 @@ store_register (const struct regcache *regcache, int tid, int regno)
 		    &ppc32_linux_tarregset);
       return;
     }
+  else if (PPC_IS_EBB_REGNUM (regno))
+    {
+      gdb_assert (tdep->have_ebb);
+
+      store_regset (regcache, tid, regno, NT_PPC_EBB,
+		    PPC_LINUX_SIZEOF_EBBREGSET,
+		    &ppc32_linux_ebbregset);
+      return;
+    }
+  else if (PPC_IS_PMU_REGNUM (regno))
+    {
+      gdb_assert (tdep->ppc_mmcr0_regnum != -1);
+
+      store_regset (regcache, tid, regno, NT_PPC_PMU,
+		    PPC_LINUX_SIZEOF_PMUREGSET,
+		    &ppc32_linux_pmuregset);
+      return;
+    }
 
   if (regaddr == -1)
     return;
@@ -1252,6 +1296,50 @@ store_fp_regs (const struct regcache *regcache, int tid, int regno)
     store_register (regcache, tid, tdep->ppc_fp0_regnum + i);
 }
 
+/* Returns true if all the registers in REGSET are valid in REGCACHE,
+   false if no registers are valid, and throws an internal error if
+   only some are valid.  The regmap field in REGSET must be of type
+   regcache_map_entry.  */
+
+static bool
+ppc_linux_regset_available_p (const struct regcache *regcache,
+			      const struct regset *regset)
+{
+  struct gdbarch *gdbarch = regcache->arch ();
+  const struct regcache_map_entry *map;
+  int count;
+  int valid = 0;
+  int total = 0;
+
+  for (map = (const struct regcache_map_entry *) regset->regmap;
+       (count = map->count) != 0;
+       map++)
+    {
+      int regno = map->regno;
+
+      /* Ignore REGCACHE_MAP_SKIP.  */
+      if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
+	{
+	  for (int i = regno; i < regno + count; i++)
+	    {
+	      if (regcache->get_register_status (i) == REG_VALID)
+		valid++;
+	      total++;
+	    }
+	}
+    }
+
+  if (valid > 0 && valid < total)
+    internal_error (__FILE__, __LINE__,
+		    _("Only some registers in a regset"
+		      "are valid."));
+
+  if (valid == total)
+    return true;
+  else
+    return false;
+}
+
 static void
 store_ppc_registers (const struct regcache *regcache, int tid)
 {
@@ -1301,6 +1389,18 @@ store_ppc_registers (const struct regcache *regcache, int tid)
     store_regset (regcache, tid, -1, NT_PPC_TAR,
 		  PPC_LINUX_SIZEOF_TARREGSET,
 		  &ppc32_linux_tarregset);
+
+  /* EBB registers can be unavailable.  */
+  if (tdep->have_ebb
+      && ppc_linux_regset_available_p (regcache, &ppc32_linux_ebbregset))
+    store_regset (regcache, tid, -1, NT_PPC_EBB,
+		  PPC_LINUX_SIZEOF_EBBREGSET,
+		  &ppc32_linux_ebbregset);
+
+  if (tdep->ppc_mmcr0_regnum != -1)
+    store_regset (regcache, tid, -1, NT_PPC_PMU,
+		  PPC_LINUX_SIZEOF_PMUREGSET,
+		  &ppc32_linux_pmuregset);
 }
 
 /* Fetch the AT_HWCAP entry from the aux vector.  */
@@ -2429,7 +2529,10 @@ ppc_linux_nat_target::read_description ()
       features.ppr_dscr = true;
       if ((hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	  && (hwcap2 & PPC_FEATURE2_TAR)
-	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET))
+	  && (hwcap2 & PPC_FEATURE2_EBB)
+	  && check_regset (tid, NT_PPC_TAR, PPC_LINUX_SIZEOF_TARREGSET)
+	  && check_regset (tid, NT_PPC_EBB, PPC_LINUX_SIZEOF_EBBREGSET)
+	  && check_regset (tid, NT_PPC_PMU, PPC_LINUX_SIZEOF_PMUREGSET))
 	features.isa207 = true;
     }
 
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index bba6ba7684..503357299e 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -507,6 +507,24 @@ static const struct regcache_map_entry ppc32_regmap_tar[] =
       { 0 }
   };
 
+static const struct regcache_map_entry ppc32_regmap_ebb[] =
+  {
+      { 1, PPC_EBBRR_REGNUM, 8 },
+      { 1, PPC_EBBHR_REGNUM, 8 },
+      { 1, PPC_BESCR_REGNUM, 8 },
+      { 0 }
+  };
+
+static const struct regcache_map_entry ppc32_regmap_pmu[] =
+  {
+      { 1, PPC_SIAR_REGNUM, 8 },
+      { 1, PPC_SDAR_REGNUM, 8 },
+      { 1, PPC_SIER_REGNUM, 8 },
+      { 1, PPC_MMCR2_REGNUM, 8 },
+      { 1, PPC_MMCR0_REGNUM, 8 },
+      { 0 }
+  };
+
 static const struct regset ppc32_linux_gregset = {
   &ppc32_linux_reg_offsets,
   ppc_linux_supply_gregset,
@@ -587,6 +605,18 @@ const struct regset ppc32_linux_tarregset = {
   regcache_collect_regset
 };
 
+const struct regset ppc32_linux_ebbregset = {
+  ppc32_regmap_ebb,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
+const struct regset ppc32_linux_pmuregset = {
+  ppc32_regmap_pmu,
+  regcache_supply_regset,
+  regcache_collect_regset
+};
+
 const struct regset *
 ppc_linux_gregset (int wordsize)
 {
@@ -662,6 +692,22 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
     cb (".reg-ppc-tar", PPC_LINUX_SIZEOF_TARREGSET,
 	PPC_LINUX_SIZEOF_TARREGSET,
 	&ppc32_linux_tarregset, "Target Address Register", cb_data);
+
+  /* EBB registers are unavailable when ptrace returns ENODATA.  Check
+     availability when generating a core file (regcache != NULL).  */
+  if (tdep->have_ebb)
+    if (regcache == NULL
+	|| REG_VALID == regcache->get_register_status (PPC_BESCR_REGNUM))
+      cb (".reg-ppc-ebb", PPC_LINUX_SIZEOF_EBBREGSET,
+	  PPC_LINUX_SIZEOF_EBBREGSET,
+	  &ppc32_linux_ebbregset, "Event-based Branching Registers",
+	  cb_data);
+
+  if (tdep->ppc_mmcr0_regnum != -1)
+    cb (".reg-ppc-pmu", PPC_LINUX_SIZEOF_PMUREGSET,
+	PPC_LINUX_SIZEOF_PMUREGSET,
+	&ppc32_linux_pmuregset, "Performance Monitor Registers",
+	cb_data);
 }
 
 static void
@@ -1077,6 +1123,7 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
   asection *ppr = bfd_get_section_by_name (abfd, ".reg-ppc-ppr");
   asection *dscr = bfd_get_section_by_name (abfd, ".reg-ppc-dscr");
   asection *tar = bfd_get_section_by_name (abfd, ".reg-ppc-tar");
+  asection *pmu = bfd_get_section_by_name (abfd, ".reg-ppc-pmu");
 
   if (! section)
     return NULL;
@@ -1112,7 +1159,12 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
   if (ppr && dscr)
     {
       features.ppr_dscr = true;
-      if (tar)
+
+      /* We don't require the EBB note section to be present in the
+	 core file to select isa207 because these registers could have
+	 been unavailable when the core file was created.  They will
+	 be in the tdep but will show as unavailable.  */
+      if (tar && pmu)
 	features.isa207 = true;
     }
 
diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h
index d6ddf69354..cce1ddd1ef 100644
--- a/gdb/ppc-linux-tdep.h
+++ b/gdb/ppc-linux-tdep.h
@@ -48,5 +48,7 @@ int ppc_linux_trap_reg_p (struct gdbarch *gdbarch);
 extern const struct regset ppc32_linux_pprregset;
 extern const struct regset ppc32_linux_dscrregset;
 extern const struct regset ppc32_linux_tarregset;
+extern const struct regset ppc32_linux_ebbregset;
+extern const struct regset ppc32_linux_pmuregset;
 
 #endif /* PPC_LINUX_TDEP_H */
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index e2b968177e..cfe32c9e87 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -265,6 +265,15 @@ struct gdbarch_tdep
     /* Decimal 128 registers.  */
     int ppc_dl0_regnum;		/* First Decimal128 argument register pair.  */
 
+    int have_ebb;
+
+    /* PMU registers.  */
+    int ppc_mmcr0_regnum;
+    int ppc_mmcr2_regnum;
+    int ppc_siar_regnum;
+    int ppc_sdar_regnum;
+    int ppc_sier_regnum;
+
     /* Offset to ABI specific location where link register is saved.  */
     int lr_frame_offset;	
 
@@ -321,12 +330,31 @@ enum {
   PPC_PPR_REGNUM = 172,
   PPC_DSCR_REGNUM = 173,
   PPC_TAR_REGNUM = 174,
+
+  /* EBB registers.  */
+  PPC_BESCR_REGNUM = 175,
+  PPC_EBBHR_REGNUM = 176,
+  PPC_EBBRR_REGNUM = 177,
+
+  /* PMU registers.  */
+  PPC_MMCR0_REGNUM = 178,
+  PPC_MMCR2_REGNUM = 179,
+  PPC_SIAR_REGNUM = 180,
+  PPC_SDAR_REGNUM = 181,
+  PPC_SIER_REGNUM = 182,
+
   PPC_NUM_REGS
 };
 
 /* Big enough to hold the size of the largest register in bytes.  */
 #define PPC_MAX_REGISTER_SIZE	64
 
+#define PPC_IS_EBB_REGNUM(i) \
+	((i) >= PPC_BESCR_REGNUM && (i) <= PPC_EBBRR_REGNUM)
+
+#define PPC_IS_PMU_REGNUM(i) \
+	((i) >= PPC_MMCR0_REGNUM && (i) <= PPC_SIER_REGNUM)
+
 /* An instruction to match.  */
 
 struct ppc_insn_pattern
diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
index 2b6e0a9c8d..0718d72d93 100644
--- a/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
+++ b/gdb/regformats/rs6000/powerpc-isa207-vsx32l.dat
@@ -145,3 +145,11 @@ expedite:r1,pc
 64:ppr
 64:dscr
 64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
diff --git a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
index 095bd7f2d3..510c6c87da 100644
--- a/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
+++ b/gdb/regformats/rs6000/powerpc-isa207-vsx64l.dat
@@ -145,3 +145,11 @@ expedite:r1,pc
 64:ppr
 64:dscr
 64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 32bbf45841..a4998c1a39 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -5819,7 +5819,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
   int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0;
   int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0;
-  int have_tar = 0;
+  int have_tar = 0, have_ebb = 0, have_pmu = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
   struct tdesc_arch_data *tdesc_data = NULL;
@@ -6159,6 +6159,64 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	}
       else
 	have_tar = 0;
+
+      /* Event-based Branching Registers.  */
+      feature = tdesc_find_feature (tdesc,
+				    "org.gnu.gdb.power.ebb");
+      if (feature != NULL)
+	{
+	  static const char *const ebb_regs[] = {
+	    "bescr", "ebbhr", "ebbrr"
+	  };
+
+	  valid_p = 1;
+	  for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+						PPC_BESCR_REGNUM + i,
+						ebb_regs[i]);
+	  if (!valid_p)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+	  have_ebb = 1;
+	}
+      else
+	have_ebb = 0;
+
+      /* Subset of the ISA 2.07 Performance Monitor Registers provided
+	 by Linux.  */
+      feature = tdesc_find_feature (tdesc,
+				    "org.gnu.gdb.power.linux.pmu");
+      if (feature != NULL)
+	{
+	  valid_p = 1;
+
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_MMCR0_REGNUM,
+					      "mmcr0");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_MMCR2_REGNUM,
+					      "mmcr2");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_SIAR_REGNUM,
+					      "siar");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_SDAR_REGNUM,
+					      "sdar");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      PPC_SIER_REGNUM,
+					      "sier");
+
+	  if (!valid_p)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+	  have_pmu = 1;
+	}
+      else
+	have_pmu = 0;
     }
 
   /* If we have a 64-bit binary on a 32-bit target, complain.  Also
@@ -6356,6 +6414,20 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1;
   tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
   tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
+  tdep->have_ebb = have_ebb;
+
+  /* If additional pmu registers are added, care must be taken when
+     setting new fields in the tdep below, to maintain compatibility
+     with features that only provide some of the registers.  Currently
+     gdb access to the pmu registers is only supported in linux, and
+     linux only provides a subset of the pmu registers defined in the
+     architecture.  */
+
+  tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1;
+  tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1;
+  tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1;
+  tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1;
+  tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1;
 
   set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
   set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
