Commit 462dd429 authored by Bibo Mao's avatar Bibo Mao Committed by Xianglai Li
Browse files

LoongArch: Add pv ipi support on guest kernel side

LoongArch inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9BTWW



------------------------------------------

PARAVIRT option and pv ipi is added on guest kernel side, function
pv_ipi_init() is to add ipi sending and ipi receiving hooks. This function
firstly checks whether system runs on VM mode. If kernel runs on VM mode,
it will call function kvm_para_available() to detect current hypervirsor
type. Now only KVM type detection is supported, the paravirt function can
work only if current hypervisor type is KVM, since there is only KVM
supported on LoongArch now.

PV IPI uses virtual IPI sender and virtual IPI receiver function. With
virutal IPI sender, ipi message is stored in DDR memory rather than
emulated HW. IPI multicast is supported, and 128 vcpus can received IPIs
at the same time like X86 KVM method. Hypercall method is used for IPI
sending.

With virtual IPI receiver, HW SW0 is used rather than real IPI HW. Since
VCPU has separate HW SW0 like HW timer, there is no trap in IPI interrupt
acknowledge. And IPI message is stored in DDR, no trap in get IPI message.

Signed-off-by: default avatarBibo Mao <maobibo@loongson.cn>
Signed-off-by: default avatarXianglai Li <lixianglai@loongson.cn>
parent 60f12ac2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -567,6 +567,15 @@ config CPU_HAS_PREFETCH
	bool
	default y

config PARAVIRT
	bool "Enable paravirtualization code"
	depends on AS_HAS_LVZ_EXTENSION
	help
          This changes the kernel so it can modify itself when it is run
	  under a hypervisor, potentially improving performance significantly
	  over full virtualization.  However, when run without a hypervisor
	  the kernel is theoretically slower and slightly larger.

config ARCH_SUPPORTS_KEXEC
	def_bool y

+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ enum ipi_msg_type {
typedef struct {
	unsigned int ipi_irqs[NR_IPI];
	unsigned int __softirq_pending;
	atomic_t message ____cacheline_aligned_in_smp;
} ____cacheline_aligned irq_cpustat_t;

DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+27 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_LOONGARCH_PARAVIRT_H
#define _ASM_LOONGARCH_PARAVIRT_H

#ifdef CONFIG_PARAVIRT
#include <linux/static_call_types.h>
struct static_key;
extern struct static_key paravirt_steal_enabled;
extern struct static_key paravirt_steal_rq_enabled;

u64 dummy_steal_clock(int cpu);
DECLARE_STATIC_CALL(pv_steal_clock, dummy_steal_clock);

static inline u64 paravirt_steal_clock(int cpu)
{
	return static_call(pv_steal_clock)(cpu);
}

int pv_ipi_init(void);
#else
static inline int pv_ipi_init(void)
{
	return 0;
}

#endif // CONFIG_PARAVIRT
#endif
+10 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2024 Loongson Technology Corporation Limited
 */
#ifndef _ASM_API_CLOCK_H
#define _ASM_API_CLOCK_H

#include <asm/paravirt.h>

#endif
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ obj-$(CONFIG_MODULES) += module.o module-sections.o
obj-$(CONFIG_STACKTRACE)	+= stacktrace.o

obj-$(CONFIG_PROC_FS)		+= proc.o
obj-$(CONFIG_PARAVIRT)		+= paravirt.o

obj-$(CONFIG_SMP)		+= smp.o

Loading