Skip to content

Commit e335300

Browse files
committed
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.
2 parents abab683 + 6bfb3a7 commit e335300

File tree

7 files changed

+50
-12
lines changed

7 files changed

+50
-12
lines changed

arch/loongarch/include/asm/kvm_host.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/kvm.h>
1313
#include <linux/kvm_types.h>
1414
#include <linux/mutex.h>
15+
#include <linux/perf_event.h>
1516
#include <linux/spinlock.h>
1617
#include <linux/threads.h>
1718
#include <linux/types.h>
@@ -176,6 +177,9 @@ struct kvm_vcpu_arch {
176177
/* Pointers stored here for easy accessing from assembly code */
177178
int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
178179

180+
/* GPA (=HVA) of PGD for secondary mmu */
181+
unsigned long kvm_pgd;
182+
179183
/* Host registers preserved across guest mode execution */
180184
unsigned long host_sp;
181185
unsigned long host_tp;
@@ -289,6 +293,8 @@ static inline int kvm_get_pmu_num(struct kvm_vcpu_arch *arch)
289293
return (arch->cpucfg[6] & CPUCFG6_PMNUM) >> CPUCFG6_PMNUM_SHIFT;
290294
}
291295

296+
bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu);
297+
292298
/* Debug: dump vcpu state */
293299
int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);
294300

arch/loongarch/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ static void __used output_kvm_defines(void)
296296
OFFSET(KVM_ARCH_HSP, kvm_vcpu_arch, host_sp);
297297
OFFSET(KVM_ARCH_HTP, kvm_vcpu_arch, host_tp);
298298
OFFSET(KVM_ARCH_HPGD, kvm_vcpu_arch, host_pgd);
299+
OFFSET(KVM_ARCH_KVMPGD, kvm_vcpu_arch, kvm_pgd);
299300
OFFSET(KVM_ARCH_HANDLE_EXIT, kvm_vcpu_arch, handle_exit);
300301
OFFSET(KVM_ARCH_HEENTRY, kvm_vcpu_arch, host_eentry);
301302
OFFSET(KVM_ARCH_GEENTRY, kvm_vcpu_arch, guest_eentry);

arch/loongarch/kvm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ config KVM
3333
select KVM_MMIO
3434
select KVM_XFER_TO_GUEST_WORK
3535
select SCHED_INFO
36+
select GUEST_PERF_EVENTS if PERF_EVENTS
3637
help
3738
Support hosting virtualized guest machines using
3839
hardware virtualization extensions. You will need

arch/loongarch/kvm/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
# Makefile for LoongArch KVM support
44
#
55

6-
ccflags-y += -I $(src)
7-
86
include $(srctree)/virt/kvm/Makefile.kvm
97

108
obj-$(CONFIG_KVM) += kvm.o

arch/loongarch/kvm/main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ static int kvm_loongarch_env_init(void)
394394
}
395395

396396
kvm_init_gcsr_flag();
397+
kvm_register_perf_callbacks(NULL);
397398

398399
/* Register LoongArch IPI interrupt controller interface. */
399400
ret = kvm_loongarch_register_ipi_device();
@@ -425,6 +426,8 @@ static void kvm_loongarch_env_exit(void)
425426
}
426427
kfree(kvm_loongarch_ops);
427428
}
429+
430+
kvm_unregister_perf_callbacks();
428431
}
429432

430433
static int kvm_loongarch_init(void)

arch/loongarch/kvm/switch.S

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,8 @@
6060
ld.d t0, a2, KVM_ARCH_GPC
6161
csrwr t0, LOONGARCH_CSR_ERA
6262

63-
/* Save host PGDL */
64-
csrrd t0, LOONGARCH_CSR_PGDL
65-
st.d t0, a2, KVM_ARCH_HPGD
66-
67-
/* Switch to kvm */
68-
ld.d t1, a2, KVM_VCPU_KVM - KVM_VCPU_ARCH
69-
70-
/* Load guest PGDL */
71-
li.w t0, KVM_GPGD
72-
ldx.d t0, t1, t0
63+
/* Load PGD for KVM hypervisor */
64+
ld.d t0, a2, KVM_ARCH_KVMPGD
7365
csrwr t0, LOONGARCH_CSR_PGDL
7466

7567
/* Mix GID and RID */

arch/loongarch/kvm/vcpu.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,34 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
360360
}
361361

362362
bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
363+
{
364+
unsigned long val;
365+
366+
preempt_disable();
367+
val = gcsr_read(LOONGARCH_CSR_CRMD);
368+
preempt_enable();
369+
370+
return (val & CSR_PRMD_PPLV) == PLV_KERN;
371+
}
372+
373+
#ifdef CONFIG_GUEST_PERF_EVENTS
374+
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
375+
{
376+
return vcpu->arch.pc;
377+
}
378+
379+
/*
380+
* Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
381+
* arrived in guest context. For LoongArch64, if PMU is not passthrough to VM,
382+
* any event that arrives while a vCPU is loaded is considered to be "in guest".
383+
*/
384+
bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
385+
{
386+
return (vcpu && !(vcpu->arch.aux_inuse & KVM_LARCH_PMU));
387+
}
388+
#endif
389+
390+
bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu)
363391
{
364392
return false;
365393
}
@@ -1462,6 +1490,15 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
14621490
hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD);
14631491
vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
14641492

1493+
/* Get GPA (=HVA) of PGD for kvm hypervisor */
1494+
vcpu->arch.kvm_pgd = __pa(vcpu->kvm->arch.pgd);
1495+
1496+
/*
1497+
* Get PGD for primary mmu, virtual address is used since there is
1498+
* memory access after loading from CSR_PGD in tlb exception fast path.
1499+
*/
1500+
vcpu->arch.host_pgd = (unsigned long)vcpu->kvm->mm->pgd;
1501+
14651502
vcpu->arch.handle_exit = kvm_handle_exit;
14661503
vcpu->arch.guest_eentry = (unsigned long)kvm_loongarch_ops->exc_entry;
14671504
vcpu->arch.csr = kzalloc(sizeof(struct loongarch_csrs), GFP_KERNEL);

0 commit comments

Comments
 (0)