• Marc Zyngier's avatar
    KVM: arm64: Fix kvm_has_feat*() handling of negative features · a1d402ab
    Marc Zyngier authored
    Oliver reports that the kvm_has_feat() helper is not behaviing as
    expected for negative feature. On investigation, the main issue
    seems to be caused by the following construct:
    
     #define get_idreg_field(kvm, id, fld)				\
     	(id##_##fld##_SIGNED ?					\
    	 get_idreg_field_signed(kvm, id, fld) :			\
    	 get_idreg_field_unsigned(kvm, id, fld))
    
    where one side of the expression evaluates as something signed,
    and the other as something unsigned. In retrospect, this is totally
    braindead, as the compiler converts this into an unsigned expression.
    When compared to something that is 0, the test is simply elided.
    
    Epic fail. Similar issue exists in the expand_field_sign() macro.
    
    The correct way to handle this is to chose between signed and unsigned
    comparisons, so that both sides of the ternary expression are of the
    same type (bool).
    
    In order to keep the code readable (sort of), we introduce new
    comparison primitives taking an operator as a parameter, and
    rewrite the kvm_has_feat*() helpers in terms of these primitives.
    
    Fixes: c62d7a23 ("KVM: arm64: Add feature checking helpers")
    Reported-by: default avatarOliver Upton <oliver.upton@linux.dev>
    Tested-by: default avatarOliver Upton <oliver.upton@linux.dev>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20241002204239.2051637-1-maz@kernel.orgSigned-off-by: default avatarMarc Zyngier <maz@kernel.org>
    a1d402ab
kvm_host.h 45.5 KB