__NR_FG_FILTER_IDS__
 };
 
-#define SR_FGF(sr, g, b, p, f)                                 \
-       {                                                       \
-               .encoding       = sr,                           \
-               .end            = sr,                           \
-               .tc             = {                             \
+#define __FGT(g, b, p, f)                                      \
+               {                                               \
                        .fgt = g ## _GROUP,                     \
                        .bit = g ## _EL2_ ## b ## _SHIFT,       \
                        .pol = p,                               \
                        .fgf = f,                               \
-               },                                              \
+               }
+
+#define FGT(g, b, p)           __FGT(g, b, p, __NO_FGF__)
+
+#define SR_FGF(sr, g, b, p, f)                                 \
+       {                                                       \
+               .encoding       = sr,                           \
+               .end            = sr,                           \
+               .tc             = __FGT(g, b, p, f),            \
                .line = __LINE__,                               \
        }
 
        SR_FGT(SYS_AMEVCNTR0_EL0(0),    HAFGRTR, AMEVCNTR00_EL0, 1),
 };
 
+/*
+ * Additional FGTs that do not fire with ESR_EL2.EC==0x18. This table
+ * isn't used for exception routing, but only as a promise that the
+ * trap is handled somewhere else.
+ */
+static const union trap_config non_0x18_fgt[] __initconst = {
+       FGT(HFGITR, nGCSSTR_EL1, 0),
+       FGT(HFGITR, SVC_EL1, 1),
+       FGT(HFGITR, SVC_EL0, 1),
+       FGT(HFGITR, ERET, 1),
+};
+
 static union trap_config get_trap_config(u32 sysreg)
 {
        return (union trap_config) {
                }
        }
 
+       for (int i = 0; i < ARRAY_SIZE(non_0x18_fgt); i++) {
+               if (!aggregate_fgt(non_0x18_fgt[i])) {
+                       ret = -EINVAL;
+                       kvm_err("non_0x18_fgt[%d] is reserved\n", i);
+               }
+       }
+
        ret = check_all_fgt_masks(ret);
 
        kvm_info("nv: %ld fine grained trap handlers\n",