From 67cb49c45feba4141ed4b962855249d30302cd7d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 10 Aug 2014 04:10:27 +1000 Subject: [PATCH] drm/nv50-/disp: audit and version PIOR_PWR method The full object interfaces are about to be exposed to userspace, so we need to check for any security-related issues and version the structs to make it easier to handle any changes we may need in the future. Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 7 ++- .../gpu/drm/nouveau/core/engine/disp/nv50.h | 5 +- .../gpu/drm/nouveau/core/engine/disp/nv84.c | 3 - .../gpu/drm/nouveau/core/engine/disp/nv94.c | 3 - .../gpu/drm/nouveau/core/engine/disp/nva3.c | 3 - .../gpu/drm/nouveau/core/engine/disp/nvd0.c | 3 - .../drm/nouveau/core/engine/disp/piornv50.c | 56 ++++++++----------- .../gpu/drm/nouveau/core/include/core/class.h | 17 ------ drivers/gpu/drm/nouveau/nv50_display.c | 16 +++++- drivers/gpu/drm/nouveau/nvif/class.h | 7 +++ 10 files changed, 50 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index ed55cc296fb4..d83d3efe8253 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -952,6 +952,10 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, return ret; } break; + case NV50_DISP_MTHD_V1_PIOR_PWR: + if (!priv->pior.power) + return -ENODEV; + return priv->pior.power(object, priv, data, size, head, outp); default: break; } @@ -1080,9 +1084,6 @@ nv50_disp_base_ofuncs = { static struct nouveau_omthds nv50_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index ec623b7314b4..62a38b5f0024 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -53,7 +53,7 @@ struct nv50_disp_priv { } sor; struct { int nr; - int (*power)(struct nv50_disp_priv *, int ext, u32 data); + int (*power)(NV50_DISP_MTHD_V1); u8 type[3]; } pior; }; @@ -99,8 +99,7 @@ int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, #define PIOR_MTHD(n) (n), (n) + 0x03 -int nv50_pior_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_pior_power(struct nv50_disp_priv *, int, u32); +int nv50_pior_power(NV50_DISP_MTHD_V1); struct nv50_disp_base { struct nouveau_parent base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 006ccec6be23..c0012d8a450a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -215,9 +215,6 @@ nv84_disp_sclass[] = { struct nouveau_omthds nv84_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 821084da766a..192c8085a1dc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -74,9 +74,6 @@ nv94_disp_sclass[] = { static struct nouveau_omthds nv94_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index cd887166f630..38a79a0e358f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -46,9 +46,6 @@ nva3_disp_sclass[] = { static struct nouveau_omthds nva3_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index c9a3b5803faa..5aa44eca8056 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -712,9 +712,6 @@ nvd0_disp_base_ofuncs = { struct nouveau_omthds nvd0_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nvd0_disp_base_scanoutpos }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, {}, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c index fe0f256f11bf..d00f89a468a7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include -#include +#include +#include +#include #include #include @@ -143,38 +144,29 @@ nv50_pior_dp_impl = { *****************************************************************************/ int -nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data) +nv50_pior_power(NV50_DISP_MTHD_V1) { - const u32 stat = data & NV50_DISP_PIOR_PWR_STATE; - const u32 soff = (or * 0x800); + const u32 soff = outp->or * 0x800; + union { + struct nv50_disp_pior_pwr_v0 v0; + } *args = data; + u32 ctrl, type; + int ret; + + nv_ioctl(object, "disp pior pwr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp pior pwr vers %d state %d type %x\n", + args->v0.version, args->v0.state, args->v0.type); + if (args->v0.type > 0x0f) + return -EINVAL; + ctrl = !!args->v0.state; + type = args->v0.type; + } else + return ret; + nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); - nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | stat); + nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); + priv->pior.type[outp->or] = type; return 0; } - -int -nv50_pior_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 type = (mthd & NV50_DISP_PIOR_MTHD_TYPE) >> 12; - const u8 or = (mthd & NV50_DISP_PIOR_MTHD_OR); - u32 *data = args; - int ret; - - if (size < sizeof(u32)) - return -EINVAL; - - mthd &= ~NV50_DISP_PIOR_MTHD_TYPE; - mthd &= ~NV50_DISP_PIOR_MTHD_OR; - switch (mthd) { - case NV50_DISP_PIOR_PWR: - ret = priv->pior.power(priv, or, data[0]); - priv->pior.type[or] = type; - break; - default: - return -EINVAL; - } - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 89dd80e50dcb..9f8066d252f0 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -53,23 +53,6 @@ struct nv04_display_scanoutpos { #define NV50_DISP_SCANOUTPOS 0x00000000 -#define NV50_DISP_PIOR_MTHD 0x00030000 -#define NV50_DISP_PIOR_MTHD_TYPE 0x0000f000 -#define NV50_DISP_PIOR_MTHD_OR 0x00000003 - -#define NV50_DISP_PIOR_PWR 0x00030000 -#define NV50_DISP_PIOR_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_PWR_STATE_OFF 0x00000000 -#define NV50_DISP_PIOR_TMDS_PWR 0x00032000 -#define NV50_DISP_PIOR_TMDS_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_TMDS_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_TMDS_PWR_STATE_OFF 0x00000000 -#define NV50_DISP_PIOR_DP_PWR 0x00036000 -#define NV50_DISP_PIOR_DP_PWR_STATE 0x00000001 -#define NV50_DISP_PIOR_DP_PWR_STATE_ON 0x00000001 -#define NV50_DISP_PIOR_DP_PWR_STATE_OFF 0x00000000 - struct nv50_display_class { }; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 844fc4ee72bb..bd85026ee067 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -2079,9 +2079,19 @@ nv50_pior_dpms(struct drm_encoder *encoder, int mode) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_disp *disp = nv50_disp(encoder->dev); - u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or; - u32 ctrl = (mode == DRM_MODE_DPMS_ON); - nvif_exec(disp->disp, NV50_DISP_PIOR_PWR + mthd, &ctrl, sizeof(ctrl)); + struct { + struct nv50_disp_mthd_v1 base; + struct nv50_disp_pior_pwr_v0 pwr; + } args = { + .base.version = 1, + .base.method = NV50_DISP_MTHD_V1_PIOR_PWR, + .base.hasht = nv_encoder->dcb->hasht, + .base.hashm = nv_encoder->dcb->hashm, + .pwr.state = mode == DRM_MODE_DPMS_ON, + .pwr.type = nv_encoder->dcb->type, + }; + + nvif_mthd(disp->disp, 0, &args, sizeof(args)); } static bool diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index e0d45faa46d4..f869f94d41c1 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -373,4 +373,11 @@ struct nv50_disp_sor_dp_pwr_v0 { __u8 pad02[6]; }; +struct nv50_disp_pior_pwr_v0 { + __u8 version; + __u8 state; + __u8 type; + __u8 pad03[5]; +}; + #endif -- 2.20.1