On 18/08/2025 12:27 pm, Jan Beulich wrote:
> On 15.08.2025 22:41, Andrew Cooper wrote:
>> ... on capable toolchains.
>>
>> This avoids needing to hold rc in a register across the RDMSR, and in most
>> cases removes direct testing and branching based on rc, as the fault label 
>> can
>> be rearranged to directly land on the out-of-line block.
>>
>> There is a subtle difference in behaviour.  The old behaviour would, on 
>> fault,
>> still produce 0's and write to val.
>>
>> The new behaviour only writes val on success, and write_msr() is the only
>> place where this matters.  Move temp out of switch() scope and initialise it
>> to 0.
> But what's the motivation behind making this behavioral change? At least in
> the cases where the return value isn't checked, it would feel safer if we
> continued clearing the value. Even if in all cases where this could matter
> (besides the one you cover here) one can prove correctness by looking at
> surrounding code.

I didn't realise I'd made a change at first, but it's a consequence of
the compiler's ability to rearrange basic blocks.

It can be fixed with ...

>
>> --- a/xen/arch/x86/include/asm/msr.h
>> +++ b/xen/arch/x86/include/asm/msr.h
>> @@ -55,6 +55,24 @@ static inline void wrmsrns(uint32_t msr, uint64_t val)
>>  /* rdmsr with exception handling */
>>  static inline int rdmsr_safe(unsigned int msr, uint64_t *val)
>>  {
>> +#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
>> +    uint64_t lo, hi;
>> +    asm_inline goto (
>> +        "1: rdmsr\n\t"
>> +        _ASM_EXTABLE(1b, %l[fault])
>> +        : "=a" (lo), "=d" (hi)
>> +        : "c" (msr)
>> +        :
>> +        : fault );
>> +
>> +    *val = lo | (hi << 32);
>> +
>> +    return 0;
>> +
>> + fault:

    *val = 0;

here, but I don't want to do this.  Because val is by pointer and
generally spilled to the stack, the compiler can't optimise away the store.

I'd far rather get a real compiler error, than to have logic relying on
the result of a faulting MSR read.

>> +    return -EFAULT;
>> +#else
>>      int rc;
>>      uint64_t lo, hi;
> ... the same being needed here?

Fixed.

~Andrew

Reply via email to