1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 6#ifndef __ASM_LOONGARCH_KVMCPU_H__ 7#define __ASM_LOONGARCH_KVMCPU_H__ 8 9#include <linux/kvm_host.h> 10#include <asm/kvm_host.h> 11 12#define LARCH_INT_SIP0 0 13#define LARCH_INT_SIP1 1 14#define LARCH_INT_IP0 2 15#define LARCH_INT_IP1 3 16#define LARCH_INT_IP2 4 17#define LARCH_INT_IP3 5 18#define LARCH_INT_IP4 6 19#define LARCH_INT_IP5 7 20#define LARCH_INT_IP6 8 21#define LARCH_INT_IP7 9 22#define LARCH_INT_PMU 10 23#define LARCH_INT_TIMER 11 24#define LARCH_INT_IPI 12 25#define LOONGARCH_EXC_MAX (LARCH_INT_IPI + 1) 26#define LOONGARCH_EXC_IPNUM (LOONGARCH_EXC_MAX) 27 28/* Controlled by 0x5 guest exst */ 29#define CPU_SIP0 (_ULCAST_(1)) 30#define CPU_SIP1 (_ULCAST_(1) << 1) 31#define CPU_PMU (_ULCAST_(1) << 10) 32#define CPU_TIMER (_ULCAST_(1) << 11) 33#define CPU_IPI (_ULCAST_(1) << 12) 34 35/* Controlled by 0x52 guest exception VIP 36 * aligned to exst bit 5~12 37 */ 38#define CPU_IP0 (_ULCAST_(1)) 39#define CPU_IP1 (_ULCAST_(1) << 1) 40#define CPU_IP2 (_ULCAST_(1) << 2) 41#define CPU_IP3 (_ULCAST_(1) << 3) 42#define CPU_IP4 (_ULCAST_(1) << 4) 43#define CPU_IP5 (_ULCAST_(1) << 5) 44#define CPU_IP6 (_ULCAST_(1) << 6) 45#define CPU_IP7 (_ULCAST_(1) << 7) 46 47#define MNSEC_PER_SEC (NSEC_PER_SEC >> 20) 48 49/* KVM_IRQ_LINE irq field index values */ 50#define KVM_LOONGSON_IRQ_TYPE_SHIFT 24 51#define KVM_LOONGSON_IRQ_TYPE_MASK 0xff 52#define KVM_LOONGSON_IRQ_VCPU_SHIFT 16 53#define KVM_LOONGSON_IRQ_VCPU_MASK 0xff 54#define KVM_LOONGSON_IRQ_NUM_SHIFT 0 55#define KVM_LOONGSON_IRQ_NUM_MASK 0xffff 56 57/* irq_type field */ 58#define KVM_LOONGSON_IRQ_TYPE_CPU_IP 0 59#define KVM_LOONGSON_IRQ_TYPE_CPU_IO 1 60#define KVM_LOONGSON_IRQ_TYPE_HT 2 61#define KVM_LOONGSON_IRQ_TYPE_MSI 3 62#define KVM_LOONGSON_IRQ_TYPE_IOAPIC 4 63#define KVM_LOONGSON_IRQ_TYPE_ROUTE 5 64 65/* out-of-kernel GIC cpu interrupt injection irq_number field */ 66#define KVM_LOONGSON_IRQ_CPU_IRQ 0 67#define KVM_LOONGSON_IRQ_CPU_FIQ 1 68#define KVM_LOONGSON_CPU_IP_NUM 8 69 70typedef union loongarch_instruction larch_inst; 71typedef int (*exit_handle_fn)(struct kvm_vcpu *); 72 73int _kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst); 74int _kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst); 75int _kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run); 76int _kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run); 77int _kvm_emu_idle(struct kvm_vcpu *vcpu); 78int _kvm_handle_pv_hcall(struct kvm_vcpu *vcpu); 79int _kvm_pending_timer(struct kvm_vcpu *vcpu); 80int _kvm_handle_fault(struct kvm_vcpu *vcpu, int fault); 81void _kvm_deliver_intr(struct kvm_vcpu *vcpu); 82void irqchip_debug_init(struct kvm *kvm); 83void irqchip_debug_destroy(struct kvm *kvm); 84 85void kvm_own_fpu(struct kvm_vcpu *vcpu); 86void kvm_own_lsx(struct kvm_vcpu *vcpu); 87void kvm_lose_fpu(struct kvm_vcpu *vcpu); 88void kvm_own_lasx(struct kvm_vcpu *vcpu); 89void kvm_own_lbt(struct kvm_vcpu *vcpu); 90void kvm_restore_lbt(struct kvm_vcpu *cpu); 91void kvm_save_lbt(struct kvm_vcpu *cpu); 92void kvm_save_fpu(struct kvm_vcpu *cpu); 93void kvm_restore_fpu(struct kvm_vcpu *cpu); 94void kvm_save_lsx(struct kvm_vcpu *cpu); 95void kvm_restore_lsx(struct kvm_vcpu *cpu); 96void kvm_restore_lsx_upper(struct kvm_vcpu *cpu); 97void kvm_save_lasx(struct kvm_vcpu *cpu); 98void kvm_restore_lasx(struct kvm_vcpu *cpu); 99void kvm_restore_lasx_upper(struct kvm_vcpu *cpu); 100 101void kvm_lose_hw_perf(struct kvm_vcpu *vcpu); 102void kvm_restore_hw_perf(struct kvm_vcpu *vcpu); 103 104void kvm_acquire_timer(struct kvm_vcpu *vcpu); 105void kvm_reset_timer(struct kvm_vcpu *vcpu); 106enum hrtimer_restart kvm_count_timeout(struct kvm_vcpu *vcpu); 107void kvm_init_timer(struct kvm_vcpu *vcpu, unsigned long hz); 108void kvm_restore_timer(struct kvm_vcpu *vcpu); 109void kvm_save_timer(struct kvm_vcpu *vcpu); 110 111/* 112 * Loongarch KVM guest interrupt handling. 113 */ 114static inline void _kvm_queue_irq(struct kvm_vcpu *vcpu, unsigned int irq) 115{ 116 set_bit(irq, &vcpu->arch.irq_pending); 117 clear_bit(irq, &vcpu->arch.irq_clear); 118} 119 120static inline void _kvm_dequeue_irq(struct kvm_vcpu *vcpu, unsigned int irq) 121{ 122 clear_bit(irq, &vcpu->arch.irq_pending); 123 set_bit(irq, &vcpu->arch.irq_clear); 124} 125 126#endif /* __ASM_LOONGARCH_KVMCPU_H__ */ 127