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

Commit 120b0c39 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nv50-/disp: audit and version SOR_HDA_ELD 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 d55b4af9
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -22,25 +22,37 @@
 * Authors: Ben Skeggs
 */

#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>

#include "nv50.h"

int
nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
nva3_hda_eld(NV50_DISP_MTHD_V1)
{
	const u32 soff = (or * 0x800);
	int i;
	union {
		struct nv50_disp_sor_hda_eld_v0 v0;
	} *args = data;
	const u32 soff = outp->or * 0x800;
	int ret, i;

	if (data && data[0]) {
	nv_ioctl(object, "disp sor hda eld size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
		nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version);
		if (size > 0x60)
			return -E2BIG;
	} else
		return ret;

	if (size && args->v0.data[0]) {
		for (i = 0; i < size; i++)
			nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]);
			nv_wr32(priv, 0x61c440 + soff, (i << 8) | args->v0.data[0]);
		for (; i < 0x60; i++)
			nv_wr32(priv, 0x61c440 + soff, (i << 8));
		nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003);
	} else
	if (data) {
	if (size) {
		nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001);
	} else {
		nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000);
+20 −8
Original line number Diff line number Diff line
@@ -22,8 +22,9 @@
 * Authors: Ben Skeggs
 */

#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>

#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
@@ -33,19 +34,30 @@
#include "nv50.h"

int
nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
nvd0_hda_eld(NV50_DISP_MTHD_V1)
{
	const u32 soff = (or * 0x030);
	int i;
	union {
		struct nv50_disp_sor_hda_eld_v0 v0;
	} *args = data;
	const u32 soff = outp->or * 0x030;
	int ret, i;

	if (data && data[0]) {
	nv_ioctl(object, "disp sor hda eld size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, true)) {
		nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version);
		if (size > 0x60)
			return -E2BIG;
	} else
		return ret;

	if (size && args->v0.data[0]) {
		for (i = 0; i < size; i++)
			nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]);
			nv_wr32(priv, 0x10ec00 + soff, (i << 8) | args->v0.data[i]);
		for (; i < 0x60; i++)
			nv_wr32(priv, 0x10ec00 + soff, (i << 8));
		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003);
	} else
	if (data) {
	if (size) {
		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001);
	} else {
		nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000);
+4 −0
Original line number Diff line number Diff line
@@ -905,6 +905,10 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd,
		return priv->dac.sense(object, priv, data, size, head, outp);
	case NV50_DISP_MTHD_V1_SOR_PWR:
		return priv->sor.power(object, priv, data, size, head, outp);
	case NV50_DISP_MTHD_V1_SOR_HDA_ELD:
		if (!priv->sor.hda_eld)
			return -ENODEV;
		return priv->sor.hda_eld(object, priv, data, size, head, outp);
	default:
		break;
	}
+3 −3
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct nv50_disp_priv {
	struct {
		int nr;
		int (*power)(NV50_DISP_MTHD_V1);
		int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32);
		int (*hda_eld)(NV50_DISP_MTHD_V1);
		int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32);
		u32 lvdsconf;
	} sor;
@@ -70,8 +70,8 @@ int nv50_dac_sense(NV50_DISP_MTHD_V1);

#define SOR_MTHD(n) (n), (n) + 0x3f

int nva3_hda_eld(struct nv50_disp_priv *, int, u8 *, u32);
int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32);
int nva3_hda_eld(NV50_DISP_MTHD_V1);
int nvd0_hda_eld(NV50_DISP_MTHD_V1);

int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
+0 −1
Original line number Diff line number Diff line
@@ -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(NVA3_DISP_SOR_HDA_ELD)     , nv50_sor_mthd },
	{ 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 },
Loading