diff mbox

ehci: fix "int" overflow for calculation ehci->last_run_ns

Message ID 1894a033.84c.15bf1938bed.Coremail.8610_28@163.com (mailing list archive)
State New, archived
Headers show

Commit Message

李林 May 10, 2017, 8:57 a.m. UTC
If we experience large delays between echi timer callbacks (i.e. because other periodic handlers have taken a lot of time to complete) we get a lot of skipped frames which then delay ehci timer callback.
 Then we will calculation  ehci->last_run_ns,but skipped_uframes is int,so "UFRAME_TIMER_NS * skipped_uframes" will be int,and if skipped_uframes is big enough ,it can overflow ,and this can not calculation the right number,then it can   raise  large amountsinterrupts;
  Observable behaviour is qemu consuming 100% host CPU time while guest is unresponsive. This misbehavior could happen for a while and QEMU does not get out from this state automatically without the patch in Branch-master repository.


     t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

Comments

Mark Cave-Ayland May 12, 2017, 12:48 p.m. UTC | #1
On 10/05/17 09:57, 李林 wrote:

>   If we experience large delays between echi timer callbacks (i.e. because other periodic handlers have taken a lot of time to complete) we get a lot of skipped frames which then delay ehci timer callback.
>  Then we will calculation  ehci->last_run_ns,but skipped_uframes is int,so "UFRAME_TIMER_NS * skipped_uframes" will be int,and if skipped_uframes is big enough ,it can overflow ,and this can not calculation the right number,then it can   raise  large amountsinterrupts;
>   Observable behaviour is qemu consuming 100% host CPU time while guest is unresponsive. This misbehavior could happen for a while and QEMU does not get out from this state automatically without the patch in Branch-master repository.
> 
> 
> diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
> index 50ef817f93..8df2f08783 100644
> --- a/hw/usb/hcd-ehci.c
> +++ b/hw/usb/hcd-ehci.c
> @@ -2238,7 +2238,7 @@ static void ehci_frame_timer(void *opaque)
>      int need_timer = 0;
>      int64_t expire_time, t_now;
>      uint64_t ns_elapsed;
> -    int uframes, skipped_uframes;
> +    uint64 uframes, skipped_uframes;
>      int i;
> 
> 
>      t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> 

Adding Gerd as USB maintainer to CC.


ATB,

Mark.
diff mbox

Patch

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 50ef817f93..8df2f08783 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2238,7 +2238,7 @@  static void ehci_frame_timer(void *opaque)
     int need_timer = 0;
     int64_t expire_time, t_now;
     uint64_t ns_elapsed;
-    int uframes, skipped_uframes;
+    uint64 uframes, skipped_uframes;
     int i;