#ifndef XEN_TURNSTILE_H #define XEN_TURNSTILE_H #ifdef __XEN__ #include #else #include #endif #define TURNSTILE_OP_SET_POLICY 0 #define TURNSTILE_OP_PROTECT_RANGE 1 #define TURNSTILE_OP_UNPROTECT_RANGE 2 #define TURNSTILE_OP_REQUEST_WRITE 3 #define TURNSTILE_OP_GET_VIOLATIONS 4 #define TURNSTILE_OP_GET_STATS 5 #define TURNSTILE_OP_UPLOAD_METADATA 6 #define TURNSTILE_POLICY_DISABLED 0 #define TURNSTILE_POLICY_AUDIT 1 #define TURNSTILE_POLICY_ENFORCE 2 #define TURNSTILE_MAX_RANGES 256 #define TURNSTILE_RING_SIZE 4096 #define TURNSTILE_MAX_FUNC_ENTRIES 65536 #define TURNSTILE_MAX_JUMP_ENTRIES 32768 #define TURNSTILE_IMPLICIT_DENIED 0 #define TURNSTILE_IMPLICIT_FTRACE 1 #define TURNSTILE_IMPLICIT_STATIC 2 struct turnstile_violation { uint64_t timestamp; uint64_t gpa; uint64_t rip; uint64_t cr3; uint32_t access_flags; uint32_t response; uint8_t insn_bytes[16]; uint32_t seq; uint32_t _pad; }; struct turnstile_stats { uint64_t violations_total; uint64_t violations_blocked; uint64_t violations_allowed; uint64_t implicit_ftrace; uint64_t implicit_static_key; uint64_t explicit_write_grants; uint64_t ring_overflows; }; struct turnstile_op_set_policy { uint32_t policy; uint32_t _pad; }; struct turnstile_op_protect_range { uint64_t gpa_start; uint64_t length; }; struct turnstile_op_request_write { uint64_t gpa_start; uint64_t length; uint32_t timeout_ms; uint32_t _pad; }; struct turnstile_op_get_violations { uint64_t buffer_ptr; uint32_t max_entries; uint32_t entries_returned; uint32_t overflow_count; uint32_t _pad; }; struct turnstile_op_upload_metadata { uint64_t buffer_ptr; uint32_t metadata_type; uint32_t count; }; #define TURNSTILE_META_FUNC_ENTRIES 0 #define TURNSTILE_META_JUMP_ENTRIES 1 #ifdef __XEN__ #include #include #include #include struct turnstile_range { uint64_t gpa_start; uint64_t gpa_end; p2m_type_t original_type; bool active; }; struct turnstile_write_grant { uint64_t gpa_start; uint64_t gpa_end; s_time_t expiry; bool active; }; struct turnstile_domain_state { rwlock_t lock; uint32_t policy; struct turnstile_range ranges[TURNSTILE_MAX_RANGES]; unsigned int num_ranges; struct turnstile_violation ring[TURNSTILE_RING_SIZE]; uint32_t ring_head; uint32_t ring_tail; uint32_t ring_seq; uint32_t overflow_count; uint64_t *func_entries; unsigned int num_func_entries; uint64_t *jump_entries; unsigned int num_jump_entries; struct turnstile_write_grant write_grant; struct turnstile_stats stats; }; int turnstile_domain_init(struct domain *d); void turnstile_domain_destroy(struct domain *d); long do_turnstile_op(unsigned int op, domid_t domid, XEN_GUEST_HANDLE_PARAM(void) arg); int turnstile_check_violation(struct domain *d, uint64_t gpa, uint64_t rip, uint64_t cr3, uint32_t access_flags, const uint8_t *insn_bytes); #endif #endif