Commit c31f6641 authored by liuyun's avatar liuyun Committed by Hongchen Zhang
Browse files

LoongArch: Fix virtual machine startup error

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



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

Signed-off-by: default avatarliuyun <liuyun@loongson.cn>
Signed-off-by: default avatarmaobibo <maobibo@loongson.cn>
Change-Id: Icf291821c13d073c3d22fbb044ff32d7c77f677f
parent 541574a6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ struct acpi_vector_group {
extern struct acpi_vector_group pch_group[MAX_IO_PICS];
extern struct acpi_vector_group msi_group[MAX_IO_PICS];

#define MAX_CORES_PER_EIO_NODE	256
#define CORES_PER_EIO_NODE	4

#define LOONGSON_CPU_UART0_VEC		10 /* CPU UART0 */
+5 −0
Original line number Diff line number Diff line
@@ -275,6 +275,11 @@ static __always_inline u64 iocsr_read64(u32 reg)
	return __iocsrrd_d(reg);
}

static __always_inline void iocsr_write8(u8 val, u32 reg)
{
	__iocsrwr_b(val, reg);
}

static __always_inline void iocsr_write32(u32 val, u32 reg)
{
	__iocsrwr_w(val, reg);
+7 −4
Original line number Diff line number Diff line
@@ -278,7 +278,7 @@ int setup_legacy_IRQ(void)
		printk("Pic domain error!\n");
		return -1;
	}
	if (pic_domain)
	if (pic_domain && !cpu_has_hypervisor)
		pch_lpc_acpi_init(pic_domain, acpi_pchlpc);

	return 0;
@@ -530,9 +530,12 @@ unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr, unsigne
	efi_bp = (struct boot_params *)bpi;
	bpi_version = get_bpi_version(&efi_bp->signature);
	pr_info("BPI%d with boot flags %llx.\n", bpi_version, efi_bp->flags);
	if (bpi_version == BPI_VERSION_NONE)
	if (bpi_version == BPI_VERSION_NONE) {
		if (cpu_has_hypervisor)
			pr_err("Fatal error, bpi ver BONE!\n");
		else
			panic("Fatal error, bpi ver BONE!\n");
	else if (bpi_version == BPI_VERSION_V2)
	} else if (bpi_version == BPI_VERSION_V2)
		parse_bpi_flags();

	fw_init_cmdline(argc, cmdptr);
+27 −13
Original line number Diff line number Diff line
@@ -58,7 +58,9 @@ static void eiointc_enable(void)

static int cpu_to_eio_node(int cpu)
{
	return cpu_logical_map(cpu) / CORES_PER_EIO_NODE;
	int cores = (cpu_has_hypervisor ? MAX_CORES_PER_EIO_NODE : CORES_PER_EIO_NODE);

	return cpu_logical_map(cpu) / cores;
}

static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode, nodemask_t *node_map)
@@ -89,6 +91,11 @@ static void eiointc_set_irq_route(int pos, unsigned int cpu, unsigned int mnode,

static DEFINE_RAW_SPINLOCK(affinity_lock);

static void virt_extioi_set_irq_route(int irq, unsigned int cpu)
{
	iocsr_write8(cpu_logical_map(cpu), EIOINTC_REG_ROUTE + irq);
}

static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, bool force)
{
	unsigned int cpu;
@@ -111,6 +118,11 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
	vector = d->hwirq;
	regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);

	if (cpu_has_hypervisor) {
		iocsr_write32(EIOINTC_ALL_ENABLE & ~BIT(vector & 0x1F), regaddr);
		virt_extioi_set_irq_route(vector, cpu);
		iocsr_write32(EIOINTC_ALL_ENABLE, regaddr);
	} else {
		/* Mask target vector */
		csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)),
				0x0, priv->node * CORES_PER_EIO_NODE);
@@ -121,6 +133,7 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
		/* Unmask target vector */
		csr_any_send(regaddr, EIOINTC_ALL_ENABLE,
				0x0, priv->node * CORES_PER_EIO_NODE);
	}

	irq_data_update_effective_affinity(d, cpumask_of(cpu));

@@ -147,13 +160,14 @@ static int eiointc_router_init(unsigned int cpu)
	uint32_t data;
	uint32_t node = cpu_to_eio_node(cpu);
	uint32_t index = eiointc_index(node);
	int cores = (cpu_has_hypervisor ? MAX_CORES_PER_EIO_NODE : CORES_PER_EIO_NODE);

	if (index < 0) {
		pr_err("Error: invalid nodemap!\n");
		return -1;
	}

	if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
	if ((cpu_logical_map(cpu) % cores) == 0) {
		eiointc_enable();

		for (i = 0; i < VEC_COUNT / 32; i++) {
@@ -170,7 +184,7 @@ static int eiointc_router_init(unsigned int cpu)
		for (i = 0; i < VEC_COUNT / 4; i++) {
			/* Route to Node-0 Core-0 */
			if (index == 0)
				bit = BIT(cpu_logical_map(0));
				bit = (cpu_has_hypervisor ? cpu_logical_map(0) : BIT(cpu_logical_map(0)));
			else
				bit = (eiointc_priv[index]->node << 4) | 1;