drm fixes for 5.3-rc8 (or final)
nouveau: - add missing MODULE_FIRMWARE definitions igenic: - hardcode panel type DPI vmwgfx: - double free fix core: - command line mode parser fixes -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJdcgYAAAoJEAx081l5xIa+Td4QAKUcxyaAMbAjJde49nsrWQvY pyLdNLLDmE3xBPCetERn8QMgGr9K4c0mcVZ2deWVU/WS10BWEe5T0JlwfTqH7VnH rmCWh5dJiHCN9sjcoM9XbOJGbOiO6b0vNd4SMwHtMLfdeIHWHJovPhsfbD89NSux NxYQRYh9l1+vsbJC6kznAi/9Itg4xQ6BCeGFgq/vJjRA23E6+D7lKeZK9cykEV7Q fevjePoFtdmuzurbWS8gEWF/1mBTp7beAUTJYn5hdh3mj4HXtrmy71XaCwzj1nqd ssn3tOmmIvTmqvoU3aR7WbOsHIiaynU0HGh4sAUoZ8BLbuk6LtqGtGSuXrevYtS0 q2QYCL0fSd2qUP64zz/hQAF0Pbfw0kUoyec/AQdVl+0Uk4rcrtLmpYNsw/2l2fKZ t5rq1quZ5FnD2GSNSi308ZhmHhjlluQzsd4oezYZndIiIG9mEPGfgrlvfWJqiFO4 MAvVhP/NilvUnTvocVZtDe+kU3WGeqOUKK5T4aKaQeR1pbh4YF5aJpAoiOHtMldq W9Dm4sXu2PSdCzFl77k9QJ7XrUC9/dlr2SZ69K7G49LKTraVaQfNeXgvSftYKjWk eO8Kxk9QvGFdtwr2K5AOHOCcBtOQOl5l8RmrgAr9nGe3OZRP4+Bc1EEhYaTFdc6n EVIZe4yo/G8yX52/wR6L =dOSF -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2019-09-06' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Dave Airlie: "Live from my friend's couch in Barcelona, latest round of drm fixes. The command line parser regression fixes look a bit larger because they come with selftests included for the bugs they fix. Otherwise a single nouveau, single ingenic and single vmwgfx fix: nouveau: - add missing MODULE_FIRMWARE definitions igenic: - hardcode panel type DPI vmwgfx: - double free fix core: - command line mode parser fixes" * tag 'drm-fixes-2019-09-06' of git://anongit.freedesktop.org/drm/drm: drm/vmwgfx: Fix double free in vmw_recv_msg() drm/nouveau/sec2/gp102: add missing MODULE_FIRMWAREs drm/selftests: modes: Add more unit tests for the cmdline parser drm/modes: Introduce a whitelist for the named modes drm/modes: Fix the command line parser to take force options into account drm/modes: Add a switch to differentiate free standing options drm/ingenic: Hardcode panel type to DPI
This commit is contained in:
commit
08d433d812
@ -1454,6 +1454,7 @@ static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
|
||||
}
|
||||
|
||||
static int drm_mode_parse_cmdline_extra(const char *str, int length,
|
||||
bool freestanding,
|
||||
const struct drm_connector *connector,
|
||||
struct drm_cmdline_mode *mode)
|
||||
{
|
||||
@ -1462,9 +1463,15 @@ static int drm_mode_parse_cmdline_extra(const char *str, int length,
|
||||
for (i = 0; i < length; i++) {
|
||||
switch (str[i]) {
|
||||
case 'i':
|
||||
if (freestanding)
|
||||
return -EINVAL;
|
||||
|
||||
mode->interlace = true;
|
||||
break;
|
||||
case 'm':
|
||||
if (freestanding)
|
||||
return -EINVAL;
|
||||
|
||||
mode->margins = true;
|
||||
break;
|
||||
case 'D':
|
||||
@ -1542,6 +1549,7 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
|
||||
if (extras) {
|
||||
int ret = drm_mode_parse_cmdline_extra(end_ptr + i,
|
||||
1,
|
||||
false,
|
||||
connector,
|
||||
mode);
|
||||
if (ret)
|
||||
@ -1669,6 +1677,22 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *drm_named_modes_whitelist[] = {
|
||||
"NTSC",
|
||||
"PAL",
|
||||
};
|
||||
|
||||
static bool drm_named_mode_is_in_whitelist(const char *mode, unsigned int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++)
|
||||
if (!strncmp(mode, drm_named_modes_whitelist[i], size))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
|
||||
* @mode_option: optional per connector mode option
|
||||
@ -1725,16 +1749,30 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
* bunch of things:
|
||||
* - We need to make sure that the first character (which
|
||||
* would be our resolution in X) is a digit.
|
||||
* - However, if the X resolution is missing, then we end up
|
||||
* with something like x<yres>, with our first character
|
||||
* being an alpha-numerical character, which would be
|
||||
* considered a named mode.
|
||||
* - If not, then it's either a named mode or a force on/off.
|
||||
* To distinguish between the two, we need to run the
|
||||
* extra parsing function, and if not, then we consider it
|
||||
* a named mode.
|
||||
*
|
||||
* If this isn't enough, we should add more heuristics here,
|
||||
* and matching unit-tests.
|
||||
*/
|
||||
if (!isdigit(name[0]) && name[0] != 'x')
|
||||
if (!isdigit(name[0]) && name[0] != 'x') {
|
||||
unsigned int namelen = strlen(name);
|
||||
|
||||
/*
|
||||
* Only the force on/off options can be in that case,
|
||||
* and they all take a single character.
|
||||
*/
|
||||
if (namelen == 1) {
|
||||
ret = drm_mode_parse_cmdline_extra(name, namelen, true,
|
||||
connector, mode);
|
||||
if (!ret)
|
||||
return true;
|
||||
}
|
||||
|
||||
named_mode = true;
|
||||
}
|
||||
|
||||
/* Try to locate the bpp and refresh specifiers, if any */
|
||||
bpp_ptr = strchr(name, '-');
|
||||
@ -1772,6 +1810,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
if (named_mode) {
|
||||
if (mode_end + 1 > DRM_DISPLAY_MODE_LEN)
|
||||
return false;
|
||||
|
||||
if (!drm_named_mode_is_in_whitelist(name, mode_end))
|
||||
return false;
|
||||
|
||||
strscpy(mode->name, name, mode_end + 1);
|
||||
} else {
|
||||
ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
|
||||
@ -1811,7 +1853,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
extra_ptr != options_ptr) {
|
||||
int len = strlen(name) - (extra_ptr - name);
|
||||
|
||||
ret = drm_mode_parse_cmdline_extra(extra_ptr, len,
|
||||
ret = drm_mode_parse_cmdline_extra(extra_ptr, len, false,
|
||||
connector, mode);
|
||||
if (ret)
|
||||
return false;
|
||||
|
@ -656,10 +656,9 @@ static int ingenic_drm_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (panel) {
|
||||
if (panel)
|
||||
bridge = devm_drm_panel_bridge_add(dev, panel,
|
||||
DRM_MODE_CONNECTOR_Unknown);
|
||||
}
|
||||
DRM_MODE_CONNECTOR_DPI);
|
||||
|
||||
priv->dma_hwdesc = dma_alloc_coherent(dev, sizeof(*priv->dma_hwdesc),
|
||||
&priv->dma_hwdesc_phys,
|
||||
|
@ -190,6 +190,9 @@ MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/desc.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/image.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/sig.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/desc-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/image-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp102/sec2/sig-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/acr/bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/acr/unload_bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/acr/ucode_load.bin");
|
||||
@ -210,6 +213,9 @@ MODULE_FIRMWARE("nvidia/gp104/nvdec/scrubber.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/desc.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/image.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/sig.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/desc-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/image-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp104/sec2/sig-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/acr/bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/acr/unload_bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/acr/ucode_load.bin");
|
||||
@ -230,6 +236,9 @@ MODULE_FIRMWARE("nvidia/gp106/nvdec/scrubber.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/desc.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/image.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/sig.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/desc-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/image-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp106/sec2/sig-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/acr/bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/acr/unload_bl.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/acr/ucode_load.bin");
|
||||
@ -250,3 +259,6 @@ MODULE_FIRMWARE("nvidia/gp107/nvdec/scrubber.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/desc.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/image.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/sig.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/desc-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/image-1.bin");
|
||||
MODULE_FIRMWARE("nvidia/gp107/sec2/sig-1.bin");
|
||||
|
@ -9,6 +9,13 @@
|
||||
|
||||
#define cmdline_test(test) selftest(test, test)
|
||||
|
||||
cmdline_test(drm_cmdline_test_force_d_only)
|
||||
cmdline_test(drm_cmdline_test_force_D_only_dvi)
|
||||
cmdline_test(drm_cmdline_test_force_D_only_hdmi)
|
||||
cmdline_test(drm_cmdline_test_force_D_only_not_digital)
|
||||
cmdline_test(drm_cmdline_test_force_e_only)
|
||||
cmdline_test(drm_cmdline_test_margin_only)
|
||||
cmdline_test(drm_cmdline_test_interlace_only)
|
||||
cmdline_test(drm_cmdline_test_res)
|
||||
cmdline_test(drm_cmdline_test_res_missing_x)
|
||||
cmdline_test(drm_cmdline_test_res_missing_y)
|
||||
|
@ -17,6 +17,136 @@
|
||||
|
||||
static const struct drm_connector no_connector = {};
|
||||
|
||||
static int drm_cmdline_test_force_e_only(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(!drm_mode_parse_command_line_for_connector("e",
|
||||
&no_connector,
|
||||
&mode));
|
||||
FAIL_ON(mode.specified);
|
||||
FAIL_ON(mode.refresh_specified);
|
||||
FAIL_ON(mode.bpp_specified);
|
||||
|
||||
FAIL_ON(mode.rb);
|
||||
FAIL_ON(mode.cvt);
|
||||
FAIL_ON(mode.interlace);
|
||||
FAIL_ON(mode.margins);
|
||||
FAIL_ON(mode.force != DRM_FORCE_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_cmdline_test_force_D_only_not_digital(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
|
||||
&no_connector,
|
||||
&mode));
|
||||
FAIL_ON(mode.specified);
|
||||
FAIL_ON(mode.refresh_specified);
|
||||
FAIL_ON(mode.bpp_specified);
|
||||
|
||||
FAIL_ON(mode.rb);
|
||||
FAIL_ON(mode.cvt);
|
||||
FAIL_ON(mode.interlace);
|
||||
FAIL_ON(mode.margins);
|
||||
FAIL_ON(mode.force != DRM_FORCE_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_connector connector_hdmi = {
|
||||
.connector_type = DRM_MODE_CONNECTOR_HDMIB,
|
||||
};
|
||||
|
||||
static int drm_cmdline_test_force_D_only_hdmi(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
|
||||
&connector_hdmi,
|
||||
&mode));
|
||||
FAIL_ON(mode.specified);
|
||||
FAIL_ON(mode.refresh_specified);
|
||||
FAIL_ON(mode.bpp_specified);
|
||||
|
||||
FAIL_ON(mode.rb);
|
||||
FAIL_ON(mode.cvt);
|
||||
FAIL_ON(mode.interlace);
|
||||
FAIL_ON(mode.margins);
|
||||
FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_connector connector_dvi = {
|
||||
.connector_type = DRM_MODE_CONNECTOR_DVII,
|
||||
};
|
||||
|
||||
static int drm_cmdline_test_force_D_only_dvi(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
|
||||
&connector_dvi,
|
||||
&mode));
|
||||
FAIL_ON(mode.specified);
|
||||
FAIL_ON(mode.refresh_specified);
|
||||
FAIL_ON(mode.bpp_specified);
|
||||
|
||||
FAIL_ON(mode.rb);
|
||||
FAIL_ON(mode.cvt);
|
||||
FAIL_ON(mode.interlace);
|
||||
FAIL_ON(mode.margins);
|
||||
FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_cmdline_test_force_d_only(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(!drm_mode_parse_command_line_for_connector("d",
|
||||
&no_connector,
|
||||
&mode));
|
||||
FAIL_ON(mode.specified);
|
||||
FAIL_ON(mode.refresh_specified);
|
||||
FAIL_ON(mode.bpp_specified);
|
||||
|
||||
FAIL_ON(mode.rb);
|
||||
FAIL_ON(mode.cvt);
|
||||
FAIL_ON(mode.interlace);
|
||||
FAIL_ON(mode.margins);
|
||||
FAIL_ON(mode.force != DRM_FORCE_OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_cmdline_test_margin_only(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(drm_mode_parse_command_line_for_connector("m",
|
||||
&no_connector,
|
||||
&mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_cmdline_test_interlace_only(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
FAIL_ON(drm_mode_parse_command_line_for_connector("i",
|
||||
&no_connector,
|
||||
&mode));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_cmdline_test_res(void *ignored)
|
||||
{
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
@ -353,7 +353,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
!!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
|
||||
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
kfree(reply);
|
||||
|
||||
reply = NULL;
|
||||
if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry. */
|
||||
continue;
|
||||
@ -377,7 +377,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
|
||||
kfree(reply);
|
||||
|
||||
reply = NULL;
|
||||
if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) {
|
||||
/* A checkpoint occurred. Retry. */
|
||||
continue;
|
||||
@ -389,10 +389,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
|
||||
break;
|
||||
}
|
||||
|
||||
if (retries == RETRIES) {
|
||||
kfree(reply);
|
||||
if (!reply)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*msg_len = reply_len;
|
||||
*msg = reply;
|
||||
|
Loading…
x
Reference in New Issue
Block a user