agp/uninorth: Fix oops caused by flushing too much
PATCH 1/1 agp/uninorth: Fix oops caused by flushing too much
This fixes a sporadic oops at boot on G5 Power Macs. The table_end variable has the address of the last byte of the table. Adding on PAGE_SIZE means we flush too much, and if the page after the table is not mapped for any reason, the kernel will oops. Instead we add on 1 because flush_dcache_range() interprets its second argument as the first byte past the range to be flushed.
---
drivers/char/agp/uninorth-agp.c +1 -1
@@ -413,7 +413,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge->gatt_table_real = (u32 *) table;/* Need to clear out any dirty data still sitting in caches */ flush_dcache_range ((unsigned long )table, - (unsigned long )(table_end +PAGE_SIZE )); + (unsigned long )table_end +1 ); bridge->gatt_table =vmap (pages, (1 << page_order),0 ,PAGE_KERNEL_NCG );if (bridge->gatt_table ==NULL )
On Mit, 2010-06-02 at 15:33 +1000, Paul Mackerras wrote:=20
Quoted 8 lines
This fixes a sporadic oops at boot on G5 Power Macs. The
table_endvariable has the address of the last byte of the table. Adding onPAGE_SIZEmeans we flush too much, and if the page after the table is not mapped for any reason, the kernel will oops. Instead we add on 1 becauseflush_dcache_range()interprets its second argument as the first byte past the range to be flushed.
=20Signed-off-by Paul Mackerras <[email protected]>
Thanks for the good catch, Paul.
drivers/char/agp/uninorth-=
Quoted 3 lines
---
=20drivers/char/agp/uninorth-= renamed from drivers/char/agp/uninorth-agp.c +0
-0
agp.c
drivers/char/agp/uninorth-agp.c static int uninorth_create_gatt_table(struct agp_brid=
Quoted 4 lines
index 6f48931..9aaa0eb 100644
drivers/char/agp/uninorth-agp.c +0
-0@@ -413,7 +413,7 @@ static int uninorth_create_gatt_table(struct agp_brid=
ge_data *bridge)
drivers/char/agp/uninorth-agp.c static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
Quoted 6 lines
drivers/char/agp/uninorth-agp.c +1
-1bridge->gatt_table_real =3D (u32 *) table;/* Need to clear out any dirty data still sitting in caches */ flush_dcache_range ((unsigned long )table, - (unsigned long )(table_end +PAGE_SIZE )); + (unsigned long )table_end +1 ); bridge->gatt_table =3D vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NC=
G);
Quoted 2 lines
=20
if (bridge->gatt_table=3D=3D NULL)
--=20
Earthling Michel D=C3=A4nzer | http://www.vmware.c=
om
Libre software enthusiast | Debian, X and DRI developer