From c4abd3178e117d3ca15a40d76df2dbb135f33d78 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 10 Aug 2014 04:10:26 +1000 Subject: [PATCH] drm/nv50-/disp: audit and version DAC_LOAD 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 --- .../drm/nouveau/core/engine/disp/dacnv50.c | 50 ++++++++----------- .../gpu/drm/nouveau/core/engine/disp/nv50.c | 3 +- .../gpu/drm/nouveau/core/engine/disp/nv50.h | 5 +- .../gpu/drm/nouveau/core/engine/disp/nv84.c | 1 - .../gpu/drm/nouveau/core/engine/disp/nv94.c | 1 - .../gpu/drm/nouveau/core/engine/disp/nva3.c | 1 - .../gpu/drm/nouveau/core/engine/disp/nvd0.c | 1 - .../gpu/drm/nouveau/core/include/core/class.h | 7 --- drivers/gpu/drm/nouveau/nv50_display.c | 23 ++++++--- drivers/gpu/drm/nouveau/nvif/class.h | 7 +++ 10 files changed, 48 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index 9fb1a8438b56..e0932b7c654c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c @@ -63,9 +63,24 @@ nv50_dac_power(NV50_DISP_MTHD_V1) } int -nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) +nv50_dac_sense(NV50_DISP_MTHD_V1) { - const u32 doff = (or * 0x800); + union { + struct nv50_disp_dac_load_v0 v0; + } *args = data; + const u32 doff = outp->or * 0x800; + u32 loadval; + int ret; + + nv_ioctl(object, "disp dac load size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp dac load vers %d data %08x\n", + args->v0.version, args->v0.data); + if (args->v0.data & 0xfff00000) + return -EINVAL; + loadval = args->v0.data; + } else + return ret; nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); @@ -78,35 +93,10 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); - nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval); + nv_debug(priv, "DAC%d sense: 0x%08x\n", outp->or, loadval); if (!(loadval & 0x80000000)) return -ETIMEDOUT; - return (loadval & 0x38000000) >> 27; -} - -int -nv50_dac_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 or = (mthd & NV50_DISP_DAC_MTHD_OR); - u32 *data = args; - int ret; - - if (size < sizeof(u32)) - return -EINVAL; - - switch (mthd & ~0x3f) { - case NV50_DISP_DAC_LOAD: - ret = priv->dac.sense(priv, or, data[0]); - if (ret >= 0) { - data[0] = ret; - ret = 0; - } - break; - default: - BUG_ON(1); - } - - return ret; + args->v0.load = (loadval & 0x38000000) >> 27; + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 00d1e34cb2a6..2a7f97891650 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -901,6 +901,8 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, switch (mthd * !!outp) { case NV50_DISP_MTHD_V1_DAC_PWR: return priv->dac.power(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_DAC_LOAD: + return priv->dac.sense(object, priv, data, size, head, outp); default: break; } @@ -1031,7 +1033,6 @@ nv50_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { 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 4a874d776368..138bc8cd1ddb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -42,7 +42,7 @@ struct nv50_disp_priv { struct { int nr; int (*power)(NV50_DISP_MTHD_V1); - int (*sense)(struct nv50_disp_priv *, int dac, u32 load); + int (*sense)(NV50_DISP_MTHD_V1); } dac; struct { int nr; @@ -65,9 +65,8 @@ int nv50_disp_base_mthd(struct nouveau_object *, u32, void *, u32); #define DAC_MTHD(n) (n), (n) + 0x03 -int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); int nv50_dac_power(NV50_DISP_MTHD_V1); -int nv50_dac_sense(struct nv50_disp_priv *, int, u32); +int nv50_dac_sense(NV50_DISP_MTHD_V1); #define SOR_MTHD(n) (n), (n) + 0x3f diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index f2414a4bc000..fed1a6ab6201 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -218,7 +218,6 @@ nv84_disp_base_omthds[] = { { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { 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 7ae79cfbdbf4..fb978f168a93 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -78,7 +78,6 @@ nv94_disp_base_omthds[] = { { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { 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 31cdf7a612c4..ee474c75128c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -51,7 +51,6 @@ nva3_disp_base_omthds[] = { { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { 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 66959cde0403..6f776a1d0f1a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -717,7 +717,6 @@ nvd0_disp_base_omthds[] = { { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { 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/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 026b123d1422..6c102d3d6d94 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -77,13 +77,6 @@ struct nv04_display_scanoutpos { #define NV94_DISP_SOR_DP_PWR_STATE_OFF 0x00000000 #define NV94_DISP_SOR_DP_PWR_STATE_ON 0x00000001 -#define NV50_DISP_DAC_MTHD 0x00020000 -#define NV50_DISP_DAC_MTHD_TYPE 0x0000f000 -#define NV50_DISP_DAC_MTHD_OR 0x00000003 - -#define NV50_DISP_DAC_LOAD 0x00020100 -#define NV50_DISP_DAC_LOAD_VALUE 0x00000007 - #define NV50_DISP_PIOR_MTHD 0x00030000 #define NV50_DISP_PIOR_MTHD_TYPE 0x0000f000 #define NV50_DISP_PIOR_MTHD_OR 0x00000003 diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index d3e6bd33670e..bb963076583d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1590,14 +1590,25 @@ nv50_dac_disconnect(struct drm_encoder *encoder) static enum drm_connector_status nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nv50_disp *disp = nv50_disp(encoder->dev); - int ret, or = nouveau_encoder(encoder)->or; - u32 load = nouveau_drm(encoder->dev)->vbios.dactestval; - if (load == 0) - load = 340; + struct { + struct nv50_disp_mthd_v1 base; + struct nv50_disp_dac_load_v0 load; + } args = { + .base.version = 1, + .base.method = NV50_DISP_MTHD_V1_DAC_LOAD, + .base.hasht = nv_encoder->dcb->hasht, + .base.hashm = nv_encoder->dcb->hashm, + }; + int ret; + + args.load.data = nouveau_drm(encoder->dev)->vbios.dactestval; + if (args.load.data == 0) + args.load.data = 340; - ret = nvif_exec(disp->disp, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); - if (ret || !load) + ret = nvif_mthd(disp->disp, 0, &args, sizeof(args)); + if (ret || !args.load.load) return connector_status_disconnected; return connector_status_connected; diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index 9681a102970d..2200fea849d4 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -333,4 +333,11 @@ struct nv50_disp_dac_pwr_v0 { __u8 pad05[3]; }; +struct nv50_disp_dac_load_v0 { + __u8 version; + __u8 load; + __u16 data; + __u8 pad04[4]; +}; + #endif -- 2.34.1