• Marc Zyngier's avatar
    ARM: 7767/1: let the ASID allocator handle suspended animation · ae120d9e
    Marc Zyngier authored
    When a CPU is running a process, the ASID for that process is
    held in a per-CPU variable (the "active ASIDs" array). When
    the ASID allocator handles a rollover, it copies the active
    ASIDs into a "reserved ASIDs" array to ensure that a process
    currently running on another CPU will continue to run unaffected.
    The active array is zero-ed to indicate that a rollover occurred.
    
    Because of this mechanism, a reserved ASID is only remembered for
    a single rollover. A subsequent rollover will completely refill
    the reserved ASIDs array.
    
    In a severely oversubscribed environment where a CPU can be
    prevented from running for extended periods of time (think virtual
    machines), the above has a horrible side effect:
    
    [P{a} denotes process P running with ASID a]
    
    	CPU-0		CPU-1
    
    	A{x}				[active = <x 0>]
    
    	[suspended]	runs B{y}	[active = <x y>]
    
    					[rollover:
    					 active = <0 0>
    					 reserved = <x y>]
    
    			runs B{y}	[active = <0 y>
    					 reserved = <x y>]
    
    					[rollover:
    					 active = <0 0>
    					 reserved = <0 y>]
    
    			runs C{x}	[active = <0 x>]
    
    	[resumes]
    
    	runs A{x}
    
    At that stage, both A and C have the same ASID, with deadly
    consequences.
    
    The fix is to preserve reserved ASIDs across rollovers if
    the CPU doesn't have an active ASID when the rollover occurs.
    
    Cc: <stable@vger.kernel.org> # 3.9
    Acked-by: default avatarWill Deacon <will.deacon@arm.com>
    Acked-by: default avatarCatalin Carinas <catalin.marinas@arm.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    ae120d9e
context.c 6.12 KB