1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (c) 2023 MediaTek Inc.
- */
- #include <linux/irqchip/arm-gic-v3.h>
- #include <linux/gzvm.h>
- #include <linux/gzvm_drv.h>
- #include "gzvm_arch_common.h"
- int gzvm_arch_create_device(u16 vm_id, struct gzvm_create_device *gzvm_dev)
- {
- struct arm_smccc_res res;
- return gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_DEVICE, vm_id,
- virt_to_phys(gzvm_dev), 0, 0, 0, 0, 0,
- &res);
- }
- /**
- * gzvm_arch_inject_irq() - Inject virtual interrupt to a VM
- * @gzvm: Pointer to struct gzvm
- * @vcpu_idx: vcpu index, only valid if PPI
- * @irq: *SPI* irq number (excluding offset value `32`)
- * @level: 1 if true else 0
- *
- * Return:
- * * 0 - Success.
- * * Negative - Failure.
- */
- int gzvm_arch_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
- u32 irq, bool level)
- {
- unsigned long a1 = assemble_vm_vcpu_tuple(gzvm->vm_id, vcpu_idx);
- struct arm_smccc_res res;
- /*
- * VMM's virtual device irq number starts from 0, but ARM's shared peripheral
- * interrupt number starts from 32. hypervisor adds offset 32
- */
- gzvm_hypcall_wrapper(MT_HVC_GZVM_IRQ_LINE, a1, irq, level,
- 0, 0, 0, 0, &res);
- if (res.a0) {
- pr_err("Failed to set IRQ level (%d) to irq#%u on vcpu %d with ret=%d\n",
- level, irq, vcpu_idx, (int)res.a0);
- return -EFAULT;
- }
- return 0;
- }
|