>From d94e5568925d7cb8a3fc628606e8fcf1374ea177 Mon Sep 17 00:00:00 2001 From: Alexander Holler Date: Wed, 23 Sep 2015 19:43:51 +0200 Subject: [PATCH 1/2] CRASH on AMD with CONFIG_AMD_IOMMU --- include/asm-generic/vmlinux.lds.h | 6 ++++++ init/main.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 8bd374d..13f9189 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -660,6 +660,11 @@ INIT_CALLS_LEVEL(7) \ VMLINUX_SYMBOL(__initcall_end) = .; +#define ANNOTATED_INITCALLS \ + VMLINUX_SYMBOL(__annotated_initcall_start) = .; \ + *(.annotated_initcall.init) \ + VMLINUX_SYMBOL(__annotated_initcall_end) = .; + #define CON_INITCALL \ VMLINUX_SYMBOL(__con_initcall_start) = .; \ *(.con_initcall.init) \ @@ -816,6 +821,7 @@ INIT_DATA \ INIT_SETUP(initsetup_align) \ INIT_CALLS \ + ANNOTATED_INITCALLS \ CON_INITCALL \ SECURITY_INITCALL \ INIT_RAM_FS \ diff --git a/init/main.c b/init/main.c index 5650655..1498f9b 100644 --- a/init/main.c +++ b/init/main.c @@ -859,12 +859,40 @@ static void __init do_initcall_level(int level) do_one_initcall(*fn); } +struct _annotated_initcall { + initcall_t initcall; + unsigned driver_id; + unsigned *dependencies; + struct device_driver *driver; +}; +extern struct _annotated_initcall __annotated_initcall_start[]; + +#define annotated_initcall(fn, id) \ + static struct _annotated_initcall __annotated_initcall_##fn __used \ + __attribute__((__section__(".annotated_initcall.init"))) = \ + { .initcall = fn, .driver_id = id } + + +static int __init foo(void) +{ + return 0; +} + +annotated_initcall(foo, 23); + static void __init do_initcalls(void) { int level; + struct _annotated_initcall *ac; - for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) + for (level = 0; level < ARRAY_SIZE(initcall_levels) - 3; level++) do_initcall_level(level); + + ac = __annotated_initcall_start; + pr_info("ac %p ID %u\n", ac, ac->driver_id); + BUG_ON(ac->driver_id != 23); + do_initcall_level(level++); + do_initcall_level(level); } /* -- 2.1.0