1/* 2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <sel4vm/guest_vcpu_fault.h> 8 9#include <sel4vm/arch/vmcs_fields.h> 10 11#include "guest_state.h" 12#include "processor/decode.h" 13 14seL4_Word get_vcpu_fault_address(vm_vcpu_t *vcpu) 15{ 16 return vm_guest_exit_get_physical(vcpu->vcpu_arch.guest_state); 17} 18 19seL4_Word get_vcpu_fault_ip(vm_vcpu_t *vcpu) 20{ 21 return vm_guest_state_get_eip(vcpu->vcpu_arch.guest_state); 22} 23 24seL4_Word get_vcpu_fault_data(vm_vcpu_t *vcpu) 25{ 26 int reg; 27 uint32_t imm; 28 int size; 29 vm_decode_ept_violation(vcpu, ®, &imm, &size); 30 int vcpu_reg = vm_decoder_reg_mapw[reg]; 31 unsigned int data; 32 vm_get_thread_context_reg(vcpu, vcpu_reg, &data); 33 return data; 34} 35 36size_t get_vcpu_fault_size(vm_vcpu_t *vcpu) 37{ 38 int reg; 39 uint32_t imm; 40 int size; 41 vm_decode_ept_violation(vcpu, ®, &imm, &size); 42 return size; 43} 44 45seL4_Word get_vcpu_fault_data_mask(vm_vcpu_t *vcpu) 46{ 47 size_t size = get_vcpu_fault_size(vcpu); 48 seL4_Word addr = get_vcpu_fault_address(vcpu); 49 seL4_Word mask = 0; 50 switch (size) { 51 case sizeof(uint8_t): 52 mask = 0x000000ff; 53 break; 54 case sizeof(uint16_t): 55 mask = 0x0000ffff; 56 break; 57 case sizeof(uint32_t): 58 mask = 0xffffffff; 59 break; 60 default: 61 ZF_LOGE("Invalid fault size"); 62 return 0; 63 } 64 mask <<= (addr & 0x3) * 8; 65 return mask; 66} 67 68bool is_vcpu_read_fault(vm_vcpu_t *vcpu) 69{ 70 unsigned int qualification = vm_guest_exit_get_qualification(vcpu->vcpu_arch.guest_state); 71 return true ? qualification & BIT(0) : false; 72} 73 74int set_vcpu_fault_data(vm_vcpu_t *vcpu, seL4_Word data) 75{ 76 int reg; 77 uint32_t imm; 78 int size; 79 vm_decode_ept_violation(vcpu, ®, &imm, &size); 80 int vcpu_reg = vm_decoder_reg_mapw[reg]; 81 return vm_set_thread_context_reg(vcpu, vcpu_reg, data); 82} 83 84void advance_vcpu_fault(vm_vcpu_t *vcpu) 85{ 86 vm_guest_exit_next_instruction(vcpu->vcpu_arch.guest_state, vcpu->vcpu.cptr); 87} 88 89void restart_vcpu_fault(vm_vcpu_t *vcpu) 90{ 91 return; 92} 93