1 /*
2  * Copyright (C) 2016 Citrix Systems R&D Ltd.
3  */
4 
5 #ifndef __XEN_LIVEPATCH_PAYLOAD_H__
6 #define __XEN_LIVEPATCH_PAYLOAD_H__
7 #include <xen/virtual_region.h>
8 
9 /* To contain the ELF Note header. */
10 struct livepatch_build_id {
11    const void *p;
12    unsigned int len;
13 };
14 
15 typedef struct payload livepatch_payload_t;
16 
17 /*
18  * The following definitions are to be used in patches. They are taken
19  * from kpatch.
20  */
21 typedef void livepatch_loadcall_t(void);
22 typedef void livepatch_unloadcall_t(void);
23 
24 typedef int livepatch_precall_t(livepatch_payload_t *arg);
25 typedef int livepatch_actioncall_t(livepatch_payload_t *arg);
26 typedef void livepatch_postcall_t(livepatch_payload_t *arg);
27 
28 struct livepatch_hooks {
29     struct {
30         livepatch_precall_t *const *pre;
31         livepatch_actioncall_t *const *action;
32         livepatch_postcall_t *const *post;
33     } apply, revert;
34 };
35 
36 struct livepatch_metadata {
37     const char *data; /* Ptr to .modinfo section with ASCII data. */
38     uint32_t len;     /* Length of the metadata section. */
39 };
40 
41 struct payload {
42     uint32_t state;                      /* One of the LIVEPATCH_STATE_*. */
43     int32_t rc;                          /* 0 or -XEN_EXX. */
44     bool reverted;                       /* Whether it was reverted. */
45     bool safe_to_reapply;                /* Can apply safely after revert. */
46     struct list_head list;               /* Linked to 'payload_list'. */
47     const void *text_addr;               /* Virtual address of .text. */
48     size_t text_size;                    /* .. and its size. */
49     const void *rw_addr;                 /* Virtual address of .data. */
50     size_t rw_size;                      /* .. and its size (if any). */
51     const void *ro_addr;                 /* Virtual address of .rodata. */
52     size_t ro_size;                      /* .. and its size (if any). */
53     unsigned int pages;                  /* Total pages for [text,rw,ro]_addr */
54     struct list_head applied_list;       /* Linked to 'applied_list'. */
55     struct livepatch_func *funcs;        /* The array of functions to patch. */
56     unsigned int nfuncs;                 /* Nr of functions to patch. */
57     const struct livepatch_symbol *symtab; /* All symbols. */
58     const char *strtab;                  /* Pointer to .strtab. */
59     struct virtual_region region;        /* symbol, bug.frame patching and
60                                             exception table (x86). */
61     unsigned int nsyms;                  /* Nr of entries in .strtab and symbols. */
62     struct livepatch_build_id id;        /* ELFNOTE_DESC(.note.gnu.build-id) of the payload. */
63     struct livepatch_build_id dep;       /* ELFNOTE_DESC(.livepatch.depends). */
64     struct livepatch_build_id xen_dep;   /* ELFNOTE_DESC(.livepatch.xen_depends). */
65     livepatch_loadcall_t *const *load_funcs;   /* The array of funcs to call after */
66     livepatch_unloadcall_t *const *unload_funcs;/* load and unload of the payload. */
67     struct livepatch_hooks hooks;        /* Pre and post hooks for apply and revert */
68     unsigned int n_load_funcs;           /* Nr of the funcs to load and execute. */
69     unsigned int n_unload_funcs;         /* Nr of funcs to call durung unload. */
70     char name[XEN_LIVEPATCH_NAME_SIZE];  /* Name of it. */
71     struct livepatch_metadata metadata;  /* Module meta data record */
72 };
73 
74 /*
75  * LIVEPATCH_LOAD_HOOK macro
76  *
77  * Declares a function pointer to be allocated in a new
78  * .livepatch.hook.load section.  This livepatch_load_data symbol is later
79  * stripped by create-diff-object so that it can be declared in multiple
80  * objects that are later linked together, avoiding global symbol
81  * collision.  Since multiple hooks can be registered, the
82  * .livepatch.hook.load section is a table of functions that will be
83  * executed in series by the livepatch infrastructure at patch load time.
84  */
85 #define LIVEPATCH_LOAD_HOOK(_fn) \
86     livepatch_loadcall_t *__weak \
87         const livepatch_load_data_##_fn __section(".livepatch.hooks.load") = _fn;
88 
89 /*
90  * LIVEPATCH_UNLOAD_HOOK macro
91  *
92  * Same as LOAD hook with s/load/unload/
93  */
94 #define LIVEPATCH_UNLOAD_HOOK(_fn) \
95      livepatch_unloadcall_t *__weak \
96         const livepatch_unload_data_##_fn __section(".livepatch.hooks.unload") = _fn;
97 
98 #define LIVEPATCH_PREAPPLY_HOOK(_fn) \
99     livepatch_precall_t *__attribute__((weak, used)) \
100         const livepatch_preapply_data_##_fn __section(".livepatch.hooks.preapply") = _fn;
101 
102 #define LIVEPATCH_APPLY_HOOK(_fn) \
103     livepatch_actioncall_t *__attribute__((weak, used)) \
104         const livepatch_apply_data_##_fn __section(".livepatch.hooks.apply") = _fn;
105 
106 #define LIVEPATCH_POSTAPPLY_HOOK(_fn) \
107     livepatch_postcall_t *__attribute__((weak, used)) \
108         const livepatch_postapply_data_##_fn __section(".livepatch.hooks.postapply") = _fn;
109 
110 #define LIVEPATCH_PREREVERT_HOOK(_fn) \
111     livepatch_precall_t *__attribute__((weak, used)) \
112         const livepatch_prerevert_data_##_fn __section(".livepatch.hooks.prerevert") = _fn;
113 
114 #define LIVEPATCH_REVERT_HOOK(_fn) \
115     livepatch_actioncall_t *__attribute__((weak, used)) \
116         const livepatch_revert_data_##_fn __section(".livepatch.hooks.revert") = _fn;
117 
118 #define LIVEPATCH_POSTREVERT_HOOK(_fn) \
119     livepatch_postcall_t *__attribute__((weak, used)) \
120         const livepatch_postrevert_data_##_fn __section(".livepatch.hooks.postrevert") = _fn;
121 
122 #endif /* __XEN_LIVEPATCH_PAYLOAD_H__ */
123 
124 /*
125  * Local variables:
126  * mode: C
127  * c-file-style: "BSD"
128  * c-basic-offset: 4
129  * tab-width: 4
130  * indent-tabs-mode: nil
131  * End:
132  */
133