This patch introdces a 'checker' field to decode_action, and calls
checkers when instruction decoding. This allows further analysis
for specific instructions.

Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 arch/arm/kernel/probes.c | 10 ++++++++++
 arch/arm/kernel/probes.h | 10 ++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/probes.c b/arch/arm/kernel/probes.c
index ec030b8..6164b4d 100644
--- a/arch/arm/kernel/probes.c
+++ b/arch/arm/kernel/probes.c
@@ -393,6 +393,7 @@ probes_decode_insn(probes_opcode_t insn, struct 
arch_probes_insn *asi,
        const struct decode_header *h = (struct decode_header *)table;
        const struct decode_header *next;
        bool matched = false;
+       probes_opcode_t origin_insn = insn;
 
        if (emulate)
                insn = prepare_emulated_insn(insn, asi, thumb);
@@ -423,17 +424,26 @@ probes_decode_insn(probes_opcode_t insn, struct 
arch_probes_insn *asi,
 
                case DECODE_TYPE_CUSTOM: {
                        struct decode_custom *d = (struct decode_custom *)h;
+                       probes_check_t *checker = 
actions[d->decoder.action].checker;
+                       if (checker && (checker(origin_insn, asi, h) == 
INSN_REJECTED))
+                               return INSN_REJECTED;
                        return actions[d->decoder.action].decoder(insn, asi, h);
                }
 
                case DECODE_TYPE_SIMULATE: {
                        struct decode_simulate *d = (struct decode_simulate *)h;
+                       probes_check_t *checker = 
actions[d->handler.action].checker;
+                       if (checker && (checker(origin_insn, asi, h) == 
INSN_REJECTED))
+                               return INSN_REJECTED;
                        asi->insn_handler = actions[d->handler.action].handler;
                        return INSN_GOOD_NO_SLOT;
                }
 
                case DECODE_TYPE_EMULATE: {
                        struct decode_emulate *d = (struct decode_emulate *)h;
+                       probes_check_t *checker = 
actions[d->handler.action].checker;
+                       if (checker && (checker(origin_insn, asi, h) == 
INSN_REJECTED))
+                               return INSN_REJECTED;
 
                        if (!emulate)
                                return actions[d->handler.action].decoder(insn,
diff --git a/arch/arm/kernel/probes.h b/arch/arm/kernel/probes.h
index 739c2a2..c56dd3d 100644
--- a/arch/arm/kernel/probes.h
+++ b/arch/arm/kernel/probes.h
@@ -309,9 +309,15 @@ typedef enum probes_insn 
(probes_custom_decode_t)(probes_opcode_t,
                                                  struct arch_probes_insn *,
                                                  const struct decode_header *);
 
+typedef enum probes_insn (probes_check_t)(probes_opcode_t,
+                                          struct arch_probes_insn *,
+                                          const struct decode_header *);
 struct decode_action {
-       probes_insn_handler_t   *handler;
-       probes_custom_decode_t  *decoder;
+       probes_check_t *checker;
+       union {
+               probes_insn_handler_t   *handler;
+               probes_custom_decode_t  *decoder;
+       };
 };
 
 #define DECODE_END                     \
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to