{ "version": "1.1", "id": "page-fault-layers-in-a-vm", "title": "세 fault 는 변환 사슬의 서로 다른 단계에서 갈라져 나가 서로 다른 계층이 받는다", "question": "Guest Page Fault · EPT Violation · Host Page Fault 는 각각 어느 단계에서 갈라지고 누가 받는가", "type": "flow", "direction": "LR", "audience": [ "VM 안의 메모리 지연을 계층별로 가르려는 사람", "fault 지표를 어느 쪽부터 볼지 정하려는 사람" ], "summary": "Guest Page Table 에서 갈라진 Guest Page Fault 는 Guest Kernel 이 받고, 그다음 단계인 EPT 에서 갈라진 EPT Violation 은 VM Exit 뒤 KVM 이 받으며, QEMU 의 Guest RAM Backing 에서 갈라진 Host Page Fault 는 Host Kernel 이 받는다.", "alt": "Guest Page Table 과 EPT, QEMU 의 Guest RAM Backing 에서 각각 fault 가 갈라져 Guest Kernel · KVM · Host Kernel 로 가는 갈래도.", "long_description": "위에서 아래로 읽는다. 맨 위 왼쪽에 Guest Page Table 이 있고 거기서 갈래가 둘이다. 하나는 Guest Page Fault 로 Guest Kernel 에 빠지고, 다른 하나는 GPA 를 들고 아래 EPT 로 내려간다. EPT 에서도 갈래가 나뉘어 EPT Violation 은 VM Exit 을 거쳐 KVM 으로 간다. 맨 위 오른쪽에는 QEMU 의 Guest RAM Backing 이 따로 있고 그쪽 갈래인 Host Page Fault 는 Host Kernel 로 간다. 받는 자리의 이름이 그대로 계층 이름이다 — Guest Kernel · KVM · Host Kernel. QEMU 갈래가 EPT 갈래와 선으로 이어져 있지 않은 것은 근거 문서가 둘을 잇는 문장을 두지 않았기 때문이다. 다섯 원인이 무엇인지와 두 사건을 항목별로 견주는 것은 본문의 표가 맡는다.", "source_context": { "document": "docs/virtualization/final/document.md", "document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210", "anchor": { "kind": "heading", "value": "48. Guest Page Fault와 EPT Violation 비교", "line": 2493 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "이 절이 세우는 것은 같은 변환 사슬 위에서 사건이 어느 단계에 갈라져 어느 계층으로 빠지는가다. 갈래와 그 갈래가 닿는 자리가 논지라 방향 있는 경로 문법이 맞는다. sequence 는 참여자끼리 주고받는 메시지에 시각 순서를 매기는 문법인데 여기서 갈리는 셋은 서로 다른 접근에서 따로 일어나는 사건이라 하나의 시각 순서로 세울 수 없다. two-zone-pipeline 은 구역 안쪽 엣지 라벨을 캔버스 위쪽에 고정하는데 이 그림은 Guest 구역 안과 Host 구역 안에 각각 갈래가 있어 그 라벨이 구역 점선에 얹힌다.", "focus_node": "ept" }, "groups": [], "nodes": [ { "id": "guest-page-table", "label": "Guest Page Table", "kind": "component", "role": "source", "shape": "box", "details": [ "GVA → GPA" ], "description": "첫 번째 translation 단계. 여기서 접근을 완료할 수 없으면 Guest Page Fault 가 난다.", "evidence": [ { "start_line": 2456, "end_line": 2458 }, { "start_line": 2497, "end_line": 2498 } ], "assumption": false }, { "id": "guest-kernel", "label": "Guest Kernel", "kind": "service", "role": "sink", "shape": "box", "description": "Guest Page Fault 를 받는 계층.", "evidence": [ { "start_line": 2500, "end_line": 2500 }, { "start_line": 2506, "end_line": 2507 } ], "assumption": false }, { "id": "ept", "label": "EPT", "kind": "component", "role": "service", "shape": "box", "emphasis": "primary", "details": [ "GPA → HPA" ], "description": "두 번째 translation 단계. Guest translation 이 성공한 뒤 여기서 막히면 EPT Violation 이 난다.", "evidence": [ { "start_line": 2478, "end_line": 2482 }, { "start_line": 2497, "end_line": 2498 } ], "assumption": false }, { "id": "kvm", "label": "KVM", "kind": "service", "role": "sink", "shape": "box", "description": "EPT Violation 을 VM Exit 뒤에 받는 계층.", "evidence": [ { "start_line": 2484, "end_line": 2486 }, { "start_line": 2500, "end_line": 2500 } ], "assumption": false }, { "id": "qemu-backing", "label": "QEMU · Guest RAM Backing", "kind": "store", "role": "source", "shape": "box", "details": [ "Host Virtual Memory" ], "description": "Host 의 일반 userspace 메모리로 관리되는 자리. demand allocation 이나 reclaim, swap 때문에 여기서 fault 가 난다.", "evidence": [ { "start_line": 2517, "end_line": 2517 }, { "start_line": 2527, "end_line": 2532 } ], "assumption": false }, { "id": "host-kernel", "label": "Host Kernel", "kind": "service", "role": "sink", "shape": "box", "description": "Host Page Fault 를 받아 필요한 Host page 를 처리하는 계층.", "evidence": [ { "start_line": 2534, "end_line": 2538 } ], "assumption": false } ], "edges": [ { "id": "guest-fault-branch", "from": "guest-page-table", "to": "guest-kernel", "label": "Guest #PF", "kind": "event", "style": "solid", "evidence": [ { "start_line": 2497, "end_line": 2500 }, { "start_line": 2506, "end_line": 2507 } ], "assumption": false }, { "id": "translation-continues", "from": "guest-page-table", "to": "ept", "label": "GPA", "kind": "data", "style": "solid", "evidence": [ { "start_line": 2474, "end_line": 2480 } ], "assumption": false }, { "id": "ept-violation-branch", "from": "ept", "to": "kvm", "label": "EPT Violation · VM Exit", "kind": "event", "style": "solid", "evidence": [ { "start_line": 2480, "end_line": 2486 }, { "start_line": 2500, "end_line": 2500 } ], "assumption": false }, { "id": "host-fault-branch", "from": "qemu-backing", "to": "host-kernel", "label": "Host #PF", "kind": "event", "style": "solid", "evidence": [ { "start_line": 2530, "end_line": 2538 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "flow 로 고른 이유는 이 절이 답하는 물음이 「어느 단계에서 갈라져 누구에게 가는가」이기 때문이다. 현재 renderer에서는 LR가 변환 사슬과 세 fault branch를 겹침 없이 보인다. Guest #PF 와 Host #PF 는 본문에서 설명하는 Guest Page Fault·Host Page Fault의 축약 라벨이고 의미를 줄이지 않는다. EPT Violation은 VM Exit까지 포함해 그대로 둔다. 없는 관계는 선으로 만들지 않는다." } }