]> git.openpandora.org Git - sgx.git/commitdiff
gpu: pvr: make the IOCTL i/f compatible for old ABI users
authorImre Deak <imre.deak@nokia.com>
Tue, 14 Dec 2010 01:04:33 +0000 (03:04 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 20 May 2012 18:43:02 +0000 (21:43 +0300)
The previous patch breaks the IOCTL i/f for current user space code.
This change will notice such calls based on the IOCTL parameter size and
fix up the param struct accordingly.

This patch can be reverted once applications are converted to use the new
ABI.

Signed-off-by: Imre Deak <imre.deak@nokia.com>
pvr/bridged_pvr_bridge.c
pvr/bridged_sgx_bridge.c
pvr/bridged_sgx_bridge.h
pvr/perproc.h
pvr/sgx_bridge_km.h
pvr/sgxinit.c

index 740981675cea9a38b60dd51d7e38a871e0c09538..f95335f89050f8c8578a8bc0f57b681abd9843b0 100644 (file)
@@ -3225,7 +3225,7 @@ static int bridged_ioctl(struct file *filp, u32 cmd, void *in, void *out,
                err = SGXGetInfoForSrvinitBW(cmd, in, out, per_proc);
                break;
        case PVRSRV_BRIDGE_SGX_DEVINITPART2:
-               err = SGXDevInitPart2BW(cmd, in, out, per_proc);
+               err = SGXDevInitPart2BW(cmd, in, out, in_size, per_proc);
                break;
 
        case PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC:
index dabcaa4b50ff9dff34d77e221f656289aafc6be9..37c2b896948702440cf8024c42aad4c71c2351eb 100644 (file)
@@ -519,7 +519,8 @@ int SGXReadDiffCountersBW(u32 ui32BridgeID,
                                psSGXReadDiffCountersIN->ui32CountersReg,
                                &psSGXReadDiffCountersOUT->ui32Time,
                                &psSGXReadDiffCountersOUT->bActive,
-                               &psSGXReadDiffCountersOUT->sDiffs);
+                               &psSGXReadDiffCountersOUT->sDiffs,
+                               psPerProc->edm_compat_abi);
 
        return 0;
 }
@@ -571,9 +572,38 @@ int SGXReadHWPerfCBBW(u32 ui32BridgeID,
        return 0;
 }
 
+static int fixup_compat_format(struct PVRSRV_PER_PROCESS_DATA *psPerProc,
+                              struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *info,
+                              size_t size)
+{
+       void **edm_buf;
+
+       if (size == sizeof(*info)) {
+               psPerProc->edm_compat_abi = 0;
+               return 0;
+       }
+
+       edm_buf = &info->sInitInfo.hKernelEDMStatusBufferMemInfo;
+
+       if (size + sizeof(*edm_buf) != sizeof(*info))
+               return -EFAULT;
+
+       /*
+        * remainder of the compat struct size after the
+        * hKernelEDMStatusBufferMemInfo field
+        */
+       size -= offsetof(struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2,
+                        sInitInfo.hKernelEDMStatusBufferMemInfo);
+       memmove(edm_buf + 1, edm_buf, size);
+       *edm_buf = NULL;
+       psPerProc->edm_compat_abi = 1;
+
+       return 0;
+}
+
 int SGXDevInitPart2BW(u32 ui32BridgeID,
                struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
-               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
+               struct PVRSRV_BRIDGE_RETURN *psRetOUT, size_t in_size,
                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
 {
        void *hDevCookieInt;
@@ -592,6 +622,11 @@ int SGXDevInitPart2BW(u32 ui32BridgeID,
                return 0;
        }
 
+       if (fixup_compat_format(psPerProc, psSGXDevInitPart2IN, in_size) < 0) {
+               psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
+               return 0;
+       }
+
        psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
                                                &hDevCookieInt,
                                                psSGXDevInitPart2IN->hDevCookie,
index c2a8c476dd55268447ec369b2dfa0c14c96a54ea..4806cb475c2349eef076760980f165eeb86c3e22 100644 (file)
@@ -76,9 +76,9 @@ int SGXReadHWPerfCBBW(u32 ui32BridgeID,
        struct PVRSRV_PER_PROCESS_DATA *psPerProc);
 
 int SGXDevInitPart2BW(u32 ui32BridgeID,
-       struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
-       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
-       struct PVRSRV_PER_PROCESS_DATA *psPerProc);
+       struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
+       struct PVRSRV_BRIDGE_RETURN *psRetOUT, size_t in_size,
+       struct PVRSRV_PER_PROCESS_DATA *psPerProc);
 
 int SGXRegisterHWRenderContextBW(u32 ui32BridgeID,
        struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT
index a89b0e4e51ed95e5a3dd59109c3e0dd8aedf13ad..11b132a47c447afd205e4ada54f0e1374672edbd 100644 (file)
@@ -45,6 +45,11 @@ struct PVRSRV_PER_PROCESS_DATA {
        IMG_BOOL bInitProcess;
 
        void *hOsPrivateData;
+
+       int edm_compat_abi;             /*
+                                        * set if old ABI is used to pass the
+                                        * EDM trace buffer address.
+                                        */
 };
 
 struct PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(u32 ui32PID);
index 3389b0cd23f3c3dcc6aabc914bc75cdfed9a90b1..2990521c988a69da5022975e666004e5c975e64e 100644 (file)
@@ -61,7 +61,8 @@ enum PVRSRV_ERROR SGXReadDiffCountersKM(void *hDevHandle, u32 ui32Reg,
                            u32 *pui32Old, IMG_BOOL bNew, u32 ui32New,
                            u32 ui32NewReset, u32 ui32CountersReg,
                            u32 *pui32Time, IMG_BOOL *pbActive,
-                           struct PVRSRV_SGXDEV_DIFF_INFO *psDiffs);
+                           struct PVRSRV_SGXDEV_DIFF_INFO *psDiffs,
+                           int edm_compat_abi);
 enum PVRSRV_ERROR SGXReadHWPerfCBKM(void *hDevHandle, u32 ui32ArraySize,
                            struct PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData,
                            u32 *pui32DataCount, u32 *pui32ClockSpeed,
index ace786ce14d8eecac42a027896e518b60b333cae..4fa29c61cef291605e0b011b693d7d2ef5a789f8 100644 (file)
@@ -1515,7 +1515,8 @@ enum PVRSRV_ERROR SGXReadDiffCountersKM(void *hDevHandle, u32 ui32Reg,
                                   u32 *pui32Old, IMG_BOOL bNew, u32 ui32New,
                                   u32 ui32NewReset, u32 ui32CountersReg,
                                   u32 *pui32Time, IMG_BOOL *pbActive,
-                                  struct PVRSRV_SGXDEV_DIFF_INFO *psDiffs)
+                                  struct PVRSRV_SGXDEV_DIFF_INFO *psDiffs,
+                                  int edm_compat_abi)
 {
        struct SYS_DATA *psSysData;
        struct PVRSRV_POWER_DEV *psPowerDevice;
@@ -1555,6 +1556,7 @@ enum PVRSRV_ERROR SGXReadDiffCountersKM(void *hDevHandle, u32 ui32Reg,
                sNew.ui32Time[0] = OSClockus();
                *pui32Time = sNew.ui32Time[0];
                if (sNew.ui32Time[0] != psPrev->ui32Time[0] && bPowered) {
+                       u32 __iomem *time_wraps;
 
                        *pui32Old =
                            OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32Reg);
@@ -1581,8 +1583,10 @@ enum PVRSRV_ERROR SGXReadDiffCountersKM(void *hDevHandle, u32 ui32Reg,
                        sNew.ui32Marker[0] = psDevInfo->ui32KickTACounter;
                        sNew.ui32Marker[1] = psDevInfo->ui32KickTARenderCounter;
 
-                       sNew.ui32Time[1] = readl(
-                               &psDevInfo->psSGXHostCtl->ui32TimeWraps);
+                       time_wraps = &psDevInfo->psSGXHostCtl->ui32TimeWraps;
+                       if (edm_compat_abi)
+                               time_wraps -= 1;
+                       sNew.ui32Time[1] = readl(time_wraps);
 
                        for (i = 0; i < PVRSRV_SGX_DIFF_NUM_COUNTERS; ++i) {
                                psDiffs->aui32Counters[i] =