 3c4f941ac7
			
		
	
	
		3c4f941ac7
		
	
	
	
	
		
			
			The patches were selected from the recent "Patch Round-up for stable 7.2.1" [0]. Those that should be relevant for our supported use-cases (and the upcoming nvme use-case) were picked. Most of the patches added now have not been submitted to qemu-stable before. The follow-up for the virtio-rng-pci migration fix will break migration between versions with the fix and without the fix when a virtio-pci-rng(-non)-transitional device is used. Luckily Proxmox VE only uses the virtio-pci-rng device, and this was fixed by 0006-virtio-rng-pci-fix-migration-compat-for-vectors.patch which was applied before any public version of Proxmox VE's QEMU 7.2 package was released. [0]: https://lists.nongnu.org/archive/html/qemu-stable/2023-03/msg00010.html [1]: https://bugzilla.redhat.com/show_bug.cgi?id=2162569 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
		
			
				
	
	
		
			81 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | |
| From: Akihiko Odaki <akihiko.odaki@daynix.com>
 | |
| Date: Tue, 31 Jan 2023 12:00:37 +0900
 | |
| Subject: [PATCH] hw/timer/hpet: Fix expiration time overflow
 | |
| 
 | |
| The expiration time provided for timer_mod() can overflow if a
 | |
| ridiculously large value is set to the comparator register. The
 | |
| resulting value can represent a past time after rounded, forcing the
 | |
| timer to fire immediately. If the timer is configured as periodic, it
 | |
| will rearm the timer again, and form an endless loop.
 | |
| 
 | |
| Check if the expiration value will overflow, and if it will, stop the
 | |
| timer instead of rearming the timer with the overflowed time.
 | |
| 
 | |
| This bug was found by Alexander Bulekov when fuzzing igb, a new
 | |
| network device emulation:
 | |
| https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
 | |
| 
 | |
| The fixed test case is:
 | |
| fuzz/crash_2d7036941dcda1ad4380bb8a9174ed0c949bcefd
 | |
| 
 | |
| Fixes: 16b29ae180 ("Add HPET emulation to qemu (Beth Kon)")
 | |
| Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
 | |
| Acked-by: Michael S. Tsirkin <mst@redhat.com>
 | |
| Message-Id: <20230131030037.18856-1-akihiko.odaki@daynix.com>
 | |
| Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
 | |
| Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
 | |
| (cherry-picked from commit 37d2bcbc2a4e9c2e9061bec72a32c7e49b9f81ec)
 | |
| Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
 | |
| ---
 | |
|  hw/timer/hpet.c | 19 +++++++++++++------
 | |
|  1 file changed, 13 insertions(+), 6 deletions(-)
 | |
| 
 | |
| diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
 | |
| index 9520471be2..5f88ffdef8 100644
 | |
| --- a/hw/timer/hpet.c
 | |
| +++ b/hw/timer/hpet.c
 | |
| @@ -352,6 +352,16 @@ static const VMStateDescription vmstate_hpet = {
 | |
|      }
 | |
|  };
 | |
|  
 | |
| +static void hpet_arm(HPETTimer *t, uint64_t ticks)
 | |
| +{
 | |
| +    if (ticks < ns_to_ticks(INT64_MAX / 2)) {
 | |
| +        timer_mod(t->qemu_timer,
 | |
| +                  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks_to_ns(ticks));
 | |
| +    } else {
 | |
| +        timer_del(t->qemu_timer);
 | |
| +    }
 | |
| +}
 | |
| +
 | |
|  /*
 | |
|   * timer expiration callback
 | |
|   */
 | |
| @@ -374,13 +384,11 @@ static void hpet_timer(void *opaque)
 | |
|              }
 | |
|          }
 | |
|          diff = hpet_calculate_diff(t, cur_tick);
 | |
| -        timer_mod(t->qemu_timer,
 | |
| -                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
 | |
| +        hpet_arm(t, diff);
 | |
|      } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
 | |
|          if (t->wrap_flag) {
 | |
|              diff = hpet_calculate_diff(t, cur_tick);
 | |
| -            timer_mod(t->qemu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 | |
| -                           (int64_t)ticks_to_ns(diff));
 | |
| +            hpet_arm(t, diff);
 | |
|              t->wrap_flag = 0;
 | |
|          }
 | |
|      }
 | |
| @@ -407,8 +415,7 @@ static void hpet_set_timer(HPETTimer *t)
 | |
|              t->wrap_flag = 1;
 | |
|          }
 | |
|      }
 | |
| -    timer_mod(t->qemu_timer,
 | |
| -                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
 | |
| +    hpet_arm(t, diff);
 | |
|  }
 | |
|  
 | |
|  static void hpet_del_timer(HPETTimer *t)
 |