Re: [Qemu-devel] [PATCH 07/14] timer: ds1338 fix wday_offset handling

2018-04-13 Thread Peter Maydell
On 24 March 2018 at 19:24, Michael Davidsaver  wrote:
> Correctly handle different real weekday in
> guest and host timezones.
> Allow guest to use any day as start of week
> (day 1).  eg. Monday instead of Sunday.
>
> Signed-off-by: Michael Davidsaver 
> ---
>  hw/timer/ds1338.c | 24 
>  1 file changed, 16 insertions(+), 8 deletions(-)
>
> diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c
> index 071c031563..a969b5c8ba 100644
> --- a/hw/timer/ds1338.c
> +++ b/hw/timer/ds1338.c
> @@ -108,7 +108,10 @@ static void capture_current_time(DS1338State *s)
>  } else {
>  ARRAY_FIELD_DP32(s->nvram, HOUR, HOUR24, to_bcd(now.tm_hour));
>  }
> -s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7 + 1;
> +s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7;
> +if (s->nvram[R_WDAY] == 0) {
> +s->nvram[R_WDAY] = 7;
> +}
>  s->nvram[R_DATE] = to_bcd(now.tm_mday);
>  s->nvram[R_MONTH] = to_bcd(now.tm_mon + 1);
>  s->nvram[R_YEAR] = to_bcd(now.tm_year - 100);
> @@ -182,17 +185,22 @@ static void ds1338_update(DS1338State *s)
>  } else {
>  now.tm_hour = from_bcd(ARRAY_FIELD_EX32(s->nvram, HOUR, HOUR24));
>  }
> -{
> -/* The day field is supposed to contain a value in
> -   the range 1-7. Otherwise behavior is undefined.
> - */
> -int user_wday = (s->nvram[R_WDAY] & 7) - 1;
> -s->wday_offset = (user_wday - now.tm_wday + 7) % 7;
> -}
> +now.tm_wday = from_bcd(s->nvram[R_WDAY]) - 1u;
>  now.tm_mday = from_bcd(s->nvram[R_DATE] & 0x3f);

You don't need to set now.tm_wday -- qemu_timedate_diff()
will not use that field in the structure you hand it.

>  now.tm_mon = from_bcd(s->nvram[R_MONTH] & 0x1f) - 1;
>  now.tm_year = from_bcd(s->nvram[R_YEAR]) + 100;
>  s->offset = qemu_timedate_diff();
> +
> +{
> +/* Round trip to get real wday_offset based on time delta and
> + * ref. timezone.
> + * Race if midnight (in ref. timezone) happens here.
> + */
> +int user_wday = now.tm_wday;
> +qemu_get_timedate(, s->offset);
> +
> +s->wday_offset = (user_wday - now.tm_wday) % 7 + 1;
> +}
>  }

Ah, this part is fixing the bug I pointed out in the earlier patch.
You should just fold that bug fix into it.

thanks
-- PMM



[Qemu-devel] [PATCH 07/14] timer: ds1338 fix wday_offset handling

2018-03-24 Thread Michael Davidsaver
Correctly handle different real weekday in
guest and host timezones.
Allow guest to use any day as start of week
(day 1).  eg. Monday instead of Sunday.

Signed-off-by: Michael Davidsaver 
---
 hw/timer/ds1338.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c
index 071c031563..a969b5c8ba 100644
--- a/hw/timer/ds1338.c
+++ b/hw/timer/ds1338.c
@@ -108,7 +108,10 @@ static void capture_current_time(DS1338State *s)
 } else {
 ARRAY_FIELD_DP32(s->nvram, HOUR, HOUR24, to_bcd(now.tm_hour));
 }
-s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7 + 1;
+s->nvram[R_WDAY] = (now.tm_wday + s->wday_offset) % 7;
+if (s->nvram[R_WDAY] == 0) {
+s->nvram[R_WDAY] = 7;
+}
 s->nvram[R_DATE] = to_bcd(now.tm_mday);
 s->nvram[R_MONTH] = to_bcd(now.tm_mon + 1);
 s->nvram[R_YEAR] = to_bcd(now.tm_year - 100);
@@ -182,17 +185,22 @@ static void ds1338_update(DS1338State *s)
 } else {
 now.tm_hour = from_bcd(ARRAY_FIELD_EX32(s->nvram, HOUR, HOUR24));
 }
-{
-/* The day field is supposed to contain a value in
-   the range 1-7. Otherwise behavior is undefined.
- */
-int user_wday = (s->nvram[R_WDAY] & 7) - 1;
-s->wday_offset = (user_wday - now.tm_wday + 7) % 7;
-}
+now.tm_wday = from_bcd(s->nvram[R_WDAY]) - 1u;
 now.tm_mday = from_bcd(s->nvram[R_DATE] & 0x3f);
 now.tm_mon = from_bcd(s->nvram[R_MONTH] & 0x1f) - 1;
 now.tm_year = from_bcd(s->nvram[R_YEAR]) + 100;
 s->offset = qemu_timedate_diff();
+
+{
+/* Round trip to get real wday_offset based on time delta and
+ * ref. timezone.
+ * Race if midnight (in ref. timezone) happens here.
+ */
+int user_wday = now.tm_wday;
+qemu_get_timedate(, s->offset);
+
+s->wday_offset = (user_wday - now.tm_wday) % 7 + 1;
+}
 }
 
 static int ds1338_send(I2CSlave *i2c, uint8_t data)
-- 
2.11.0