提交 1e30fe10 编写于 作者: L liuyun 提交者: openeuler-sync-bot

LoongArch: Fix virtual machine startup error

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

--------------------------------
Signed-off-by: Nliuyun <liuyun@loongson.cn>
Signed-off-by: Nmaobibo <maobibo@loongson.cn>
Change-Id: Icf291821c13d073c3d22fbb044ff32d7c77f677f
(cherry picked from commit c31f6641)
上级 24ad06a5
......@@ -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 */
......
......@@ -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);
......
......@@ -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)
panic("Fatal error, bpi ver BONE!\n");
else if (bpi_version == BPI_VERSION_V2)
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)
parse_bpi_flags();
fw_init_cmdline(argc, cmdptr);
......
......@@ -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,16 +118,22 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
vector = d->hwirq;
regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2);
/* Mask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)),
0x0, priv->node * CORES_PER_EIO_NODE);
/* Set route for target vector */
eiointc_set_irq_route(vector, cpu, priv->node, &priv->node_map);
/* Unmask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE,
0x0, priv->node * CORES_PER_EIO_NODE);
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);
/* Set route for target vector */
eiointc_set_irq_route(vector, cpu, priv->node, &priv->node_map);
/* 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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册