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>
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:
psSGXReadDiffCountersIN->ui32CountersReg,
&psSGXReadDiffCountersOUT->ui32Time,
&psSGXReadDiffCountersOUT->bActive,
- &psSGXReadDiffCountersOUT->sDiffs);
+ &psSGXReadDiffCountersOUT->sDiffs,
+ psPerProc->edm_compat_abi);
return 0;
}
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;
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,
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
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);
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,
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;
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);
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] =