Module Name: src Committed By: jmcneill Date: Tue Jan 28 21:20:45 UTC 2025
Modified Files: src/sys/arch/arm/cortex: gicv3_its.c Log Message: gicv3_its: Fix indirect L2 device table allocation. To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/arch/arm/cortex/gicv3_its.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/cortex/gicv3_its.c diff -u src/sys/arch/arm/cortex/gicv3_its.c:1.40 src/sys/arch/arm/cortex/gicv3_its.c:1.41 --- src/sys/arch/arm/cortex/gicv3_its.c:1.40 Sun Dec 15 11:24:14 2024 +++ src/sys/arch/arm/cortex/gicv3_its.c Tue Jan 28 21:20:45 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: gicv3_its.c,v 1.40 2024/12/15 11:24:14 jmcneill Exp $ */ +/* $NetBSD: gicv3_its.c,v 1.41 2025/01/28 21:20:45 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #define _INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.40 2024/12/15 11:24:14 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.41 2025/01/28 21:20:45 jmcneill Exp $"); #include <sys/param.h> #include <sys/kmem.h> @@ -419,30 +419,32 @@ gicv3_its_device_map(struct gicv3_its *i } if (itstab->tab_indirect) { - /* Need to allocate the L2 table. */ uint64_t *l1_tab = itstab->tab_l1; - struct gicv3_its_page_table *pt; const u_int index = devid / itstab->tab_l2_num_ids; - pt = kmem_alloc(sizeof(*pt), KM_SLEEP); - pt->pt_dev_id = devid; - gicv3_dma_alloc(its->its_gic, &pt->pt_dma, itstab->tab_l2_entry_size, - itstab->tab_page_size); - LIST_INSERT_HEAD(&itstab->tab_pt, pt, pt_list); - - if (!itstab->tab_shareable) { - cpu_dcache_wb_range((vaddr_t)pt->pt_dma.base, - itstab->tab_l2_entry_size); - } - l1_tab[index] = pt->pt_dma.segs[0].ds_addr | GITS_BASER_Valid; - if (!itstab->tab_shareable) { - cpu_dcache_wb_range((vaddr_t)&l1_tab[index], - sizeof(l1_tab[index])); - } - dsb(sy); + if ((l1_tab[index] & GITS_BASER_Valid) == 0) { + /* Need to allocate the L2 table. */ + struct gicv3_its_page_table *pt; + + pt = kmem_alloc(sizeof(*pt), KM_SLEEP); + pt->pt_index = index; + gicv3_dma_alloc(its->its_gic, &pt->pt_dma, itstab->tab_l2_entry_size, + itstab->tab_page_size); + LIST_INSERT_HEAD(&itstab->tab_pt, pt, pt_list); + + if (!itstab->tab_shareable) { + cpu_dcache_wb_range((vaddr_t)pt->pt_dma.base, + itstab->tab_l2_entry_size); + } + l1_tab[index] = pt->pt_dma.segs[0].ds_addr | GITS_BASER_Valid; + if (!itstab->tab_shareable) { + cpu_dcache_wb_range((vaddr_t)&l1_tab[index], + sizeof(l1_tab[index])); + } + dsb(sy); - DPRINTF(("ITS: Allocated L2 entry at index %u for devid 0x%x\n", - index, devid)); + DPRINTF(("ITS: Allocated L2 entry at index %u\n", index)); + } } dev = kmem_alloc(sizeof(*dev), KM_SLEEP);