~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/livepatch/shadow-vars.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/livepatch/shadow-vars.rst (Version linux-6.12-rc7) and /Documentation/livepatch/shadow-vars.rst (Version linux-5.15.171)


  1 ================                                    1 ================
  2 Shadow Variables                                    2 Shadow Variables
  3 ================                                    3 ================
  4                                                     4 
  5 Shadow variables are a simple way for livepatc      5 Shadow variables are a simple way for livepatch modules to associate
  6 additional "shadow" data with existing data st      6 additional "shadow" data with existing data structures.  Shadow data is
  7 allocated separately from parent data structur      7 allocated separately from parent data structures, which are left
  8 unmodified.  The shadow variable API described      8 unmodified.  The shadow variable API described in this document is used
  9 to allocate/add and remove/free shadow variabl      9 to allocate/add and remove/free shadow variables to/from their parents.
 10                                                    10 
 11 The implementation introduces a global, in-ker     11 The implementation introduces a global, in-kernel hashtable that
 12 associates pointers to parent objects and a nu     12 associates pointers to parent objects and a numeric identifier of the
 13 shadow data.  The numeric identifier is a simp     13 shadow data.  The numeric identifier is a simple enumeration that may be
 14 used to describe shadow variable version, clas     14 used to describe shadow variable version, class or type, etc.  More
 15 specifically, the parent pointer serves as the     15 specifically, the parent pointer serves as the hashtable key while the
 16 numeric id subsequently filters hashtable quer     16 numeric id subsequently filters hashtable queries.  Multiple shadow
 17 variables may attach to the same parent object     17 variables may attach to the same parent object, but their numeric
 18 identifier distinguishes between them.             18 identifier distinguishes between them.
 19                                                    19 
 20                                                    20 
 21 1. Brief API summary                               21 1. Brief API summary
 22 ====================                               22 ====================
 23                                                    23 
 24 (See the full API usage docbook notes in livep     24 (See the full API usage docbook notes in livepatch/shadow.c.)
 25                                                    25 
 26 A hashtable references all shadow variables.       26 A hashtable references all shadow variables.  These references are
 27 stored and retrieved through a <obj, id> pair.     27 stored and retrieved through a <obj, id> pair.
 28                                                    28 
 29 * The klp_shadow variable data structure encap     29 * The klp_shadow variable data structure encapsulates both tracking
 30   meta-data and shadow-data:                       30   meta-data and shadow-data:
 31                                                    31 
 32   - meta-data                                      32   - meta-data
 33                                                    33 
 34     - obj - pointer to parent object               34     - obj - pointer to parent object
 35     - id - data identifier                         35     - id - data identifier
 36                                                    36 
 37   - data[] - storage for shadow data               37   - data[] - storage for shadow data
 38                                                    38 
 39 It is important to note that the klp_shadow_al     39 It is important to note that the klp_shadow_alloc() and
 40 klp_shadow_get_or_alloc() are zeroing the vari     40 klp_shadow_get_or_alloc() are zeroing the variable by default.
 41 They also allow to call a custom constructor f     41 They also allow to call a custom constructor function when a non-zero
 42 value is needed. Callers should provide whatev     42 value is needed. Callers should provide whatever mutual exclusion
 43 is required.                                       43 is required.
 44                                                    44 
 45 Note that the constructor is called under klp_     45 Note that the constructor is called under klp_shadow_lock spinlock. It allows
 46 to do actions that can be done only once when      46 to do actions that can be done only once when a new variable is allocated.
 47                                                    47 
 48 * klp_shadow_get() - retrieve a shadow variabl     48 * klp_shadow_get() - retrieve a shadow variable data pointer
 49   - search hashtable for <obj, id> pair            49   - search hashtable for <obj, id> pair
 50                                                    50 
 51 * klp_shadow_alloc() - allocate and add a new      51 * klp_shadow_alloc() - allocate and add a new shadow variable
 52   - search hashtable for <obj, id> pair            52   - search hashtable for <obj, id> pair
 53                                                    53 
 54   - if exists                                      54   - if exists
 55                                                    55 
 56     - WARN and return NULL                         56     - WARN and return NULL
 57                                                    57 
 58   - if <obj, id> doesn't already exist             58   - if <obj, id> doesn't already exist
 59                                                    59 
 60     - allocate a new shadow variable               60     - allocate a new shadow variable
 61     - initialize the variable using a custom c     61     - initialize the variable using a custom constructor and data when provided
 62     - add <obj, id> to the global hashtable        62     - add <obj, id> to the global hashtable
 63                                                    63 
 64 * klp_shadow_get_or_alloc() - get existing or      64 * klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
 65   - search hashtable for <obj, id> pair            65   - search hashtable for <obj, id> pair
 66                                                    66 
 67   - if exists                                      67   - if exists
 68                                                    68 
 69     - return existing shadow variable              69     - return existing shadow variable
 70                                                    70 
 71   - if <obj, id> doesn't already exist             71   - if <obj, id> doesn't already exist
 72                                                    72 
 73     - allocate a new shadow variable               73     - allocate a new shadow variable
 74     - initialize the variable using a custom c     74     - initialize the variable using a custom constructor and data when provided
 75     - add <obj, id> pair to the global hashtab     75     - add <obj, id> pair to the global hashtable
 76                                                    76 
 77 * klp_shadow_free() - detach and free a <obj,      77 * klp_shadow_free() - detach and free a <obj, id> shadow variable
 78   - find and remove a <obj, id> reference from     78   - find and remove a <obj, id> reference from global hashtable
 79                                                    79 
 80     - if found                                     80     - if found
 81                                                    81 
 82       - call destructor function if defined        82       - call destructor function if defined
 83       - free shadow variable                       83       - free shadow variable
 84                                                    84 
 85 * klp_shadow_free_all() - detach and free all  !!  85 * klp_shadow_free_all() - detach and free all <*, id> shadow variables
 86   - find and remove any <_, id> references fro !!  86   - find and remove any <*, id> references from global hashtable
 87                                                    87 
 88     - if found                                     88     - if found
 89                                                    89 
 90       - call destructor function if defined        90       - call destructor function if defined
 91       - free shadow variable                       91       - free shadow variable
 92                                                    92 
 93                                                    93 
 94 2. Use cases                                       94 2. Use cases
 95 ============                                       95 ============
 96                                                    96 
 97 (See the example shadow variable livepatch mod     97 (See the example shadow variable livepatch modules in samples/livepatch/
 98 for full working demonstrations.)                  98 for full working demonstrations.)
 99                                                    99 
100 For the following use-case examples, consider     100 For the following use-case examples, consider commit 1d147bfa6429
101 ("mac80211: fix AP powersave TX vs.  wakeup ra    101 ("mac80211: fix AP powersave TX vs.  wakeup race"), which added a
102 spinlock to net/mac80211/sta_info.h :: struct     102 spinlock to net/mac80211/sta_info.h :: struct sta_info.  Each use-case
103 example can be considered a stand-alone livepa    103 example can be considered a stand-alone livepatch implementation of this
104 fix.                                              104 fix.
105                                                   105 
106                                                   106 
107 Matching parent's lifecycle                       107 Matching parent's lifecycle
108 ---------------------------                       108 ---------------------------
109                                                   109 
110 If parent data structures are frequently creat    110 If parent data structures are frequently created and destroyed, it may
111 be easiest to align their shadow variables lif    111 be easiest to align their shadow variables lifetimes to the same
112 allocation and release functions.  In this cas    112 allocation and release functions.  In this case, the parent data
113 structure is typically allocated, initialized,    113 structure is typically allocated, initialized, then registered in some
114 manner.  Shadow variable allocation and setup     114 manner.  Shadow variable allocation and setup can then be considered
115 part of the parent's initialization and should    115 part of the parent's initialization and should be completed before the
116 parent "goes live" (ie, any shadow variable ge    116 parent "goes live" (ie, any shadow variable get-API requests are made
117 for this <obj, id> pair.)                         117 for this <obj, id> pair.)
118                                                   118 
119 For commit 1d147bfa6429, when a parent sta_inf    119 For commit 1d147bfa6429, when a parent sta_info structure is allocated,
120 allocate a shadow copy of the ps_lock pointer,    120 allocate a shadow copy of the ps_lock pointer, then initialize it::
121                                                   121 
122   #define PS_LOCK 1                               122   #define PS_LOCK 1
123   struct sta_info *sta_info_alloc(struct ieee8    123   struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
124                                   const u8 *ad    124                                   const u8 *addr, gfp_t gfp)
125   {                                               125   {
126         struct sta_info *sta;                     126         struct sta_info *sta;
127         spinlock_t *ps_lock;                      127         spinlock_t *ps_lock;
128                                                   128 
129         /* Parent structure is created */         129         /* Parent structure is created */
130         sta = kzalloc(sizeof(*sta) + hw->sta_d    130         sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
131                                                   131 
132         /* Attach a corresponding shadow varia    132         /* Attach a corresponding shadow variable, then initialize it */
133         ps_lock = klp_shadow_alloc(sta, PS_LOC    133         ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
134                                    NULL, NULL)    134                                    NULL, NULL);
135         if (!ps_lock)                             135         if (!ps_lock)
136                 goto shadow_fail;                 136                 goto shadow_fail;
137         spin_lock_init(ps_lock);                  137         spin_lock_init(ps_lock);
138         ...                                       138         ...
139                                                   139 
140 When requiring a ps_lock, query the shadow var    140 When requiring a ps_lock, query the shadow variable API to retrieve one
141 for a specific struct sta_info:::                 141 for a specific struct sta_info:::
142                                                   142 
143   void ieee80211_sta_ps_deliver_wakeup(struct     143   void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
144   {                                               144   {
145         spinlock_t *ps_lock;                      145         spinlock_t *ps_lock;
146                                                   146 
147         /* sync with ieee80211_tx_h_unicast_ps    147         /* sync with ieee80211_tx_h_unicast_ps_buf */
148         ps_lock = klp_shadow_get(sta, PS_LOCK)    148         ps_lock = klp_shadow_get(sta, PS_LOCK);
149         if (ps_lock)                              149         if (ps_lock)
150                 spin_lock(ps_lock);               150                 spin_lock(ps_lock);
151         ...                                       151         ...
152                                                   152 
153 When the parent sta_info structure is freed, f    153 When the parent sta_info structure is freed, first free the shadow
154 variable::                                        154 variable::
155                                                   155 
156   void sta_info_free(struct ieee80211_local *l    156   void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
157   {                                               157   {
158         klp_shadow_free(sta, PS_LOCK, NULL);      158         klp_shadow_free(sta, PS_LOCK, NULL);
159         kfree(sta);                               159         kfree(sta);
160         ...                                       160         ...
161                                                   161 
162                                                   162 
163 In-flight parent objects                          163 In-flight parent objects
164 ------------------------                          164 ------------------------
165                                                   165 
166 Sometimes it may not be convenient or possible    166 Sometimes it may not be convenient or possible to allocate shadow
167 variables alongside their parent objects.  Or     167 variables alongside their parent objects.  Or a livepatch fix may
168 require shadow variables for only a subset of     168 require shadow variables for only a subset of parent object instances.
169 In these cases, the klp_shadow_get_or_alloc()     169 In these cases, the klp_shadow_get_or_alloc() call can be used to attach
170 shadow variables to parents already in-flight.    170 shadow variables to parents already in-flight.
171                                                   171 
172 For commit 1d147bfa6429, a good spot to alloca    172 For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
173 inside ieee80211_sta_ps_deliver_wakeup()::        173 inside ieee80211_sta_ps_deliver_wakeup()::
174                                                   174 
175   int ps_lock_shadow_ctor(void *obj, void *sha    175   int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
176   {                                               176   {
177         spinlock_t *lock = shadow_data;           177         spinlock_t *lock = shadow_data;
178                                                   178 
179         spin_lock_init(lock);                     179         spin_lock_init(lock);
180         return 0;                                 180         return 0;
181   }                                               181   }
182                                                   182 
183   #define PS_LOCK 1                               183   #define PS_LOCK 1
184   void ieee80211_sta_ps_deliver_wakeup(struct     184   void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
185   {                                               185   {
186         spinlock_t *ps_lock;                      186         spinlock_t *ps_lock;
187                                                   187 
188         /* sync with ieee80211_tx_h_unicast_ps    188         /* sync with ieee80211_tx_h_unicast_ps_buf */
189         ps_lock = klp_shadow_get_or_alloc(sta,    189         ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
190                         sizeof(*ps_lock), GFP_    190                         sizeof(*ps_lock), GFP_ATOMIC,
191                         ps_lock_shadow_ctor, N    191                         ps_lock_shadow_ctor, NULL);
192                                                   192 
193         if (ps_lock)                              193         if (ps_lock)
194                 spin_lock(ps_lock);               194                 spin_lock(ps_lock);
195         ...                                       195         ...
196                                                   196 
197 This usage will create a shadow variable, only    197 This usage will create a shadow variable, only if needed, otherwise it
198 will use one that was already created for this    198 will use one that was already created for this <obj, id> pair.
199                                                   199 
200 Like the previous use-case, the shadow spinloc    200 Like the previous use-case, the shadow spinlock needs to be cleaned up.
201 A shadow variable can be freed just before its    201 A shadow variable can be freed just before its parent object is freed,
202 or even when the shadow variable itself is no     202 or even when the shadow variable itself is no longer required.
203                                                   203 
204                                                   204 
205 Other use-cases                                   205 Other use-cases
206 ---------------                                   206 ---------------
207                                                   207 
208 Shadow variables can also be used as a flag in    208 Shadow variables can also be used as a flag indicating that a data
209 structure was allocated by new, livepatched co    209 structure was allocated by new, livepatched code.  In this case, it
210 doesn't matter what data value the shadow vari    210 doesn't matter what data value the shadow variable holds, its existence
211 suggests how to handle the parent object.         211 suggests how to handle the parent object.
212                                                   212 
213                                                   213 
214 3. References                                     214 3. References
215 =============                                     215 =============
216                                                   216 
217 * https://github.com/dynup/kpatch                 217 * https://github.com/dynup/kpatch
218                                                   218 
219   The livepatch implementation is based on the    219   The livepatch implementation is based on the kpatch version of shadow
220   variables.                                      220   variables.
221                                                   221 
222 * http://files.mkgnu.net/files/dynamos/doc/pap    222 * http://files.mkgnu.net/files/dynamos/doc/papers/dynamos_eurosys_07.pdf
223                                                   223 
224   Dynamic and Adaptive Updates of Non-Quiescen    224   Dynamic and Adaptive Updates of Non-Quiescent Subsystems in Commodity
225   Operating System Kernels (Kritis Makris, Kyu    225   Operating System Kernels (Kritis Makris, Kyung Dong Ryu 2007) presented
226   a datatype update technique called "shadow d    226   a datatype update technique called "shadow data structures".
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php