-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Background and motivation
Currently, the cpuid instruction also functions as a full serializing instruction --- one that ensures all modifications to flags, registers, and memory are drained before the next instruction can execute --- on x86 hardware. This allows developers to effectively disable speculative execution at potentially vulnerable program points (any number of spectre variants), and to flush the instruction cache in the event that one processor modifies the executing code space of another processor, i.e., a cross-modifying write.
However, cpuid has overhead in that it clobbers EAX, EBX, ECX, and EDX registers. Intel exposes a new instruction, serialize under the cpuid feature flag SERIALIZE which acts as a full serializing instruction without the overhead of clobbering the registers as cpuid does.
API Proposal
namespace System.Runtime.Intrinsics.X86
{
/// <summary>
/// This class provides access to Intel SERIALIZE hardware instruction via intrinsics
/// </summary>
[Intrinsic]
[CLSCompliant(false)]
public abstract class Serialize : X86Base
{
internal Serialize() { }
public static new bool IsSupported { get => IsSupported; }
/// <summary>
/// void _serialize (void);
/// </summary>
public static void Serialize() => Serialize();
}
}API Usage
Broadly speaking, the developer can issues Serialize.Serialize() whenever they want to disable speculative execution for branching code paths, e.g.,
Serialize.Serialize();
if (someCondition)
{
// Potentially vulnerable code due to spectre variants
}Alternative Designs
dotnet developers currently need to call System.Runtime.Intrinsics.X86.X86Base.CpuId() to issue a full serializing instruction which has the extra overhead stated above as opposed to issuing the serialize instruction.
Risks
As serialize functions as an alternative to cpuid with less overhead and a 0-arg use, we don't foresee any additional risks here.