본문 바로가기
apple silicon

hypervisor virtio

by pwnhub 2025. 9. 5.

 

virtio -> virtual I/O

https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net

 

Introduction to virtio-networking and vhost-net

Virtio was developed as a standardized open interface for virtual machines (VMs) to access simplified devices such as block devices and network adaptors. Virtio-net is a virtual ethernet card and is the most complex device supported so far by virtio.

www.redhat.com

사실 이 글이 GOAT 이긴 한데, 대충 정리해보겠다

 

 

Virtio는 paravirtualization을 구현하는 framework이다.

virtio-networking 은 host 쪽 vhost-net과 guest 쪽 virtio-net 으로 구성된다.

KVM + qemu + libvirt 스택 기준으로 설명하면

 

유저가 N개의 vm을 생성하면 유저랜드 쪽에 qemu가 N개의 프로세스를 실행하고, 해당 N개의 프로세스가 libvirt와 통신하며 hw interaction을 구현한다.

 

libvirt 는 xml format으로 작성된 파일을 qemu CLI로 변환해주는 인터페이스이다.

커널 측엔 커널 모듈로 존재하는 KVM이 이러한 가상화를 제공한다.

 

virtio-networking 에는 크게 2가지 파트가 있다.

control plane : data plane 을 제어하기 위한 host-guest 통신을 제어한다

data plane : host-guest 간 패킷을 전송한다

 

data plane 은 효율적으로 많은 패킷을 전송해야한다. 즉, 네트워크 대역폭이 높아야한다.

control plane 은 이러한 data plane을 위한 host-guest 협상 및 관리를 맡는다.

 

virtio는 virtio spec 과 vhost protocol이 있다.

OASIS라는 오픈소스 관련 표준화 기구에서 정의한 virtio spec은 control/data plane 구성 방식을 표준화한다.

해당 스펙은 표준으로써 virtio가 공유한다.

vhost protocol은 기존 userland <-> kernel 간의 통신을 data plane으로 줄여 통신할 수 있게 만든 프로토콜이다.

vhost-net <-> virtio-net 간의 통신으로 이해할 수 있다.

 

호스트의 유저랜드에서 유저 프로세스로 게스트 커널+유저랜드가 돌아간다.

해당 프로세스가 qemu-system-x86에 해당한다.

 

이제부터 virtio 표준 spec 을 알아보도록 하겠다.

virtio의 control plane 은 qemu process에 구현되며 data plane은 qemu process 밖(vhost-net 과 virtio-net 사이 공유메모리)에 구성된다.

qemu process에 data plane이 구현된다면 host kernel 과 guest kernel 사이의 모든 패킷 전달마다 context switch가 발생한다.

이로인한 오버헤드를 줄이고자 data plane을 사이에 두는 것이다.

 

 

vhost-net 은 host 커널 공간에 들어있는 백엔드이다.

virtio-net 은 guest 커널에 들어간 프론트엔드이다.

각각의 커널에 드라이버 형태로 들어간다.

data plane 을 향해서 rx/tx 통신을 진행하고, data plane에는 virtqueue라는 버퍼가 존재하여 해당 버퍼에 패킷을 담는다.

실제 패킷 포워딩은 host kernel에서 발생한다.

 

 

virtio는 결국 kernel 로 packet을 전달하며 context switch overhead를 줄여준다.

그러나 data plane에 쌓엔 패킷은 언젠가 전달 되어야한다. interrupt 기반으로 구현되어있다.

guest에서 패킷을 shared queue에 충분히 쌓은 경우 host에 vIRQ라는 interrupt를 발생시키고, vhost thread가 패킷을 처리하게 된다.

해당 interrupt로 packet을 처리할 때 마다 VM-Entry, VM-Exit 이 발생하며 overhead가 발생한다. 그래도 충분히 의미있는 수준의 overhead를 해소하여 최근에는 표준처럼 쓰인다.

 

guest -> 다른 guest

guest -> external

인 경우 OVS를 통해 작동한다.

 

OVS는 Open vSwitch이다. 여러 vm과 물리 NIC을 port로 연결하는 방식이다.

virtio-networking 에서 내부 네트워크 스위치 역할을 한다.

vhost-net 백엔드에서 올라온 패킷을 어디로 전달할 지 결정하고, 다른 VM/외부 네트워크 NIC 으로 패킷을 포워딩한다.

 

User space에는 ovsdb-server와 ovs-vswitchd 가 존재한다.

ovsdb-server는 OVS 설정을 저장하고 있다. 여기에 브릿지, 포트, 플로우 테이블 등의 설정이 들어간다

ovs-vswitchd는 OVS 메인 데몬으로 커널 모듈과 통신하여 데이터 경로를 설정한다. control plane 역할을 한다.

 

Kernel space에는 OVS Kernel module이 올라간다.

이는 data plane 에 해당하며, 실제 패밋을 포워딩한다.

새로운 플로우가 들어온 경우 ovs-vswitchd에 쿼리하여 플로우 엔트리를 설치한다.

플로우 캐시를 유지하며, 일치하는 엔트리를 빠르게 처리한다.

 

virtio-networking 관점에서는 각 VM은 vhost-net backend의 OVS 가상 포트로 연결된다.

host의 물리 NIC도 OVS의 포트로 연결된다.

OVS bridge가 모든 포트를 switch 도메인으로 묶는다.

 

 

 

'apple silicon' 카테고리의 다른 글

zeroday in KVM ( arm linux kernel ) - How to report (1)  (0) 2025.09.05
what is KVM?  (0) 2025.09.05
hypervisor type 1 vs type 2  (0) 2025.09.05