dbs-upcall 0.1.0

dbs-upcall is a direct communication tool between VMM and guest
Documentation
# dbs-upcall

`dbs-upcall` is a direct communication tool between VMM and guest developed upon vsock. The server side of the upcall is a driver in guest kernel (kernel patches are needed for this feature) and it'll start to serve the requests after the kernel starts. And the client side is in VMM , it'll be a thread that communicates with vsock through uds.

We have accomplished device hotplug / hot-unplug directly through upcall in order to avoid virtualization of ACPI to minimize virtual machines' overhead. And there could be many other usage through this direct communication channel. 

## Design

### Server Design

The server side of upcall is a driver in guest kernel and the vsock port is 0xDB.
After the vsock is connected, upcall related service will be registered and a kthread providing corresponding service will be created.
The upcall service thread will first send a message with message type Connect to try to connect with the client side (VMM). After service successfully connects, the service thread will get into a loop for continuously receiving requests from the client side and processing the requests until the service stops.

The service we currently support:
1. device manager : supports cpu hotplug / hot-unplug, virtio-mmio devices hotplug / hot-unplug

### Client Design
The client side is in VMM and we abstract related logic into this crate `dbs-upcall`.

The upcall state machine for the client side:
![Upcall State Machine](./images/upcall_state_machine.png)

The client side's workflow:
1. [Current State: WaitingServer] Check the connection with vsock server.
2. [Current State: WaitingService]Check the connection with upcall server side in the guest kernel for message type Connect and magic version.
3. [Current State: ServiceConnected] The request could be sent through upcall in this state.

If step 1 and 2 failed, upcall will try to reconnect.
If request is sent in step 3, upcall state will change to ServiceBusy and upcall will not process other requests in this state.

### Message Design
There are two parts for the upcall request message : message header and message load.
And there are three parts for the upcall reply messgae: message header, result and message load.

Message Header contains following information and it remains the same for the request and the reply : 
1. magic_version(u32): magic version for identifying upcall and the service type
2. msg_size(u32): size of the message load
3. msg_type(u32): type for the message to identify its usage  (e.g. ADD_CPU)
4. msg_flags(u32): reserved

For the upcall request message, message load currently contains two kinds of msg_load.
msg_load type 1: add_mmio_dev - for virtio-mmio hotplug / hot-unplug request:
1. mmio_base
2. mmio_size
3. mmio_irq

msg_load type 2: cpu_dev_info - for cpu hotplug / hot-unplug request:
1. count
2. apic_ver
3. apic_ids[256]
   
For the upcall reply message, reply contains result and two kinds of msg_load.
If result is 0, the operation is successful.
If result is not 0, result refers to the error code.

msg_load type 1: add_mmio_dev - for virtio-mmio reply:
currently empty

msg_load type 2: cpu_dev_reply_info - for cpu hotplug / hot-unplug reply:
1. apic_index

## Kernel Patches

Kernel patches are needed for dbs-upcall. You could go to [kernel patches](/kernel) to get the patches.
`0001-dragonball-introduce-dragonball-driver.patch` in `/kernel` is needed as a prerequisite to enable upcall.
`0001-upcall-add-vsock-server-and-upcall-support.patch` in `/kernel/upcall`is the patch for enabling upcall.
The patches have been tested on linux kernel 4.19 (stable).

## License

This project is licensed under [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).