--- a/sys/dev/drm/radeon/radeon_combios.c +++ b/sys/dev/drm/radeon/radeon_combios.c @@ -654,8 +654,11 @@ clk = RBIOS8(offset + 3 + (i * 5) + 3); data = RBIOS8(offset + 3 + (i * 5) + 4); /* gpiopad */ - i2c = combios_setup_i2c_bus(rdev, DDC_MONID, - (1 << clk), (1 << data)); + if ((clk < 32) && (data < 32)) + i2c = combios_setup_i2c_bus(rdev, DDC_MONID, + (1 << clk), (1 << data)); + else + i2c.valid = false; break; } } @@ -2683,7 +2686,7 @@ i2c_bus.hw_capable = true; i2c_bus.mm_i2c = true; i2c_bus.i2c_id = 0xa0; - } else if (gpio == DDC_GPIO) + } else if ((gpio == DDC_GPIO) && (clk_bit < 32) && (data_bit < 32)) i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit); else i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0); @@ -3100,8 +3103,17 @@ WREG32_PLL(addr, val); break; case 1: - shift = RBIOS8(offset) * 8; + shift = RBIOS8(offset); offset++; + if (shift > 3) { + /* shift >= 32 bits is undefined behavior; + * skip the 2 operand bytes and the write */ + DRM_ERROR("combios pll table: bad shift %u\n", + (unsigned)shift); + offset += 2; + break; + } + shift *= 8; and_mask = RBIOS8(offset) << shift; and_mask |= ~(0xff << shift); offset++;