From 1862ee22ce2e28087299aebb6556a5cdc122d0ef Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Fri, 23 Jan 2015 14:45:55 +1030 Subject: virtio-mmio: Update the device to OASIS spec version This patch add a support for second version of the virtio-mmio device, which follows OASIS "Virtual I/O Device (VIRTIO) Version 1.0" specification. Main changes: 1. The control register symbolic names use the new device/driver nomenclature rather than the old guest/host one. 2. The driver detect the device version (version 1 is the pre-OASIS spec, version 2 is compatible with fist revision of the OASIS spec) and drives the device accordingly. 3. New version uses direct addressing (64 bit address split into two low/high register) instead of the guest page size based one, and addresses each part of the queue (descriptors, available, used) separately. 4. The device activity is now explicitly triggered by writing to the "queue ready" register. 5. Whole 64 bit features are properly handled now (both ways). Signed-off-by: Pawel Moll Acked-by: Michael S. Tsirkin Signed-off-by: Rusty Russell --- include/linux/virtio_mmio.h | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/virtio_mmio.h b/include/linux/virtio_mmio.h index 5c7b6f0daef8..c4b09689ab64 100644 --- a/include/linux/virtio_mmio.h +++ b/include/linux/virtio_mmio.h @@ -51,23 +51,29 @@ /* Virtio vendor ID - Read Only */ #define VIRTIO_MMIO_VENDOR_ID 0x00c -/* Bitmask of the features supported by the host +/* Bitmask of the features supported by the device (host) * (32 bits per set) - Read Only */ -#define VIRTIO_MMIO_HOST_FEATURES 0x010 +#define VIRTIO_MMIO_DEVICE_FEATURES 0x010 -/* Host features set selector - Write Only */ -#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 +/* Device (host) features set selector - Write Only */ +#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014 -/* Bitmask of features activated by the guest +/* Bitmask of features activated by the driver (guest) * (32 bits per set) - Write Only */ -#define VIRTIO_MMIO_GUEST_FEATURES 0x020 +#define VIRTIO_MMIO_DRIVER_FEATURES 0x020 /* Activated features set selector - Write Only */ -#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 +#define VIRTIO_MMIO_DRIVER_FEATURES_SEL 0x024 + + +#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */ /* Guest's memory page size in bytes - Write Only */ #define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 +#endif + + /* Queue selector - Write Only */ #define VIRTIO_MMIO_QUEUE_SEL 0x030 @@ -77,12 +83,21 @@ /* Queue size for the currently selected queue - Write Only */ #define VIRTIO_MMIO_QUEUE_NUM 0x038 + +#ifndef VIRTIO_MMIO_NO_LEGACY /* LEGACY DEVICES ONLY! */ + /* Used Ring alignment for the currently selected queue - Write Only */ #define VIRTIO_MMIO_QUEUE_ALIGN 0x03c /* Guest's PFN for the currently selected queue - Read Write */ #define VIRTIO_MMIO_QUEUE_PFN 0x040 +#endif + + +/* Ready bit for the currently selected queue - Read Write */ +#define VIRTIO_MMIO_QUEUE_READY 0x044 + /* Queue notifier - Write Only */ #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 @@ -95,6 +110,21 @@ /* Device status register - Read Write */ #define VIRTIO_MMIO_STATUS 0x070 +/* Selected queue's Descriptor Table address, 64 bits in two halves */ +#define VIRTIO_MMIO_QUEUE_DESC_LOW 0x080 +#define VIRTIO_MMIO_QUEUE_DESC_HIGH 0x084 + +/* Selected queue's Available Ring address, 64 bits in two halves */ +#define VIRTIO_MMIO_QUEUE_AVAIL_LOW 0x090 +#define VIRTIO_MMIO_QUEUE_AVAIL_HIGH 0x094 + +/* Selected queue's Used Ring address, 64 bits in two halves */ +#define VIRTIO_MMIO_QUEUE_USED_LOW 0x0a0 +#define VIRTIO_MMIO_QUEUE_USED_HIGH 0x0a4 + +/* Configuration atomicity value */ +#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc + /* The config space is defined by each driver as * the per-driver configuration space - Read Write */ #define VIRTIO_MMIO_CONFIG 0x100 -- cgit From 18c137371b2ea86d263b75665a4904a0b8872990 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Feb 2015 15:15:09 +1030 Subject: lguest: add operations to get/set a register from the Launcher. We use the ptrace API struct, and we currently don't let them set anything but the normal registers (we'd have to filter the others). Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index 495203ff221c..f27cae27b0c1 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -63,6 +63,8 @@ enum lguest_req LHREQ_IRQ, /* + irq */ LHREQ_BREAK, /* No longer used */ LHREQ_EVENTFD, /* + address, fd. */ + LHREQ_GETREG, /* + offset within struct pt_regs (then read value). */ + LHREQ_SETREG, /* + offset within struct pt_regs, value. */ }; /* -- cgit From 69a09dc1742ffbb3b02f3a1e03da4801e96452e9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Feb 2015 15:15:09 +1030 Subject: lguest: write more information to userspace about pending traps. This is preparation for userspace handling MMIO and ioport accesses. Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index f27cae27b0c1..c4451ebece47 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -67,6 +67,19 @@ enum lguest_req LHREQ_SETREG, /* + offset within struct pt_regs, value. */ }; +/* + * This is what read() of the lguest fd populates. trap == + * LGUEST_TRAP_ENTRY for an LHCALL_NOTIFY (addr is the + * argument), 14 for a page fault in the MMIO region (addr is + * the trap address, insn is the instruction), or 13 for a GPF + * (insn is the instruction). + */ +struct lguest_pending { + __u8 trap; + __u8 insn[7]; + __u32 addr; +}; + /* * The alignment to use between consumer and producer parts of vring. * x86 pagesize for historical reasons. -- cgit From 8ed313001a892f240269dea05d4b925cbd150492 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Feb 2015 15:15:09 +1030 Subject: lguest: add infrastructure for userspace to deliver a trap to the guest. This is required for instruction emulation to move to userspace. Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index c4451ebece47..3c402b843e03 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -65,6 +65,7 @@ enum lguest_req LHREQ_EVENTFD, /* + address, fd. */ LHREQ_GETREG, /* + offset within struct pt_regs (then read value). */ LHREQ_SETREG, /* + offset within struct pt_regs, value. */ + LHREQ_TRAP, /* + trap number to deliver to guest. */ }; /* -- cgit From b3e28b65de254570140832cf7c95255ab4d501bb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Feb 2015 15:22:01 +1030 Subject: lguest: remove lguest bus definitions from header. Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 49 ++--------------------------------------- 1 file changed, 2 insertions(+), 47 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index 3c402b843e03..677cde735d4b 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -8,52 +8,13 @@ * * The Guest needs devices to do anything useful. Since we don't let it touch * real devices (think of the damage it could do!) we provide virtual devices. - * We could emulate a PCI bus with various devices on it, but that is a fairly - * complex burden for the Host and suboptimal for the Guest, so we have our own - * simple lguest bus and we use "virtio" drivers. These drivers need a set of - * routines from us which will actually do the virtual I/O, but they handle all - * the net/block/console stuff themselves. This means that if we want to add - * a new device, we simply need to write a new virtio driver and create support - * for it in the Launcher: this code won't need to change. + * We emulate a PCI bus with virtio devices on it; we used to have our own + * lguest bus which was far simpler, but this tests the virtio 1.0 standard. * * Virtio devices are also used by kvm, so we can simply reuse their optimized * device drivers. And one day when everyone uses virtio, my plan will be * complete. Bwahahahah! - * - * Devices are described by a simplified ID, a status byte, and some "config" - * bytes which describe this device's configuration. This is placed by the - * Launcher just above the top of physical memory: - */ -struct lguest_device_desc { - /* The device type: console, network, disk etc. Type 0 terminates. */ - __u8 type; - /* The number of virtqueues (first in config array) */ - __u8 num_vq; - /* - * The number of bytes of feature bits. Multiply by 2: one for host - * features and one for Guest acknowledgements. - */ - __u8 feature_len; - /* The number of bytes of the config array after virtqueues. */ - __u8 config_len; - /* A status byte, written by the Guest. */ - __u8 status; - __u8 config[0]; -}; - -/*D:135 - * This is how we expect the device configuration field for a virtqueue - * to be laid out in config space. */ -struct lguest_vqconfig { - /* The number of entries in the virtio_ring */ - __u16 num; - /* The interrupt we get when something happens. */ - __u16 irq; - /* The page number of the virtio ring for this device. */ - __u32 pfn; -}; -/*:*/ /* Write command first word is a request. */ enum lguest_req @@ -80,10 +41,4 @@ struct lguest_pending { __u8 insn[7]; __u32 addr; }; - -/* - * The alignment to use between consumer and producer parts of vring. - * x86 pagesize for historical reasons. - */ -#define LGUEST_VRING_ALIGN 4096 #endif /* _LINUX_LGUEST_LAUNCHER */ -- cgit From d9bab50aa46ce46dd4537d455eb13b200cdac516 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 11 Feb 2015 15:28:01 +1030 Subject: lguest: remove NOTIFY call and eventfd facility. Disappointing, as this was kind of neat (especially getting to use RCU to manage the address -> eventfd mapping). But now the devices are PCI handled in userspace, we get rid of both the NOTIFY hypercall and the interface to connect an eventfd. Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index 677cde735d4b..acd5b12565cc 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -23,7 +23,7 @@ enum lguest_req LHREQ_GETDMA, /* No longer used */ LHREQ_IRQ, /* + irq */ LHREQ_BREAK, /* No longer used */ - LHREQ_EVENTFD, /* + address, fd. */ + LHREQ_EVENTFD, /* No longer used. */ LHREQ_GETREG, /* + offset within struct pt_regs (then read value). */ LHREQ_SETREG, /* + offset within struct pt_regs, value. */ LHREQ_TRAP, /* + trap number to deliver to guest. */ -- cgit