2018-11-21 19:15:06 +08:00
.. _modularity:
ACRN Hypervisor: Modular Design
###############################
Overview
***** ***
2021-04-02 07:28:25 +08:00
ACRN highly emphasizes modular design, which is the separation of
functionality into modules that define a concise set of interfaces. The goals
of modular design include:
2018-11-21 19:15:06 +08:00
* **Understandability** A modular design is easier to understand due to
encapsulation.
* **Testability** Modules can be integrated and tested in the reverse order of
2020-09-01 06:40:08 +08:00
dependencies among them. Modular integration tests help improve the coverage
2018-11-21 19:15:06 +08:00
of tests and identify corner cases that are hard to trigger when testing the
hypervisor as a whole.
* **Configurability** Modular design makes it easy to configure certain
2021-04-02 07:28:25 +08:00
functionalities in or out. This is crucial in safety-critical scenarios,
because absence of irrelevant code is required in both MISRA-C and
functional safety standards.
* **Meet functional safety requirements** Functional safety standards
explicitly require a hierarchical structure of modules in software
architectural design. This applies to any safety integrity level defined in
2018-12-04 12:59:02 +08:00
[IEC_61508-3]_ and [ISO_26262-6]_ .
2018-11-21 19:15:06 +08:00
Principles
***** *****
2021-04-02 07:28:25 +08:00
* Each source file belongs to one module only. One module may consist of one
or multiple source files, though. A source file can be a C source, a C
header, or an assembly file.
* Each module has well-defined interfaces, including the exported functions
and global variables. Functions and variables that are not interfaces are
static and used inside the module only.
2018-11-21 19:15:06 +08:00
* Dependencies among the modules should be acyclic. Any cyclic dependency must
be deviated explicitly.
2021-04-02 07:28:25 +08:00
* The complexity of a module should be limited.
2018-11-21 19:15:06 +08:00
Minimizing Cyclic Dependencies
==============================
2021-04-02 07:28:25 +08:00
Cyclic dependencies are mostly avoided through careful definition of module
boundaries. The following methods can be used when a cyclic dependency cannot
be resolved by design:
2018-11-21 19:15:06 +08:00
2021-04-02 07:28:25 +08:00
* **Use callbacks** Callback registration and invocation help to reverse
dependencies between modules and break cyclic dependencies. However,
callbacks must be used with care due to their dynamic behavior. Send
proposals or patches to the
2018-11-21 19:15:06 +08:00
`acrn-dev mailing list <https://lists.projectacrn.org/g/acrn-dev> `_ for
2021-04-02 07:28:25 +08:00
discussing whether specific callbacks are appropriate.
* **Making the cyclic dependency an exception** A specific cyclic dependency
can be regarded as an exception if it is well justified and a workaround is
2018-11-21 19:15:06 +08:00
available to break the cyclic dependency for integration testing.
Measuring Complexity
====================
ACRN uses the number of functions and the cyclomatic complexity [CC]_ of each
2021-04-02 07:28:25 +08:00
function to measure the complexity of a module. Concrete criteria on
complexity will be determined during the process of enhancing the modularity
of the hypervisor. The current recommendation is to limit the cyclomatic
complexity of a function to under 20.
2018-11-21 19:15:06 +08:00
Architecture
***** ***** **
2021-04-02 07:28:25 +08:00
The following figure shows the high-level components of ACRN hypervisor:
2018-11-21 19:15:06 +08:00
.. figure :: images/modularity-architecture.png
:align: center
:name: modularity-architecture
Layered Architecture of ACRN Hypervisor
The components are listed as follows.
2021-04-02 07:28:25 +08:00
* **Boot** This component carries out the most basic hardware initialization
to enable the execution of C code.
2018-11-21 19:15:06 +08:00
* **Library** This component consists of subroutines that require no explicit
initialization. Examples include standard memory and string manipulation
2021-04-02 07:28:25 +08:00
functions like strncpy, atomic operations, and bitmap operations. This
2018-11-21 19:15:06 +08:00
component is independent from and widely used in the other components.
2020-10-03 06:24:32 +08:00
* **Hardware Management and Utilities** This component abstracts hardware
resources and provide services such as timers and physical interrupt handler
2018-11-21 19:15:06 +08:00
registration to the upper layers.
2021-04-02 07:28:25 +08:00
* **Virtual CPU** This component implements CPU, memory, and interrupt
virtualization. The vCPU loop module in this component handles VM exit
events by calling the proper handler in the other components. Hypercalls are
implemented as a special type of VM exit event. This component is also able
to inject upcall interrupts to the Service VM.
2018-11-21 19:15:06 +08:00
* **Device Emulation** This component implements devices that are emulated in
2021-04-02 07:28:25 +08:00
the hypervisor itself, such as the virtual programmable interrupt
controllers including vPIC, vLAPIC, and vIOAPIC.
* **Passthrough Management** This component manages devices that are passed
through to specific VMs.
2018-11-21 19:15:06 +08:00
* **Extended Device Emulation** This component implements an I/O request
2021-04-02 07:28:25 +08:00
mechanism that enables the hypervisor to forward I/O accesses from a User
VM to the Service VM for emulation.
* **VM Management** This component manages the creation, deletion, and other
2018-11-21 19:15:06 +08:00
lifecycle operations of VMs.
* **Hypervisor Initialization** This component invokes the initialization
2021-04-02 07:28:25 +08:00
subroutines in the other components to bring up the hypervisor and start
the Service VM in sharing mode or all the VMs in partitioning mode.
2018-11-21 19:15:06 +08:00
ACRN hypervisor adopts a layered design where higher layers can invoke the
interfaces of lower layers but not vice versa. The only exception is the
invocation of initialization routine in the **Boot** component, illustrated as
the arrow from bottom to top on the left side of figure
:numref: `modularity-architecture` . This exception is made due to the following
reasons.
* **Boot** enables the execution of C code and thus has to be the lowest layer
in the architecture.
2021-04-02 07:28:25 +08:00
* **Hypervisor Initialization** contains the hypervisor initialization
function that calls the initialization functions of each layer. Thus this
component is the highest layer to minimize reverse dependencies.
* **Boot** shall invoke the hypervisor initialization routine after bringing
up the hardware. This inevitably causes a reverse dependency from **Boot**
to **Hypervisor Initialization** .
2018-11-21 19:15:06 +08:00
To enable integration testing of a layer in the middle (e.g. **Virtual CPU** ),
2021-04-02 07:28:25 +08:00
**Boot** will invoke a customized function that invokes only the
initialization functions of that layer as well as the layers below.
2018-11-21 19:15:06 +08:00
References
***** *****
2019-03-09 03:01:04 +08:00
.. [IEC_61508-3] IEC 61508-3:2010, Functional safety of electrical/electronic/programmable electronic safety-related systems - Part 3: Software requirements
2018-11-21 19:15:06 +08:00
.. [ISO_26262-6] ISO 26262-6:2011, Road vehicles - Functional safety - Part 6: Product development at the software level
.. [CC] Cyclomatic complexity - Wikipedia, https://en.wikipedia.org/wiki/Cyclomatic_complexity