xref: /linux/Documentation/livepatch/shadow-vars.rst (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1439e7271SJoe Lawrence================
2439e7271SJoe LawrenceShadow Variables
3439e7271SJoe Lawrence================
4439e7271SJoe Lawrence
5439e7271SJoe LawrenceShadow variables are a simple way for livepatch modules to associate
6439e7271SJoe Lawrenceadditional "shadow" data with existing data structures.  Shadow data is
7439e7271SJoe Lawrenceallocated separately from parent data structures, which are left
8439e7271SJoe Lawrenceunmodified.  The shadow variable API described in this document is used
919205da6SPetr Mladekto allocate/add and remove/free shadow variables to/from their parents.
10439e7271SJoe Lawrence
11439e7271SJoe LawrenceThe implementation introduces a global, in-kernel hashtable that
12439e7271SJoe Lawrenceassociates pointers to parent objects and a numeric identifier of the
13439e7271SJoe Lawrenceshadow data.  The numeric identifier is a simple enumeration that may be
14439e7271SJoe Lawrenceused to describe shadow variable version, class or type, etc.  More
15439e7271SJoe Lawrencespecifically, the parent pointer serves as the hashtable key while the
16439e7271SJoe Lawrencenumeric id subsequently filters hashtable queries.  Multiple shadow
17439e7271SJoe Lawrencevariables may attach to the same parent object, but their numeric
18439e7271SJoe Lawrenceidentifier distinguishes between them.
19439e7271SJoe Lawrence
20439e7271SJoe Lawrence
21439e7271SJoe Lawrence1. Brief API summary
22439e7271SJoe Lawrence====================
23439e7271SJoe Lawrence
24439e7271SJoe Lawrence(See the full API usage docbook notes in livepatch/shadow.c.)
25439e7271SJoe Lawrence
26439e7271SJoe LawrenceA hashtable references all shadow variables.  These references are
27439e7271SJoe Lawrencestored and retrieved through a <obj, id> pair.
28439e7271SJoe Lawrence
29439e7271SJoe Lawrence* The klp_shadow variable data structure encapsulates both tracking
30439e7271SJoe Lawrence  meta-data and shadow-data:
3189e33ea7SMauro Carvalho Chehab
32439e7271SJoe Lawrence  - meta-data
3389e33ea7SMauro Carvalho Chehab
34439e7271SJoe Lawrence    - obj - pointer to parent object
35439e7271SJoe Lawrence    - id - data identifier
3689e33ea7SMauro Carvalho Chehab
37439e7271SJoe Lawrence  - data[] - storage for shadow data
38439e7271SJoe Lawrence
39439e7271SJoe LawrenceIt is important to note that the klp_shadow_alloc() and
40e91c2518SPetr Mladekklp_shadow_get_or_alloc() are zeroing the variable by default.
41e91c2518SPetr MladekThey also allow to call a custom constructor function when a non-zero
42e91c2518SPetr Mladekvalue is needed. Callers should provide whatever mutual exclusion
43e91c2518SPetr Mladekis required.
44e91c2518SPetr Mladek
45e91c2518SPetr MladekNote that the constructor is called under klp_shadow_lock spinlock. It allows
46e91c2518SPetr Mladekto do actions that can be done only once when a new variable is allocated.
47439e7271SJoe Lawrence
48439e7271SJoe Lawrence* klp_shadow_get() - retrieve a shadow variable data pointer
49439e7271SJoe Lawrence  - search hashtable for <obj, id> pair
50439e7271SJoe Lawrence
51439e7271SJoe Lawrence* klp_shadow_alloc() - allocate and add a new shadow variable
52439e7271SJoe Lawrence  - search hashtable for <obj, id> pair
5389e33ea7SMauro Carvalho Chehab
54439e7271SJoe Lawrence  - if exists
5589e33ea7SMauro Carvalho Chehab
56439e7271SJoe Lawrence    - WARN and return NULL
5789e33ea7SMauro Carvalho Chehab
58439e7271SJoe Lawrence  - if <obj, id> doesn't already exist
5989e33ea7SMauro Carvalho Chehab
60439e7271SJoe Lawrence    - allocate a new shadow variable
61e91c2518SPetr Mladek    - initialize the variable using a custom constructor and data when provided
62439e7271SJoe Lawrence    - add <obj, id> to the global hashtable
63439e7271SJoe Lawrence
64439e7271SJoe Lawrence* klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
65439e7271SJoe Lawrence  - search hashtable for <obj, id> pair
6689e33ea7SMauro Carvalho Chehab
67439e7271SJoe Lawrence  - if exists
6889e33ea7SMauro Carvalho Chehab
69439e7271SJoe Lawrence    - return existing shadow variable
7089e33ea7SMauro Carvalho Chehab
71439e7271SJoe Lawrence  - if <obj, id> doesn't already exist
7289e33ea7SMauro Carvalho Chehab
73439e7271SJoe Lawrence    - allocate a new shadow variable
74e91c2518SPetr Mladek    - initialize the variable using a custom constructor and data when provided
75439e7271SJoe Lawrence    - add <obj, id> pair to the global hashtable
76439e7271SJoe Lawrence
77439e7271SJoe Lawrence* klp_shadow_free() - detach and free a <obj, id> shadow variable
78439e7271SJoe Lawrence  - find and remove a <obj, id> reference from global hashtable
7989e33ea7SMauro Carvalho Chehab
803b2c77d0SPetr Mladek    - if found
8189e33ea7SMauro Carvalho Chehab
823b2c77d0SPetr Mladek      - call destructor function if defined
833b2c77d0SPetr Mladek      - free shadow variable
84439e7271SJoe Lawrence
85e368cd72SDavid Vernet* klp_shadow_free_all() - detach and free all <_, id> shadow variables
86e368cd72SDavid Vernet  - find and remove any <_, id> references from global hashtable
8789e33ea7SMauro Carvalho Chehab
883b2c77d0SPetr Mladek    - if found
8989e33ea7SMauro Carvalho Chehab
903b2c77d0SPetr Mladek      - call destructor function if defined
913b2c77d0SPetr Mladek      - free shadow variable
92439e7271SJoe Lawrence
93439e7271SJoe Lawrence
94439e7271SJoe Lawrence2. Use cases
95439e7271SJoe Lawrence============
96439e7271SJoe Lawrence
97439e7271SJoe Lawrence(See the example shadow variable livepatch modules in samples/livepatch/
98439e7271SJoe Lawrencefor full working demonstrations.)
99439e7271SJoe Lawrence
100439e7271SJoe LawrenceFor the following use-case examples, consider commit 1d147bfa6429
101439e7271SJoe Lawrence("mac80211: fix AP powersave TX vs.  wakeup race"), which added a
102439e7271SJoe Lawrencespinlock to net/mac80211/sta_info.h :: struct sta_info.  Each use-case
103439e7271SJoe Lawrenceexample can be considered a stand-alone livepatch implementation of this
104439e7271SJoe Lawrencefix.
105439e7271SJoe Lawrence
106439e7271SJoe Lawrence
107439e7271SJoe LawrenceMatching parent's lifecycle
108439e7271SJoe Lawrence---------------------------
109439e7271SJoe Lawrence
110439e7271SJoe LawrenceIf parent data structures are frequently created and destroyed, it may
111439e7271SJoe Lawrencebe easiest to align their shadow variables lifetimes to the same
112439e7271SJoe Lawrenceallocation and release functions.  In this case, the parent data
113439e7271SJoe Lawrencestructure is typically allocated, initialized, then registered in some
114439e7271SJoe Lawrencemanner.  Shadow variable allocation and setup can then be considered
115439e7271SJoe Lawrencepart of the parent's initialization and should be completed before the
116439e7271SJoe Lawrenceparent "goes live" (ie, any shadow variable get-API requests are made
117439e7271SJoe Lawrencefor this <obj, id> pair.)
118439e7271SJoe Lawrence
119439e7271SJoe LawrenceFor commit 1d147bfa6429, when a parent sta_info structure is allocated,
12089e33ea7SMauro Carvalho Chehaballocate a shadow copy of the ps_lock pointer, then initialize it::
121439e7271SJoe Lawrence
122439e7271SJoe Lawrence  #define PS_LOCK 1
123439e7271SJoe Lawrence  struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
124439e7271SJoe Lawrence				  const u8 *addr, gfp_t gfp)
125439e7271SJoe Lawrence  {
126439e7271SJoe Lawrence	struct sta_info *sta;
127439e7271SJoe Lawrence	spinlock_t *ps_lock;
128439e7271SJoe Lawrence
129439e7271SJoe Lawrence	/* Parent structure is created */
130439e7271SJoe Lawrence	sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
131439e7271SJoe Lawrence
132439e7271SJoe Lawrence	/* Attach a corresponding shadow variable, then initialize it */
133e91c2518SPetr Mladek	ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
134e91c2518SPetr Mladek				   NULL, NULL);
135439e7271SJoe Lawrence	if (!ps_lock)
136439e7271SJoe Lawrence		goto shadow_fail;
137439e7271SJoe Lawrence	spin_lock_init(ps_lock);
138439e7271SJoe Lawrence	...
139439e7271SJoe Lawrence
140439e7271SJoe LawrenceWhen requiring a ps_lock, query the shadow variable API to retrieve one
14189e33ea7SMauro Carvalho Chehabfor a specific struct sta_info:::
142439e7271SJoe Lawrence
143439e7271SJoe Lawrence  void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
144439e7271SJoe Lawrence  {
145439e7271SJoe Lawrence	spinlock_t *ps_lock;
146439e7271SJoe Lawrence
147439e7271SJoe Lawrence	/* sync with ieee80211_tx_h_unicast_ps_buf */
148439e7271SJoe Lawrence	ps_lock = klp_shadow_get(sta, PS_LOCK);
149439e7271SJoe Lawrence	if (ps_lock)
150439e7271SJoe Lawrence		spin_lock(ps_lock);
151439e7271SJoe Lawrence	...
152439e7271SJoe Lawrence
153439e7271SJoe LawrenceWhen the parent sta_info structure is freed, first free the shadow
15489e33ea7SMauro Carvalho Chehabvariable::
155439e7271SJoe Lawrence
156439e7271SJoe Lawrence  void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
157439e7271SJoe Lawrence  {
1583b2c77d0SPetr Mladek	klp_shadow_free(sta, PS_LOCK, NULL);
159439e7271SJoe Lawrence	kfree(sta);
160439e7271SJoe Lawrence	...
161439e7271SJoe Lawrence
162439e7271SJoe Lawrence
163439e7271SJoe LawrenceIn-flight parent objects
164439e7271SJoe Lawrence------------------------
165439e7271SJoe Lawrence
166439e7271SJoe LawrenceSometimes it may not be convenient or possible to allocate shadow
167439e7271SJoe Lawrencevariables alongside their parent objects.  Or a livepatch fix may
168a5907065SBhaskar Chowdhuryrequire shadow variables for only a subset of parent object instances.
169a5907065SBhaskar ChowdhuryIn these cases, the klp_shadow_get_or_alloc() call can be used to attach
170439e7271SJoe Lawrenceshadow variables to parents already in-flight.
171439e7271SJoe Lawrence
172439e7271SJoe LawrenceFor commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
17389e33ea7SMauro Carvalho Chehabinside ieee80211_sta_ps_deliver_wakeup()::
174439e7271SJoe Lawrence
175e91c2518SPetr Mladek  int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
176e91c2518SPetr Mladek  {
177e91c2518SPetr Mladek	spinlock_t *lock = shadow_data;
178e91c2518SPetr Mladek
179e91c2518SPetr Mladek	spin_lock_init(lock);
180e91c2518SPetr Mladek	return 0;
181e91c2518SPetr Mladek  }
182e91c2518SPetr Mladek
183439e7271SJoe Lawrence  #define PS_LOCK 1
184439e7271SJoe Lawrence  void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
185439e7271SJoe Lawrence  {
186439e7271SJoe Lawrence	spinlock_t *ps_lock;
187439e7271SJoe Lawrence
188439e7271SJoe Lawrence	/* sync with ieee80211_tx_h_unicast_ps_buf */
189439e7271SJoe Lawrence	ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
190e91c2518SPetr Mladek			sizeof(*ps_lock), GFP_ATOMIC,
191e91c2518SPetr Mladek			ps_lock_shadow_ctor, NULL);
192e91c2518SPetr Mladek
193439e7271SJoe Lawrence	if (ps_lock)
194439e7271SJoe Lawrence		spin_lock(ps_lock);
195439e7271SJoe Lawrence	...
196439e7271SJoe Lawrence
197439e7271SJoe LawrenceThis usage will create a shadow variable, only if needed, otherwise it
198439e7271SJoe Lawrencewill use one that was already created for this <obj, id> pair.
199439e7271SJoe Lawrence
200439e7271SJoe LawrenceLike the previous use-case, the shadow spinlock needs to be cleaned up.
201439e7271SJoe LawrenceA shadow variable can be freed just before its parent object is freed,
202439e7271SJoe Lawrenceor even when the shadow variable itself is no longer required.
203439e7271SJoe Lawrence
204439e7271SJoe Lawrence
205439e7271SJoe LawrenceOther use-cases
206439e7271SJoe Lawrence---------------
207439e7271SJoe Lawrence
208439e7271SJoe LawrenceShadow variables can also be used as a flag indicating that a data
209439e7271SJoe Lawrencestructure was allocated by new, livepatched code.  In this case, it
210439e7271SJoe Lawrencedoesn't matter what data value the shadow variable holds, its existence
211439e7271SJoe Lawrencesuggests how to handle the parent object.
212439e7271SJoe Lawrence
213439e7271SJoe Lawrence
214439e7271SJoe Lawrence3. References
215439e7271SJoe Lawrence=============
216439e7271SJoe Lawrence
217439e7271SJoe Lawrence* https://github.com/dynup/kpatch
21889e33ea7SMauro Carvalho Chehab
219439e7271SJoe Lawrence  The livepatch implementation is based on the kpatch version of shadow
220439e7271SJoe Lawrence  variables.
221439e7271SJoe Lawrence
222439e7271SJoe Lawrence* http://files.mkgnu.net/files/dynamos/doc/papers/dynamos_eurosys_07.pdf
22389e33ea7SMauro Carvalho Chehab
224439e7271SJoe Lawrence  Dynamic and Adaptive Updates of Non-Quiescent Subsystems in Commodity
225439e7271SJoe Lawrence  Operating System Kernels (Kritis Makris, Kyung Dong Ryu 2007) presented
226439e7271SJoe Lawrence  a datatype update technique called "shadow data structures".
227