From 18b619da4d7c48ba60cd5ce4eba7c042c7f93dac Mon Sep 17 00:00:00 2001 From: Shiqing Gao Date: Thu, 7 Mar 2019 10:02:00 +0800 Subject: [PATCH] doc: add the doc for 'Error Detection and Handling' This patch adds the doc for 'Error Detection and Handling'. Signed-off-by: Shiqing Gao --- ..._of_error_detection_and_error_handling.png | Bin 0 -> 33198 bytes doc/developer-guides/index.rst | 1 + doc/developer-guides/sw_design_guidelines.rst | 489 ++++++++++++++++++ 3 files changed, 490 insertions(+) create mode 100644 doc/developer-guides/images/work_flow_of_error_detection_and_error_handling.png create mode 100644 doc/developer-guides/sw_design_guidelines.rst diff --git a/doc/developer-guides/images/work_flow_of_error_detection_and_error_handling.png b/doc/developer-guides/images/work_flow_of_error_detection_and_error_handling.png new file mode 100644 index 0000000000000000000000000000000000000000..76f4903f0d99c729cbaaf00d14fed4a77b9710b9 GIT binary patch literal 33198 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.vcpu_array[vcpu_id])->state != VCPU_OFFLINE + */ + static inline struct acrn_vcpu *vcpu_from_vid(struct acrn_vm *vm, uint16_t vcpu_id) + { + return &(vm->hw.vcpu_array[vcpu_id]); + } + +``vcpu_from_vid`` is called by ``hcall_set_vcpu_regs``, which is a hypercall. +``hcall_set_vcpu_regs`` is an external interface and ``vcpu_id`` is provided by +VM. In this case, we shall add the error checking codes before calling +``vcpu_from_vid`` to make sure that the passed parameters are valid and the +pre-conditions are guaranteed. + +Here is the sample codes for error checking before calling ``vcpu_from_vid``: + +.. code-block:: c + + status = 0; + + if (vcpu_id >= CONFIG_MAX_VCPUS_PER_VM) { + pr_err("vcpu id is out of range \r\n"); + status = -EINVAL; + } else if ((&(vm->hw.vcpu_array[vcpu_id]))->state == VCPU_OFFLINE) { + pr_err("vcpu is offline \r\n"); + status = -EINVAL; + } + + if (status == 0) { + vcpu = vcpu_from_vid(vm, vcpu_id); + ... + } + + +Module Level +============ + +Fulfillment to FuSa Standards +----------------------------- + +The fulfillment matrix of error detection and error handling on a module level +to FuSa Standards [IEC_61508-7]_ in ACRN hypervisor is shown in +:numref:`fulfillment_matrix_module_level` below. + +.. table:: Fulfillment to FuSa Standards on Module Level + :align: center + :widths: auto + :name: fulfillment_matrix_module_level + + +-----------------------+---------------+----------+---------------------------------------------------+ + | Technique/Measure | Ref in | SIL3 | Company Solution | + | | IEC 61508-7 | | | + +=======================+===============+==========+===================================================+ + | Design and coding | C.2.6 | HR | This technique will be used for internal functions| + | standards | Table B.1 | | of the hypervisor. Plan to use data verification, | + | | | | with explicit specification of pre-conditions and | + | | | | post-conditions for functions. | + +-----------------------+---------------+----------+---------------------------------------------------+ + + +Error Handling Methods +---------------------- + +The error handling methods used in the ACRN hypervisor on a module level are +shown below. + +**Panic the system via ASSERT** + The hypervisor can panic the system when the below cases occur. It shall + only be used for debugging, used to check pre-conditions and post-conditions + to catch design errors. + + This method applies to the following case: + + - Software design errors occur. + + +Rules of Error Detection and Error Handling +------------------------------------------- + +The rules of error detection and error handling on a module level are shown in +:numref:`rules_module_level` below. + +.. table:: Rules of Error Detection and Error Handling on Module Level + :align: center + :widths: auto + :name: rules_module_level + + +--------------------+-----------+----------------------------+---------------------------+-------------------------+ + | Resource Class | Failure | Error Detection via | Error Handling Policy | Example | + | | Mode | Hypervisor | | | + +====================+===========+============================+===========================+=========================+ + | Internal data of | N/A | Partial. | The hypervisor shall use | virtual PCI device | + | the hypervisor | | The related pre-conditions | the internal resource/data| information, defined | + | | | are required. | directly. | with array 'pci_vdevs[]'| + | | | The design will guarantee | | through static | + | | | the correctness and the | | allocation. | + | | | test cases will verify the | | | + | | | related pre-conditions. | | | + | | | If the design can not | | | + | | | guarantee the correctness, | | | + | | | the related error handling | | | + | | | codes need to be added. | | | + | | | Note: Some examples of | | | + | | | pre-conditions are listed, | | | + | | | like non-empty array, valid| | | + | | | array size and non-null | | | + | | | pointer. | | | + +--------------------+-----------+----------------------------+---------------------------+-------------------------+ + | Configuration data | Corrupted | No. | The bootloader initializes| 'vm_config->pci_ptdevs' | + | of the VM | VM config | The related pre-conditions | hypervisor (including | is configured | + | | | are required. | code, data, and bss) and | statically. | + | | | Note: VM configuration data| verifies the integrity of | | + | | | are auto generated based on| hypervisor image in which | | + | | | different board configs, | VM configurations are. | | + | | | they are defined | Thus hypervisor does not | | + | | | as static structure. | need any additional | | + | | | | mechanism. | | + +--------------------+-----------+----------------------------+---------------------------+-------------------------+ + | Configuration data | N/A | No. | The hypervisor shall use | The maximum number of | + | of the hypervisor | | The related pre-conditions | the internal resource/data| PCI devices in the VM, | + | | | are required. | directly. | defined with | + | | | The design will guarantee | | CONFIG_MAX_PCI_DEV_NUM | + | | | the correctness and this | | through configuration. | + | | | shall be verified manually.| | | + +--------------------+-----------+----------------------------+---------------------------+-------------------------+ + + +Examples +-------- + +Here are some examples to illustrate when error handling codes are required on +a module level. + +**Example_1: Analyze the function 'partition_mode_vpci_init'** + +.. code-block:: c + + /** + * @pre vm != NULL + * @pre vm->vpci->pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + */ + static int32_t partition_mode_vpci_init(const struct acrn_vm *vm) + { + struct acrn_vpci *vpci = (struct acrn_vpci *)&(vm->vpci); + struct pci_vdev *vdev; + struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id); + struct acrn_vm_pci_ptdev_config *ptdev_config; + uint32_t i; + + vpci->pci_vdev_cnt = vm_config->pci_ptdev_num; + + for (i = 0U; i < vpci->pci_vdev_cnt; i++) { + vdev = &vpci->pci_vdevs[i]; + vdev->vpci = vpci; + ptdev_config = &vm_config->pci_ptdevs[i]; + vdev->vbdf.value = ptdev_config->vbdf.value; + + if (vdev->vbdf.value != 0U) { + partition_mode_pdev_init(vdev, ptdev_config->pbdf); + vdev->ops = &pci_ops_vdev_pt; + } else { + vdev->ops = &pci_ops_vdev_hostbridge; + } + + if (vdev->ops->init != NULL) { + if (vdev->ops->init(vdev) != 0) { + pr_err("%s() failed at PCI device (vbdf %x)!", + __func__, vdev->vbdf); + } + } + } + + return 0; + } + +``get_vm_config`` is called by ``partition_mode_vpci_init``. +There are one pre-condition and two post-conditions of ``get_vm_config``. +It indicates that the caller of ``get_vm_config`` shall guarantee these +pre-conditions and ``get_vm_config`` itself shall guarantee the post-condition. + +.. code-block:: c + + /** + * @pre vm_id < CONFIG_MAX_VM_NUM + * @post retval != NULL + * @post retval->pci_ptdev_num <= MAX_PCI_DEV_NUM + */ + struct acrn_vm_config *get_vm_config(uint16_t vm_id) + { + return &vm_configs[vm_id]; + } + +**Question_1: Is error checking required for 'vm_config'?** + +No. Because 'vm_config' is getting data from ``get_vm_config`` and the +post-condition of ``get_vm_config`` guarantees that the return value is not NULL. + + +**Question_2: Is error checking required for 'vdev'?** + +No. Here are the reasons: + +a) The pre-condition of ``partition_mode_vpci_init`` guarantees that 'vm' is not + NULL. It indicates that 'vpci' is not NULL. Since 'vdev' is getting data from + the array 'pci_vdevs[]' via indexing, 'vdev' is not NULL as long as the index + is valid. + +b) The post-condition of ``get_vm_config`` guarantees that 'vpci->pci_vdev_cnt' + is less than or equal to 'CONFIG_MAX_PCI_DEV_NUM', which is the array size of + 'pci_vdevs[]'. It indicates that the index used to get 'vdev' is always + valid. + +Given the two reasons above, 'vdev' is always not NULL. So, the error checking +codes are not required for 'vdev'. + + +**Question_3: Is error checking required for 'ptdev_config'?** + +No. 'ptdev_config' is getting data from the array 'pci_vdevs[]', which is the +physical PCI device information coming from Board Support Package and firmware. +For physical PCI device information, the related application constraints +shall be defined in the design document or safety manual. For debug purpose, +developers could use ASSERT here to catch the Board Support Package or firmware +failures, which does not guarantee these application constraints. + + +**Question_4: Is error checking required for 'vdev->ops->init'?** + +No. Here are the reasons: + +a) Question_2 proves that 'vdev' is always not NULL. + +b) 'vdev->ops' is fully initialized before 'vdev->ops->init' is called. + +Given the two reasons above, 'vdev->ops->init' is always not NULL. So, the error +checking codes are not required for 'vdev->ops->init'. + + +**Question_5: How to handle the case when 'vdev->ops->init(vdev)' returns non-zero?** + +This case indicates that the initialization of specific virtual device fails. +Investigation has to be done to figure out the root-cause. Default fatal error +handler shall be invoked here if it is caused by a hardware failure or invalid +boot information. + + +**Example_2: Analyze the function 'partition_mode_vpci_deinit'** + +.. code-block:: c + + /** + * @pre vdev != NULL + * @pre vm->vpci->pci_vdev_cnt <= CONFIG_MAX_PCI_DEV_NUM + */ + static void partition_mode_vpci_deinit(const struct acrn_vm *vm) + { + struct pci_vdev *vdev; + uint32_t i; + + for (i = 0U; i < vm->vpci.pci_vdev_cnt; i++) { + vdev = (struct pci_vdev *) &(vm->vpci.pci_vdevs[i]); + if ((vdev->ops != NULL) && (vdev->ops->deinit != NULL)) { + if (vdev->ops->deinit(vdev) != 0) { + pr_err("vdev->ops->deinit failed!"); + } + } + /* TODO: implement the deinit of 'vdev->ops' */ + } + } + + +**Question_6: Is error checking required for 'vdev->ops' and 'vdev->ops->init'?** + +Yes. Because 'vdev->ops' and 'vdev->ops->init' can not be guaranteed to be +not NULL. If the VM called ``partition_mode_vpci_deinit`` twice, it may be NULL. + +References +********** + +.. [IEC_61508-7] IEC 61508-7:2010, Functional safety of electrical/electronic/programmable electronic safety-related systems - Part 7: Overview of techniques and measures +