51 lines
1.3 KiB
C
Executable File
51 lines
1.3 KiB
C
Executable File
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2023 MediaTek Inc.
|
|
*/
|
|
|
|
#include <linux/irqchip/arm-gic-v3.h>
|
|
#include <linux/gzvm.h>
|
|
#include <linux/soc/mediatek/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;
|
|
}
|