1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <config.h> 8#include <types.h> 9#include <object.h> 10#include <kernel/vspace.h> 11#include <api/faults.h> 12#include <api/syscall.h> 13 14bool_t Arch_handleFaultReply(tcb_t *receiver, tcb_t *sender, word_t faultType) 15{ 16 switch (faultType) { 17 case seL4_Fault_VMFault: 18 return true; 19 20#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 21 case seL4_Fault_VGICMaintenance: 22 return true; 23 case seL4_Fault_VCPUFault: 24 return true; 25 case seL4_Fault_VPPIEvent: 26 return true; 27#endif 28 default: 29 fail("Invalid fault"); 30 } 31} 32 33word_t Arch_setMRs_fault(tcb_t *sender, tcb_t *receiver, word_t *receiveIPCBuffer, word_t faultType) 34{ 35 switch (faultType) { 36 case seL4_Fault_VMFault: { 37 if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) { 38 word_t ipa, va; 39 va = getRestartPC(sender); 40 ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS)); 41 setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, ipa); 42 } else { 43 setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, getRestartPC(sender)); 44 } 45 setMR(receiver, receiveIPCBuffer, seL4_VMFault_Addr, 46 seL4_Fault_VMFault_get_address(sender->tcbFault)); 47 setMR(receiver, receiveIPCBuffer, seL4_VMFault_PrefetchFault, 48 seL4_Fault_VMFault_get_instructionFault(sender->tcbFault)); 49 return setMR(receiver, receiveIPCBuffer, seL4_VMFault_FSR, 50 seL4_Fault_VMFault_get_FSR(sender->tcbFault)); 51 } 52 53#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 54 case seL4_Fault_VGICMaintenance: 55 if (seL4_Fault_VGICMaintenance_get_idxValid(sender->tcbFault)) { 56 return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX, 57 seL4_Fault_VGICMaintenance_get_idx(sender->tcbFault)); 58 } else { 59 return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX, -1); 60 } 61 case seL4_Fault_VCPUFault: 62 return setMR(receiver, receiveIPCBuffer, seL4_VCPUFault_HSR, seL4_Fault_VCPUFault_get_hsr(sender->tcbFault)); 63 case seL4_Fault_VPPIEvent: 64 return setMR(receiver, receiveIPCBuffer, seL4_VPPIEvent_IRQ, seL4_Fault_VPPIEvent_get_irq_w(sender->tcbFault)); 65#endif 66 67 default: 68 fail("Invalid fault"); 69 } 70} 71