VirtualBox

Changeset 61973 in vbox for trunk


Ignore:
Timestamp:
Jul 1, 2016 11:02:10 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
108420
Message:

DevVGA: bugref:8447: update and clear HGSMI IRQ flag under lock to avoid a race

Location:
trunk/src/VBox/Devices/Graphics
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r61006 r61973  
    30533053                if (u32 == HGSMIOFFSET_VOID)
    30543054                {
    3055                     PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_LOW);
    3056                     HGSMIClearHostGuestFlags(pThis->pHGSMI,
    3057                                              HGSMIHOSTFLAGS_IRQ
     3055                    PDMCritSectEnter(&pThis->critSectIRQ, VERR_SEM_BUSY);
     3056
     3057                    if (pThis->fu32PendingGuestFlags == 0)
     3058                    {
     3059                        PDMDevHlpPCISetIrqNoWait(pDevIns, 0, PDM_IRQ_LEVEL_LOW);
     3060                        HGSMIClearHostGuestFlags(pThis->pHGSMI,
     3061                                                 HGSMIHOSTFLAGS_IRQ
    30583062#  ifdef VBOX_VDMA_WITH_WATCHDOG
    3059                                              | HGSMIHOSTFLAGS_WATCHDOG
     3063                                                 | HGSMIHOSTFLAGS_WATCHDOG
    30603064#  endif
    3061                                              | HGSMIHOSTFLAGS_VSYNC
    3062                                              | HGSMIHOSTFLAGS_HOTPLUG
    3063                                              | HGSMIHOSTFLAGS_CURSOR_CAPABILITIES
    3064                                              );
     3065                                                 | HGSMIHOSTFLAGS_VSYNC
     3066                                                 | HGSMIHOSTFLAGS_HOTPLUG
     3067                                                 | HGSMIHOSTFLAGS_CURSOR_CAPABILITIES
     3068                                                );
     3069                    }
     3070                    else
     3071                    {
     3072                        HGSMISetHostGuestFlags(pThis->pHGSMI, HGSMIHOSTFLAGS_IRQ | pThis->fu32PendingGuestFlags);
     3073                        pThis->fu32PendingGuestFlags = 0;
     3074                        /* Keep the IRQ unchanged. */
     3075                    }
     3076
     3077                    PDMCritSectLeave(&pThis->critSectIRQ);
    30653078                }
    30663079                else
     
    59415954    }
    59425955
     5956    PDMR3CritSectDelete(&pThis->critSectIRQ);
    59435957    PDMR3CritSectDelete(&pThis->CritSect);
    59445958    return VINF_SUCCESS;
     
    61706184    AssertRCReturn(rc, rc);
    61716185    rc = PDMDevHlpSetDeviceCritSect(pDevIns, &pThis->CritSect);
     6186    AssertRCReturn(rc, rc);
     6187
     6188    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->critSectIRQ, RT_SRC_POS, "VGA#%u_IRQ", iInstance);
    61726189    AssertRCReturn(rc, rc);
    61736190
  • trunk/src/VBox/Devices/Graphics/DevVGA.h

    r60465 r61973  
    602602    uint8_t                     Padding10[14];
    603603#  endif
     604
     605    /** The critical section serializes the HGSMI IRQ setting/clearing. */
     606    PDMCRITSECT                 critSectIRQ;
     607    /** VBVARaiseIRQ flags which were set when the guest was still processing previous IRQ. */
     608    uint32_t                    fu32PendingGuestFlags;
     609    uint32_t                    Padding11;
    604610# endif /* VBOX_WITH_HGSMI */
    605611
     
    689695
    690696void VBVARaiseIrq (PVGASTATE pVGAState, uint32_t fFlags);
    691 void VBVARaiseIrqNoWait(PVGASTATE pVGAState, uint32_t fFlags);
    692697
    693698int VBVAInfoView(PVGASTATE pVGAState, const VBVAINFOVIEW *pView);
  • trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp

    r60905 r61973  
    20822082    PPDMDEVINS pDevIns = pVGAState->pDevInsR3;
    20832083
    2084     PDMCritSectEnter(&pVGAState->CritSect, VERR_SEM_BUSY);
    2085     HGSMISetHostGuestFlags(pVGAState->pHGSMI, HGSMIHOSTFLAGS_IRQ | fFlags);
    2086     PDMCritSectLeave(&pVGAState->CritSect);
    2087 
    2088     /* Set IRQ only for a running VM.
    2089      * If HGSMIHOSTFLAGS_IRQ is set, then vgaR3Resume/vgaR3PowerOn will
    2090      * set the postponed IRQ.
    2091      */
    2092     VMSTATE enmVMState = PDMDevHlpVMState(pDevIns);
    2093     if (   enmVMState == VMSTATE_RUNNING
    2094         || enmVMState == VMSTATE_RUNNING_LS)
    2095     {
    2096         PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
    2097     }
    2098 }
    2099 
    2100 static DECLCALLBACK(int) vbvaRaiseIrqEMT(PVGASTATE pVGAState, uint32_t fFlags)
    2101 {
    2102     VBVARaiseIrq(pVGAState, fFlags);
    2103     return VINF_SUCCESS;
    2104 }
    2105 
    2106 void VBVARaiseIrqNoWait(PVGASTATE pVGAState, uint32_t fFlags)
    2107 {
    2108     /* we can not use PDMDevHlpPCISetIrqNoWait here, because we need to set IRG host flag and raise IRQ atomically,
    2109      * otherwise there might be a situation, when:
    2110      * 1. Flag is set
    2111      * 2. guest issues an IRQ clean request, that cleans up the flag and the interrupt
    2112      * 3. IRQ is set */
    2113     VMR3ReqCallNoWait(PDMDevHlpGetVM(pVGAState->pDevInsR3), VMCPUID_ANY, (PFNRT)vbvaRaiseIrqEMT, 2, pVGAState, fFlags);
     2084    PDMCritSectEnter(&pVGAState->critSectIRQ, VERR_SEM_BUSY);
     2085
     2086    const uint32_t fu32CurrentGuestFlags = HGSMIGetHostGuestFlags(pVGAState->pHGSMI);
     2087    if ((fu32CurrentGuestFlags & HGSMIHOSTFLAGS_IRQ) == 0)
     2088    {
     2089        /* No IRQ set yet. */
     2090        Assert(pVGAState->fu32PendingGuestFlags == 0);
     2091
     2092        HGSMISetHostGuestFlags(pVGAState->pHGSMI, HGSMIHOSTFLAGS_IRQ | fFlags);
     2093
     2094        /* If VM is not running, the IRQ will be set in VBVAOnResume. */
     2095        const VMSTATE enmVMState = PDMDevHlpVMState(pDevIns);
     2096        if (   enmVMState == VMSTATE_RUNNING
     2097            || enmVMState == VMSTATE_RUNNING_LS)
     2098            PDMDevHlpPCISetIrqNoWait(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
     2099    }
     2100    else
     2101    {
     2102        /* IRQ already set, remember the new flags. */
     2103        pVGAState->fu32PendingGuestFlags |= HGSMIHOSTFLAGS_IRQ | fFlags;
     2104    }
     2105
     2106    PDMCritSectLeave(&pVGAState->critSectIRQ);
    21142107}
    21152108
     
    21182111    PPDMDEVINS pDevIns = pThis->pDevInsR3;
    21192112
    2120     PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
    2121     bool fIrq = RT_BOOL(HGSMIGetHostGuestFlags(pThis->pHGSMI) & HGSMIHOSTFLAGS_IRQ);
    2122     PDMCritSectLeave(&pThis->CritSect);
    2123 
    2124     if (fIrq)
    2125         PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
     2113    PDMCritSectEnter(&pThis->critSectIRQ, VERR_SEM_BUSY);
     2114
     2115    if (HGSMIGetHostGuestFlags(pThis->pHGSMI) & HGSMIHOSTFLAGS_IRQ)
     2116        PDMDevHlpPCISetIrqNoWait(pDevIns, 0, PDM_IRQ_LEVEL_HIGH);
     2117
     2118    PDMCritSectLeave(&pThis->critSectIRQ);
    21262119}
    21272120
     
    24372430#if defined(VBOX_WITH_HGSMI) && (defined(VBOX_WITH_VIDEOHWACCEL) || defined(VBOX_WITH_VDMA) || defined(VBOX_WITH_WDDM))
    24382431    PVGASTATE pVGAState = (PVGASTATE)pvCallback;
    2439     VBVARaiseIrqNoWait (pVGAState, 0);
     2432    VBVARaiseIrq (pVGAState, 0);
    24402433#else
    24412434    NOREF(pvCallback);
     
    29332926    pThis->fHostCursorCapabilities &= ~fCapabilitiesRemoved;
    29342927    if (pThis->fGuestCaps & VBVACAPS_IRQ && pThis->fGuestCaps & VBVACAPS_DISABLE_CURSOR_INTEGRATION)
    2935         VBVARaiseIrqNoWait(pThis, HGSMIHOSTFLAGS_CURSOR_CAPABILITIES);
     2928        VBVARaiseIrq(pThis, HGSMIHOSTFLAGS_CURSOR_CAPABILITIES);
    29362929    PDMCritSectLeave(&pThis->CritSect);
    29372930}
  • trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp

    r58700 r61973  
    25922592                vboxVDMACrCmdProcess(pVdma, pCmd, cbCmd);
    25932593                VBoxVBVAExHPDataCompleteCmd(pCmdVbva, cbCmd);
    2594                 VBVARaiseIrqNoWait(pVGAState, 0);
     2594                VBVARaiseIrq(pVGAState, 0);
    25952595                break;
    25962596            case VBVAEXHOST_DATA_TYPE_GUESTCTL:
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette