|
|
Subscribe / Log in / New account

Avoiding retpolines with static calls

Avoiding retpolines with static calls

Posted Mar 27, 2020 7:36 UTC (Fri) by josh (subscriber, #17465)
Parent article: Avoiding retpolines with static calls

If we compile the kernel with link-time optimization, in theory the compiler could know every possible value stored into a function pointer, such as a filesystem driver's callback functions. Together with a compiler plugin, could that allow generating devirtualized function calls to a fixed set of callback functions?

(This would also allow eliminating a type of callback entirely if no non-NUL function is ever stored in that function pointer. That could optimize various kinds of function pointers that don't always get used in a given struct of pointers.)


to post comments

Avoiding retpolines with static calls

Posted Mar 27, 2020 9:07 UTC (Fri) by epa (subscriber, #39769) [Link] (13 responses)

I was wondering how much of this would be dealt with if the kernel used C++, with virtual functions taking the place of the current indirect calls. A good C++ compiler, if it knows the type of an object, can optimize a virtual function call into a direct call. Though I don't know whether any compiler has the option to generate retpolines or similar armouring.

Avoiding retpolines with static calls

Posted Mar 27, 2020 9:31 UTC (Fri) by gus3 (guest, #61103) [Link] (11 responses)

It isn't a virtual "function"; it's a virtual method bound to an object. It's most useful when the derived class of the object is unknown at runtime, so the call is made through the base class instead, which fetches the method pointer from the object (via _vptr in g++) in order to make the "proper" call.

Avoiding retpolines with static calls

Posted Mar 27, 2020 9:39 UTC (Fri) by epa (subscriber, #39769) [Link] (10 responses)

I was trying to follow the C++ terminology that calls them functions rather than methods. To be completely clear I should have said 'virtual member function'. See http://www.stroustrup.com/glossary.html

Avoiding retpolines with static calls

Posted Mar 28, 2020 10:41 UTC (Sat) by ncm (guest, #165) [Link] (9 responses)

This is correct. Furthermore, a virtual member function *really is* just a function. The implied object is just a pointer argument passed to the function, and might not even be used there.

Fetishism around object-oriented conventions is worse than pointless. Virtual calling is a language mechanism that has various uses, implementing polymorphic runtime binding being one among them.

Sometimes virtual calls perform better than calling through a function pointer, because there is less choice. But sometimes the function pointer call is faster, particularly if the pointer rarely or never changes. On modern cores, both are hardly slower than a direct call except in pathological cases.

A virtual call, by offering fewer choices for what could happen, is often easier for a reader to understand than a call through a function pointer. So, it is often a good idea to cobble up a base class just to provide a virtual call, even where there is logically no meaningful object involved. Having cobbled one up, though, it often becomes useful to park things there. Having parked things there, it may be worth formalizing a class with invariants. Or it might not.

Avoiding retpolines with static calls

Posted Mar 28, 2020 19:12 UTC (Sat) by nivedita76 (subscriber, #121790) [Link] (8 responses)

The technique in the article is for the "pathological" case of retpolines, which don't allow speculation and hence are guaranteed to be much slower than direct calls.

Avoiding retpolines with static calls

Posted Mar 29, 2020 3:18 UTC (Sun) by ncm (guest, #165) [Link] (7 responses)

It seems like a virtual call would be closely akin to the static mechanism, as the vtable array of function pointers is in the object-code, "text" section.

But of course C++ code is hard to get into the kernel. Linus's deliberate choice to use C++ keywords in kernel headers is one barrier to overcome.

Avoiding retpolines with static calls

Posted Mar 29, 2020 4:06 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link]

Virtual calls in C++ defeat the whole purpose of the exercise. They still require an indirect jump and so can be exploited by Spectre.

Avoiding retpolines with static calls

Posted Mar 29, 2020 10:41 UTC (Sun) by ballombe (subscriber, #9523) [Link] (4 responses)

You are missing th historical perspective.
Stroupstrup deliberate choice to break C compatibility by adding new keyword to C++ is one barrier to overcome.

Avoiding retpolines with static calls

Posted Mar 29, 2020 12:28 UTC (Sun) by mpr22 (subscriber, #60784) [Link]

The historical perspective includes the fact that Linux is newer than C++.

Avoiding retpolines with static calls

Posted Apr 3, 2020 18:07 UTC (Fri) by adobriyan (subscriber, #30858) [Link]

In a perfect world (lets call it TexC) keywords would start with backslash...

\let foo: u32 = 0;

Avoiding retpolines with static calls

Posted Apr 4, 2020 17:18 UTC (Sat) by nix (subscriber, #2304) [Link] (1 responses)

I think that's overdoing it. Even C's done that, repeatedly. Do you blame the ANSI C committee for adding new keywords? (They added almost as many as C++ did.)

Avoiding retpolines with static calls

Posted Apr 6, 2020 15:03 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

Aren't they all in the `_Upper` namespace (namepattern?) though? C reserved that long ago (and is why C++ can't use it either; C may add names there at any time).

Avoiding retpolines with static calls

Posted Mar 29, 2020 15:11 UTC (Sun) by nivedita76 (subscriber, #121790) [Link]

I'm not sure what you mean by that. The "static" mechanism discussed in the article is self-modifying code that patches the text to make a direct call. The vtable array is just a const array of function pointers, but is still accessed via an indirect call, which would have all the overhead of retpoline blocking branch prediction. The "closely akin" method would be if the compiler optimizes the virtual function call to a couple of test-and-direct-branch based on knowledge of what types could be involved.

Avoiding retpolines with static calls

Posted Mar 29, 2020 15:07 UTC (Sun) by nivedita76 (subscriber, #121790) [Link]

I would hope that the -mindirect-branch option if used also uses retpolines for virtual calls, not just function pointers.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds