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

Re: [PATCH 2/2] x86/vPIT: account for "counter stopped" time


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Thu, 1 Jun 2023 13:48:38 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=tToSUdSCbOvnHB2O9LkNMXWIiRBIIw5xDKVTTFw/dkY=; b=CiH6ZMh1Jog8RKLXBxgFntKK6eW+BcAe8u0ij8mNNdHTT7BiYxsdydwRNy4thWIOWDTyUI3U/go4iCEBeNsi+YLAVxqhD67H0HjBn+waNmQ1Mw1Lo4IqSs+3uyOlp/RGas8ZS71Qg3a8NvUEXeoQDIPoNSbYVbsr7JEYa+x+yqb8XTGvj/48ZG/ciYBiT5uMF5omaOu1tM2IVNuQ5jth8Rea8rYOR/2lKqTcidNXClJWbarezeFsPcyQtv+oznbT9zP2EX34nR/LB2Mot4lJrtX4DRttt5k5+njFVEHPhLsuEePYDsTm79iXY5M8AcerseorXU9uGMSgu5xTsnL8kQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FY6YFbMmpOi78Z+NrLKJkKGSEIPcHYjuVFzchglaZMxk9spBO4R1inFcL0CSlJtxYDvGjZzfxopM3I/Ikv3tcgXZH0uAQ6zven/Xf2++5kJn5gArZ9WFCOwZUY5oYSMb19EfHbl+qydkAa7bin1FeFL/LLqzwyHO3yC3pOg0jYdOOHu0is49gR63SxHJNFhkfUuaOQ655Rr+ksJarqqxcOzcku1WI6Tkzhpi8AykyHlZwpY7m3h3rAQ62gK2JQcvISnc3kjh5Y7wcZMyd6SQG6bovujPBltrHWvz5oV+XPWllzHRmcn/mFo1fr6PP+KPbWi57C789T+7WUG3ybalmA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Thu, 01 Jun 2023 11:49:17 +0000
  • Ironport-data: A9a23:zmYdua4QAsNmEFtglyTKNQxRtB7GchMFZxGqfqrLsTDasY5as4F+v mIfXG7UafyONDH3fY0lYYXnoUIG6sKDyIdnTwBoqCs2Hi5G8cbLO4+Ufxz6V8+wwm8vb2o8t plDNYOQRCwQZiWBzvt4GuG59RGQ7YnRGvynTraCYnsrLeNdYH9JoQp5nOIkiZJfj9G8Agec0 fv/uMSaM1K+s9JOGjt8B5mr9lU35JwehBtC5gZlPa4T5QeF/5UoJMl3yZ+ZfiOQrrZ8RoZWd 86bpJml82XQ+QsaC9/Nut4XpWVTH9Y+lSDX4pZnc/DKbipq/0Te4Y5iXBYoUm9Fii3hojxE4 I4lWapc6+seFvakdOw1C3G0GszlVEFM0OevzXOX6aR/w6BaGpdFLjoH4EweZOUlFuhL7W5m3 KYGNRMfLSq6pvOU/r78FfZ1g+gYI5y+VG8fkikIITDxK98DGMiGaYOVoNhS0XE3m9xEGuvYa 4wBcz1zYR/cYhpJfFAKFJY5m+TujX76G9FagAvN+exrvC6MlEooiOKF3Nn9I7RmQe1PmUmVv CTe9nnRCRAGLt2PjzGC9xpAg8eWxHumBNtCTOHQGvhCkHC+3TExCCIsb3Tn/PC/jlWHaf4PN BlBksYphe1onKCxdfH/VRClpH+PvjYHRsFdVeY97Wml2qfSpgqUGGUAZjpAc8A98t87QyQw0 V2ElM+vAiZg2JWKTVqN+7HSqim9URX5NkcHbC4ACAEDvN/qpdhrigqVF445VqmoktfyBDf8h SiQqzQzjKkSishN0Lin+VfAgHSnoZ2hohMJ2zg7l1mNtmtRDLNJraTxgbQHxZ6s9Lqkc2Q=
  • Ironport-hdrordr: A9a23:88bUR6gD5KBn5KeAFWTkgmB0aXBQXrkji2hC6mlwRA09TyX4ra CTdZEgviMc5wx9ZJhNo7q90cq7IE80i6Qb3WB5B97LYOCMggeVxe9Zg7ff/w==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Tue, May 30, 2023 at 05:30:40PM +0200, Jan Beulich wrote:
> For an approach like that used in "x86: detect PIT aliasing on ports
> other than 0x4[0-3]" [1] to work, channel 2 may not (appear to) continue
> counting when "gate" is low. Record the time when "gate" goes low, and
> adjust pit_get_{count,out}() accordingly. Additionally for most of the
> modes a rising edge of "gate" doesn't mean just "resume counting", but
> "initiate counting", i.e. specifically the reloading of the counter with
> its init value.
> 
> No special handling for state save/load: See the comment near the end of
> pit_load().
> 
> [1] https://lists.xen.org/archives/html/xen-devel/2023-05/msg00898.html
> 
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> TBD: "gate" can only ever be low for chan2 (with "x86/vPIT: check/bound
>      values loaded from state save record" [2] in place), so in
>      principle we could get away without a new pair of arrays, but just
>      two individual fields. At the expense of more special casing in
>      code.

Hm, I guess we could rename to pit_set_gate_ch2 and remove the ch
parameter.  That would be OK for me.

> TBD: Should we deal with other aspects of "gate low" in pit_get_out()
>      here as well, right away? I was hoping to get away without ...
>      (Note how the two functions also disagree in their placement of the
>      "default" labels, even if that's largely benign when taking into
>      account that modes 6 and 7 are transformed to 2 and 3 respectively
>      by pit_load(). A difference would occur only before the guest first
>      sets the mode, as pit_reset() sets it to 7.)

I'm in general afraid of doing changes here (apart from bugfixes)
because we don't really have a good way to test them AFAIK, maybe you
do have some XTF or similar tests to exercise those paths?

> Other observations:
> - Loading of new counts occurs too early in some of the modes (2/3: at
>   end of current sequence or when gate goes high; 1/5: only when gate
>   goes high).
> - BCD counting doesn't appear to be properly supported either (at least
>   that's mentioned in the public header).
> 
> [2] https://lists.xen.org/archives/html/xen-devel/2023-05/msg00887.html
> 
> --- a/xen/arch/x86/emul-i8254.c
> +++ b/xen/arch/x86/emul-i8254.c
> @@ -65,7 +65,10 @@ static int pit_get_count(PITState *pit,
>  
>      ASSERT(spin_is_locked(&pit->lock));
>  
> -    d = muldiv64(get_guest_time(v) - pit->count_load_time[channel],
> +    d = pit->hw.channels[channel].gate || (c->mode & 3) == 1
> +        ? get_guest_time(v) - pit->count_load_time[channel]
> +        : pit->count_stop_time[channel];
> +    d = muldiv64(d - pit->stopped_time[channel],
>                   PIT_FREQ, SYSTEM_TIME_HZ);
>  
>      switch ( c->mode )
> @@ -109,6 +112,7 @@ static void pit_load_count(PITState *pit
>          pit->count_load_time[channel] = 0;
>      else
>          pit->count_load_time[channel] = get_guest_time(v);
> +    pit->stopped_time[channel] = 0;

Don't you need to also set count_stop_time == count_load_time in case
the counter is disabled? (s->gate == 0).

>      s->count = val;
>      period = DIV_ROUND(val * SYSTEM_TIME_HZ, PIT_FREQ);
>  
> @@ -147,7 +151,10 @@ static int pit_get_out(PITState *pit, in
>  
>      ASSERT(spin_is_locked(&pit->lock));
>  
> -    d = muldiv64(get_guest_time(v) - pit->count_load_time[channel], 
> +    d = pit->hw.channels[channel].gate || (s->mode & 3) == 1
> +        ? get_guest_time(v) - pit->count_load_time[channel]
> +        : pit->count_stop_time[channel];
> +    d = muldiv64(d - pit->stopped_time[channel],
>                   PIT_FREQ, SYSTEM_TIME_HZ);
>  
>      switch ( s->mode )
> @@ -181,22 +188,39 @@ static void pit_set_gate(PITState *pit,
>  
>      ASSERT(spin_is_locked(&pit->lock));
>  
> -    switch ( s->mode )
> -    {
> -    default:
> -    case 0:
> -    case 4:
> -        /* XXX: just disable/enable counting */
> -        break;
> -    case 1:
> -    case 5:
> -    case 2:
> -    case 3:
> -        /* Restart counting on rising edge. */
> -        if ( s->gate < val )
> -            pit->count_load_time[channel] = get_guest_time(v);
> -        break;
> -    }
> +    if ( s->gate > val )
> +        switch ( s->mode )
> +        {
> +        case 0:
> +        case 2:
> +        case 3:
> +        case 4:
> +            /* Disable counting. */
> +            if ( !channel )
> +                destroy_periodic_time(&pit->pt0);
> +            pit->count_stop_time[channel] = get_guest_time(v);
> +            break;
> +        }
> +
> +    if ( s->gate < val )

Shouldn't this be an else if?

Thanks, Roger.



 


Rackspace

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