Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,85 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* LoongArch Constant Timer specific interface
*/
#ifndef SELFTEST_KVM_ARCH_TIMER_H
#define SELFTEST_KVM_ARCH_TIMER_H
#include "processor.h"
/* LoongArch timer frequency is constant 100MHZ */
#define TIMER_FREQ (100UL << 20)
#define msec_to_cycles(msec) (TIMER_FREQ * (unsigned long)(msec) / 1000)
#define usec_to_cycles(usec) (TIMER_FREQ * (unsigned long)(usec) / 1000000)
#define cycles_to_usec(cycles) ((unsigned long)(cycles) * 1000000 / TIMER_FREQ)
static inline unsigned long timer_get_cycles(void)
{
unsigned long val = 0;
__asm__ __volatile__(
"rdtime.d %0, $zero\n\t"
: "=r"(val)
:
);
return val;
}
static inline unsigned long timer_get_cfg(void)
{
return csr_read(LOONGARCH_CSR_TCFG);
}
static inline unsigned long timer_get_val(void)
{
return csr_read(LOONGARCH_CSR_TVAL);
}
static inline void disable_timer(void)
{
csr_write(0, LOONGARCH_CSR_TCFG);
}
static inline void timer_irq_enable(void)
{
unsigned long val;
val = csr_read(LOONGARCH_CSR_ECFG);
val |= ECFGF_TIMER;
csr_write(val, LOONGARCH_CSR_ECFG);
}
static inline void timer_irq_disable(void)
{
unsigned long val;
val = csr_read(LOONGARCH_CSR_ECFG);
val &= ~ECFGF_TIMER;
csr_write(val, LOONGARCH_CSR_ECFG);
}
static inline void timer_set_next_cmp_ms(unsigned int msec, bool period)
{
unsigned long val;
val = msec_to_cycles(msec) & CSR_TCFG_VAL;
val |= CSR_TCFG_EN;
if (period)
val |= CSR_TCFG_PERIOD;
csr_write(val, LOONGARCH_CSR_TCFG);
}
static inline void __delay(u64 cycles)
{
u64 start = timer_get_cycles();
while ((timer_get_cycles() - start) < cycles)
cpu_relax();
}
static inline void udelay(unsigned long usec)
{
__delay(usec_to_cycles(usec));
}
#endif /* SELFTEST_KVM_ARCH_TIMER_H */
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SELFTEST_KVM_UTIL_ARCH_H
#define SELFTEST_KVM_UTIL_ARCH_H
struct kvm_mmu_arch {};
struct kvm_vm_arch {};
#endif // SELFTEST_KVM_UTIL_ARCH_H
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* LoongArch PMU specific interface
*/
#ifndef SELFTEST_KVM_PMU_H
#define SELFTEST_KVM_PMU_H
#include "processor.h"
#define LOONGARCH_CPUCFG6 0x6
#define CPUCFG6_PMP BIT(0)
#define CPUCFG6_PAMVER GENMASK(3, 1)
#define CPUCFG6_PMNUM GENMASK(7, 4)
#define CPUCFG6_PMNUM_SHIFT 4
#define CPUCFG6_PMBITS GENMASK(13, 8)
#define CPUCFG6_PMBITS_SHIFT 8
#define CPUCFG6_UPM BIT(14)
/* Performance Counter registers */
#define LOONGARCH_CSR_PERFCTRL0 0x200 /* perf event 0 config */
#define LOONGARCH_CSR_PERFCNTR0 0x201 /* perf event 0 count value */
#define LOONGARCH_CSR_PERFCTRL1 0x202 /* perf event 1 config */
#define LOONGARCH_CSR_PERFCNTR1 0x203 /* perf event 1 count value */
#define LOONGARCH_CSR_PERFCTRL2 0x204 /* perf event 2 config */
#define LOONGARCH_CSR_PERFCNTR2 0x205 /* perf event 2 count value */
#define LOONGARCH_CSR_PERFCTRL3 0x206 /* perf event 3 config */
#define LOONGARCH_CSR_PERFCNTR3 0x207 /* perf event 3 count value */
#define CSR_PERFCTRL_PLV0 BIT(16)
#define CSR_PERFCTRL_PLV1 BIT(17)
#define CSR_PERFCTRL_PLV2 BIT(18)
#define CSR_PERFCTRL_PLV3 BIT(19)
#define CSR_PERFCTRL_PMIE BIT(20)
#define PMU_ENVENT_ENABLED (CSR_PERFCTRL_PLV0 | CSR_PERFCTRL_PLV1 | CSR_PERFCTRL_PLV2 | CSR_PERFCTRL_PLV3)
/* Hardware event codes (from LoongArch perf_event.c */
#define LOONGARCH_PMU_EVENT_CYCLES 0x00 /* CPU cycles */
#define LOONGARCH_PMU_EVENT_INSTR_RETIRED 0x01 /* Instructions retired */
#define PERF_COUNT_HW_BRANCH_INSTRUCTIONS 0x02 /* Branch instructions */
#define PERF_COUNT_HW_BRANCH_MISSES 0x03 /* Branch misses */
#define NUM_LOOPS 1000
#define EXPECTED_INSTR_MIN (NUM_LOOPS + 10) /* Loop + overhead */
#define EXPECTED_CYCLES_MIN NUM_LOOPS /* At least 1 cycle per iteration */
#define UPPER_BOUND (10 * NUM_LOOPS)
#define PMU_OVERFLOW (1ULL << 63)
static inline void pmu_irq_enable(void)
{
unsigned long val;
val = csr_read(LOONGARCH_CSR_ECFG);
val |= ECFGF_PMU;
csr_write(val, LOONGARCH_CSR_ECFG);
}
static inline void pmu_irq_disable(void)
{
unsigned long val;
val = csr_read(LOONGARCH_CSR_ECFG);
val &= ~ECFGF_PMU;
csr_write(val, LOONGARCH_CSR_ECFG);
}
#endif
@@ -0,0 +1,235 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SELFTEST_KVM_PROCESSOR_H
#define SELFTEST_KVM_PROCESSOR_H
#ifndef __ASSEMBLER__
#include "ucall_common.h"
#else
/* general registers */
#define zero $r0
#define ra $r1
#define tp $r2
#define sp $r3
#define a0 $r4
#define a1 $r5
#define a2 $r6
#define a3 $r7
#define a4 $r8
#define a5 $r9
#define a6 $r10
#define a7 $r11
#define t0 $r12
#define t1 $r13
#define t2 $r14
#define t3 $r15
#define t4 $r16
#define t5 $r17
#define t6 $r18
#define t7 $r19
#define t8 $r20
#define u0 $r21
#define fp $r22
#define s0 $r23
#define s1 $r24
#define s2 $r25
#define s3 $r26
#define s4 $r27
#define s5 $r28
#define s6 $r29
#define s7 $r30
#define s8 $r31
#endif
/*
* LoongArch page table entry definition
* Original header file arch/loongarch/include/asm/loongarch.h
*/
#define _PAGE_VALID_SHIFT 0
#define _PAGE_DIRTY_SHIFT 1
#define _PAGE_PLV_SHIFT 2 /* 2~3, two bits */
#define PLV_KERN 0
#define PLV_USER 3
#define PLV_MASK 0x3
#define _CACHE_SHIFT 4 /* 4~5, two bits */
#define _PAGE_PRESENT_SHIFT 7
#define _PAGE_WRITE_SHIFT 8
#define _PAGE_VALID BIT_ULL(_PAGE_VALID_SHIFT)
#define _PAGE_PRESENT BIT_ULL(_PAGE_PRESENT_SHIFT)
#define _PAGE_WRITE BIT_ULL(_PAGE_WRITE_SHIFT)
#define _PAGE_DIRTY BIT_ULL(_PAGE_DIRTY_SHIFT)
#define _PAGE_USER (PLV_USER << _PAGE_PLV_SHIFT)
#define __READABLE (_PAGE_VALID)
#define __WRITEABLE (_PAGE_DIRTY | _PAGE_WRITE)
/* Coherent Cached */
#define _CACHE_CC BIT_ULL(_CACHE_SHIFT)
#define PS_4K 0x0000000c
#define PS_16K 0x0000000e
#define PS_64K 0x00000010
#define PS_DEFAULT_SIZE PS_16K
/* LoongArch Basic CSR registers */
#define LOONGARCH_CSR_CRMD 0x0 /* Current mode info */
#define CSR_CRMD_PG_SHIFT 4
#define CSR_CRMD_PG BIT_ULL(CSR_CRMD_PG_SHIFT)
#define CSR_CRMD_IE_SHIFT 2
#define CSR_CRMD_IE BIT_ULL(CSR_CRMD_IE_SHIFT)
#define CSR_CRMD_PLV_SHIFT 0
#define CSR_CRMD_PLV_WIDTH 2
#define CSR_CRMD_PLV (0x3UL << CSR_CRMD_PLV_SHIFT)
#define PLV_MASK 0x3
#define LOONGARCH_CSR_PRMD 0x1
#define LOONGARCH_CSR_EUEN 0x2
#define LOONGARCH_CSR_ECFG 0x4
#define ECFGB_PMU 10
#define ECFGF_PMU (BIT_ULL(ECFGB_PMU))
#define ECFGB_TIMER 11
#define ECFGF_TIMER (BIT_ULL(ECFGB_TIMER))
#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */
#define CSR_ESTAT_EXC_SHIFT 16
#define CSR_ESTAT_EXC_WIDTH 6
#define CSR_ESTAT_EXC (0x3f << CSR_ESTAT_EXC_SHIFT)
#define EXCCODE_INT 0 /* Interrupt */
#define INT_PMI 10 /* PMU interrupt */
#define INT_TI 11 /* Timer interrupt*/
#define LOONGARCH_CSR_ERA 0x6 /* ERA */
#define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */
#define LOONGARCH_CSR_EENTRY 0xc
#define LOONGARCH_CSR_TLBIDX 0x10 /* TLB Index, EHINV, PageSize */
#define CSR_TLBIDX_PS_SHIFT 24
#define CSR_TLBIDX_PS_WIDTH 6
#define CSR_TLBIDX_PS (0x3fUL << CSR_TLBIDX_PS_SHIFT)
#define CSR_TLBIDX_SIZEM 0x3f000000
#define CSR_TLBIDX_SIZE CSR_TLBIDX_PS_SHIFT
#define LOONGARCH_CSR_ASID 0x18 /* ASID */
#define LOONGARCH_CSR_PGDL 0x19
#define LOONGARCH_CSR_PGDH 0x1a
/* Page table base */
#define LOONGARCH_CSR_PGD 0x1b
#define LOONGARCH_CSR_PWCTL0 0x1c
#define LOONGARCH_CSR_PWCTL1 0x1d
#define LOONGARCH_CSR_STLBPGSIZE 0x1e
#define LOONGARCH_CSR_CPUID 0x20
#define LOONGARCH_CSR_KS0 0x30
#define LOONGARCH_CSR_KS1 0x31
#define LOONGARCH_CSR_TMID 0x40
#define LOONGARCH_CSR_TCFG 0x41
#define CSR_TCFG_VAL (BIT_ULL(48) - BIT_ULL(2))
#define CSR_TCFG_PERIOD_SHIFT 1
#define CSR_TCFG_PERIOD (0x1UL << CSR_TCFG_PERIOD_SHIFT)
#define CSR_TCFG_EN (0x1UL)
#define LOONGARCH_CSR_TVAL 0x42
#define LOONGARCH_CSR_TINTCLR 0x44 /* Timer interrupt clear */
#define CSR_TINTCLR_TI_SHIFT 0
#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT)
/* TLB refill exception entry */
#define LOONGARCH_CSR_TLBRENTRY 0x88
#define LOONGARCH_CSR_TLBRSAVE 0x8b
#define LOONGARCH_CSR_TLBREHI 0x8e
#define CSR_TLBREHI_PS_SHIFT 0
#define CSR_TLBREHI_PS (0x3fUL << CSR_TLBREHI_PS_SHIFT)
#define read_cpucfg(reg) \
({ \
register unsigned long __v; \
__asm__ __volatile__( \
"cpucfg %0, %1\n\t" \
: "=r" (__v) \
: "r" (reg) \
: "memory"); \
__v; \
})
#define csr_read(csr) \
({ \
register unsigned long __v; \
__asm__ __volatile__( \
"csrrd %[val], %[reg]\n\t" \
: [val] "=r" (__v) \
: [reg] "i" (csr) \
: "memory"); \
__v; \
})
#define csr_write(v, csr) \
({ \
register unsigned long __v = v; \
__asm__ __volatile__ ( \
"csrwr %[val], %[reg]\n\t" \
: [val] "+r" (__v) \
: [reg] "i" (csr) \
: "memory"); \
__v; \
})
#define EXREGS_GPRS (32)
#ifndef __ASSEMBLER__
void handle_tlb_refill(void);
void handle_exception(void);
struct ex_regs {
unsigned long regs[EXREGS_GPRS];
unsigned long pc;
unsigned long estat;
unsigned long badv;
unsigned long prmd;
};
#define PC_OFFSET_EXREGS offsetof(struct ex_regs, pc)
#define ESTAT_OFFSET_EXREGS offsetof(struct ex_regs, estat)
#define BADV_OFFSET_EXREGS offsetof(struct ex_regs, badv)
#define PRMD_OFFSET_EXREGS offsetof(struct ex_regs, prmd)
#define EXREGS_SIZE sizeof(struct ex_regs)
#define VECTOR_NUM 64
typedef void(*handler_fn)(struct ex_regs *);
struct handlers {
handler_fn exception_handlers[VECTOR_NUM];
};
void loongarch_vcpu_setup(struct kvm_vcpu *vcpu);
void vm_init_descriptor_tables(struct kvm_vm *vm);
void vm_install_exception_handler(struct kvm_vm *vm, int vector, handler_fn handler);
static inline void cpu_relax(void)
{
asm volatile("nop" ::: "memory");
}
static inline void local_irq_enable(void)
{
unsigned int flags = CSR_CRMD_IE;
register unsigned int mask asm("$t0") = CSR_CRMD_IE;
__asm__ __volatile__(
"csrxchg %[val], %[mask], %[reg]\n\t"
: [val] "+r" (flags)
: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
: "memory");
}
static inline void local_irq_disable(void)
{
unsigned int flags = 0;
register unsigned int mask asm("$t0") = CSR_CRMD_IE;
__asm__ __volatile__(
"csrxchg %[val], %[mask], %[reg]\n\t"
: [val] "+r" (flags)
: [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD)
: "memory");
}
#else
#define PC_OFFSET_EXREGS ((EXREGS_GPRS + 0) * 8)
#define ESTAT_OFFSET_EXREGS ((EXREGS_GPRS + 1) * 8)
#define BADV_OFFSET_EXREGS ((EXREGS_GPRS + 2) * 8)
#define PRMD_OFFSET_EXREGS ((EXREGS_GPRS + 3) * 8)
#define EXREGS_SIZE ((EXREGS_GPRS + 4) * 8)
#endif
#endif /* SELFTEST_KVM_PROCESSOR_H */
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SELFTEST_KVM_UCALL_H
#define SELFTEST_KVM_UCALL_H
#include "kvm_util.h"
#define UCALL_EXIT_REASON KVM_EXIT_MMIO
/*
* ucall_exit_mmio_addr holds per-VM values (global data is duplicated by each
* VM), it must not be accessed from host code.
*/
extern gva_t *ucall_exit_mmio_addr;
static inline void ucall_arch_do_ucall(gva_t uc)
{
WRITE_ONCE(*ucall_exit_mmio_addr, uc);
}
#endif