1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2023 MediaTek Inc.
4 */
5
6 #include <linux/irqchip/arm-gic-v3.h>
7 #include <linux/gzvm.h>
8 #include <linux/soc/mediatek/gzvm_drv.h>
9 #include "gzvm_arch_common.h"
10
gzvm_arch_create_device(u16 vm_id,struct gzvm_create_device * gzvm_dev)11 int gzvm_arch_create_device(u16 vm_id, struct gzvm_create_device *gzvm_dev)
12 {
13 struct arm_smccc_res res;
14
15 return gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_DEVICE, vm_id,
16 virt_to_phys(gzvm_dev), 0, 0, 0, 0, 0,
17 &res);
18 }
19
20 /**
21 * gzvm_arch_inject_irq() - Inject virtual interrupt to a VM
22 * @gzvm: Pointer to struct gzvm
23 * @vcpu_idx: vcpu index, only valid if PPI
24 * @irq: *SPI* irq number (excluding offset value `32`)
25 * @level: 1 if true else 0
26 *
27 * Return:
28 * * 0 - Success.
29 * * Negative - Failure.
30 */
gzvm_arch_inject_irq(struct gzvm * gzvm,unsigned int vcpu_idx,u32 irq,bool level)31 int gzvm_arch_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
32 u32 irq, bool level)
33 {
34 unsigned long a1 = assemble_vm_vcpu_tuple(gzvm->vm_id, vcpu_idx);
35 struct arm_smccc_res res;
36
37 /*
38 * VMM's virtual device irq number starts from 0, but ARM's shared peripheral
39 * interrupt number starts from 32. hypervisor adds offset 32
40 */
41 gzvm_hypcall_wrapper(MT_HVC_GZVM_IRQ_LINE, a1, irq, level,
42 0, 0, 0, 0, &res);
43 if (res.a0) {
44 pr_err("Failed to set IRQ level (%d) to irq#%u on vcpu %d with ret=%d\n",
45 level, irq, vcpu_idx, (int)res.a0);
46 return -EFAULT;
47 }
48
49 return 0;
50 }
51