[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] x86/rtc: Avoid UIP flag being set for longer than expected


  • To: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 18 Apr 2024 15:24:50 +0200
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 18 Apr 2024 13:25:03 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 08.04.2024 18:26, Ross Lagerwall wrote:
> In a test, OVMF reported an error initializing the RTC without
> indicating the precise nature of the error. The only plausible
> explanation I can find is as follows:
> 
> As part of the initialization, OVMF reads register C and then reads
> register A repatedly until the UIP flag is not set. If this takes longer
> than 100 ms, OVMF fails and reports an error. This may happen with the
> following sequence of events:
> 
> At guest time=0s, rtc_init() calls check_update_timer() which schedules
> update_timer for t=(1 - 244us).
> 
> At t=1s, the update_timer function happens to have been called >= 244us
> late.

Any theory on why this timer runs so late? (It needs dealing with anyway,
but I'm still curious.)

> In the timer callback, it sets the UIP flag and schedules
> update_timer2 for t=1s.
> 
> Before update_timer2 runs, the guest reads register C which calls
> check_update_timer(). check_update_timer() stops the scheduled
> update_timer2 and since the guest time is now outside of the update
> cycle, it schedules update_timer for t=(2 - 244us).
> 
> The UIP flag will therefore be set for a whole second from t=1 to t=2
> while the guest repeatedly reads register A waiting for the UIP flag to
> clear. Fix it by clearing the UIP flag when scheduling update_timer.

I can accept this as a workaround (perhaps with a tweak, see below), but
I wonder whether we couldn't do this in a less ad hoc way. If stop_timer()
returned whether the timer was actually stopped, couldn't the clearing of
UIP be made conditional upon that?

> --- a/xen/arch/x86/hvm/rtc.c
> +++ b/xen/arch/x86/hvm/rtc.c
> @@ -202,6 +202,7 @@ static void check_update_timer(RTCState *s)
>          }
>          else
>          {
> +            s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
>              next_update_time = (USEC_PER_SEC - guest_usec - 244) * 
> NS_PER_USEC;
>              expire_time = NOW() + next_update_time;
>              s->next_update_time = expire_time;

Is rtc_update_timer2() clearing UIP then still necessary, ahead of calling
here? Hmm, yes, it is; the question is rather why the function calls
check_update_timer() when all that'll do (due to UF now being set) is stop
the other timer (in case it's also running) and clear ->use_timer.

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.