From a3761fa2483f48d158234760d5e25e5071e41537 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 LVDS_SCRIPT 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 | 16 ++++++++- .../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 - .../drm/nouveau/core/engine/disp/sornv50.c | 4 --- .../gpu/drm/nouveau/core/include/core/class.h | 2 -- drivers/gpu/drm/nouveau/nv50_display.c | 33 ++++++++++++------- drivers/gpu/drm/nouveau/nvif/class.h | 7 ++++ 9 files changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index bb5caa7e2176..93e06ae67c66 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -913,6 +913,21 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, if (!priv->sor.hdmi) return -ENODEV; return priv->sor.hdmi(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: { + union { + struct nv50_disp_sor_lvds_script_v0 v0; + } *args = data; + nv_ioctl(object, "disp sor lvds script size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor lvds script " + "vers %d name %04x\n", + args->v0.version, args->v0.script); + priv->sor.lvdsconf = args->v0.script; + return 0; + } else + return ret; + } + break; default: break; } @@ -1041,7 +1056,6 @@ nv50_disp_base_ofuncs = { static struct nouveau_omthds nv50_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_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/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 49cbecf981e6..006ccec6be23 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -215,7 +215,6 @@ nv84_disp_sclass[] = { struct nouveau_omthds nv84_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_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 7234237f4031..f926e967f19d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -74,7 +74,6 @@ nv94_disp_sclass[] = { static struct nouveau_omthds nv94_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_TMDS_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 488623386cba..e87ee1eee690 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -46,7 +46,6 @@ nva3_disp_sclass[] = { static struct nouveau_omthds nva3_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_TMDS_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 7f035f33f25e..bceb7bd2c261 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -712,7 +712,6 @@ nvd0_disp_base_ofuncs = { struct nouveau_omthds nvd0_disp_base_omthds[] = { { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nvd0_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 5f2d71c3f71e..25344feb93cc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -84,10 +84,6 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) } switch (mthd & ~0x3f) { - case NV50_DISP_SOR_LVDS_SCRIPT: - priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; - ret = 0; - break; case NV94_DISP_SOR_DP_PWR: if (outp) { struct nvkm_output_dp *outpdp = (void *)outp; diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index e54d9cc54887..d63edc73a7a0 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -59,8 +59,6 @@ struct nv04_display_scanoutpos { #define NV50_DISP_SOR_MTHD_LINK 0x00000004 #define NV50_DISP_SOR_MTHD_OR 0x00000003 -#define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 -#define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff #define NV94_DISP_SOR_DP_PWR 0x00016000 #define NV94_DISP_SOR_DP_PWR_STATE 0x00000001 #define NV94_DISP_SOR_DP_PWR_STATE_OFF 0x00000000 diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e83ed52da239..ac80bdc7cbbf 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1882,15 +1882,24 @@ static void nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, struct drm_display_mode *mode) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); + struct { + struct nv50_disp_mthd_v1 base; + struct nv50_disp_sor_lvds_script_v0 lvds; + } lvds = { + .base.version = 1, + .base.method = NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT, + .base.hasht = nv_encoder->dcb->hasht, + .base.hashm = nv_encoder->dcb->hashm, + }; struct nv50_disp *disp = nv50_disp(encoder->dev); struct nv50_mast *mast = nv50_mast(encoder->dev); struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_connector *nv_connector; struct nvbios *bios = &drm->vbios; - u32 lvds = 0, mask, ctrl; + u32 mask, ctrl; u8 owner = 1 << nv_crtc->index; u8 proto = 0xf; u8 depth = 0x0; @@ -1916,31 +1925,31 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, if (bios->fp_no_ddc) { if (bios->fp.dual_link) - lvds |= 0x0100; + lvds.lvds.script |= 0x0100; if (bios->fp.if_is_24bit) - lvds |= 0x0200; + lvds.lvds.script |= 0x0200; } else { if (nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) { if (((u8 *)nv_connector->edid)[121] == 2) - lvds |= 0x0100; + lvds.lvds.script |= 0x0100; } else if (mode->clock >= bios->fp.duallink_transition_clk) { - lvds |= 0x0100; + lvds.lvds.script |= 0x0100; } - if (lvds & 0x0100) { + if (lvds.lvds.script & 0x0100) { if (bios->fp.strapless_is_24bit & 2) - lvds |= 0x0200; + lvds.lvds.script |= 0x0200; } else { if (bios->fp.strapless_is_24bit & 1) - lvds |= 0x0200; + lvds.lvds.script |= 0x0200; } if (nv_connector->base.display_info.bpc == 8) - lvds |= 0x0200; + lvds.lvds.script |= 0x0200; } - nvif_exec(disp->disp, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, &lvds, sizeof(lvds)); + nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); break; case DCB_OUTPUT_DP: if (nv_connector->base.display_info.bpc == 6) { diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index abc6efab5dc6..a3d433859cbc 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -360,4 +360,11 @@ struct nv50_disp_sor_hdmi_pwr_v0 { __u8 pad04[4]; }; +struct nv50_disp_sor_lvds_script_v0 { + __u8 version; + __u8 pad01[1]; + __u16 script; + __u8 pad04[4]; +}; + #endif -- 2.34.1