提交 c31f6641 编写于 作者: L liuyun 提交者: Hongchen Zhang

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
上级 541574a6
...@@ -53,6 +53,7 @@ struct acpi_vector_group { ...@@ -53,6 +53,7 @@ struct acpi_vector_group {
extern struct acpi_vector_group pch_group[MAX_IO_PICS]; extern struct acpi_vector_group pch_group[MAX_IO_PICS];
extern struct acpi_vector_group msi_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 CORES_PER_EIO_NODE 4
#define LOONGSON_CPU_UART0_VEC 10 /* CPU UART0 */ #define LOONGSON_CPU_UART0_VEC 10 /* CPU UART0 */
......
...@@ -275,6 +275,11 @@ static __always_inline u64 iocsr_read64(u32 reg) ...@@ -275,6 +275,11 @@ static __always_inline u64 iocsr_read64(u32 reg)
return __iocsrrd_d(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) static __always_inline void iocsr_write32(u32 val, u32 reg)
{ {
__iocsrwr_w(val, reg); __iocsrwr_w(val, reg);
......
...@@ -278,7 +278,7 @@ int setup_legacy_IRQ(void) ...@@ -278,7 +278,7 @@ int setup_legacy_IRQ(void)
printk("Pic domain error!\n"); printk("Pic domain error!\n");
return -1; return -1;
} }
if (pic_domain) if (pic_domain && !cpu_has_hypervisor)
pch_lpc_acpi_init(pic_domain, acpi_pchlpc); pch_lpc_acpi_init(pic_domain, acpi_pchlpc);
return 0; return 0;
...@@ -530,9 +530,12 @@ unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr, unsigne ...@@ -530,9 +530,12 @@ unsigned long legacy_boot_init(unsigned long argc, unsigned long cmdptr, unsigne
efi_bp = (struct boot_params *)bpi; efi_bp = (struct boot_params *)bpi;
bpi_version = get_bpi_version(&efi_bp->signature); bpi_version = get_bpi_version(&efi_bp->signature);
pr_info("BPI%d with boot flags %llx.\n", bpi_version, efi_bp->flags); 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"); panic("Fatal error, bpi ver BONE!\n");
else if (bpi_version == BPI_VERSION_V2) } else if (bpi_version == BPI_VERSION_V2)
parse_bpi_flags(); parse_bpi_flags();
fw_init_cmdline(argc, cmdptr); fw_init_cmdline(argc, cmdptr);
......
...@@ -58,7 +58,9 @@ static void eiointc_enable(void) ...@@ -58,7 +58,9 @@ static void eiointc_enable(void)
static int cpu_to_eio_node(int cpu) 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) 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, ...@@ -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 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) static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, bool force)
{ {
unsigned int cpu; unsigned int cpu;
...@@ -111,6 +118,11 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af ...@@ -111,6 +118,11 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
vector = d->hwirq; vector = d->hwirq;
regaddr = EIOINTC_REG_ENABLE + ((vector >> 5) << 2); 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 */ /* Mask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)), csr_any_send(regaddr, EIOINTC_ALL_ENABLE & (~BIT(vector & 0x1F)),
0x0, priv->node * CORES_PER_EIO_NODE); 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 ...@@ -121,6 +133,7 @@ static int eiointc_set_irq_affinity(struct irq_data *d, const struct cpumask *af
/* Unmask target vector */ /* Unmask target vector */
csr_any_send(regaddr, EIOINTC_ALL_ENABLE, csr_any_send(regaddr, EIOINTC_ALL_ENABLE,
0x0, priv->node * CORES_PER_EIO_NODE); 0x0, priv->node * CORES_PER_EIO_NODE);
}
irq_data_update_effective_affinity(d, cpumask_of(cpu)); irq_data_update_effective_affinity(d, cpumask_of(cpu));
...@@ -147,13 +160,14 @@ static int eiointc_router_init(unsigned int cpu) ...@@ -147,13 +160,14 @@ static int eiointc_router_init(unsigned int cpu)
uint32_t data; uint32_t data;
uint32_t node = cpu_to_eio_node(cpu); uint32_t node = cpu_to_eio_node(cpu);
uint32_t index = eiointc_index(node); uint32_t index = eiointc_index(node);
int cores = (cpu_has_hypervisor ? MAX_CORES_PER_EIO_NODE : CORES_PER_EIO_NODE);
if (index < 0) { if (index < 0) {
pr_err("Error: invalid nodemap!\n"); pr_err("Error: invalid nodemap!\n");
return -1; return -1;
} }
if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) { if ((cpu_logical_map(cpu) % cores) == 0) {
eiointc_enable(); eiointc_enable();
for (i = 0; i < VEC_COUNT / 32; i++) { for (i = 0; i < VEC_COUNT / 32; i++) {
...@@ -170,7 +184,7 @@ static int eiointc_router_init(unsigned int cpu) ...@@ -170,7 +184,7 @@ static int eiointc_router_init(unsigned int cpu)
for (i = 0; i < VEC_COUNT / 4; i++) { for (i = 0; i < VEC_COUNT / 4; i++) {
/* Route to Node-0 Core-0 */ /* Route to Node-0 Core-0 */
if (index == 0) if (index == 0)
bit = BIT(cpu_logical_map(0)); bit = (cpu_has_hypervisor ? cpu_logical_map(0) : BIT(cpu_logical_map(0)));
else else
bit = (eiointc_priv[index]->node << 4) | 1; bit = (eiointc_priv[index]->node << 4) | 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册