mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-03 21:45:08 -04:00
Merge tag 'loongarch-kvm-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson into HEAD
LoongArch KVM changes for v6.15 1. Remove unnecessary header include path. 2. Remove PGD saving during VM context switch. 3. Add perf events support for guest VM.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <linux/kvm.h>
|
||||
#include <linux/kvm_types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/types.h>
|
||||
@@ -176,6 +177,9 @@ struct kvm_vcpu_arch {
|
||||
/* Pointers stored here for easy accessing from assembly code */
|
||||
int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
|
||||
/* GPA (=HVA) of PGD for secondary mmu */
|
||||
unsigned long kvm_pgd;
|
||||
|
||||
/* Host registers preserved across guest mode execution */
|
||||
unsigned long host_sp;
|
||||
unsigned long host_tp;
|
||||
@@ -289,6 +293,8 @@ static inline int kvm_get_pmu_num(struct kvm_vcpu_arch *arch)
|
||||
return (arch->cpucfg[6] & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT;
|
||||
}
|
||||
|
||||
bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu);
|
||||
|
||||
/* Debug: dump vcpu state */
|
||||
int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);
|
||||
|
||||
|
||||
@@ -296,6 +296,7 @@ static void __used output_kvm_defines(void)
|
||||
OFFSET(KVM_ARCH_HSP, kvm_vcpu_arch, host_sp);
|
||||
OFFSET(KVM_ARCH_HTP, kvm_vcpu_arch, host_tp);
|
||||
OFFSET(KVM_ARCH_HPGD, kvm_vcpu_arch, host_pgd);
|
||||
OFFSET(KVM_ARCH_KVMPGD, kvm_vcpu_arch, kvm_pgd);
|
||||
OFFSET(KVM_ARCH_HANDLE_EXIT, kvm_vcpu_arch, handle_exit);
|
||||
OFFSET(KVM_ARCH_HEENTRY, kvm_vcpu_arch, host_eentry);
|
||||
OFFSET(KVM_ARCH_GEENTRY, kvm_vcpu_arch, guest_eentry);
|
||||
|
||||
@@ -33,6 +33,7 @@ config KVM
|
||||
select KVM_MMIO
|
||||
select KVM_XFER_TO_GUEST_WORK
|
||||
select SCHED_INFO
|
||||
select GUEST_PERF_EVENTS if PERF_EVENTS
|
||||
help
|
||||
Support hosting virtualized guest machines using
|
||||
hardware virtualization extensions. You will need
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
# Makefile for LoongArch KVM support
|
||||
#
|
||||
|
||||
ccflags-y += -I $(src)
|
||||
|
||||
include $(srctree)/virt/kvm/Makefile.kvm
|
||||
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
||||
@@ -394,6 +394,7 @@ static int kvm_loongarch_env_init(void)
|
||||
}
|
||||
|
||||
kvm_init_gcsr_flag();
|
||||
kvm_register_perf_callbacks(NULL);
|
||||
|
||||
/* Register LoongArch IPI interrupt controller interface. */
|
||||
ret = kvm_loongarch_register_ipi_device();
|
||||
@@ -425,6 +426,8 @@ static void kvm_loongarch_env_exit(void)
|
||||
}
|
||||
kfree(kvm_loongarch_ops);
|
||||
}
|
||||
|
||||
kvm_unregister_perf_callbacks();
|
||||
}
|
||||
|
||||
static int kvm_loongarch_init(void)
|
||||
|
||||
@@ -60,16 +60,8 @@
|
||||
ld.d t0, a2, KVM_ARCH_GPC
|
||||
csrwr t0, LOONGARCH_CSR_ERA
|
||||
|
||||
/* Save host PGDL */
|
||||
csrrd t0, LOONGARCH_CSR_PGDL
|
||||
st.d t0, a2, KVM_ARCH_HPGD
|
||||
|
||||
/* Switch to kvm */
|
||||
ld.d t1, a2, KVM_VCPU_KVM - KVM_VCPU_ARCH
|
||||
|
||||
/* Load guest PGDL */
|
||||
li.w t0, KVM_GPGD
|
||||
ldx.d t0, t1, t0
|
||||
/* Load PGD for KVM hypervisor */
|
||||
ld.d t0, a2, KVM_ARCH_KVMPGD
|
||||
csrwr t0, LOONGARCH_CSR_PGDL
|
||||
|
||||
/* Mix GID and RID */
|
||||
|
||||
@@ -360,6 +360,34 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
|
||||
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
unsigned long val;
|
||||
|
||||
preempt_disable();
|
||||
val = gcsr_read(LOONGARCH_CSR_CRMD);
|
||||
preempt_enable();
|
||||
|
||||
return (val & CSR_PRMD_PPLV) == PLV_KERN;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GUEST_PERF_EVENTS
|
||||
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return vcpu->arch.pc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
|
||||
* arrived in guest context. For LoongArch64, if PMU is not passthrough to VM,
|
||||
* any event that arrives while a vCPU is loaded is considered to be "in guest".
|
||||
*/
|
||||
bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (vcpu && !(vcpu->arch.aux_inuse & KVM_LARCH_PMU));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1462,6 +1490,15 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD);
|
||||
vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
|
||||
|
||||
/* Get GPA (=HVA) of PGD for kvm hypervisor */
|
||||
vcpu->arch.kvm_pgd = __pa(vcpu->kvm->arch.pgd);
|
||||
|
||||
/*
|
||||
* Get PGD for primary mmu, virtual address is used since there is
|
||||
* memory access after loading from CSR_PGD in tlb exception fast path.
|
||||
*/
|
||||
vcpu->arch.host_pgd = (unsigned long)vcpu->kvm->mm->pgd;
|
||||
|
||||
vcpu->arch.handle_exit = kvm_handle_exit;
|
||||
vcpu->arch.guest_eentry = (unsigned long)kvm_loongarch_ops->exc_entry;
|
||||
vcpu->arch.csr = kzalloc(sizeof(struct loongarch_csrs), GFP_KERNEL);
|
||||
|
||||
Reference in New Issue
Block a user