Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Linux KVM のコードを追いかけてみよう

8 333 vues

Publié le

第1回カーネル/VM探検隊 Linux KVM のコードを追いかけてみよう のスライドです。

Publié dans : Technologie
  • Soyez le premier à commenter

Linux KVM のコードを追いかけてみよう

  1. 1. Linux KVM /VM 1 by Tsuyoshi Ozawa, softlab@univ. of Tsukuba. Twitter: oza_x86 2009 8 13 1
  2. 2. 2009 8 13 2
  3. 3. 1. VMM 2. Intel-VT 3. Linux KVM KVM 2009 8 13 3
  4. 4. VMM 2009 8 13 4
  5. 5. VMM 2009 8 13 5
  6. 6. Virtual Machine Monitor 2009 8 13 6
  7. 7. Virtual Machine Monitor 1. 2. (OS) 2009 8 13 7
  8. 8. VMM 2009 8 13 8
  9. 9. 2009 8 13 9
  10. 10. 2009 8 13 10
  11. 11. Qemu 2009 8 13 11
  12. 12. 2009 8 13 12
  13. 13. 2009 8 13 13
  14. 14. Qemu 2009 8 13 14
  15. 15. 2009 8 13 15
  16. 16. CPU 2009 8 13 16
  17. 17. Main Memory ... ALU movl %eax %ebx ... 2009 8 13 17
  18. 18. Main Memory ... ALU movl %eax %ebx ... fetch 2009 8 13 18
  19. 19. Qemu ... 2009 8 13 19
  20. 20. Qemu Main Memory ... ALU movl %eax %ebx ... fetch 2009 8 13 20
  21. 21. opcode = mem[pc]; execute(opcode); 2009 8 13 21
  22. 22. mov opcode = mem[pc]; execute(opcode); jmp 2009 8 13 22
  23. 23. • 2009 8 13 23
  24. 24. 2009 8 13 24
  25. 25. opcode[0..N] = mem[pc]; mid_ops=compile(opcode); execute(mid_ops); 2009 8 13 25
  26. 26. opcode[0..N] = mem[pc]; mid_ops=compile(opcode); execute(mid_ops); 2009 8 13 26
  27. 27. opcode[0..N] = mem[pc]; mid_ops=compile(opcode); execute(mid_ops); 2009 8 13 27
  28. 28. 2009 8 13 28
  29. 29. 2009 8 13 29
  30. 30. • • • 2009 8 13 30
  31. 31. 2009 8 13 31
  32. 32. 2009 8 13 32
  33. 33. VMM 2009 8 13 33
  34. 34. KVM 2009 8 13 34
  35. 35. • 2009 8 13 35
  36. 36. .section .data message: .ascii "hello,gas!n" .section .text .global _start _start: movl $4,%eax movl $1,%ebx movl $message,%ecx movl $12,%edx int $0x80 2009 8 13 36
  37. 37. ./a.out hello,gas! 2009 8 13 37
  38. 38. Hello world 2009 8 13 38
  39. 39. printf(“HelloWorld¥n”) 2009 8 13 39
  40. 40. printf 2009 8 13 40
  41. 41. 2009 8 13 41
  42. 42. 2009 8 13 42
  43. 43. write 2009 8 13 43
  44. 44. write out 2009 8 13 44
  45. 45. .section .data message: .ascii "hello,gas!n" .section .text .global _start _start: movl $4,%eax movl $1,%ebx movl $message,%ecx out movl $12,%edx int $0x80 2009 8 13 45
  46. 46. ... outb %ax ... 2009 8 13 46
  47. 47. Program Display CPU outb 2009 8 13 47
  48. 48. hello,gas! 2009 8 13 48
  49. 49. • 2009 8 13 49
  50. 50. • VM 2009 8 13 50
  51. 51. .section .data message: .ascii "hello,gas!n" .section .text .global _start _start: movl $4,%eax movl $1,%ebx movl $message,%ecx out movl $12,%edx int $0x80 2009 8 13 51
  52. 52. ... outb $hogehoge ... 2009 8 13 52
  53. 53. hello,gas! 2009 8 13 53
  54. 54. OS . 2009 8 13 54
  55. 55. VM Virtual Program Display VirtualCPU outb 2009 8 13 55
  56. 56. VM Program Real Display VirtualCPU outb 2009 8 13 56
  57. 57. hello,gas! on host system?! 2009 8 13 57
  58. 58. 2009 8 13 58
  59. 59. 2009 8 13 59
  60. 60. 2009 8 13 60
  61. 61. 2009 8 13 61
  62. 62. VM out Virtual Program Display CPU 2009 8 13 62
  63. 63. VM out Virtual Program Display CPU outb 2009 8 13 63
  64. 64. VM out 2009 8 13 64
  65. 65. Emu Code trap CPU 2009 8 13 65
  66. 66. Emu Code CPU handle 2009 8 13 66
  67. 67. VM out Emu ret Code CPU 2009 8 13 67
  68. 68. VM out ack Virtual Program Display CPU 2009 8 13 68
  69. 69. VM out out 2009 8 13 69
  70. 70. 2009 8 13 70
  71. 71. 2009 8 13 71
  72. 72. x86 2009 8 13 72
  73. 73. ? 2009 8 13 73
  74. 74. 2009 8 13 74
  75. 75. 2009 8 13 75
  76. 76. ? 2009 8 13 76
  77. 77. 2009 8 13 77
  78. 78. x86 ? 2009 8 13 78
  79. 79. ... ? 2009 8 13 79
  80. 80. 2009 8 13 80
  81. 81. 2009 8 13 81
  82. 82. x86 • • Hypervisor Call • Xen 2009 8 13 82
  83. 83. x86 • • LilyVM 2009 8 13 83
  84. 84. x86 • • (JIT ) • VMWare 2009 8 13 84
  85. 85. 2009 8 13 85
  86. 86. Intel ( AMD-V ) 2009 8 13 86
  87. 87. Intel-VT 2009 8 13 87
  88. 88. CPU ? 2009 8 13 88
  89. 89. User Privilege 2009 8 13 89
  90. 90. User Privilege 2009 8 13 90
  91. 91. 2009 8 13 91
  92. 92. User User warp Privilege Privilege 2009 8 13 92
  93. 93. 2009 8 13 93
  94. 94. User User Privilege Privilege 2009 8 13 94
  95. 95. User User Privilege Privilege 2009 8 13 95
  96. 96. User User Privilege Privilege trap 2009 8 13 96
  97. 97. User User Privilege Privilege Intel-VT 2009 8 13 97
  98. 98. User Privilege 2009 8 13 98
  99. 99. VMX-Root Mode (VM ) 2009 8 13 99
  100. 100. User Privilege 2009 8 13 100
  101. 101. VMX-non root Mode ( ) 2009 8 13 101
  102. 102. VMX non Root Mode 2009 8 13 102
  103. 103. User User Privilege Privilege 2009 8 13 103
  104. 104. vmlaunch vmresume 2009 8 13 104
  105. 105. KVM 2009 8 13 105
  106. 106. KVM 2009 8 13 106
  107. 107. Kernel-based Virtul Machine 2009 8 13 107
  108. 108. KVM 2009 8 13 108
  109. 109. KVM • •Intel-VT • •Qemu • •Linux • •Linux 2009 8 13 109
  110. 110. KVM • •Intel-VT • •Qemu • •Linux • •Linux KVM 2009 8 13 110
  111. 111. KVM • •VM • • • • OS 2009 8 13 111
  112. 112. 2009 8 13 112
  113. 113. 2009 8 13 113
  114. 114. Main loop 2009 8 13 114
  115. 115. KVM 2009 8 13 115
  116. 116. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 116
  117. 117. 2009 8 13 117
  118. 118. VMX VMX non Root Root Mode Mode 2009 8 13 118
  119. 119. 2009 8 13 119
  120. 120. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 120
  121. 121. VMX non Root Mode 2009 8 13 121
  122. 122. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 122
  123. 123. User Qemu KVM Program Qemu Linux Guest KVM Kernel Kernel 2009 8 13 123
  124. 124. ./qemu -hda disk1.img (-hda ) 2009 8 13 124
  125. 125. User Qemu Program $ ./qemu -hda disk1 Linux Guest KVM Kernel Kernel 2009 8 13 125
  126. 126. User Qemu Program Qemu Linux Guest KVM Kernel Kernel 2009 8 13 126
  127. 127. Qemu 2009 8 13 127
  128. 128. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel 2009 8 13 128
  129. 129. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 129
  130. 130. 2009 8 13 130
  131. 131. 2009 8 13 131
  132. 132. vmlaunch vmresume 2009 8 13 132
  133. 133. VMX non Root Mode 2009 8 13 133
  134. 134. User Qemu Program Linux Guest KVM VT Kernel Kernel 2009 8 13 134
  135. 135. 2009 8 13 135
  136. 136. vmlaunch vmresume 2009 8 13 136
  137. 137. User Qemu Program vmlaunch / vmresume Linux Guest KVM Kernel Kernel 2009 8 13 137
  138. 138. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 138
  139. 139. VMX non root Mode 2009 8 13 139
  140. 140. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 140
  141. 141. 2009 8 13 141
  142. 142. VMX non Root Mode IO 2009 8 13 142
  143. 143. 2009 8 13 143
  144. 144. outb %ax 2009 8 13 144
  145. 145. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 145
  146. 146. User Qemu Program Linux Guest KVM Kernel Kernel outb %ax 2009 8 13 146
  147. 147. VMX Root Mode 2009 8 13 147
  148. 148. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 148
  149. 149. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 149
  150. 150. 2009 8 13 150
  151. 151. Qemu 2009 8 13 151
  152. 152. User Qemu Program IOCTL return Linux Guest KVM Kernel Kernel 2009 8 13 152
  153. 153. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 153
  154. 154. User Qemu Program io Linux Guest KVM Kernel Kernel 2009 8 13 154
  155. 155. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 155
  156. 156. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 156
  157. 157. 2009 8 13 157
  158. 158. IOCTL CPU 2009 8 13 158
  159. 159. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel 2009 8 13 159
  160. 160. 2009 8 13 160
  161. 161. ... 2009 8 13 161
  162. 162. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel vmlaunch vmresume 2009 8 13 162
  163. 163. 2009 8 13 163
  164. 164. 2009 8 13 164
  165. 165. KVM kvm-85 2009 8 13 165
  166. 166. 2009 8 13 166
  167. 167. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 167
  168. 168. Qemu 2009 8 13 168
  169. 169. $./qemu -hda disk1 ... 2009 8 13 169
  170. 170. qemu/vl.c main.c 2009 8 13 170
  171. 171. 4439 int 4440 { main (int argc, char **argv, char **envp) // . Shadow page table . 5425 kvm_qemu_create_context() // 5493 kvm_init(smp_cpus); ... // qemu/hw/pc.c 5554 machine->init(ram_size, vga_ram_size, boot_devices, 5555 kernel_filename, kernel_cmdline, 5556 initrd_filename, cpu_model); ... ... 5742 main_loop(); ... 5747 } 2009 8 13 171
  172. 172. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 172
  173. 173. User Qemu Program Qemu Linux Guest KVM Kernel Kernel 2009 8 13 173
  174. 174. - •machine->init • • qemu/hw/pc.c pc_init1 2009 8 13 174
  175. 175. 2009 8 13 175
  176. 176. 2009 8 13 176
  177. 177. pc_init1 pc_new_cpu cpu_init = cpu_x86_init kvm_init_cpu pthread_create ap_main_loop kvm_main_loop_cpu 2009 8 13 177
  178. 178. 2009 8 13 178
  179. 179. 2009 8 13 179
  180. 180. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel 2009 8 13 180
  181. 181. IOCTL 2009 8 13 181
  182. 182. ... qemu/kvm-all.c kvm_cpu_exec 2009 8 13 182
  183. 183. 378 static int kvm_main_loop_cpu (CPUState *env) 379 { 394 while (1) { 395 while (!has_work(env)) 396 kvm_main_loop_wait(env, 1000); 397 if (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) 398 env->halted = 0; // . .... 404 } 405 if (!env->halted && !env->kvm_cpu_state.init) { 406 kvm_cpu_exec(env); // } } 413 } 2009 8 13 183
  184. 184. int kvm_cpu_exec(){ ... 461 ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); 478 switch (run->exit_reason) { 479 case KVM_EXIT_IO: 481 ret = kvm_handle_io(env, run->io.port, 482 (uint8_t *)run + run>io.data_offset, 483 run->io.direction, 484 run->io.size, 485 run->io.count); 486 break; case KVM_EXIT_MMIO: .... ... 2009 8 13 184
  185. 185. 648 int kvm_vcpu_ioctl(CPUState *env, int type, ...) 649 { 658 ret = ioctl(env->kvm_fd, type, arg); 659 if (ret == -1) 660 ret = -errno; 661 662 return ret; 663 } 2009 8 13 185
  186. 186. 2009 8 13 186
  187. 187. IOCTL 2009 8 13 187
  188. 188. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel 2009 8 13 188
  189. 189. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 189
  190. 190. 2009 8 13 190
  191. 191. 2009 8 13 191
  192. 192. IOCTL 2009 8 13 192
  193. 193. IOCTL 2009 8 13 193
  194. 194. 2009 8 13 194
  195. 195. static struct file_operations kvm_vcpu_fops = { .release = kvm_vcpu_release, .unlocked_ioctl = kvm_vcpu_ioctl, .compat_ioctl = kvm_vcpu_ioctl, .mmap = kvm_vcpu_mmap, }; 2009 8 13 195
  196. 196. // file->f_op = kvm_vcpu_fops; 2009 8 13 196
  197. 197. kvm_vcpu_ioctl 2009 8 13 197
  198. 198. static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { switch (ioctl) { case KVM_RUN: r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run); break; .... } 2009 8 13 198
  199. 199. VMX non Root Mode 2009 8 13 199
  200. 200. User Qemu Program Linux Guest KVM VT Kernel Kernel 2009 8 13 200
  201. 201. ... 2009 8 13 201
  202. 202. kvm_arch_vcpu_ioctl_run __vcpu_run vcpu_enter_guest vmx_vcpu_run 2009 8 13 202
  203. 203. vmx_vcpu_run kernel/x86/vmx.c 2009 8 13 203
  204. 204. User Qemu Program vmlaunch / vmresume Linux Guest KVM Kernel Kernel 2009 8 13 204
  205. 205. 2009 8 13 205
  206. 206. 2009 8 13 206
  207. 207. include/asm-x86/vmx.h #define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2" #define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3" 2009 8 13 207
  208. 208. 2009 8 13 208
  209. 209. vmlaunch/vmresume 2009 8 13 209
  210. 210. User Qemu Program vmlaunch / vmresume Linux Guest KVM Kernel Kernel 2009 8 13 210
  211. 211. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 211
  212. 212. VMX non-root mode 2009 8 13 212
  213. 213. 2009 8 13 213
  214. 214. VMX non Root Mode IO 2009 8 13 214
  215. 215. 2009 8 13 215
  216. 216. 2009 8 13 216
  217. 217. outb %ax 2009 8 13 217
  218. 218. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 218
  219. 219. User Qemu Program Linux Guest KVM Kernel Kernel outb %ax 2009 8 13 219
  220. 220. 2009 8 13 220
  221. 221. "jne .Llaunched nt" __ex(ASM_VMX_VMLAUNCH) "nt" "jmp .Lkvm_vmx_return nt" ".Llaunched: " __ex(ASM_VMX_VMRESUME) "nt" ".Lkvm_vmx_return: " vmlaunch /* */ vmresume ... ... 2009 8 13 221
  222. 222. "jne .Llaunched nt" __ex(ASM_VMX_VMLAUNCH) "nt" "jmp .Lkvm_vmx_return nt" ".Llaunched: " __ex(ASM_VMX_VMRESUME) "nt" ".Lkvm_vmx_return: " /* */ ... 2009 8 13 222
  223. 223. 2009 8 13 223
  224. 224. 2009 8 13 224
  225. 225. out 2009 8 13 225
  226. 226. out in . 2009 8 13 226
  227. 227. Intel-VT 2009 8 13 227
  228. 228. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 228
  229. 229. 2009 8 13 229
  230. 230. Qemu 2009 8 13 230
  231. 231. User Qemu Program IOCTL return Linux Guest KVM Kernel Kernel 2009 8 13 231
  232. 232. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 232
  233. 233. int kvm_cpu_exec(){ ... 461 ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); 478 switch (run->exit_reason) { 479 case KVM_EXIT_IO: 481 ret = kvm_handle_io(env, run->io.port, 482 (uint8_t *)run + run>io.data_offset, 483 run->io.direction, 484 run->io.size, 485 run->io.count); 486 break; case KVM_EXIT_MMIO: .... ... 2009 8 13 233
  234. 234. outb 2009 8 13 234
  235. 235. int kvm_cpu_exec(){ ... // 461 ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); 478 switch (run->exit_reason) { 479 case KVM_EXIT_IO: 481 ret = kvm_handle_io(env, run->io.port, 482 (uint8_t *)run + run>io.data_offset, 483 run->io.direction, 484 run->io.size, 485 run->io.count); 486 break; case KVM_EXIT_MMIO: outb .... ... 2009 8 13 235
  236. 236. 2009 8 13 236
  237. 237. IO 2009 8 13 237
  238. 238. User Qemu Program io Linux Guest KVM Kernel Kernel 2009 8 13 238
  239. 239. 2009 8 13 239
  240. 240. out 2009 8 13 240
  241. 241. outb %al 2009 8 13 241
  242. 242. outb %al 2009 8 13 242
  243. 243. ( ) 2009 8 13 243
  244. 244. int kvm_cpu_exec(){ ... // 461 ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); 478 switch (run->exit_reason) { 479 case KVM_EXIT_IO: 481 ret = kvm_handle_io(env, run->io.port, 482 (uint8_t *)run + run>io.data_offset, 483 run->io.direction, 484 run->io.size, 485 run->io.count); 486 break; case KVM_EXIT_MMIO: .... ... 2009 8 13 244
  245. 245. kvm_handle_io cpu_outb ioport_write 2009 8 13 245
  246. 246. static void ioport_write(int index, uint32_t address, uint32_t data) { static IOPortWriteFunc *default_func[3] = { default_ioport_writeb, default_ioport_writew, default_ioport_writel }; IOPortWriteFunc *func = ioport_write_table[index][address]; if (!func) func = default_func[index]; func(ioport_opaque[address], address, data); } ioport_write_table 2009 8 13 246
  247. 247. ( ) 2009 8 13 247
  248. 248. User Qemu Program io Linux Guest KVM Kernel Kernel 2009 8 13 248
  249. 249. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 249
  250. 250. User Qemu Program Linux Guest KVM Kernel Kernel 2009 8 13 250
  251. 251. 2009 8 13 251
  252. 252. IOCTL CPU 2009 8 13 252
  253. 253. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel 2009 8 13 253
  254. 254. 2009 8 13 254
  255. 255. ... 2009 8 13 255
  256. 256. User Qemu Program IOCTL Linux Guest KVM Kernel Kernel vmlaunch 2009 8 13 vmresume 256
  257. 257. 2009 8 13 257
  258. 258. 378 static int kvm_main_loop_cpu(CPUState *env) 379 { 394 while (1) { 395 while (!has_work(env)) 396 kvm_main_loop_wait(env, 1000); 397 if (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) 398 env->halted = 0; // . .... 404 } 405 if (!env->halted && !env->kvm_cpu_state.init) { 406 kvm_cpu_exec(env); // } } 413 } 2009 8 13 258
  259. 259. 2009 8 13 259
  260. 260. Twitter 2009 8 13 260

×