I think the suggestion is much simpler. If you convince gcc/binutils to
leave the .reloc section in vmlinux, and make that available to the
kernel itself, then you can scan all the kernel's relocs to find ones
which refer to paravirt_ops, and use those to determine which are
callsites that can be patched.
The main upside is that all the callsites are just normal C calls;
there's no special syntax or strange macros, and we get the full benefit
of typechecking, etc.
But I can see a few downsides compared the current scheme:
1. Identifying the callsites is a somewhat hackish process of looking
at a reloc and doing a bit of dissassembly to see what is using
the reloc, to identify calls and jumps
2. There's nothing explicit to tell us how much space there is to
patch into; we just have to assume sizeof(indirect call/jmp)
3. There's no information about the register environment at the
callsite, so we just have to adopt normal C ABI rules. For the
patch sites in hand-written asm, this could be tricky.
4. gcc could do strange things which prevent detection of patch
sites. For example, it might CSE the value of, say,
paravirt_ops.irq_enable, which would be a reasonable optimisation,
but prevent any of the resulting indirect calls from being
patched. In general it relies on gcc to generate identifiable
callsites, which is a bit unpredictable.
5. There's still a moderate amount of binutils hackery to get the
relocs into the right form, and there's plenty of scope for it to
screw up.
[ Roswell technology deleted ]