1. Overview ----------- This document describes the driver set for Unisys Secure Partitioning (s-Par(R)). s-Par is firmware that provides hardware partitioning capabilities for splitting large-scale Intel x86 servers into multiple isolated partitions. s-Par provides a set of para-virtualized device drivers to allow guest partitions on the same server to share devices that would normally be unsharable, specifically: * visornic - network interface * visorhba - scsi disk adapter * visorinput - keyboard and mouse These drivers conform to the standard Linux bus/device model described within Documentation/driver-model/, and utilize a driver named visorbus to present the virtual busses involved. Drivers in the 'visor*' driver set are commonly referred to as "guest drivers" or "client drivers". All drivers except visorbus expose a device of a specific usable class to the Linux guest environment (e.g., block, network, or input), and are collectively referred to as "function drivers". The back-end for each device is owned and managed by a small, single-purpose service partition in the s-Par firmware, which communicates with each guest partition sharing that device through an area of shared memory called a "channel". In s-Par nomenclature, the back-end is often referred to as the "service partition", "IO partition" (for virtual network and scsi disk devices), or "console partition" (for virtual keyboard and mouse devices). Each virtual device requires exactly 1 dedicated channel, which the guest driver and back-end use to communicate. The hypervisor need not intervene (other than normal interrupt handling) in the interactions that occur across this channel. NOT covered in this document: * s-Par also supports sharing physical PCI adapters via SR-IOV, but because this requires no specific support in the guest partitions, it will not be discussed in this document. Shared SR-IOV devices should be used wherever possible for highest performance. * Because the s-Par back-end provides a standard EFI framebuffer to each guest, the already-existing efifb Linux driver is used to provide guest video access. Thus, the only s-Par-unique support that is necessary to provide a guest graphics console are for keyboard and mouse (via visorinput). 2. Driver Descriptions ---------------------- 2.1. visorbus ------------- 2.1.1. Overview --------------- The visorbus driver handles the virtual busses on which all of the virtual devices reside. It provides a registration function named visorbus_register_visor_driver() that is called by each of the function drivers at initialization time, which the function driver uses to tell visorbus about the device classes (via specifying a list of device type GUIDs) it wants to handle. For use by function drivers, visorbus provides implementation for struct visor_driver and struct visor_device, as well as utility functions for communicating with the back-end. visorbus is associated with ACPI id "PNP0A07" in modules.alias, so if built as a module it will typically be loaded automatically via standard udev or systemd (God help us) configurations. visorbus can similarly force auto-loading of function drivers for virtual devices it discovers, as it includes a MODALIAS environment variable of this form in the hotplug uevent environment when each virtual device is discovered: visorbus:<device type GUID> visorbus notifies each function driver when a device of its registered class arrives and departs, by calling the function driver's probe() and remove() methods. The actual struct device objects that correspond to each virtual bus and each virtual device are created and owned by visorbus. These device objects are created in response to messages from the s-Par back-end received on a special control channel called the "controlvm channel" (each guest partition has access to exactly 1 controlvm channel), and have a lifetime that is independent of the function drivers that control them. 2.1.2. "struct visor device" Function Driver Interfaces ------------------------------------------------------- The interface between visorbus and its function drivers is defined in visorbus.h, and described below. When a visor function driver loads, it calls visorbus_register_visor_driver() to register itself with visorbus. The significant information passed in this exchange is as follows: * the GUID(s) of the channel type(s) that are handled by this driver, as well as a "friendly name" identifying each (this will be published under /sys/devices/visorbus<x>/dev<y>) * the addresses of callback functions to be called whenever a virtual device/channel with the appropriate channel-type GUID(s) appears or disappears * the address of a "channel_interrupt" function, which will be automatically called at specific intervals to enable the driver to poll the device channel for activity The following functions implemented within each function driver will be called automatically by the visorbus driver at appropriate times: * The probe() function notifies about the creation of each new virtual device/channel instance. * The remove() function notifies about the destruction of a virtual device/channel instance. * The channel_interrupt() function is called at frequent intervals to give the function driver an opportunity to poll the virtual device channel for requests. Information is passed to this function to enable the function driver to use the visorchannel_signalinsert() and visorchannel_signalremove() functions to respond to and initiate activity over the channel. (Note that since it is the visorbus driver that determines when this is called, it is very easy to switch to interrupt-driven mechanisms when available for particular virtual device types.) * The pause() function is called should it ever be necessary to direct the function driver to temporarily stop accessing the device channel. An example of when this is needed is when the service partition implementing the back-end of the virtual device needs to be recovered. After a successful return of pause(), the function driver must not access the device channel until a subsequent resume() occurs. * The resume() function is the "book-end" to pause(), and is described above. If/when a function driver creates a Linux device (that needs to be accessed from usermode), it calls visorbus_registerdevnode(), passing the major and minor number of the device. (Of course not all function drivers will need to do this.) This simply creates the appropriate "devmajorminor" sysfs entry described below, so that a hotplug script can use it to create a device node. 2.1.3. sysfs Advertised Information ----------------------------------- Because visorbus is a standard Linux bus driver in the model described in Documentation/driver-model/, the hierarchy of s-Par virtual devices is published in the sysfs tree beneath /bus/visorbus/, e.g., /sys/bus/visorbus/devices/ might look like: vbus1:dev1 -> ../../../devices/visorbus1/vbus1:dev1 vbus1:dev2 -> ../../../devices/visorbus1/vbus1:dev2 vbus1:dev3 -> ../../../devices/visorbus1/vbus1:dev3 vbus2:dev0 -> ../../../devices/visorbus2/vbus2:dev0 vbus2:dev1 -> ../../../devices/visorbus2/vbus2:dev1 vbus2:dev2 -> ../../../devices/visorbus2/vbus2:dev2 visorbus1 -> ../../../devices/visorbus1 visorbus2 -> ../../../devices/visorbus2 visor_device notes: * Each visorbus<n> entry denotes the existence of a struct visor_device denoting virtual bus #<n>. A unique s-Par channel exists for each such virtual bus. * Virtual bus numbers uniquely identify s-Par back-end service partitions. In this example, bus 1 corresponds to the s-Par console partition (controls keyboard, video, and mouse), whereas bus 2 corresponds to the s-Par IO partition (controls network and disk). * Each vbus<x>:dev<y> entry denotes the existence of a struct visor_device denoting virtual device #<y> outboard of virtual bus #<x>. A unique s-Par channel exists for each such virtual device. * If a function driver has loaded and claimed a particular device, the bus/visorbus/devices/vbus<x>:dev<y>/driver symlink will indicate that function driver. Every active visorbus device will have a sysfs subtree under: /sys/devices/visorbus<x>/vbus<x>:dev<y>/ The following files exist under /sys/devices/visorbus<x>/vbus<x>:dev<y>: subsystem link to sysfs tree that describes the visorbus bus type; e.g.: ../../../bus/visorbus driver link to sysfs tree that describes the function driver controlling this device; e.g.: ../../../bus/visorbus/drivers/visorhba Note that this "driver" link will not exist if the appropriate function driver has not been loaded yet. devmajorminor <devname> if applicable, each file here identifies (via ... its file contents) the "<major>:<minor>" needed for a device node to enable access from usermode. There is exactly one file here for each different device node that can be accessed (from usermode). Note that this info is provided by a particular function driver, so these will not exist until AFTER the appropriate function driver controlling this device class is loaded. channel properties of the device channel (all in ascii text format) clientpartition handle identifying the guest (client) side of this channel, e.g. 0x10000000. nbytes total size of this channel in bytes physaddr the guest physical address for the base of the channel typeguid a GUID identifying the channel type, in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx notation typename a "friendly name" for this channel type, e.g., "keyboard". Note that this name is provided by a particular function driver, so "typename" will return an empty string until AFTER the appropriate function driver controlling this channel type is loaded zoneguid a GUID identifying the channel zone, in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx notation 2.2. visorhba ------------- The visorhba driver registers with visorbus as the function driver to handle virtual scsi disk devices, specified using the SPAR_VHBA_CHANNEL_PROTOCOL_UUID type in the visorbus_register_visor_driver() call. visorhba uses scsi_add_host() to expose a Linux block device (e.g., /sys/block/) in the guest environment for each s-Par virtual device. visorhba provides access to a shared SCSI host bus adapter and one or more disk devices, by proxying SCSI commands between the guest and the service partition that owns the shared SCSI adapter, using a channel between the guest and the service partition. The disks that appear on the shared bus are defined by the s-Par configuration and enforced by the service partition, while the guest driver handles sending commands and handling responses. Each disk is shared as a whole to a guest. Sharing the bus adapter in this way provides resiliency; should the device encounter an error, only the service partition is rebooted, and the device is reinitialized. This allows guests to continue running and to recover from the error. When compiled as a module, visorhba can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: "visorbus:"+SPAR_VHBA_CHANNEL_PROTOCOL_UUID_STR i.e.: alias visorbus:414815ed-c58c-11da-95a9-00e08161165f visorhba 2.3. visornic ------------- The visornic driver registers with visorbus as the function driver to handle virtual network devices, specified using the SPAR_VNIC_CHANNEL_PROTOCOL_UUID type in the visorbus_register_visor_driver() call. visornic uses register_netdev() to expose a Linux device of class net (e.g., /sys/class/net/) in the guest environment for each s-Par virtual device. visornic provides a paravirtualized network interface to a guest by proxying buffer information between the guest and the service partition that owns the shared network interface, using a channel between the guest and the service partition. The connectivity of this interface with the shared interface and possibly other guest partitions is defined by the s-Par configuration and enforced by the service partition; the guest driver handles communication and link status. When compiled as a module, visornic can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: "visorbus:"+SPAR_VNIC_CHANNEL_PROTOCOL_UUID_STR i.e.: alias visorbus:8cd5994d-c58e-11da-95a9-00e08161165f visornic 2.4. visorinput --------------- The visorinput driver registers with visorbus as the function driver to handle human input devices, specified using the SPAR_KEYBOARD_CHANNEL_PROTOCOL_UUID and SPAR_MOUSE_CHANNEL_PROTOCOL_UUID types in the visorbus_register_visor_driver() call. visorinput uses input_register_device() to expose devices of class input (e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices. A s-Par virtual keyboard device maps 1-to-1 with a Linux input device named "visor Keyboard", while a s-Par virtual mouse device has 2 Linux input devices created for it: 1 named "visor Wheel", and 1 named "visor Mouse". By registering as input class devices, modern versions of X will automatically find and properly use s-Par virtual keyboard and mouse devices. As the s-Par back-end reports keyboard and mouse activity via events on the virtual device channel, the visorinput driver delivers the activity to the Linux environment by calling input_report_key() and input_report_abs(). You can interact with the guest console using the usyscon Partition Desktop (a.k.a., "pd") application, provided as part of s-Par. After installing the usyscon Partition Desktop into a Linux environment via the usyscon_partitiondesktop-*.rpm, or into a Windows environment via PartitionDesktop.msi, you will be able to launch a console for your guest Linux environment by clicking the console icon in the s-Par web UI. When compiled as a module, visorinput can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: "visorbus:"+SPAR_MOUSE_CHANNEL_PROTOCOL_UUID_STR "visorbus:"+SPAR_KEYBOARD_CHANNEL_PROTOCOL_UUID_STR i.e.: alias visorbus:c73416d0-b0b8-44af-b304-9d2ae99f1b3d visorinput alias visorbus:addf07d4-94a9-46e2-81c3-61abcdbdbd87 visorinput 3. Minimum Required Driver Set ------------------------------ visorbus is required for every Linux guest running under s-Par. visorhba is typically required for a Linux guest running under s-Par, as it is required if your guest boot disk is a virtual device provided by the s-Par back-end, which is the default configuration. However, for advanced configurations where the Linux guest boots via an SR-IOV-provided HBA or SAN disk for example, visorhba is not technically required. visornic is typically required for a Linux guest running under s-Par, as it is required if your guest network interface is a virtual device provided by the s-Par back-end, which is the default configuration. However, for configurations where the Linux guest is provided with an SR-IOV NIC for example, visornic is not technically required. visorinput is only required for a Linux guest running under s-Par if you require graphics-mode access to your guest console.