refactor: 문서 개선 중

This commit is contained in:
donghyeon-ka
2026-09-21 14:30:55 +09:00
parent c93cdea150
commit 805a18f486
1497 changed files with 525837 additions and 59152 deletions
@@ -10,21 +10,21 @@ Guest 구역 안에서 Keycloak · PostgreSQL 의 GVA 가 Guest TLB 와 Guest Pa
## Elements and evidence
- **Boundary: Guest** (boundary): VM Boundary 안쪽. Guest Userspace 와 Guest Kernel 이 여기 있고 GVA 가 GPA 가 되는 첫 번째 변환이 여기서 끝난다. Evidence: L4034L4053.
- **Boundary: Host RAM** (boundary): 변환이 끝난 주소가 닿는 실제 서버 메모리. Evidence: L4069L4079.
- **Keycloak · PostgreSQL** (actor): Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. Evidence: L4034L4038.
- **Guest TLB** (component): 최근 변환 결과를 담아 두는 CPU 안의 캐시. Evidence: L4043L4045.
- **Guest Page Table** (component): GVA 를 GPA 로 바꾸는 첫 번째 변환 표. Evidence: L4048L4053.
- **EPT** (component): VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. Evidence: L4055L4067.
- **Host Physical Memory** (store): HPA 가 가리키는 실제 서버 메모리. Evidence: L4069L4072.
- **NUMA Node 0** (store): physical page 가 놓일 수 있는 한쪽 NUMA node. Evidence: L4073L4075.
- **NUMA Node 1** (store): physical page 가 놓일 수 있는 다른 쪽 NUMA node. Evidence: L4073L4075.
- **Boundary: Guest** (boundary): VM Boundary 안쪽. Guest Userspace 와 Guest Kernel 이 여기 있고 GVA 가 GPA 가 되는 첫 번째 변환이 여기서 끝난다. Evidence: L4047L4066.
- **Boundary: Host RAM** (boundary): 변환이 끝난 주소가 닿는 실제 서버 메모리. Evidence: L4082L4092.
- **Keycloak · PostgreSQL** (actor): Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. Evidence: L4047L4051.
- **Guest TLB** (component): 최근 변환 결과를 담아 두는 CPU 안의 캐시. Evidence: L4056L4058.
- **Guest Page Table** (component): GVA 를 GPA 로 바꾸는 첫 번째 변환 표. Evidence: L4061L4066.
- **EPT** (component): VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. Evidence: L4068L4080.
- **Host Physical Memory** (store): HPA 가 가리키는 실제 서버 메모리. Evidence: L4082L4085.
- **NUMA Node 0** (store): physical page 가 놓일 수 있는 한쪽 NUMA node. Evidence: L4086L4088.
- **NUMA Node 1** (store): physical page 가 놓일 수 있는 다른 쪽 NUMA node. Evidence: L4086L4088.
## Relationships
- **EPT → Host Physical Memory:** HPA. Evidence: L4062L4071.
- **Host Physical Memory → NUMA Node 0:** Physical Page. Evidence: L4071L4075.
- **Host Physical Memory → NUMA Node 1:** Physical Page. Evidence: L4071L4075.
- **Guest Page Table → EPT:** VM Boundary. Evidence: L4053L4062.
- **Keycloak · PostgreSQL → Guest TLB:** GVA. Evidence: L4036L4043.
- **Guest TLB → Guest Page Table:** TLB Miss. Evidence: L4043L4048.
- **EPT → Host Physical Memory:** HPA. Evidence: L4075L4084.
- **Host Physical Memory → NUMA Node 0:** Physical Page. Evidence: L4084L4088.
- **Host Physical Memory → NUMA Node 1:** Physical Page. Evidence: L4084L4088.
- **Guest Page Table → EPT:** VM Boundary. Evidence: L4066L4075.
- **Keycloak · PostgreSQL → Guest TLB:** GVA. Evidence: L4049L4056.
- **Guest TLB → Guest Page Table:** TLB Miss. Evidence: L4056L4061.
@@ -1,6 +1,6 @@
# Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다
# Question: Guest 프로세스가 읽은 주소는 어느 계층을 차례로 지나 어떤 물리 메모리에 닿는가
direction: down
direction: right
g0: "Guest" {
n0: "Keycloak · PostgreSQL" {
shape: person
@@ -0,0 +1,28 @@
digraph techviz {
graph [rankdir=LR, splines=ortho, nodesep=0.55, ranksep=0.85];
node [fontname=Helvetica, fontsize=11, margin="0.18,0.12", style="rounded,filled", fillcolor=white, color="#2d4357", penwidth=1.5];
edge [fontname=Helvetica, fontsize=10, color="#364b5f", penwidth=1.4, arrowsize=0.75];
subgraph cluster_0 {
label="Guest";
style="rounded,dashed";
color="#66788a";
n0 [label="Keycloak · PostgreSQL", shape=box, style="rounded,dashed,filled"];
n1 [label="Guest TLB", shape=box, style="rounded,filled"];
n2 [label="Guest Page Table", shape=box, style="rounded,filled"];
}
subgraph cluster_1 {
label="Host RAM";
style="rounded,dashed";
color="#66788a";
n4 [label="Host Physical Memory", shape=box, style="rounded,filled"];
n5 [label="NUMA Node 0", shape=box, style="rounded,filled"];
n6 [label="NUMA Node 1", shape=box, style="rounded,filled"];
}
n3 [label="EPT", shape=box, style="rounded,filled"];
n0 -> n1 [label="GVA", style=solid];
n1 -> n2 [label="TLB Miss", style=solid];
n2 -> n3 [label="VM Boundary", style=solid];
n3 -> n4 [label="HPA", style=solid];
n4 -> n5 [label="Physical Page", style=solid];
n4 -> n6 [label="Physical Page", style=solid];
}
@@ -1,65 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2026-07-23T00:00:00.000Z" agent="techviz-harness" version="24.7.17" type="device">
<diagram id="guest-memory-address-translation-path" name="Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다">
<mxGraphModel dx="680" dy="1078" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="1900" dy="352" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1900" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="g_guest" value="Guest" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="129.5" y="35.0" width="241.0" height="494.0" as="geometry"/>
<mxGeometry x="40.0" y="91.0" width="861.0" height="160.0" as="geometry"/>
</mxCell>
<mxCell id="g_host-ram" value="Host RAM" style="swimlane;html=1;rounded=1;startSize=30;horizontal=1;dashed=1;strokeWidth=1.5;fillColor=#f7f9fb;strokeColor=#66788a;fontStyle=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="40.0" y="737.0" width="420.0" height="296.0" as="geometry"/>
<mxGeometry x="1311.0" y="35.0" width="544.0" height="272.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest-process" value="Keycloak · PostgreSQL&lt;br/&gt;Guest Userspace" tooltip="Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. | Evidence: L4034-L4038" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="159.5" y="81.0" width="181.0" height="71.0" as="geometry"/>
<mxCell id="n_guest-process" value="Keycloak · PostgreSQL&lt;br/&gt;Guest Userspace" tooltip="Guest 안에서 메모리를 읽는 프로세스. 여기서 GVA 가 출발한다. | Evidence: L4047-L4051" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="70.0" y="145.5" width="181.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest-tlb" value="Guest TLB&lt;br/&gt;Guest Kernel" tooltip="최근 변환 결과를 담아 두는 CPU 안의 캐시. | Evidence: L4043-L4045" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="175.0" y="248.0" width="150.0" height="71.0" as="geometry"/>
<mxCell id="n_guest-tlb" value="Guest TLB&lt;br/&gt;Guest Kernel" tooltip="최근 변환 결과를 담아 두는 CPU 안의 캐시. | Evidence: L4056-L4058" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="411.0" y="145.5" width="150.0" height="71.0" as="geometry"/>
</mxCell>
<mxCell id="n_guest-page-table" value="Guest Page Table&lt;br/&gt;Guest Kernel&lt;br/&gt;GVA → GPA" tooltip="GVA 를 GPA 로 바꾸는 첫 번째 변환 표. | Evidence: L4048-L4053" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="175.0" y="415.0" width="150.0" height="88.0" as="geometry"/>
<mxCell id="n_guest-page-table" value="Guest Page Table&lt;br/&gt;Guest Kernel&lt;br/&gt;GVA → GPA" tooltip="GVA 를 GPA 로 바꾸는 첫 번째 변환 표. | Evidence: L4061-L4066" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="721.0" y="137.0" width="150.0" height="88.0" as="geometry"/>
</mxCell>
<mxCell id="n_ept" value="EPT&lt;br/&gt;KVM / CPU&lt;br/&gt;GPA → HPA" tooltip="VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. | Evidence: L4055-L4067" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="175.0" y="599.0" width="150.0" height="88.0" as="geometry"/>
<mxCell id="n_ept" value="EPT&lt;br/&gt;KVM / CPU&lt;br/&gt;GPA → HPA" tooltip="VM Boundary 바깥에서 GPA 를 HPA 로 바꾸는 두 번째 변환 표. KVM 과 CPU 가 맡는다. | Evidence: L4068-L4080" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;strokeColor=#2563eb;strokeWidth=2;" vertex="1" parent="1">
<mxGeometry x="1031.0" y="137.0" width="150.0" height="88.0" as="geometry"/>
</mxCell>
<mxCell id="n_host-physical-memory" value="Host Physical Memory" tooltip="HPA 가 가리키는 실제 서버 메모리. | Evidence: L4069-L4072" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="163.0" y="783.0" width="174.0" height="64.0" as="geometry"/>
<mxCell id="n_host-physical-memory" value="Host Physical Memory" tooltip="HPA 가 가리키는 실제 서버 메모리. | Evidence: L4082-L4085" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1341.0" y="149.0" width="174.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_numa-node-0" value="NUMA Node 0" tooltip="physical page 가 놓일 수 있는 한쪽 NUMA node. | Evidence: L4073-L4075" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="70.0" y="943.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_numa-node-0" value="NUMA Node 0" tooltip="physical page 가 놓일 수 있는 한쪽 NUMA node. | Evidence: L4086-L4088" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1675.0" y="81.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="n_numa-node-1" value="NUMA Node 1" tooltip="physical page 가 놓일 수 있는 다른 쪽 NUMA node. | Evidence: L4073-L4075" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="280.0" y="943.0" width="150.0" height="64.0" as="geometry"/>
<mxCell id="n_numa-node-1" value="NUMA Node 1" tooltip="physical page 가 놓일 수 있는 다른 쪽 NUMA node. | Evidence: L4086-L4088" style="whiteSpace=wrap;html=1;rounded=1;strokeWidth=2;fontSize=14;fontStyle=1;fillColor=#ffffff;strokeColor=#2d4357;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1675.0" y="217.0" width="150.0" height="64.0" as="geometry"/>
</mxCell>
<mxCell id="e_ept-to-host-memory" value="HPA" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_ept" target="n_host-physical-memory">
<mxGeometry relative="1" as="geometry">
<mxPoint x="274.0" y="735.0" as="offset"/>
<mxPoint x="1261.0" y="153.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_host-memory-to-node-0" value="Physical Page" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-physical-memory" target="n_numa-node-0">
<mxGeometry relative="1" as="geometry">
<mxPoint x="193.0" y="867.0" as="offset"/>
<mxPoint x="1619.0" y="142.5" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_host-memory-to-node-1" value="Physical Page" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_host-physical-memory" target="n_numa-node-1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="307.0" y="867.0" as="offset"/>
<mxPoint x="1619.0" y="219.5" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_page-table-to-ept" value="VM Boundary" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-page-table" target="n_ept">
<mxGeometry relative="1" as="geometry">
<mxPoint x="274.0" y="551.0" as="offset"/>
<mxPoint x="951.0" y="153.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_process-to-tlb" value="GVA" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-process" target="n_guest-tlb">
<mxGeometry relative="1" as="geometry">
<mxPoint x="274.0" y="200.0" as="offset"/>
<mxPoint x="331.0" y="153.0" as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_tlb-to-page-table" value="TLB Miss" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;endArrow=block;endFill=1;" edge="1" parent="1" source="n_guest-tlb" target="n_guest-page-table">
<mxGeometry relative="1" as="geometry">
<mxPoint x="274.0" y="367.0" as="offset"/>
<mxPoint x="641.0" y="153.0" as="offset"/>
</mxGeometry>
</mxCell>
</root>
@@ -6,10 +6,10 @@
{
"id": "group-guest",
"type": "rectangle",
"x": 129.5,
"y": 35.0,
"width": 241.0,
"height": 494.0,
"x": 40.0,
"y": 91.0,
"width": 861.0,
"height": 160.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f8f9fa",
@@ -36,8 +36,8 @@
{
"id": "group-label-guest",
"type": "text",
"x": 145.5,
"y": 41.0,
"x": 56.0,
"y": 97.0,
"width": 100,
"height": 24,
"angle": 0,
@@ -75,10 +75,10 @@
{
"id": "group-host-ram",
"type": "rectangle",
"x": 40.0,
"y": 737.0,
"width": 420.0,
"height": 296.0,
"x": 1311.0,
"y": 35.0,
"width": 544.0,
"height": 272.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#f8f9fa",
@@ -105,8 +105,8 @@
{
"id": "group-label-host-ram",
"type": "text",
"x": 56.0,
"y": 743.0,
"x": 1327.0,
"y": 41.0,
"width": 100,
"height": 24,
"angle": 0,
@@ -144,10 +144,10 @@
{
"id": "edge-ept-to-host-memory",
"type": "arrow",
"x": 250.0,
"y": 687.0,
"width": 0.0,
"height": 96.0,
"x": 1181.0,
"y": 181.0,
"width": 160.0,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -174,16 +174,16 @@
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
96.0
160.0,
0.0
]
],
"lastCommittedPoint": null,
@@ -204,8 +204,8 @@
{
"id": "edge-label-ept-to-host-memory",
"type": "text",
"x": 229.0,
"y": 723.0,
"x": 1216.0,
"y": 141.0,
"width": 90,
"height": 24,
"angle": 0,
@@ -243,10 +243,10 @@
{
"id": "edge-host-memory-to-node-0",
"type": "arrow",
"x": 145.0,
"y": 847.0,
"width": 96.0,
"height": 96.0,
"x": 1515.0,
"y": 113.0,
"width": 160.0,
"height": 59.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -269,20 +269,20 @@
"locked": false,
"points": [
[
96.0,
0.0,
59.0
],
[
80.0,
59.0
],
[
80.0,
0.0
],
[
96.0,
48.0
],
[
0.0,
48.0
],
[
0.0,
96.0
160.0,
0.0
]
],
"lastCommittedPoint": null,
@@ -303,8 +303,8 @@
{
"id": "edge-label-host-memory-to-node-0",
"type": "text",
"x": 141.0,
"y": 855.0,
"x": 1567.0,
"y": 130.5,
"width": 104,
"height": 24,
"angle": 0,
@@ -342,10 +342,10 @@
{
"id": "edge-host-memory-to-node-1",
"type": "arrow",
"x": 259.0,
"y": 847.0,
"width": 96.0,
"height": 96.0,
"x": 1515.0,
"y": 190.0,
"width": 160.0,
"height": 59.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -372,16 +372,16 @@
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
96.0,
48.0
80.0,
59.0
],
[
96.0,
96.0
160.0,
59.0
]
],
"lastCommittedPoint": null,
@@ -402,8 +402,8 @@
{
"id": "edge-label-host-memory-to-node-1",
"type": "text",
"x": 255.0,
"y": 855.0,
"x": 1567.0,
"y": 207.5,
"width": 104,
"height": 24,
"angle": 0,
@@ -441,10 +441,10 @@
{
"id": "edge-page-table-to-ept",
"type": "arrow",
"x": 250.0,
"y": 503.0,
"width": 0.0,
"height": 96.0,
"x": 871.0,
"y": 181.0,
"width": 160.0,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -471,16 +471,16 @@
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
96.0
160.0,
0.0
]
],
"lastCommittedPoint": null,
@@ -501,8 +501,8 @@
{
"id": "edge-label-page-table-to-ept",
"type": "text",
"x": 229.0,
"y": 539.0,
"x": 906.0,
"y": 141.0,
"width": 90,
"height": 24,
"angle": 0,
@@ -540,10 +540,10 @@
{
"id": "edge-process-to-tlb",
"type": "arrow",
"x": 250.0,
"y": 152.0,
"width": 0.0,
"height": 96.0,
"x": 251.0,
"y": 181.0,
"width": 160.0,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -570,16 +570,16 @@
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
96.0
160.0,
0.0
]
],
"lastCommittedPoint": null,
@@ -600,8 +600,8 @@
{
"id": "edge-label-process-to-tlb",
"type": "text",
"x": 229.0,
"y": 188.0,
"x": 286.0,
"y": 141.0,
"width": 90,
"height": 24,
"angle": 0,
@@ -639,10 +639,10 @@
{
"id": "edge-tlb-to-page-table",
"type": "arrow",
"x": 250.0,
"y": 319.0,
"width": 0.0,
"height": 96.0,
"x": 561.0,
"y": 181.0,
"width": 160.0,
"height": 0.0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
@@ -669,16 +669,16 @@
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
48.0
80.0,
0.0
],
[
0.0,
96.0
160.0,
0.0
]
],
"lastCommittedPoint": null,
@@ -699,8 +699,8 @@
{
"id": "edge-label-tlb-to-page-table",
"type": "text",
"x": 229.0,
"y": 355.0,
"x": 596.0,
"y": 141.0,
"width": 90,
"height": 24,
"angle": 0,
@@ -738,8 +738,8 @@
{
"id": "node-guest-process",
"type": "rectangle",
"x": 159.5,
"y": 81.0,
"x": 70.0,
"y": 145.5,
"width": 181.0,
"height": 71.0,
"angle": 0,
@@ -768,8 +768,8 @@
{
"id": "node-label-guest-process",
"type": "text",
"x": 169.5,
"y": 91.0,
"x": 80.0,
"y": 155.5,
"width": 161.0,
"height": 51.0,
"angle": 0,
@@ -807,8 +807,8 @@
{
"id": "node-guest-tlb",
"type": "rectangle",
"x": 175.0,
"y": 248.0,
"x": 411.0,
"y": 145.5,
"width": 150.0,
"height": 71.0,
"angle": 0,
@@ -837,8 +837,8 @@
{
"id": "node-label-guest-tlb",
"type": "text",
"x": 185.0,
"y": 258.0,
"x": 421.0,
"y": 155.5,
"width": 130.0,
"height": 51.0,
"angle": 0,
@@ -876,8 +876,8 @@
{
"id": "node-guest-page-table",
"type": "rectangle",
"x": 175.0,
"y": 415.0,
"x": 721.0,
"y": 137.0,
"width": 150.0,
"height": 88.0,
"angle": 0,
@@ -906,8 +906,8 @@
{
"id": "node-label-guest-page-table",
"type": "text",
"x": 185.0,
"y": 425.0,
"x": 731.0,
"y": 147.0,
"width": 130.0,
"height": 68.0,
"angle": 0,
@@ -945,8 +945,8 @@
{
"id": "node-ept",
"type": "rectangle",
"x": 175.0,
"y": 599.0,
"x": 1031.0,
"y": 137.0,
"width": 150.0,
"height": 88.0,
"angle": 0,
@@ -975,8 +975,8 @@
{
"id": "node-label-ept",
"type": "text",
"x": 185.0,
"y": 609.0,
"x": 1041.0,
"y": 147.0,
"width": 130.0,
"height": 68.0,
"angle": 0,
@@ -1014,8 +1014,8 @@
{
"id": "node-host-physical-memory",
"type": "rectangle",
"x": 163.0,
"y": 783.0,
"x": 1341.0,
"y": 149.0,
"width": 174.0,
"height": 64.0,
"angle": 0,
@@ -1044,8 +1044,8 @@
{
"id": "node-label-host-physical-memory",
"type": "text",
"x": 173.0,
"y": 793.0,
"x": 1351.0,
"y": 159.0,
"width": 154.0,
"height": 44.0,
"angle": 0,
@@ -1083,8 +1083,8 @@
{
"id": "node-numa-node-0",
"type": "rectangle",
"x": 70.0,
"y": 943.0,
"x": 1675.0,
"y": 81.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -1113,8 +1113,8 @@
{
"id": "node-label-numa-node-0",
"type": "text",
"x": 80.0,
"y": 953.0,
"x": 1685.0,
"y": 91.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -1152,8 +1152,8 @@
{
"id": "node-numa-node-1",
"type": "rectangle",
"x": 280.0,
"y": 943.0,
"x": 1675.0,
"y": 217.0,
"width": 150.0,
"height": 64.0,
"angle": 0,
@@ -1182,8 +1182,8 @@
{
"id": "node-label-numa-node-1",
"type": "text",
"x": 290.0,
"y": 953.0,
"x": 1685.0,
"y": 227.0,
"width": 130.0,
"height": 44.0,
"angle": 0,
@@ -2,30 +2,41 @@
"harness_version": "0.2.0",
"spec_id": "guest-memory-address-translation-path",
"spec_version": "1.1",
"spec_sha256": "9db86cb8c5f81b1c5886877e1efd3ae4d4174d839fb29cffd5f8ae102508f2f3",
"spec_sha256": "e30f27d5ec8b8a67d37f29129f6d6988f5713e779480a2be0ae5417d8d3c143b",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210",
"anchor": {
"kind": "heading",
"value": "87. 최종 기준 그림",
"line": 4029
"line": 4042
}
},
"outputs": [
"guest-memory-address-translation-path.svg",
"guest-memory-address-translation-path.drawio",
"guest-memory-address-translation-path.mmd",
"guest-memory-address-translation-path.d2",
"guest-memory-address-translation-path.dot",
"guest-memory-address-translation-path.drawio",
"guest-memory-address-translation-path.excalidraw",
"guest-memory-address-translation-path.alt.md"
],
"lint_issue_count": 0,
"lint_issue_count": 2,
"assumption_count": 0,
"assumptions_allowed": false,
"composition_profile": "component-flow",
"reference_ids": [
"payment-event-flow"
],
"diagram_only": true
"diagram_only": true,
"source_spec_file_sha256": "f61398e1b5a1282f1904e0674b0bc1ecf6eccea307053bd176c40eff3580d445",
"output_sha256": {
"guest-memory-address-translation-path.svg": "713f7a4c829230fb80d915946f08f7af1b190336ad8b27222885f8e010099c35",
"guest-memory-address-translation-path.mmd": "84e22ae6bfaf94daaf62c61270b00aba3160c87a6084b9033a77adac7e3efc90",
"guest-memory-address-translation-path.d2": "060efab06f41aa65df54cb1f19ad2fb0a9e05c4fadfb896cfc6cac5a260571e2",
"guest-memory-address-translation-path.dot": "e3e795e40a234ff708981b04c15d4924eaa8cd71779b81c24633b52bfecd9ba0",
"guest-memory-address-translation-path.drawio": "584d77a986cf771141d4246570b52f4590a79e840831ad2924585494ecd2f5b6",
"guest-memory-address-translation-path.excalidraw": "dcc857856e9a2cf2abde5812668c1987710f8655230a4a8e8299ffa74298a6ff",
"guest-memory-address-translation-path.alt.md": "ea2406106c239086672848f73b69658275fff87d34399e9837f570173c0d7a26"
}
}
@@ -1,6 +1,6 @@
%% Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다
%% question: Guest 프로세스가 읽은 주소는 어느 계층을 차례로 지나 어떤 물리 메모리에 닿는가
flowchart TB
flowchart LR
subgraph g_guest["Guest"]
n0(["Keycloak · PostgreSQL"])
n1["Guest TLB"]
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="680" height="1078" viewBox="0 0 680 1078" role="img" aria-labelledby="diagram-title diagram-description">
<svg xmlns="http://www.w3.org/2000/svg" width="1900" height="352" viewBox="0 0 1900 352" role="img" aria-labelledby="diagram-title diagram-description">
<title id="diagram-title">Guest 의 메모리 접근 한 번은 이름이 두 번 바뀌며 네 계층을 지난다</title>
<desc id="diagram-description">위에서 아래로 읽는다. 맨 위 Guest 구역 안에 Keycloak · PostgreSQL 이 있고 그 접근은 GVA 로 Guest TLB 에 들어간다. TLB 에 변환이 없으면 TLB Miss 로 Guest Page Table 을 조회하고 거기서 GVA 가 GPA 가 된다. 그 GPA 는 VM Boundary 를 넘어 Guest 구역 밖의 EPT 로 가고 EPT 가 GPA 를 HPA 로 바꾼다. HPA 는 Host RAM 구역의 Host Physical Memory 에 닿고, 그 physical page 는 맨 아래에서 NUMA Node 0 또는 NUMA Node 1 가운데 한쪽에 놓인다. 상자 안 작은 글씨는 그 단계가 어느 계층인지와 무엇을 무엇으로 바꾸는지를 적은 것이다. 어느 단계에서 접근이 완료되지 못할 때 무엇이 일어나는지와 QEMU 가 이 경로를 어떻게 준비하는지는 본문의 문단과 표가 맡는다.</desc>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;guest-memory-address-translation-path&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;87. 최종 기준 그림&quot;,&quot;line&quot;:4029}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<metadata>{&quot;techviz&quot;:{&quot;spec_version&quot;:&quot;1.1&quot;,&quot;id&quot;:&quot;guest-memory-address-translation-path&quot;,&quot;profile&quot;:&quot;component-flow&quot;},&quot;source_context&quot;:{&quot;document&quot;:&quot;docs/virtualization/final/document.md&quot;,&quot;document_sha256&quot;:&quot;8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210&quot;,&quot;anchor&quot;:{&quot;kind&quot;:&quot;heading&quot;,&quot;value&quot;:&quot;87. 최종 기준 그림&quot;,&quot;line&quot;:4042}},&quot;evidence_policy&quot;:&quot;Each factual element cites source lines or is marked assumption.&quot;,&quot;diagram_only&quot;:true}</metadata>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
@@ -49,67 +49,67 @@
.timeline-detail { font-size: 11px; fill: #4b5563; text-anchor: middle; }
</style>
</defs>
<rect class="canvas" width="680" height="1078" />
<rect class="group-box" x="129.5" y="35.0" width="241.0" height="494.0" rx="8" />
<rect class="group-label-bg" x="143.5" y="25.0" width="90.0" height="22" />
<text class="group-label" x="153.5" y="40.0">Guest</text>
<rect class="group-box" x="40.0" y="737.0" width="420.0" height="296.0" rx="8" />
<rect class="group-label-bg" x="54.0" y="727.0" width="90.0" height="22" />
<text class="group-label" x="64.0" y="742.0">Host RAM</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="250.0,687.0 250.0,735.0 250.0,735.0 250.0,783.0" data-evidence="4062-4071" />
<rect class="edge-label-bg" x="252.0" y="721.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="274.0" y="736.0">HPA</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="241.0,847.0 241.0,895.0 145.0,895.0 145.0,943.0" data-evidence="4071-4075" />
<rect class="edge-label-bg" x="140.4" y="853.0" width="105.1" height="22" rx="3" />
<text class="edge-label" x="193.0" y="868.0">Physical Page</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="259.0,847.0 259.0,895.0 355.0,895.0 355.0,943.0" data-evidence="4071-4075" />
<rect class="edge-label-bg" x="254.4" y="853.0" width="105.1" height="22" rx="3" />
<text class="edge-label" x="307.0" y="868.0">Physical Page</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="250.0,503.0 250.0,551.0 250.0,551.0 250.0,599.0" data-evidence="4053-4062" />
<rect class="edge-label-bg" x="228.2" y="537.0" width="91.7" height="22" rx="3" />
<text class="edge-label" x="274.0" y="552.0">VM Boundary</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="250.0,152.0 250.0,200.0 250.0,200.0 250.0,248.0" data-evidence="4036-4043" />
<rect class="edge-label-bg" x="252.0" y="186.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="274.0" y="201.0">GVA</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="250.0,319.0 250.0,367.0 250.0,367.0 250.0,415.0" data-evidence="4043-4048" />
<rect class="edge-label-bg" x="238.2" y="353.0" width="71.6" height="22" rx="3" />
<text class="edge-label" x="274.0" y="368.0">TLB Miss</text>
<rect class="canvas" width="1900" height="352" />
<rect class="group-box" x="40.0" y="91.0" width="861.0" height="160.0" rx="8" />
<rect class="group-label-bg" x="54.0" y="81.0" width="90.0" height="22" />
<text class="group-label" x="64.0" y="96.0">Guest</text>
<rect class="group-box" x="1311.0" y="35.0" width="544.0" height="272.0" rx="8" />
<rect class="group-label-bg" x="1325.0" y="25.0" width="90.0" height="22" />
<text class="group-label" x="1335.0" y="40.0">Host RAM</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="1181.0,181.0 1261.0,181.0 1261.0,181.0 1341.0,181.0" data-evidence="4075-4084" />
<rect class="edge-label-bg" x="1239.0" y="139.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="1261.0" y="154.0">HPA</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="1515.0,172.0 1595.0,172.0 1595.0,113.0 1675.0,113.0" data-evidence="4084-4088" />
<rect class="edge-label-bg" x="1566.5" y="128.5" width="105.1" height="22" rx="3" />
<text class="edge-label" x="1619.0" y="143.5">Physical Page</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="1515.0,190.0 1595.0,190.0 1595.0,249.0 1675.0,249.0" data-evidence="4084-4088" />
<rect class="edge-label-bg" x="1566.5" y="205.5" width="105.1" height="22" rx="3" />
<text class="edge-label" x="1619.0" y="220.5">Physical Page</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="871.0,181.0 951.0,181.0 951.0,181.0 1031.0,181.0" data-evidence="4066-4075" />
<rect class="edge-label-bg" x="905.1" y="139.0" width="91.7" height="22" rx="3" />
<text class="edge-label" x="951.0" y="154.0">VM Boundary</text>
<polyline class="edge kind-data style-solid emphasis-normal" points="251.0,181.0 331.0,181.0 331.0,181.0 411.0,181.0" data-evidence="4049-4056" />
<rect class="edge-label-bg" x="309.0" y="139.0" width="44.0" height="22" rx="3" />
<text class="edge-label" x="331.0" y="154.0">GVA</text>
<polyline class="edge kind-control style-solid emphasis-normal" points="561.0,181.0 641.0,181.0 641.0,181.0 721.0,181.0" data-evidence="4056-4061" />
<rect class="edge-label-bg" x="605.2" y="139.0" width="71.6" height="22" rx="3" />
<text class="edge-label" x="641.0" y="154.0">TLB Miss</text>
<g id="node-guest-process">
<rect class="node-shape kind-actor emphasis-normal role-source" data-evidence="4034-4038" x="159.5" y="81.0" width="181.0" height="71.0" rx="7" />
<text class="node-label" x="250.0" y="108.0">Keycloak · PostgreSQL</text>
<line class="node-detail-divider" x1="173.5" y1="129.0" x2="326.5" y2="129.0" />
<text class="node-detail" x="175.5" y="146.0">Guest Userspace</text>
<rect class="node-shape kind-actor emphasis-normal role-source" data-evidence="4047-4051" x="70.0" y="145.5" width="181.0" height="71.0" rx="7" />
<text class="node-label" x="160.5" y="172.5">Keycloak · PostgreSQL</text>
<line class="node-detail-divider" x1="84.0" y1="193.5" x2="237.0" y2="193.5" />
<text class="node-detail" x="86.0" y="210.5">Guest Userspace</text>
</g>
<g id="node-guest-tlb">
<rect class="node-shape kind-component emphasis-normal role-store" data-evidence="4043-4045" x="175.0" y="248.0" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="250.0" y="275.0">Guest TLB</text>
<line class="node-detail-divider" x1="189.0" y1="296.0" x2="311.0" y2="296.0" />
<text class="node-detail" x="191.0" y="313.0">Guest Kernel</text>
<rect class="node-shape kind-component emphasis-normal role-store" data-evidence="4056-4058" x="411.0" y="145.5" width="150.0" height="71.0" rx="7" />
<text class="node-label" x="486.0" y="172.5">Guest TLB</text>
<line class="node-detail-divider" x1="425.0" y1="193.5" x2="547.0" y2="193.5" />
<text class="node-detail" x="427.0" y="210.5">Guest Kernel</text>
</g>
<g id="node-guest-page-table">
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="4048-4053" x="175.0" y="415.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="250.0" y="442.0">Guest Page Table</text>
<line class="node-detail-divider" x1="189.0" y1="463.0" x2="311.0" y2="463.0" />
<text class="node-detail" x="191.0" y="480.0">Guest Kernel</text>
<text class="node-detail" x="191.0" y="496.0">GVA → GPA</text>
<rect class="node-shape kind-component emphasis-normal role-service" data-evidence="4061-4066" x="721.0" y="137.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="796.0" y="164.0">Guest Page Table</text>
<line class="node-detail-divider" x1="735.0" y1="185.0" x2="857.0" y2="185.0" />
<text class="node-detail" x="737.0" y="202.0">Guest Kernel</text>
<text class="node-detail" x="737.0" y="218.0">GVA → GPA</text>
</g>
<g id="node-ept">
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="4055-4067" x="175.0" y="599.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="250.0" y="626.0">EPT</text>
<line class="node-detail-divider" x1="189.0" y1="647.0" x2="311.0" y2="647.0" />
<text class="node-detail" x="191.0" y="664.0">KVM / CPU</text>
<text class="node-detail" x="191.0" y="680.0">GPA → HPA</text>
<rect class="node-shape kind-component emphasis-primary role-service" data-evidence="4068-4080" x="1031.0" y="137.0" width="150.0" height="88.0" rx="7" />
<text class="node-label" x="1106.0" y="164.0">EPT</text>
<line class="node-detail-divider" x1="1045.0" y1="185.0" x2="1167.0" y2="185.0" />
<text class="node-detail" x="1047.0" y="202.0">KVM / CPU</text>
<text class="node-detail" x="1047.0" y="218.0">GPA → HPA</text>
</g>
<g id="node-host-physical-memory">
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="4069-4072" x="163.0" y="783.0" width="174.0" height="64.0" rx="7" />
<text class="node-label" x="250.0" y="813.0">Host Physical Memory</text>
<rect class="node-shape kind-store emphasis-normal role-store" data-evidence="4082-4085" x="1341.0" y="149.0" width="174.0" height="64.0" rx="7" />
<text class="node-label" x="1428.0" y="179.0">Host Physical Memory</text>
</g>
<g id="node-numa-node-0">
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4073-4075" x="70.0" y="943.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="145.0" y="973.0">NUMA Node 0</text>
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4086-4088" x="1675.0" y="81.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="1750.0" y="111.0">NUMA Node 0</text>
</g>
<g id="node-numa-node-1">
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4073-4075" x="280.0" y="943.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="355.0" y="973.0">NUMA Node 1</text>
<rect class="node-shape kind-store emphasis-normal role-sink" data-evidence="4086-4088" x="1675.0" y="217.0" width="150.0" height="64.0" rx="7" />
<text class="node-label" x="1750.0" y="247.0">NUMA Node 1</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB