Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103076635
D41554.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D41554.diff
View Options
diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c
--- a/sys/arm64/arm64/gicv3_its.c
+++ b/sys/arm64/arm64/gicv3_its.c
@@ -221,7 +221,10 @@
/* An ITS private table */
struct its_ptable {
vm_offset_t ptab_vaddr;
- unsigned long ptab_size;
+ /* Size of the L1 table */
+ size_t ptab_l1_size;
+ /* Number of L1 entries */
+ int ptab_l1_nidents;
};
/* ITS collection description. */
@@ -246,6 +249,8 @@
cpuset_t sc_cpus;
struct domainset *sc_ds;
u_int gic_irq_cpu;
+ int sc_devbits;
+ int sc_dev_table_idx;
struct its_ptable sc_its_ptab[GITS_BASER_NUM];
struct its_col *sc_its_cols[MAXCPU]; /* Per-CPU collections */
@@ -476,7 +481,8 @@
vm_offset_t table;
vm_paddr_t paddr;
uint64_t cache, reg, share, tmp, type;
- size_t esize, its_tbl_size, nidents, nitspages, npages;
+ size_t its_tbl_size, nitspages, npages;
+ size_t l1_esize, l1_nidents;
int i, page_size;
int devbits;
@@ -505,6 +511,7 @@
devbits = GITS_TYPER_DEVB(gic_its_read_8(sc, GITS_TYPER));
cache = GITS_BASER_CACHE_WAWB;
}
+ sc->sc_devbits = devbits;
share = GITS_BASER_SHARE_IS;
for (i = 0; i < GITS_BASER_NUM; i++) {
@@ -515,7 +522,7 @@
continue;
/* The table entry size */
- esize = GITS_BASER_ESIZE(reg);
+ l1_esize = GITS_BASER_ESIZE(reg);
/* Find the tables page size */
page_size = gicv3_its_table_page_size(sc, i);
@@ -527,8 +534,13 @@
switch(type) {
case GITS_BASER_TYPE_DEV:
- nidents = (1 << devbits);
- its_tbl_size = esize * nidents;
+ if (sc->sc_dev_table_idx != -1)
+ device_printf(dev,
+ "Warning: Multiple device tables found\n");
+
+ sc->sc_dev_table_idx = i;
+ l1_nidents = (1 << devbits);
+ its_tbl_size = l1_esize * l1_nidents;
its_tbl_size = roundup2(its_tbl_size, page_size);
break;
case GITS_BASER_TYPE_VP:
@@ -550,7 +562,8 @@
(1ul << 48) - 1, PAGE_SIZE_64K, 0);
sc->sc_its_ptab[i].ptab_vaddr = table;
- sc->sc_its_ptab[i].ptab_size = npages * PAGE_SIZE;
+ sc->sc_its_ptab[i].ptab_l1_size = its_tbl_size;
+ sc->sc_its_ptab[i].ptab_l1_nidents = l1_nidents;
paddr = vtophys(table);
@@ -874,6 +887,7 @@
sc = device_get_softc(dev);
+ sc->sc_dev_table_idx = -1;
sc->sc_irq_length = gicv3_get_nirqs(dev);
sc->sc_irq_base = GIC_FIRST_LPI;
sc->sc_irq_base += device_get_unit(dev) * sc->sc_irq_length;
@@ -1200,6 +1214,23 @@
return (its_dev);
}
+static bool
+its_device_alloc(struct gicv3_its_softc *sc, int devid)
+{
+ struct its_ptable *ptable;
+
+ /* No device table */
+ if (sc->sc_dev_table_idx < 0) {
+ if (devid < (1 << sc->sc_devbits))
+ return (true);
+ return (false);
+ }
+
+ ptable = &sc->sc_its_ptab[sc->sc_dev_table_idx];
+ /* Check the devid is within the table limit */
+ return (devid < ptable->ptab_l1_nidents);
+}
+
static struct its_dev *
its_device_get(device_t dev, device_t child, u_int nvecs)
{
@@ -1225,6 +1256,11 @@
its_dev->lpis.lpi_num = nvecs;
its_dev->lpis.lpi_free = nvecs;
+ if (!its_device_alloc(sc, its_dev->devid)) {
+ free(its_dev, M_GICV3_ITS);
+ return (NULL);
+ }
+
if (vmem_alloc(sc->sc_irq_alloc, nvecs, M_FIRSTFIT | M_NOWAIT,
&irq_base) != 0) {
free(its_dev, M_GICV3_ITS);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 21, 3:23 PM (21 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14763358
Default Alt Text
D41554.diff (3 KB)
Attached To
Mode
D41554: gicv3: Add checks for the device ID
Attached
Detach File
Event Timeline
Log In to Comment