Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4abd317 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent bf0eb898
Loading
Loading
Loading
Loading
+20 −30
Original line number Diff line number Diff line
@@ -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;
}
+2 −1
Original line number Diff line number Diff line
@@ -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 },
+2 −3
Original line number Diff line number Diff line
@@ -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

+0 −1
Original line number Diff line number Diff line
@@ -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 },
+0 −1
Original line number Diff line number Diff line
@@ -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 },
Loading