• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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