ANDROID: virt: geniezone: Refactoring vgic to align with upstream v6
Refactor the implementation of virtual gic as below. - Remove the codes related to vgic ppi because the virtual interrupt injection interface is only exposed to VMM which does peripheral device emulation, we can assume only spi is used. - Simplify the api for virtual interrupt injection. Change-Id: I18ece99f8a678b72483a93ab47b080871d2bb81c Signed-off-by: kevenny hsieh <kevenny.hsieh@mediatek.com> Signed-off-by: Yingshiuan Pan <yingshiuan.pan@mediatek.com> Signed-off-by: Liju-Clr Chen <liju-clr.chen@mediatek.com> Signed-off-by: Yi-De Wu <yi-de.wu@mediatek.com> Bug: 301179926 Link: https://lore.kernel.org/all/20230919111210.19615-9-yi-de.wu@mediatek.com/
This commit is contained in:
parent
f9291d7af0
commit
544b128747
@ -8,60 +8,36 @@
|
||||
#include <linux/gzvm_drv.h>
|
||||
#include "gzvm_arch_common.h"
|
||||
|
||||
/**
|
||||
* is_irq_valid() - Check the irq number and irq_type are matched
|
||||
* @irq: interrupt number
|
||||
* @irq_type: interrupt type
|
||||
*
|
||||
* Return:
|
||||
* true if irq is valid else false.
|
||||
*/
|
||||
static bool is_irq_valid(u32 irq, u32 irq_type)
|
||||
int gzvm_arch_create_device(u16 vm_id, struct gzvm_create_device *gzvm_dev)
|
||||
{
|
||||
switch (irq_type) {
|
||||
case GZVM_IRQ_TYPE_CPU:
|
||||
/* 0 ~ 15: SGI */
|
||||
if (likely(irq <= GZVM_IRQ_CPU_FIQ))
|
||||
return true;
|
||||
break;
|
||||
case GZVM_IRQ_TYPE_PPI:
|
||||
/* 16 ~ 31: PPI */
|
||||
if (likely(irq >= GZVM_VGIC_NR_SGIS &&
|
||||
irq < GZVM_VGIC_NR_PRIVATE_IRQS))
|
||||
return true;
|
||||
break;
|
||||
case GZVM_IRQ_TYPE_SPI:
|
||||
/* 32 ~ : SPT */
|
||||
if (likely(irq >= GZVM_VGIC_NR_PRIVATE_IRQS))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
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_vgic_inject_irq() - Inject virtual interrupt to a VM
|
||||
* gzvm_arch_inject_irq() - Inject virtual interrupt to a VM
|
||||
* @gzvm: Pointer to struct gzvm
|
||||
* @vcpu_idx: vcpu index, only valid if PPI
|
||||
* @irq_type: Interrupt type
|
||||
* @irq: irq number
|
||||
* @irq: *SPI* irq number (excluding offset value `32`)
|
||||
* @level: 1 if true else 0
|
||||
*
|
||||
* Return:
|
||||
* * 0 - Success.
|
||||
* * Negative - Failure.
|
||||
*/
|
||||
static int gzvm_vgic_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 irq_type, u32 irq, bool level)
|
||||
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;
|
||||
|
||||
if (!unlikely(is_irq_valid(irq, irq_type)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
@ -72,37 +48,3 @@ static int gzvm_vgic_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gzvm_vgic_inject_spi() - Inject virtual spi interrupt
|
||||
* @gzvm: Pointer to struct gzvm
|
||||
* @vcpu_idx: vcpu index
|
||||
* @spi_irq: This is spi interrupt number (starts from 0 instead of 32)
|
||||
* @level: 1 if true else 0
|
||||
*
|
||||
* Return:
|
||||
* * 0 if succeed else other negative values indicating each errors
|
||||
*/
|
||||
static int gzvm_vgic_inject_spi(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 spi_irq, bool level)
|
||||
{
|
||||
return gzvm_vgic_inject_irq(gzvm, 0, GZVM_IRQ_TYPE_SPI,
|
||||
spi_irq + GZVM_VGIC_NR_PRIVATE_IRQS,
|
||||
level);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int gzvm_arch_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 irq_type, u32 irq, bool level)
|
||||
{
|
||||
/* default use spi */
|
||||
return gzvm_vgic_inject_spi(gzvm, vcpu_idx, irq, level);
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __GZVM_ARCH_H__
|
||||
#define __GZVM_ARCH_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define GZVM_VGIC_NR_SGIS 16
|
||||
#define GZVM_VGIC_NR_PPIS 16
|
||||
#define GZVM_VGIC_NR_PRIVATE_IRQS (GZVM_VGIC_NR_SGIS + GZVM_VGIC_NR_PPIS)
|
||||
|
||||
#endif /* __GZVM_ARCH_H__ */
|
@ -7,6 +7,6 @@
|
||||
#define __GZ_COMMON_H__
|
||||
|
||||
int gzvm_irqchip_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 irq_type, u32 irq, bool level);
|
||||
u32 irq, bool level);
|
||||
|
||||
#endif /* __GZVM_COMMON_H__ */
|
||||
|
@ -39,18 +39,15 @@ struct gzvm_kernel_irqfd {
|
||||
static struct workqueue_struct *irqfd_cleanup_wq;
|
||||
|
||||
/**
|
||||
* irqfd_set_spi(): irqfd to inject virtual interrupt.
|
||||
* irqfd_set_irq(): irqfd to inject virtual interrupt.
|
||||
* @gzvm: Pointer to gzvm.
|
||||
* @irq_source_id: irq source id.
|
||||
* @irq: This is spi interrupt number (starts from 0 instead of 32).
|
||||
* @level: irq triggered level.
|
||||
* @line_status: irq status.
|
||||
*/
|
||||
static void irqfd_set_spi(struct gzvm *gzvm, int irq_source_id, u32 irq,
|
||||
int level, bool line_status)
|
||||
static void irqfd_set_irq(struct gzvm *gzvm, u32 irq, int level)
|
||||
{
|
||||
if (level)
|
||||
gzvm_irqchip_inject_irq(gzvm, irq_source_id, 0, irq, level);
|
||||
gzvm_irqchip_inject_irq(gzvm, 0, irq, level);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,8 +128,7 @@ static int irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync,
|
||||
|
||||
eventfd_ctx_do_read(irqfd->eventfd, &cnt);
|
||||
/* gzvm's irq injection is not blocked, don't need workq */
|
||||
irqfd_set_spi(gzvm, GZVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi,
|
||||
1, false);
|
||||
irqfd_set_irq(gzvm, irqfd->gsi, 1);
|
||||
}
|
||||
|
||||
if (flags & EPOLLHUP) {
|
||||
|
@ -269,24 +269,23 @@ gzvm_vm_ioctl_set_memory_region(struct gzvm *gzvm,
|
||||
}
|
||||
|
||||
int gzvm_irqchip_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 irq_type, u32 irq, bool level)
|
||||
u32 irq, bool level)
|
||||
{
|
||||
return gzvm_arch_inject_irq(gzvm, vcpu_idx, irq_type, irq, level);
|
||||
return gzvm_arch_inject_irq(gzvm, vcpu_idx, irq, level);
|
||||
}
|
||||
|
||||
static int gzvm_vm_ioctl_irq_line(struct gzvm *gzvm,
|
||||
struct gzvm_irq_level *irq_level)
|
||||
{
|
||||
u32 irq = irq_level->irq;
|
||||
u32 irq_type, vcpu_idx, vcpu2_idx, irq_num;
|
||||
u32 vcpu_idx, vcpu2_idx, irq_num;
|
||||
bool level = irq_level->level;
|
||||
|
||||
irq_type = FIELD_GET(GZVM_IRQ_LINE_TYPE, irq);
|
||||
vcpu_idx = FIELD_GET(GZVM_IRQ_LINE_VCPU, irq);
|
||||
vcpu2_idx = FIELD_GET(GZVM_IRQ_LINE_VCPU2, irq) * (GZVM_IRQ_VCPU_MASK + 1);
|
||||
irq_num = FIELD_GET(GZVM_IRQ_LINE_NUM, irq);
|
||||
|
||||
return gzvm_irqchip_inject_irq(gzvm, vcpu_idx + vcpu2_idx, irq_type, irq_num,
|
||||
return gzvm_irqchip_inject_irq(gzvm, vcpu_idx + vcpu2_idx, irq_num,
|
||||
level);
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define ERR_NOT_SUPPORTED (-24)
|
||||
#define ERR_NOT_IMPLEMENTED (-27)
|
||||
#define ERR_FAULT (-40)
|
||||
#define GZVM_USERSPACE_IRQ_SOURCE_ID 0
|
||||
#define GZVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1
|
||||
|
||||
/*
|
||||
@ -133,7 +132,7 @@ int gzvm_arch_inform_exit(u16 vm_id);
|
||||
|
||||
int gzvm_arch_create_device(u16 vm_id, struct gzvm_create_device *gzvm_dev);
|
||||
int gzvm_arch_inject_irq(struct gzvm *gzvm, unsigned int vcpu_idx,
|
||||
u32 irq_type, u32 irq, bool level);
|
||||
u32 irq, bool level);
|
||||
|
||||
void gzvm_notify_acked_irq(struct gzvm *gzvm, unsigned int gsi);
|
||||
int gzvm_irqfd(struct gzvm *gzvm, struct gzvm_irqfd *args);
|
||||
|
@ -34,4 +34,3 @@ mandatory-y += termbits.h
|
||||
mandatory-y += termios.h
|
||||
mandatory-y += types.h
|
||||
mandatory-y += unistd.h
|
||||
mandatory-y += gzvm_arch.h
|
||||
|
@ -1,10 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_GENERIC_GZVM_ARCH_H
|
||||
#define __ASM_GENERIC_GZVM_ARCH_H
|
||||
/* geniezone only supports aarch64 platform for now */
|
||||
|
||||
#endif /* __ASM_GENERIC_GZVM_ARCH_H */
|
@ -16,8 +16,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#include <asm/gzvm_arch.h>
|
||||
|
||||
#define GZVM_CAP_VM_GPA_SIZE 0xa5
|
||||
#define GZVM_CAP_PROTECTED_VM 0xffbadab1
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user