← Documents Documentation/livepatch/shadow-vars.rst GitHub 원문 ↗

Linux 6.18.37 · Livepatch

Shadow Variables

기존 kernel object를 수정하지 않고 `<obj, id>`로 별도 shadow data를 연결하는 API와 lifecycle 패턴입니다.

Source pathDocumentation/livepatch/shadow-vars.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

shadow-vars.rst:1-226

Shadow variable은 parent object pointer와 numeric id를 key로 사용해 기존 구조체 밖에 새 data를 저장합니다. 원래 layout을 바꾸지 않아 이미 존재하는 object에도 라이브패치 상태를 추가할 수 있습니다.

새 parent의 lifecycle에 allocation·free를 맞추거나 `klp_shadow_get_or_alloc()`으로 in-flight object에 lazy attach할 수 있으며, parent가 사라지기 전에 반드시 shadow reference를 정리해야 합니다.

Constructor는 `klp_shadow_lock` 아래에서 새 allocation 때 한 번만 실행되므로 호출 context와 별도 mutual exclusion 요구를 함께 고려해야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

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

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Shadow variable 개요

1-20

Shadow variable은 라이브패치 모듈이 기존 data structure에 별도의 추가 데이터를 연결하는 간단한 방법입니다. Shadow data는 parent structure와 따로 할당되므로 기존 구조체의 layout과 내용은 바꾸지 않습니다.

이 API는 parent에 shadow variable을 할당·추가하고, 필요가 끝나면 분리·해제합니다. 이미 실행 중인 kernel object에 새 field가 생긴 것과 비슷한 효과를 내지만, 원래 object의 ABI나 allocation size를 건드리지 않는 것이 핵심입니다.

구현은 kernel 전역 hashtable을 사용합니다. Parent object pointer가 기본 key가 되고 numeric identifier가 query를 추가로 구분합니다. 같은 parent에 여러 shadow variable을 붙일 수 있으며, id는 shadow data의 version, class, type 등을 나타내는 단순 enumeration으로 사용할 수 있습니다.

Shadow variable 식별 모델
요소역할결과
`obj`Parent object pointer이자 hashtable key어느 기존 object에 붙는지 식별
`id`Version·class·type을 나타내는 numeric identifier같은 parent의 여러 shadow 구분
`<obj, id>`완전한 lookup pair하나의 `klp_shadow`와 연결
`data[]`별도 할당된 shadow storageParent layout을 바꾸지 않고 새 상태 저장

Parent pointer와 numeric id의 조합이 하나의 shadow data를 가리킵니다.

================
Shadow Variables
================

Shadow variables are a simple way for livepatch modules to associate
additional "shadow" data with existing data structures.  Shadow data is
allocated separately from parent data structures, which are left
unmodified.  The shadow variable API described in this document is used
to allocate/add and remove/free shadow variables to/from their parents.

The implementation introduces a global, in-kernel hashtable that
associates pointers to parent objects and a numeric identifier of the
shadow data.  The numeric identifier is a simple enumeration that may be
used to describe shadow variable version, class or type, etc.  More
specifically, the parent pointer serves as the hashtable key while the
numeric id subsequently filters hashtable queries.  Multiple shadow
variables may attach to the same parent object, but their numeric
identifier distinguishes between them.

API 요약과 동기화 규칙

21-93

전체 API 사용 설명은 `livepatch/shadow.c`의 docbook note에 있습니다. 모든 shadow variable은 하나의 hashtable에서 참조되며 `<obj, id>` pair로 저장하고 조회합니다.

`struct klp_shadow`는 tracking metadata와 실제 shadow data를 함께 담습니다. Metadata의 `obj`는 parent object pointer이고 `id`는 data identifier이며, flexible storage인 `data[]`에 shadow data가 들어갑니다.

`klp_shadow_alloc()`과 `klp_shadow_get_or_alloc()`은 기본적으로 새 variable을 0으로 초기화합니다. 0이 아닌 초기값이나 별도 초기화가 필요하면 custom constructor와 data를 전달할 수 있습니다. 호출자는 필요한 mutual exclusion을 직접 제공해야 합니다.

Constructor는 `klp_shadow_lock` spinlock을 잡은 상태에서 실행됩니다. 따라서 새로운 variable이 실제로 할당되는 단 한 번의 시점에만 해야 하는 작업을 constructor에 넣을 수 있지만, spinlock context에서 허용되는 작업만 수행해야 합니다.

`klp_shadow_get()`은 `<obj, id>`를 hashtable에서 찾아 shadow data pointer를 반환합니다.

`klp_shadow_alloc()`은 같은 pair가 이미 있으면 warning을 내고 `NULL`을 반환합니다. 없으면 새 `klp_shadow`를 할당하고, 제공된 경우 custom constructor와 data로 초기화한 다음 전역 hashtable에 추가합니다.

`klp_shadow_get_or_alloc()`은 pair가 있으면 기존 variable을 반환하고, 없을 때만 새 variable을 할당·초기화·등록합니다. 여러 경로가 이미 실행 중인 parent에 필요할 때 lazy initialization하는 용도에 맞습니다.

`klp_shadow_free()`는 특정 `<obj, id>` reference를 hashtable에서 제거합니다. 찾았다면 정의된 destructor를 호출한 뒤 variable을 해제합니다. `klp_shadow_free_all()`은 특정 id를 가진 모든 `<_, id>` entry에 같은 정리 절차를 적용합니다.

Shadow variable API 계약
APIPair가 있을 때Pair가 없을 때정리 범위
`klp_shadow_get()`기존 data pointer 반환찾지 못함없음
`klp_shadow_alloc()`WARN 후 `NULL`0 초기화·constructor·등록없음
`klp_shadow_get_or_alloc()`기존 variable 반환0 초기화·constructor·등록없음
`klp_shadow_free()`destructor 후 제거·해제동작 없음특정 `<obj, id>`
`klp_shadow_free_all()`일치 entry마다 destructor·해제동작 없음모든 `<_, id>`

조회·생성·정리 함수의 중복 pair 처리 차이입니다.

새 shadow variable 생성 경로
`<obj, id>`로 전역 hashtable 검색`klp_shadow_alloc()`: 이미 있으면 WARN과 `NULL``klp_shadow_get_or_alloc()`: 이미 있으면 기존 pointer 반환없으면 zeroed `klp_shadow` 할당`klp_shadow_lock` 아래에서 optional constructor 실행전역 hashtable에 `<obj, id>` 등록

두 allocation API는 중복 pair를 만났을 때의 정책이 다릅니다.

1. Brief API summary
====================

(See the full API usage docbook notes in livepatch/shadow.c.)

A hashtable references all shadow variables.  These references are
stored and retrieved through a <obj, id> pair.

* The klp_shadow variable data structure encapsulates both tracking
  meta-data and shadow-data:

  - meta-data

    - obj - pointer to parent object
    - id - data identifier

  - data[] - storage for shadow data

It is important to note that the klp_shadow_alloc() and
klp_shadow_get_or_alloc() are zeroing the variable by default.
They also allow to call a custom constructor function when a non-zero
value is needed. Callers should provide whatever mutual exclusion
is required.

Note that the constructor is called under klp_shadow_lock spinlock. It allows
to do actions that can be done only once when a new variable is allocated.

* klp_shadow_get() - retrieve a shadow variable data pointer
  - search hashtable for <obj, id> pair

* klp_shadow_alloc() - allocate and add a new shadow variable
  - search hashtable for <obj, id> pair

  - if exists

    - WARN and return NULL

  - if <obj, id> doesn't already exist

    - allocate a new shadow variable
    - initialize the variable using a custom constructor and data when provided
    - add <obj, id> to the global hashtable

* klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
  - search hashtable for <obj, id> pair

  - if exists

    - return existing shadow variable

  - if <obj, id> doesn't already exist

    - allocate a new shadow variable
    - initialize the variable using a custom constructor and data when provided
    - add <obj, id> pair to the global hashtable

* klp_shadow_free() - detach and free a <obj, id> shadow variable
  - find and remove a <obj, id> reference from global hashtable

    - if found

      - call destructor function if defined
      - free shadow variable

* klp_shadow_free_all() - detach and free all <_, id> shadow variables
  - find and remove any <_, id> references from global hashtable

    - if found

      - call destructor function if defined
      - free shadow variable

사용 사례: lifecycle 일치와 in-flight object

94-213

완전한 예제는 `samples/livepatch/`의 shadow variable 라이브패치 모듈에 있습니다. 여기서는 commit `1d147bfa6429`("mac80211: fix AP powersave TX vs. wakeup race")가 `net/mac80211/sta_info.h`의 `struct sta_info`에 spinlock을 추가한 상황을 사용합니다. 각 예시는 그 수정의 독립적인 라이브패치 구현으로 볼 수 있습니다.

Parent data structure가 자주 생성되고 파괴된다면 shadow variable lifetime을 parent의 allocation·release 함수에 맞추는 방법이 가장 단순합니다. Parent를 할당하고 초기화해 외부에 등록하기 전에 shadow allocation과 setup도 끝내야 합니다. 즉 `<obj, id>`에 대한 get 요청이 시작되기 전에 shadow가 준비되어야 합니다.

예제의 `sta_info_alloc()`은 parent `sta_info`를 `kzalloc()`한 다음 `PS_LOCK` id의 `spinlock_t` 크기로 `klp_shadow_alloc()`을 호출합니다. 실패하면 `shadow_fail`로 이동하고, 성공하면 `spin_lock_init()`으로 새 lock을 초기화합니다.

`ieee80211_sta_ps_deliver_wakeup()`은 특정 `sta_info`에 연결된 lock을 `klp_shadow_get(sta, PS_LOCK)`으로 조회합니다. Pointer가 있으면 `spin_lock()`을 호출해 `ieee80211_tx_h_unicast_ps_buf`와 동기화합니다.

Parent를 해제하는 `sta_info_free()`에서는 `kfree(sta)`보다 먼저 `klp_shadow_free(sta, PS_LOCK, NULL)`을 호출합니다. Parent pointer가 hashtable key이므로 parent memory가 사라지기 전에 연결을 제거해야 합니다.

Parent lifecycle과 일치시키는 패턴
Parent `sta_info` 할당`klp_shadow_alloc(sta, PS_LOCK, ...)``spin_lock_init(ps_lock)` 후 parent 공개사용 경로에서 `klp_shadow_get()`Parent 해제 직전 `klp_shadow_free()`마지막으로 `kfree(sta)`

Shadow를 parent의 초기화와 정리 순서 안에 넣습니다.

항상 parent와 함께 shadow를 만들기 어렵거나, livepatch fix가 parent instance 일부에만 shadow를 요구할 수도 있습니다. 이미 실행 중인 in-flight parent에는 `klp_shadow_get_or_alloc()`을 사용해 필요한 순간에 shadow를 붙일 수 있습니다.

예제의 `ps_lock_shadow_ctor()`는 `shadow_data`를 `spinlock_t`로 받아 `spin_lock_init()`을 수행합니다. `ieee80211_sta_ps_deliver_wakeup()`은 `GFP_ATOMIC`과 이 constructor를 넘겨 `klp_shadow_get_or_alloc()`을 호출합니다.

이 사용법은 `<obj, id>` pair에 variable이 없을 때만 생성하며, 이미 있다면 기존 lock을 사용합니다. Constructor가 allocation 시 한 번만 호출되므로 중복 초기화도 피합니다.

이전 사례와 마찬가지로 shadow spinlock은 정리해야 합니다. Parent object 해제 직전에 제거할 수도 있고, shadow 자체가 더 이상 필요하지 않은 더 이른 시점에 해제할 수도 있습니다.

Shadow variable은 새 라이브패치 code가 특정 data structure를 할당했다는 flag로도 사용할 수 있습니다. 이 경우 저장된 값보다 `<obj, id>` entry의 존재 자체가 parent object를 어떤 방식으로 처리해야 하는지 알려 줍니다.

두 lifecycle 전략
전략생성 API적합한 상황정리 시점
Parent lifecycle 일치`klp_shadow_alloc()`모든 새 parent에 shadow가 필요하고 allocation 경로 수정 가능Parent 해제 직전
In-flight lazy attach`klp_shadow_get_or_alloc()`기존 object 또는 일부 instance에만 필요Parent 해제 전 또는 shadow 불필요 시점
존재 flag상황에 따라 allocation API 선택새 code가 만든 object 여부 표시표시 의미가 끝나기 전

Parent 생성 시점에 개입할 수 있는지와 필요한 instance 범위로 선택합니다.

2. Use cases
============

(See the example shadow variable livepatch modules in samples/livepatch/
for full working demonstrations.)

For the following use-case examples, consider commit 1d147bfa6429
("mac80211: fix AP powersave TX vs.  wakeup race"), which added a
spinlock to net/mac80211/sta_info.h :: struct sta_info.  Each use-case
example can be considered a stand-alone livepatch implementation of this
fix.


Matching parent's lifecycle
---------------------------

If parent data structures are frequently created and destroyed, it may
be easiest to align their shadow variables lifetimes to the same
allocation and release functions.  In this case, the parent data
structure is typically allocated, initialized, then registered in some
manner.  Shadow variable allocation and setup can then be considered
part of the parent's initialization and should be completed before the
parent "goes live" (ie, any shadow variable get-API requests are made
for this <obj, id> pair.)

For commit 1d147bfa6429, when a parent sta_info structure is allocated,
allocate a shadow copy of the ps_lock pointer, then initialize it::

  #define PS_LOCK 1
  struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
                                  const u8 *addr, gfp_t gfp)
  {
        struct sta_info *sta;
        spinlock_t *ps_lock;

        /* Parent structure is created */
        sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);

        /* Attach a corresponding shadow variable, then initialize it */
        ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
                                   NULL, NULL);
        if (!ps_lock)
                goto shadow_fail;
        spin_lock_init(ps_lock);
        ...

When requiring a ps_lock, query the shadow variable API to retrieve one
for a specific struct sta_info:::

  void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
  {
        spinlock_t *ps_lock;

        /* sync with ieee80211_tx_h_unicast_ps_buf */
        ps_lock = klp_shadow_get(sta, PS_LOCK);
        if (ps_lock)
                spin_lock(ps_lock);
        ...

When the parent sta_info structure is freed, first free the shadow
variable::

  void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
  {
        klp_shadow_free(sta, PS_LOCK, NULL);
        kfree(sta);
        ...


In-flight parent objects
------------------------

Sometimes it may not be convenient or possible to allocate shadow
variables alongside their parent objects.  Or a livepatch fix may
require shadow variables for only a subset of parent object instances.
In these cases, the klp_shadow_get_or_alloc() call can be used to attach
shadow variables to parents already in-flight.

For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
inside ieee80211_sta_ps_deliver_wakeup()::

  int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
  {
        spinlock_t *lock = shadow_data;

        spin_lock_init(lock);
        return 0;
  }

  #define PS_LOCK 1
  void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
  {
        spinlock_t *ps_lock;

        /* sync with ieee80211_tx_h_unicast_ps_buf */
        ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
                        sizeof(*ps_lock), GFP_ATOMIC,
                        ps_lock_shadow_ctor, NULL);

        if (ps_lock)
                spin_lock(ps_lock);
        ...

This usage will create a shadow variable, only if needed, otherwise it
will use one that was already created for this <obj, id> pair.

Like the previous use-case, the shadow spinlock needs to be cleaned up.
A shadow variable can be freed just before its parent object is freed,
or even when the shadow variable itself is no longer required.


Other use-cases
---------------

Shadow variables can also be used as a flag indicating that a data
structure was allocated by new, livepatched code.  In this case, it
doesn't matter what data value the shadow variable holds, its existence
suggests how to handle the parent object.

참고 자료와 기원

214-226

Linux livepatch의 shadow variable 구현은 GitHub의 `dynup/kpatch`에 있는 kpatch 버전을 기반으로 합니다.

이 개념의 연구 배경은 Kritis Makris와 Kyung Dong Ryu가 2007년에 발표한 "Dynamic and Adaptive Updates of Non-Quiescent Subsystems in Commodity Operating System Kernels"입니다. 이 논문은 실행을 완전히 멈출 수 없는 subsystem의 datatype을 갱신하는 기법을 `shadow data structures`라는 이름으로 제시했습니다.

참고 자료
자료기여
`https://github.com/dynup/kpatch`Linux livepatch shadow variable 구현의 기반
DynaMOS EuroSys 2007 논문Shadow data structure를 이용한 datatype update 기법

현재 구현과 개념적 배경을 각각 제공하는 자료입니다.

3. References
=============

* https://github.com/dynup/kpatch

  The livepatch implementation is based on the kpatch version of shadow
  variables.

* http://files.mkgnu.net/files/dynamos/doc/papers/dynamos_eurosys_07.pdf

  Dynamic and Adaptive Updates of Non-Quiescent Subsystems in Commodity
  Operating System Kernels (Kritis Makris, Kyung Dong Ryu 2007) presented
  a datatype update technique called "shadow data structures".