Am 24.08.2010 14:22, schrieb Avi Kivity:
> First of all we need a virtio/s390 specification, like we have a
> virtio/pci spec.
Here is something that I started a year ago but never finished.
Christian
guest/host interface for s390/virtio devices
KVM_DEVICE_DESCRIPTOR PAGE
0 8 16 24 31
+--------+--------+--------+--------+
0 | type | num_vq | featlen| conflen|
+--------+--------+--------+--------+
1 | status | |
+--------+ +------>+
2 | config | |
+ + |
... |
|
+-----------------------------------------------------+
|
| CONFIG ARRAY
| 0 8 16 24 31
+-------->+--------+--------+--------+--------+
0 | |
+ +
1 | |
+ +
2 | |
+ virtqueue 0 +------>+
3 | | |
+ + |
4 | | |
+ + |
5 | | |
+--------+--------+--------+--------+ |
|///////////////////////////////////+ |
|///////////////////////////////////+ |
+--------+--------+--------+--------+ |
| | |
+ + |
| | |
+ + |
| | |
+ virtqueue num_vq - 1 +------>+
| | |
+ + |
| | |
+ + |
| | |
+--------+--------+--------+--------+ |
num_vq*6 | feature bits (featlen * 2 Bytes) | |
+ +--------+--------+ |
| | | |
+--------+--------+ + |
| config space (conflen Bytes) | |
+ +--------+ |
| | |
+--------+--------+--------+ |
|
|
+-----------------------------------------------------+
|
| VIRTQUEUE
| 0 8 16 24 31
|-------->+--------+--------+--------+--------+
0 | interrupt token ... |
+ +
1 | ... set by guest |
+--------+--------+--------+--------+
2 | virtio ring address |
+ +
3 | ... set by host |
+--------+--------+--------+--------+
4 | number of elems |/////////////////+
+--------+--------+/////////////////+
5 |///////////////////////////////////+
+--------+--------+--------+--------+
COMPLETE KVM_DEVICE_DESCRIPTOR PAGE
0 8 16 24 31
+--------+--------+--------+--------+
0 | type | num_vq | featlen| conflen|
+--------+--------+--------+--------+
1 | status | interrupt token |
+--------+ +
2 | virtqueue 0(set by guest) |
+ +--------+--------+--------+
3 | | virtio ring address |
+--------+ +
4 | virtqueue 0 (set by host) |
+ +--------+--------+--------+
5 | | number of descr |////////|
+--------+--------+--------+////////+
6 |///////////////////////////////////|
+////////+--------+--------+--------+
7 |////////| interrupt token |
+--------+ +
8 | virtqueue 1(set by guest) |
+ +--------+--------+--------+
9 | | virtio ring address |
+--------+ +
10 | virtqueue 1 (set by host) |
+ +--------+--------+--------+
11 | | number of descr |////////|
+--------+--------+--------+////////+
12 |///////////////////////////////////|
+////////+--------+--------+--------+
13 |////////|
+--------+ .....
? |///////////////////////////////////|
+////////+--------+--------+--------+
? |////////| feature bits |
+--------+ (size multiple +--------+
| of 2 bytes) | |
+--------+--------+--------+ +
| config space (size of any length) |
+ +++++++++++++++++++
| |
+--------+--------+
Host->Guest notification:
-------------------------
via external interrupt with
- real storage 0x86-0x87 : 0x2603 --> host interrupt
- real storage 0x84: 0xd --> VIRTIO_SUBCODE_64
- real storage 0x11B8-0x11bf: the interrupt token (is a pointer to a struct
virtqueue -> set by guest)
- real storage 0x83:
0: normal interrupt
1: config change
Guest->Host notification:
-------------------------
via diagnose call:
diag 2,4,0x500\n"
The calling convention is similar to the
* s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1
* as hypercall number and R7 as parameter 6. The return value is
* written to R2. We use the diagnose instru
hypercall numbers are
#define KVM_S390_VIRTIO_NOTIFY 0
#define KVM_S390_VIRTIO_RESET 1
#define KVM_S390_VIRTIO_SET_STATUS 2
Virtio Ring: (3Pages)
---------------------
0 8 16 24 31
+--------+--------+--------+--------+\
0 | Desriptor 0: | \
+ guest physical address + \
1 | | \
+--------+--------+--------+--------+ one descriptor
2 | Descriptor 0: Length | /
+--------+--------+--------+--------+ /
3 | D0: Flags | D0: Next | /
+--------+--------+--------+--------+/
| |
...
| |
+--------+--------+--------+--------+
0 | Descriptor num -1 |
+ - guest physical address 64bit +
1 | - Length 32bit |
+ - flags 16 bit +
2 | - next 16 bit |
+ +
3 | |
+--------+--------+--------+--------+
|///////////////////////////////////|
...
|///////////////////////////////////|
+--------+--------+--------+--------+
4096 | avail_flags | avail_idx |
+--------+--------+--------+--------+
4097 | available 0 | available 1 |
+--------+--------+--------+--------+
| |
...
| |
+--------+--------+--------+--------+
| available num-2 | available num-1 |
+--------+--------+--------+--------+
|///////////////////////////////////|
...
|///////////////////////////////////|
+--------+--------+--------+--------+
8192 | used_flags | used_idx |
+--------+--------+--------+--------+
| used_elem_id 0 |
+--------+--------+--------+--------+
| used_elem_len 0 |
+--------+--------+--------+--------+
| |
...
| |
+--------+--------+--------+--------+
| used_elem_id num-1 |
+--------+--------+--------+--------+
| used_elem_len num-1 |
+--------+--------+--------+--------+