1 /*
2  * Copyright (c) 2019 Amazon.com, Inc. or its affiliates. All rights reserved.
3  *
4  */
5 
6 #include "config.h"
7 #include <xen/lib.h>
8 #include <xen/types.h>
9 #include <xen/version.h>
10 #include <xen/livepatch.h>
11 #include <xen/livepatch_payload.h>
12 
13 #include <public/sysctl.h>
14 
15 static const char hello_world_patch_this_fnc[] = "xen_extra_version";
16 extern const char *xen_hello_world(void);
17 
18 static unsigned int apply_cnt;
19 
pre_apply_hook(livepatch_payload_t * payload)20 static int pre_apply_hook(livepatch_payload_t *payload)
21 {
22     int i;
23 
24     printk(KERN_DEBUG "%s: Hook starting.\n", __func__);
25 
26     for (i = 0; i < payload->nfuncs; i++)
27     {
28         struct livepatch_func *func = &payload->funcs[i];
29 
30         BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
31         printk(KERN_DEBUG "%s: pre applied: %s\n", __func__, func->name);
32     }
33 
34     printk(KERN_DEBUG "%s: Hook done.\n", __func__);
35 
36     return 0;
37 }
38 
apply_hook(livepatch_payload_t * payload)39 static int apply_hook(livepatch_payload_t *payload)
40 {
41     int i;
42 
43     printk(KERN_DEBUG "%s: Hook starting.\n", __func__);
44 
45     for (i = 0; i < payload->nfuncs; i++)
46     {
47         struct livepatch_func *func = &payload->funcs[i];
48 
49         apply_cnt++;
50         printk(KERN_DEBUG "%s: applying: %s\n", __func__, func->name);
51     }
52 
53     printk(KERN_DEBUG "%s: Hook done.\n", __func__);
54 
55     return -EINVAL; /* Mark action as inconsistent */
56 }
57 
post_apply_hook(livepatch_payload_t * payload)58 static void post_apply_hook(livepatch_payload_t *payload)
59 {
60     int i;
61 
62     printk(KERN_DEBUG "%s: Hook starting.\n", __func__);
63 
64     for (i = 0; i < payload->nfuncs; i++)
65     {
66         struct livepatch_func *func = &payload->funcs[i];
67 
68         BUG_ON(apply_cnt != 1);
69         BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
70         printk(KERN_DEBUG "%s: post applied: %s\n", __func__, func->name);
71     }
72 
73     printk(KERN_DEBUG "%s: Hook done.\n", __func__);
74 }
75 
pre_revert_hook(livepatch_payload_t * payload)76 static int pre_revert_hook(livepatch_payload_t *payload)
77 {
78     int i;
79 
80     printk(KERN_DEBUG "%s: Hook starting.\n", __func__);
81 
82     for (i = 0; i < payload->nfuncs; i++)
83     {
84         struct livepatch_func *func = &payload->funcs[i];
85 
86         BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
87         printk(KERN_DEBUG "%s: pre reverted: %s\n", __func__, func->name);
88     }
89 
90     printk(KERN_DEBUG "%s: Hook done.\n", __func__);
91 
92     return 0;
93 }
94 
post_revert_hook(livepatch_payload_t * payload)95 static void post_revert_hook(livepatch_payload_t *payload)
96 {
97     int i;
98 
99     printk(KERN_DEBUG "%s: Hook starting.\n", __func__);
100 
101     for (i = 0; i < payload->nfuncs; i++)
102     {
103         struct livepatch_func *func = &payload->funcs[i];
104 
105         BUG_ON(func->applied == LIVEPATCH_FUNC_APPLIED);
106         printk(KERN_DEBUG "%s: post reverted: %s\n", __func__, func->name);
107     }
108 
109     printk(KERN_DEBUG "%s: Hook done.\n", __func__);
110 }
111 
112 LIVEPATCH_APPLY_HOOK(apply_hook);
113 
114 LIVEPATCH_PREAPPLY_HOOK(pre_apply_hook);
115 LIVEPATCH_POSTAPPLY_HOOK(post_apply_hook);
116 LIVEPATCH_PREREVERT_HOOK(pre_revert_hook);
117 LIVEPATCH_POSTREVERT_HOOK(post_revert_hook);
118 
119 struct livepatch_func __section(".livepatch.funcs") livepatch_xen_hello_world = {
120     .version = LIVEPATCH_PAYLOAD_VERSION,
121     .name = hello_world_patch_this_fnc,
122     .new_addr = xen_hello_world,
123     .old_addr = xen_extra_version,
124     .new_size = NEW_CODE_SZ,
125     .old_size = OLD_CODE_SZ,
126 };
127 
128 /*
129  * Local variables:
130  * mode: C
131  * c-file-style: "BSD"
132  * c-basic-offset: 4
133  * tab-width: 4
134  * indent-tabs-mode: nil
135  * End:
136  */
137