Skip to content

Commit 59bf394

Browse files
committed
virtio: refactoring
Signed-off-by: Nobuhiro MIKI <nob@bobuhiro11.net>
1 parent 29203eb commit 59bf394

File tree

4 files changed

+76
-73
lines changed

4 files changed

+76
-73
lines changed

machine/machine.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,13 @@ func New(nCpus int, tapIfName string) (*Machine, error) {
158158
return nil, err
159159
}
160160

161-
v := virtio.NewNet(virtioNetIRQ, m, t, m.mem)
162-
go v.TxThreadEntry()
163-
go v.RxThreadEntry()
161+
virtioNet := virtio.NewNet(virtioNetIRQ, m, t, m.mem)
162+
go virtioNet.TxThreadEntry()
163+
go virtioNet.RxThreadEntry()
164164

165165
m.pci = pci.New(
166166
pci.NewBridge(), // 00:00.0 for PCI bridge
167-
v, // 00:01.0 for Virtio PCI
167+
virtioNet, // 00:01.0 for Virtio net
168168
)
169169

170170
return m, nil

virtio/common.go

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package virtio
2+
3+
const (
4+
// The number of free descriptors in virt queue must exceed
5+
// MAX_SKB_FRAGS (16). Otherwise, packet transmission from
6+
// the guest to the host will be stopped.
7+
//
8+
// refs https://github.com/torvalds/linux/blob/5859a2b/drivers/net/virtio_net.c#L1754
9+
QueueSize = 32
10+
)
11+
12+
type IRQInjector interface {
13+
InjectVirtioNetIRQ() error
14+
}
15+
16+
type commonHeader struct {
17+
_ uint32 // hostFeatures
18+
_ uint32 // guestFeatures
19+
_ uint32 // queuePFN
20+
queueNUM uint16
21+
queueSEL uint16
22+
_ uint16 // queueNotify
23+
_ uint8 // status
24+
isr uint8
25+
}
26+
27+
// refs: https://wiki.osdev.org/Virtio#Virtual_Queue_Descriptor
28+
type VirtQueue struct {
29+
DescTable [QueueSize]struct {
30+
Addr uint64
31+
Len uint32
32+
Flags uint16
33+
Next uint16
34+
}
35+
36+
AvailRing struct {
37+
Flags uint16
38+
Idx uint16
39+
Ring [QueueSize]uint16
40+
UsedEvent uint16
41+
}
42+
43+
// padding for 4096 byte alignment
44+
_ [4096 - ((16*QueueSize + 6 + 2*QueueSize) % 4096)]uint8
45+
46+
UsedRing struct {
47+
Flags uint16
48+
Idx uint16
49+
Ring [QueueSize]struct {
50+
Idx uint32
51+
Len uint32
52+
}
53+
availEvent uint16
54+
}
55+
}

virtio/net.go

+10-62
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,17 @@ var (
2424
)
2525

2626
const (
27-
IOPortStart = 0x6200
28-
IOPortSize = 0x100
29-
30-
// The number of free descriptors in virt queue must exceed
31-
// MAX_SKB_FRAGS (16). Otherwise, packet transmission from
32-
// the guest to the host will be stopped.
33-
//
34-
// refs https://github.com/torvalds/linux/blob/5859a2b/drivers/net/virtio_net.c#L1754
35-
QueueSize = 32
27+
NetIOPortStart = 0x6200
28+
NetIOPortSize = 0x100
3629
)
3730

38-
type IRQInjector interface {
39-
InjectVirtioNetIRQ() error
40-
}
41-
42-
type Hdr struct {
31+
type netHdr struct {
4332
commonHeader commonHeader
4433
_ netHeader
4534
}
4635

4736
type Net struct {
48-
Hdr Hdr
37+
Hdr netHdr
4938

5039
VirtQueue [2]*VirtQueue
5140
Mem []byte
@@ -60,7 +49,7 @@ type Net struct {
6049
IRQInjector IRQInjector
6150
}
6251

63-
func (h Hdr) Bytes() ([]byte, error) {
52+
func (h netHdr) Bytes() ([]byte, error) {
6453
buf := new(bytes.Buffer)
6554

6655
if err := binary.Write(buf, binary.LittleEndian, h); err != nil {
@@ -70,17 +59,6 @@ func (h Hdr) Bytes() ([]byte, error) {
7059
return buf.Bytes(), nil
7160
}
7261

73-
type commonHeader struct {
74-
_ uint32 // hostFeatures
75-
_ uint32 // guestFeatures
76-
_ uint32 // queuePFN
77-
queueNUM uint16
78-
queueSEL uint16
79-
_ uint16 // queueNotify
80-
_ uint8 // status
81-
isr uint8
82-
}
83-
8462
type netHeader struct {
8563
_ [6]uint8 // mac
8664
_ uint16 // netStatus
@@ -95,7 +73,7 @@ func (v Net) GetDeviceHeader() pci.DeviceHeader {
9573
SubsystemID: 1, // Network Card
9674
Command: 1, // Enable IO port
9775
BAR: [6]uint32{
98-
IOPortStart | 0x1,
76+
NetIOPortStart | 0x1,
9977
},
10078
// https://github.com/torvalds/linux/blob/fb3b0673b7d5b477ed104949450cd511337ba3c6/drivers/pci/setup-irq.c#L30-L55
10179
InterruptPin: 1,
@@ -105,7 +83,7 @@ func (v Net) GetDeviceHeader() pci.DeviceHeader {
10583
}
10684

10785
func (v Net) IOInHandler(port uint64, bytes []byte) error {
108-
offset := int(port - IOPortStart)
86+
offset := int(port - NetIOPortStart)
10987

11088
b, err := v.Hdr.Bytes()
11189
if err != nil {
@@ -260,7 +238,7 @@ func (v *Net) Tx() error {
260238
}
261239

262240
func (v *Net) IOOutHandler(port uint64, bytes []byte) error {
263-
offset := int(port - IOPortStart)
241+
offset := int(port - NetIOPortStart)
264242

265243
switch offset {
266244
case 8:
@@ -281,12 +259,12 @@ func (v *Net) IOOutHandler(port uint64, bytes []byte) error {
281259
}
282260

283261
func (v Net) GetIORange() (start, end uint64) {
284-
return IOPortStart, IOPortStart + IOPortSize
262+
return NetIOPortStart, NetIOPortStart + NetIOPortSize
285263
}
286264

287265
func NewNet(irq uint8, irqInjector IRQInjector, tap io.ReadWriter, mem []byte) *Net {
288266
res := &Net{
289-
Hdr: Hdr{
267+
Hdr: netHdr{
290268
commonHeader: commonHeader{
291269
queueNUM: QueueSize,
292270
isr: 0x0,
@@ -306,33 +284,3 @@ func NewNet(irq uint8, irqInjector IRQInjector, tap io.ReadWriter, mem []byte) *
306284

307285
return res
308286
}
309-
310-
// refs: https://wiki.osdev.org/Virtio#Virtual_Queue_Descriptor
311-
type VirtQueue struct {
312-
DescTable [QueueSize]struct {
313-
Addr uint64
314-
Len uint32
315-
Flags uint16
316-
Next uint16
317-
}
318-
319-
AvailRing struct {
320-
Flags uint16
321-
Idx uint16
322-
Ring [QueueSize]uint16
323-
UsedEvent uint16
324-
}
325-
326-
// padding for 4096 byte alignment
327-
_ [4096 - ((16*QueueSize + 6 + 2*QueueSize) % 4096)]uint8
328-
329-
UsedRing struct {
330-
Flags uint16
331-
Idx uint16
332-
Ring [QueueSize]struct {
333-
Idx uint32
334-
Len uint32
335-
}
336-
availEvent uint16
337-
}
338-
}

virtio/net_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func TestGetDeviceHeader(t *testing.T) {
3333
func TestGetIORange(t *testing.T) {
3434
t.Parallel()
3535

36-
expected := uint64(virtio.IOPortSize)
36+
expected := uint64(virtio.NetIOPortSize)
3737
s, e := virtio.NewNet(9, &mockInjector{}, bytes.NewBuffer([]byte{}), []byte{}).GetIORange()
3838
actual := e - s
3939

@@ -48,7 +48,7 @@ func TestIOInHandler(t *testing.T) {
4848
expected := []byte{0x20, 0x00}
4949
v := virtio.NewNet(9, &mockInjector{}, bytes.NewBuffer([]byte{}), []byte{})
5050
actual := make([]byte, 2)
51-
_ = v.IOInHandler(virtio.IOPortStart+12, actual)
51+
_ = v.IOInHandler(virtio.NetIOPortStart+12, actual)
5252

5353
if !bytes.Equal(expected, actual) {
5454
t.Fatalf("expected: %v, actual: %v", expected, actual)
@@ -67,11 +67,11 @@ func TestSetQueuePhysAddr(t *testing.T) {
6767
base + 0x0089a000,
6868
}
6969

70-
_ = v.IOOutHandler(virtio.IOPortStart+14, []byte{0x0, 0x0}) // Select Queue #0
71-
_ = v.IOOutHandler(virtio.IOPortStart+8, []byte{0x45, 0x03, 0x00, 0x00}) // Set Phys Address
70+
_ = v.IOOutHandler(virtio.NetIOPortStart+14, []byte{0x0, 0x0}) // Select Queue #0
71+
_ = v.IOOutHandler(virtio.NetIOPortStart+8, []byte{0x45, 0x03, 0x00, 0x00}) // Set Phys Address
7272

73-
_ = v.IOOutHandler(virtio.IOPortStart+14, []byte{0x1, 0x0}) // Select Queue #1
74-
_ = v.IOOutHandler(virtio.IOPortStart+8, []byte{0x9a, 0x08, 0x00, 0x00}) // Set Phys Address
73+
_ = v.IOOutHandler(virtio.NetIOPortStart+14, []byte{0x1, 0x0}) // Select Queue #1
74+
_ = v.IOOutHandler(virtio.NetIOPortStart+8, []byte{0x9a, 0x08, 0x00, 0x00}) // Set Phys Address
7575

7676
actual := [2]uint32{
7777
uint32(uintptr(unsafe.Pointer(v.VirtQueue[0]))),
@@ -102,7 +102,7 @@ func TestQueueNotifyHandler(t *testing.T) {
102102

103103
// Select Queue #1
104104
sel := byte(1)
105-
_ = v.IOOutHandler(virtio.IOPortStart+14, []byte{sel, 0x0})
105+
_ = v.IOOutHandler(virtio.NetIOPortStart+14, []byte{sel, 0x0})
106106

107107
// Init virt queue
108108
vq := virtio.VirtQueue{}

0 commit comments

Comments
 (0)