[PATCH OLK-6.6 0/5] bugfixes for vtimer-irqbypass
Jinqian Yang (4): arm64: add check for GICv4.1 before enabling vtimer KVM: arm64: Fix mbigen vtimer interrupt loss bug irqchip/gic-v3-its: Read ITS_VERSION with vendor checking mbigen: fix soft pg bug on HIP12 Zhou Wang (1): irqchip: add hip12 support for vtimer irq bypass arch/arm64/kvm/arch_timer.c | 23 +++- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- drivers/irqchip/irq-gic-v3-its.c | 2 +- drivers/irqchip/irq-gic-v3.c | 8 ++ drivers/irqchip/irq-mbigen.c | 202 +++++++++++++++++++++++++------ 5 files changed, 195 insertions(+), 42 deletions(-) -- 2.33.0
If the user adds "kvm-arm.vtimer_irqbypass=1" to enable vtimer but does not enable GICv4.1, "vtimer_mbigen_device_probe" will still attempt to configure the mbigen register of vtimer, which may lead to unexpected behavior. This patch adds a check to ensure that vtimer is only enabled when GICv4.1 is enabled. Fixes: d306753c582d ("KVM: arm64: arch_timer: Probe vtimer irqbypass capability") Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- drivers/irqchip/irq-gic-v3.c | 8 ++++++++ drivers/irqchip/irq-mbigen.c | 16 ++++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index fa02b0cb1497..8600b443df42 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -20,7 +20,7 @@ static bool group0_trap; static bool group1_trap; static bool common_trap; static bool dir_trap; -static bool gicv4_enable; +bool gicv4_enable; void vgic_v3_set_underflow(struct kvm_vcpu *vcpu) { diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 849d2e0db4fd..8ab2dcb942db 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1368,6 +1368,14 @@ static int __gic_update_rdist_properties(struct redist_region *region, return 1; } +#ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS +bool is_vtimer_supported(void) +{ + return gic_data.rdists.has_vtimer; +} +EXPORT_SYMBOL(is_vtimer_supported); +#endif + static void gic_update_rdist_properties(void) { gic_data.ppi_nr = UINT_MAX; diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index a6aba60df599..d80e4195ddc3 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -706,6 +706,18 @@ static bool vtimer_mbigen_should_probe(struct mbigen_device *mgn_chip) #define CHIP1_TB_PERI_PHY_BASE 0x20c614002018 extern bool vtimer_irqbypass; +extern bool gicv4_enable; +extern bool is_vtimer_supported(void); + +static bool is_vtimer_enabled(void) +{ + /* + * 'gicv4_enable' indicates whether the user enables GICv4. + * 'is_vtimer_supported()' check whether vtimer is supported. + * 'vtimer_irqbypass' indicates whether the user enables vtimer. + */ + return gicv4_enable && is_vtimer_supported() && vtimer_irqbypass; +} static int vtimer_mbigen_set_regs(struct platform_device *pdev) { @@ -716,7 +728,7 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) u32 val; struct vtimer_mbigen_device *chip; - if (!vtimer_irqbypass) + if (!is_vtimer_enabled()) return 0; if (!mgn_chip) @@ -796,7 +808,7 @@ static int vtimer_mbigen_device_probe(struct platform_device *pdev) struct vtimer_mbigen_device *vtimer_mgn_chip; int err; - if (!vtimer_irqbypass) + if (!is_vtimer_enabled()) return 0; err = vtimer_mbigen_set_regs(pdev); -- 2.33.0
The software assumes that when mbigen active is set to 1, the mbigen has already sent the write request interrupt to the ITS. However, the hardware actually goes through two stages. In the first stage, the MBIX output is set to 1, indicating that there is a write request that needs to be signaled, and at this point, the mbigen active is set to 1. In the second stage, the mbix_wr signals the write request. If the software clears the active bit by writing to MBIX_INT_CLR between the first and second stages, the write request will also be cleared. However, the software has already saved the active=1 state, which results in an incorrect state. Fixes: 78feb450c1fb ("KVM: arm64: GICv4.1: Add support for MBIGEN save/restore") Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- arch/arm64/kvm/arch_timer.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 55c800c095c0..ed7957e4466c 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -771,8 +771,19 @@ static void kvm_vtimer_mbigen_restore_stat(struct kvm_vcpu *vcpu) vtimer_mbigen_set_vector(vcpu->cpu, vpeid); - if (mbigen_ctx->active) - vtimer_mbigen_set_active(vcpu->cpu, true); + /* + * There exists a corner case in kvm_timer_vcpu_load/put. The + * vtimer has expired, mbigen is active, but the message has + * not been sent to the ITS. Therefore, if we restore the mbigen + * active state, it cannot be cleared permanently and all subsequent + * vtimer interrupts will be blocked. To avoid this, we choose not + * to restore it. If the guest kernel is Linux, there is no problem + * doing this. + * This solution may cause an extra interrupt to be sent. This extra + * interrupt may be merged with the previous pending interrupt, or + * the extra interrupt may be cleared when the Linux guest is processing + * the previous interrupt. + */ mbigen_ctx->loaded = true; out: @@ -1047,10 +1058,6 @@ static void kvm_vtimer_mbigen_save_stat(struct kvm_vcpu *vcpu) mbigen_ctx->active = vtimer_mbigen_get_active(vcpu->cpu); - /* Clear active state in MBIGEN now that we've saved everything. */ - if (mbigen_ctx->active) - vtimer_mbigen_set_active(vcpu->cpu, false); - mbigen_ctx->loaded = false; out: local_irq_restore(flags); @@ -1086,6 +1093,10 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu) #ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS if (vtimer_is_irqbypass()) { kvm_vtimer_mbigen_save_stat(vcpu); + /* + * After enabling the automatic clearing of mbigen active state, + * hardware ensures that the active state is cleared here. + */ kvm_vtimer_mbigen_auto_clr_set(vcpu, true); } #endif -- 2.33.0
When reading ITS_VERSION, only vendor checking is required, no chip checking is needed to avoid compatibility adaptation issues. Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- drivers/irqchip/irq-gic-v3-its.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 7a755b3260a0..c3fea74fd5a2 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -6115,7 +6115,7 @@ static struct its_node __init *its_node_init(struct resource *res, its->fwnode_handle = handle; #ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS - if (readl_relaxed(its_base + GITS_IIDR) == 0x00051736) + if (read_cpuid_implementor() == ARM_CPU_IMP_HISI) its->version = readl_relaxed(its_base + GITS_VERSION); #endif return its; -- 2.33.0
From: Zhou Wang <wangzhou1@hisilicon.com> Add related base address of vtimer irq bypass to support it on HIP12, currently GITS_IIDR in HIP12 is not set, so let's use CPU MIDR to find HIP12. Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> --- drivers/irqchip/irq-mbigen.c | 94 ++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 25 deletions(-) diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index d80e4195ddc3..a49b4b660383 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -689,21 +689,50 @@ static bool vtimer_mbigen_should_probe(struct mbigen_device *mgn_chip) return true; } -#define CHIP0_TA_MBIGEN_PHY_BASE 0x4604400000 -#define CHIP0_TA_MBIGEN_ITS_BASE 0x84028 -#define CHIP0_TA_PERI_PHY_BASE 0x4614002018 - -#define CHIP0_TB_MBIGEN_PHY_BASE 0xc604400000 -#define CHIP0_TB_PERI_PHY_BASE 0xc614002018 -#define CHIP0_TB_MBIGEN_ITS_BASE 0x4028 +struct its_mbigen_addr { + resource_size_t chip0_ta_mbigen_base; + unsigned long chip0_ta_peri_base; + u32 chip0_ta_mbigen_its_base; + resource_size_t chip0_tb_mbigen_base; + unsigned long chip0_tb_peri_base; + u32 chip0_tb_mbigen_its_base; + resource_size_t chip1_ta_mbigen_base; + unsigned long chip1_ta_peri_base; + u32 chip1_ta_mbigen_its_base; + resource_size_t chip1_tb_mbigen_base; + unsigned long chip1_tb_peri_base; + u32 chip1_tb_mbigen_its_base; +}; -#define CHIP1_TA_MBIGEN_PHY_BASE 0x204604400000 -#define CHIP1_TA_PERI_PHY_BASE 0x204614002018 -#define CHIP1_TA_MBIGEN_ITS_BASE 0x2084028 +struct its_mbigen_addr hip09_its_mbigen_addr = { + .chip0_ta_mbigen_base = 0x4604400000, + .chip0_ta_peri_base = 0x4614002018, + .chip0_ta_mbigen_its_base = 0x84028, + .chip0_tb_mbigen_base = 0xc604400000, + .chip0_tb_peri_base = 0xc614002018, + .chip0_tb_mbigen_its_base = 0x4028, + .chip1_ta_mbigen_base = 0x204604400000, + .chip1_ta_peri_base = 0x204614002018, + .chip1_ta_mbigen_its_base = 0x2084028, + .chip1_tb_mbigen_base = 0x20c604400000, + .chip1_tb_peri_base = 0x20c614002018, + .chip1_tb_mbigen_its_base = 0x2004028, +}; -#define CHIP1_TB_MBIGEN_PHY_BASE 0x20c604400000 -#define CHIP1_TB_MBIGEN_ITS_BASE 0x2004028 -#define CHIP1_TB_PERI_PHY_BASE 0x20c614002018 +struct its_mbigen_addr hip12_its_mbigen_addr = { + .chip0_ta_mbigen_base = 0x420120000, + .chip0_ta_peri_base = 0x41c0f013c, + .chip0_ta_mbigen_its_base = 0x4880, + .chip0_tb_mbigen_base = 0x520120000, + .chip0_tb_peri_base = 0x51c0f013c, + .chip0_tb_mbigen_its_base = 0x5880, + .chip1_ta_mbigen_base = 0x4420120000, + .chip1_ta_peri_base = 0x441c0f013c, + .chip1_ta_mbigen_its_base = 0x44880, + .chip1_tb_mbigen_base = 0x4520120000, + .chip1_tb_peri_base = 0x451c0f013c, + .chip1_tb_mbigen_its_base = 0x45880, +}; extern bool vtimer_irqbypass; extern bool gicv4_enable; @@ -727,6 +756,21 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) unsigned int mpidr_aff3; u32 val; struct vtimer_mbigen_device *chip; + struct its_mbigen_addr *addr_table; + u32 midr; + + midr = read_cpuid_id(); + switch (midr) { + case MIDR_HISI_LINXICORE9100: + addr_table = &hip09_its_mbigen_addr; + break; + case MIDR_HISI_HIP12: + addr_table = &hip12_its_mbigen_addr; + break; + default: + pr_err("Do not support vtimer irq bypass in this chip.\n"); + return -EINVAL; + } if (!is_vtimer_enabled()) return 0; @@ -743,8 +787,8 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res->start == CHIP0_TA_MBIGEN_PHY_BASE) { - addr = ioremap(CHIP0_TA_PERI_PHY_BASE, 4); + if (res->start == addr_table->chip0_ta_mbigen_base) { + addr = ioremap(addr_table->chip0_ta_peri_base, 4); if (!addr) { pr_err("Unable to map CHIP0-TA-PERI\n"); return -ENOMEM; @@ -754,11 +798,11 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) iounmap(addr); addr = mgn_chip->base + MBIX_VPPI_ITS_TA; - writel_relaxed(CHIP0_TA_MBIGEN_ITS_BASE, addr); + writel_relaxed(addr_table->chip0_ta_mbigen_its_base, addr); } - if (res->start == CHIP0_TB_MBIGEN_PHY_BASE) { - addr = ioremap(CHIP0_TB_PERI_PHY_BASE, 4); + if (res->start == addr_table->chip0_tb_mbigen_base) { + addr = ioremap(addr_table->chip0_tb_peri_base, 4); if (!addr) { pr_err("Unable to map CHIP0-TB-PERI\n"); return -ENOMEM; @@ -768,11 +812,11 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) iounmap(addr); addr = mgn_chip->base + MBIX_VPPI_ITS_TA; - writel_relaxed(CHIP0_TB_MBIGEN_ITS_BASE, addr); + writel_relaxed(addr_table->chip0_tb_mbigen_its_base, addr); } - if (res->start == CHIP1_TA_MBIGEN_PHY_BASE) { - addr = ioremap(CHIP1_TA_PERI_PHY_BASE, 4); + if (res->start == addr_table->chip1_ta_mbigen_base) { + addr = ioremap(addr_table->chip1_ta_peri_base, 4); if (!addr) { pr_err("Unable to map CHIP1-TA-PERI\n"); return -ENOMEM; @@ -782,11 +826,11 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) iounmap(addr); addr = mgn_chip->base + MBIX_VPPI_ITS_TA; - writel_relaxed(CHIP1_TA_MBIGEN_ITS_BASE, addr); + writel_relaxed(addr_table->chip1_ta_mbigen_its_base, addr); } - if (res->start == CHIP1_TB_MBIGEN_PHY_BASE) { - addr = ioremap(CHIP1_TB_PERI_PHY_BASE, 4); + if (res->start == addr_table->chip1_tb_mbigen_base) { + addr = ioremap(addr_table->chip1_tb_peri_base, 4); if (!addr) { pr_err("Unable to map CHIP1-TB-PERI\n"); return -ENOMEM; @@ -796,7 +840,7 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) iounmap(addr); addr = mgn_chip->base + MBIX_VPPI_ITS_TA; - writel_relaxed(CHIP1_TB_MBIGEN_ITS_BASE, addr); + writel_relaxed(addr_table->chip1_tb_mbigen_its_base, addr); } return 0; -- 2.33.0
if core0(0.0.0.0) is not reported to OS, mbigen drive will error. Because vtimer cannot find `cpu_base` througth mpidr. Fixes: 3ce0ad7d0b4c ("mbigen: vtimer mbigen driver support") Signed-off-by: Jinqian Yang <yangjinqian1@huawei.com> --- drivers/irqchip/irq-mbigen.c | 94 +++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c index a49b4b660383..a0c6920b5f63 100644 --- a/drivers/irqchip/irq-mbigen.c +++ b/drivers/irqchip/irq-mbigen.c @@ -111,6 +111,7 @@ struct vtimer_mbigen_device { int mpidr_aff3; struct list_head entry; spinlock_t vmgn_lock; + resource_size_t gicr_base; }; #endif @@ -136,9 +137,25 @@ static LIST_HEAD(vtimer_mgn_list); * absolute offset of a cpu relative to the base cpu. */ #define GICR_LENGTH 0x40000 -static inline int get_abs_offset(int cpu, int cpu_base) +static inline int get_abs_offset(int cpu, struct vtimer_mbigen_device *chip) { - return ((get_gicr_paddr(cpu) - get_gicr_paddr(cpu_base)) / GICR_LENGTH); + int abs_offset; + + /* + * The soft pg of HIP12 might cause OS to fail to find the cpu_base + * with aff<2,1,0>=0, which is used to get the base address of GICR0. + * Therefore, the base address of GICR0 is written into the OS for + * calculating the absolute core offset. + */ + if (read_cpuid_id() == MIDR_HISI_HIP12) { + abs_offset = ((get_gicr_paddr(cpu) - chip->gicr_base) + / GICR_LENGTH); + } else { + abs_offset = ((get_gicr_paddr(cpu) - get_gicr_paddr(chip->cpu_base)) + / GICR_LENGTH); + } + + return abs_offset; } static struct vtimer_mbigen_device *get_vtimer_mbigen(int cpu_id) @@ -168,7 +185,7 @@ void vtimer_mbigen_set_vector(int cpu_id, u16 vpeid) if (!chip) return; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); addr = chip->base + VTIMER_MBIGEN_REG_VEC_OFFSET + cpu_abs_offset * VTIMER_MBIGEN_REG_WIDTH; @@ -195,7 +212,7 @@ bool vtimer_mbigen_get_active(int cpu_id) if (!chip) return false; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); addr = chip->base + VTIMER_MBIGEN_REG_ATV_STAT_OFFSET + (cpu_abs_offset / PPIS_PER_MBIGEN_NODE) * VTIMER_MBIGEN_REG_WIDTH; @@ -216,7 +233,7 @@ void vtimer_mbigen_set_auto_clr(int cpu_id, bool set) if (!chip) return; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); offset = set ? VTIMER_MBIGEN_REG_SET_AUTO_CLR_OFFSET : VTIMER_MBIGEN_REG_CLR_AUTO_CLR_OFFSET; addr = chip->base + offset + @@ -239,7 +256,7 @@ void vtimer_gic_set_auto_clr(int cpu_id, bool set) if (!chip) return; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); offset = set ? VTIMER_GIC_REG_SET_AUTO_CLR_OFFSET : VTIMER_GIC_REG_CLR_AUTO_CLR_OFFSET; addr = chip->base + offset + @@ -262,7 +279,7 @@ void vtimer_mbigen_set_active(int cpu_id, bool set) if (!chip) return; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); offset = set ? VTIMER_MBIGEN_REG_ATV_STAT_OFFSET : VTIMER_MBIGEN_REG_ATV_CLR_OFFSET; addr = chip->base + offset + @@ -284,7 +301,7 @@ static int vtimer_mbigen_set_type(unsigned int cpu_id) if (!chip) return -EINVAL; - cpu_abs_offset = get_abs_offset(cpu_id, chip->cpu_base); + cpu_abs_offset = get_abs_offset(cpu_id, chip); addr = chip->base + VTIMER_MBIGEN_REG_TYPE_OFFSET + (cpu_abs_offset / PPIS_PER_MBIGEN_NODE) * VTIMER_MBIGEN_REG_WIDTH; @@ -627,6 +644,14 @@ static int vtimer_mbigen_chip_match_cpu(struct vtimer_mbigen_device *chip) { int cpu; + /* + * HIP12 does not need cpu_base. it uses gicr_base for + * calculating abs_offset. + */ + if (read_cpuid_id() == MIDR_HISI_HIP12) { + return 0; + } + for_each_possible_cpu(cpu) { int mpidr_aff3 = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 3); @@ -689,6 +714,26 @@ static bool vtimer_mbigen_should_probe(struct mbigen_device *mgn_chip) return true; } +#define MPIDR_AFF3_SOCKETID_SHIFT 3 +#define MPIDR_AFF3_CHIP0_VDIE0 (0 | (0 << MPIDR_AFF3_SOCKETID_SHIFT)) +#define MPIDR_AFF3_CHIP0_VDIE1 (1 | (0 << MPIDR_AFF3_SOCKETID_SHIFT)) +#define MPIDR_AFF3_CHIP1_VDIE0 (0 | (1 << MPIDR_AFF3_SOCKETID_SHIFT)) +#define MPIDR_AFF3_CHIP1_VDIE1 (1 | (1 << MPIDR_AFF3_SOCKETID_SHIFT)) + +struct gicr_addr { + resource_size_t chip0_vdie0_gicr_base; + resource_size_t chip0_vdie1_gicr_base; + resource_size_t chip1_vdie0_gicr_base; + resource_size_t chip1_vdie1_gicr_base; +}; + +struct gicr_addr hip12_gicr_addr = { + .chip0_vdie0_gicr_base = 0x480100000, + .chip0_vdie1_gicr_base = 0x580100000, + .chip1_vdie0_gicr_base = 0x4480100000, + .chip1_vdie1_gicr_base = 0x4580100000, +}; + struct its_mbigen_addr { resource_size_t chip0_ta_mbigen_base; unsigned long chip0_ta_peri_base; @@ -846,6 +891,32 @@ static int vtimer_mbigen_set_regs(struct platform_device *pdev) return 0; } +static resource_size_t vtimer_mbigen_chip_get_gicrbase(struct vtimer_mbigen_device *chip) +{ + if (read_cpuid_id() != MIDR_HISI_HIP12) { + return 0; + } + + if (chip->mpidr_aff3 == MPIDR_AFF3_CHIP0_VDIE0) { + chip->gicr_base = hip12_gicr_addr.chip0_vdie0_gicr_base; + return 0; + } + if (chip->mpidr_aff3 == MPIDR_AFF3_CHIP0_VDIE1) { + chip->gicr_base = hip12_gicr_addr.chip0_vdie1_gicr_base; + return 0; + } + if (chip->mpidr_aff3 == MPIDR_AFF3_CHIP1_VDIE0) { + chip->gicr_base = hip12_gicr_addr.chip1_vdie0_gicr_base; + return 0; + } + if (chip->mpidr_aff3 == MPIDR_AFF3_CHIP1_VDIE1) { + chip->gicr_base = hip12_gicr_addr.chip1_vdie1_gicr_base; + return 0; + } + + return -EINVAL; +} + static int vtimer_mbigen_device_probe(struct platform_device *pdev) { struct mbigen_device *mgn_chip = platform_get_drvdata(pdev); @@ -870,6 +941,13 @@ static int vtimer_mbigen_device_probe(struct platform_device *pdev) mgn_chip->vtimer_mbigen_chip = vtimer_mgn_chip; vtimer_mgn_chip->base = mgn_chip->base; vtimer_mgn_chip->mpidr_aff3 = vtimer_mbigen_chip_read_aff3(vtimer_mgn_chip); + vtimer_mgn_chip->gicr_base = 0; + err = vtimer_mbigen_chip_get_gicrbase(vtimer_mgn_chip); + if (err) { + dev_err(&pdev->dev, + "Fail to get gicr base on HIP12\n"); + goto out; + } vtimer_mgn_chip->cpu_base = -1; err = vtimer_mbigen_chip_match_cpu(vtimer_mgn_chip); if (err) { -- 2.33.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/21873 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/J44... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/21873 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/J44...
participants (2)
-
Jinqian Yang -
patchwork bot