In your sequences in asm/paravirt.h, you explicitly save the caller-save regs: static inline void raw_local_irq_restore(unsigned long f) { __asm__ __volatile__(paravirt_alt("pushl %%ecx; pushl %%edx\n\t" "pushl %1; call *%0\n\t" "popl %1; popl %%edx; popl %%ecx", PARAVIRT_RESTORE_FLAGS) : : "m" (paravirt_ops.restore_fl), "a"(f) : "memory"); } Wouldn't adding ecx/edx (and maybe eax, where it has no other use) to the asm's clobber list be sufficient? This also has the nice effect of making these registers are freely available for inlined code to use as temps, and making the register usage match the normal ABI calling convention. On the other hand, I suppose, if the inlined code doesn't need the registers, it is a waste to make gcc rearrange things. Assuming always clobbering ecx and edx would cause too much gcc reloading, it seems reasonable to me to say that any paravirt code sequence can use eax as input, output or scratch, and (say) ecx is also available for scratch. If it needs more (like a call to C function would), then it needs to save anything else it wants to clobber. J