Bug 1614376 - Part 3. Add support for device ID ranges in blocklist rules. r=jrmuizel

Currently the blocklist can block groups of devices, called a
DeviceFamily. However this only allows us to check specific IDs and not
ranges of device IDs like we do currently for the WebRender allowlist.
This patch allows a device family to now specify start and end values
for device IDs we want to match in the blocklist rule.

Differential Revision: https://phabricator.services.mozilla.com/D62324

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew Osmond 2020-02-13 15:51:40 +00:00
Родитель cbd1d387e2
Коммит b96a8b6503
3 изменённых файлов: 191 добавлений и 36 удалений

Просмотреть файл

@ -102,16 +102,52 @@ GfxDriverInfo::~GfxDriverInfo() {
}
}
void GfxDeviceFamily::Append(const nsAString& aDeviceId) {
mIds.AppendElement(aDeviceId);
}
void GfxDeviceFamily::AppendRange(int32_t aBeginDeviceId,
int32_t aEndDeviceId) {
mRanges.AppendElement(
GfxDeviceFamily::DeviceRange{aBeginDeviceId, aEndDeviceId});
}
nsresult GfxDeviceFamily::Contains(nsAString& aDeviceId) const {
for (const auto& id : mIds) {
if (id.Equals(aDeviceId, nsCaseInsensitiveStringComparator())) {
return NS_OK;
}
}
if (mRanges.IsEmpty()) {
return NS_ERROR_NOT_AVAILABLE;
}
nsresult valid = NS_OK;
int32_t deviceId = aDeviceId.ToInteger(&valid, 16);
if (valid != NS_OK) {
return NS_ERROR_INVALID_ARG;
}
for (const auto& range : mRanges) {
if (deviceId >= range.mBegin && deviceId <= range.mEnd) {
return NS_OK;
}
}
return NS_ERROR_NOT_AVAILABLE;
}
// Macros for appending a device to the DeviceFamily.
#define APPEND_DEVICE(device) APPEND_DEVICE2(#device)
#define APPEND_DEVICE2(device) \
deviceFamily->AppendElement(NS_LITERAL_STRING(device))
#define APPEND_DEVICE2(device) deviceFamily->Append(NS_LITERAL_STRING(device))
#define APPEND_RANGE(start, end) deviceFamily->AppendRange(start, end)
const GfxDeviceFamily* GfxDriverInfo::GetDeviceFamily(DeviceFamily id) {
// The code here is too sensitive to fall through to the default case if the
// code is invalid.
NS_ASSERTION(id >= 0 && id < DeviceFamilyMax,
"DeviceFamily id is out of range");
if (id >= DeviceFamilyMax) {
MOZ_ASSERT_UNREACHABLE("DeviceFamily id is out of range");
return nullptr;
}
// If it already exists, we must have processed it once, so return it now.
if (sDeviceFamilies[id]) {
@ -393,8 +429,105 @@ const GfxDeviceFamily* GfxDriverInfo::GetDeviceFamily(DeviceFamily id) {
/* GT218GLM */
APPEND_DEVICE(0x0a7c);
break;
case NvidiaRolloutWebRender:
APPEND_RANGE(0x06c0, INT32_MAX);
break;
case IntelRolloutWebRender:
// skylake gt2+
APPEND_DEVICE(0x1912);
APPEND_DEVICE(0x1913);
APPEND_DEVICE(0x1915);
APPEND_DEVICE(0x1916);
APPEND_DEVICE(0x1917);
APPEND_DEVICE(0x191a);
APPEND_DEVICE(0x191b);
APPEND_DEVICE(0x191d);
APPEND_DEVICE(0x191e);
APPEND_DEVICE(0x1921);
APPEND_DEVICE(0x1923);
APPEND_DEVICE(0x1926);
APPEND_DEVICE(0x1927);
APPEND_DEVICE(0x192b);
APPEND_DEVICE(0x1932);
APPEND_DEVICE(0x193b);
APPEND_DEVICE(0x193d);
// kabylake gt2+
APPEND_DEVICE(0x5912);
APPEND_DEVICE(0x5916);
APPEND_DEVICE(0x5917);
APPEND_DEVICE(0x591a);
APPEND_DEVICE(0x591b);
APPEND_DEVICE(0x591c);
APPEND_DEVICE(0x591d);
APPEND_DEVICE(0x591e);
APPEND_DEVICE(0x5921);
APPEND_DEVICE(0x5926);
APPEND_DEVICE(0x5923);
APPEND_DEVICE(0x5927);
APPEND_DEVICE(0x593b);
// coffeelake gt2+
APPEND_DEVICE(0x3e91);
APPEND_DEVICE(0x3e92);
APPEND_DEVICE(0x3e96);
APPEND_DEVICE(0x3e98);
APPEND_DEVICE(0x3e9a);
APPEND_DEVICE(0x3e9b);
APPEND_DEVICE(0x3e94);
APPEND_DEVICE(0x3ea0);
APPEND_DEVICE(0x3ea9);
APPEND_DEVICE(0x3ea2);
APPEND_DEVICE(0x3ea6);
APPEND_DEVICE(0x3ea7);
APPEND_DEVICE(0x3ea8);
APPEND_DEVICE(0x3ea5);
// broadwell gt2+
APPEND_DEVICE(0x1612);
APPEND_DEVICE(0x1616);
APPEND_DEVICE(0x161a);
APPEND_DEVICE(0x161b);
APPEND_DEVICE(0x161d);
APPEND_DEVICE(0x161e);
APPEND_DEVICE(0x1622);
APPEND_DEVICE(0x1626);
APPEND_DEVICE(0x162a);
APPEND_DEVICE(0x162b);
APPEND_DEVICE(0x162d);
APPEND_DEVICE(0x162e);
APPEND_DEVICE(0x1632);
APPEND_DEVICE(0x1636);
APPEND_DEVICE(0x163a);
APPEND_DEVICE(0x163b);
APPEND_DEVICE(0x163d);
APPEND_DEVICE(0x163e);
// HD Graphics 4600
APPEND_DEVICE(0x0412);
APPEND_DEVICE(0x0416);
APPEND_DEVICE(0x041a);
APPEND_DEVICE(0x041b);
APPEND_DEVICE(0x041e);
APPEND_DEVICE(0x0a12);
APPEND_DEVICE(0x0a16);
APPEND_DEVICE(0x0a1a);
APPEND_DEVICE(0x0a1b);
APPEND_DEVICE(0x0a1e);
break;
case AtiRolloutWebRender:
APPEND_RANGE(0x6600, 0x66af);
APPEND_RANGE(0x6700, 0x671f);
APPEND_RANGE(0x6780, 0x683f);
APPEND_RANGE(0x6860, 0x687f);
APPEND_RANGE(0x6900, 0x69ff);
APPEND_DEVICE(0x7300);
APPEND_RANGE(0x7310, 0x731f);
APPEND_RANGE(0x9830, 0x986f);
APPEND_RANGE(0x9900, 0x99ff);
break;
// This should never happen, but we get a warning if we don't handle this.
case DeviceFamilyMax:
default:
NS_WARNING("Invalid DeviceFamily id");
break;
}

Просмотреть файл

@ -189,6 +189,9 @@ enum DeviceFamily {
Bug1207665,
Bug1447141,
NvidiaBlockWebRender,
NvidiaRolloutWebRender,
IntelRolloutWebRender,
AtiRolloutWebRender,
DeviceFamilyMax
};
@ -264,7 +267,26 @@ enum class ScreenSizeStatus : uint8_t {
};
/* Array of devices to match, or an empty array for all devices */
typedef nsTArray<nsString> GfxDeviceFamily;
class GfxDeviceFamily final {
public:
GfxDeviceFamily() = default;
void Append(const nsAString& aDeviceId);
void AppendRange(int32_t aBeginDeviceId, int32_t aEndDeviceId);
bool IsEmpty() const { return mIds.IsEmpty() && mRanges.IsEmpty(); }
nsresult Contains(nsAString& aDeviceId) const;
private:
struct DeviceRange {
int32_t mBegin;
int32_t mEnd;
};
nsTArray<nsString> mIds;
nsTArray<DeviceRange> mRanges;
};
struct GfxDriverInfo {
// If |ownDevices| is true, you are transferring ownership of the devices

Просмотреть файл

@ -64,29 +64,29 @@ class ShutdownObserver : public nsIObserver {
delete GfxInfoBase::sFeatureStatus;
GfxInfoBase::sFeatureStatus = nullptr;
for (uint32_t i = 0; i < DeviceFamilyMax; i++) {
delete GfxDriverInfo::sDeviceFamilies[i];
GfxDriverInfo::sDeviceFamilies[i] = nullptr;
for (auto& deviceFamily : GfxDriverInfo::sDeviceFamilies) {
delete deviceFamily;
deviceFamily = nullptr;
}
for (uint32_t i = 0; i < DesktopMax; i++) {
delete GfxDriverInfo::sDesktopEnvironment[i];
GfxDriverInfo::sDesktopEnvironment[i] = nullptr;
for (auto& desktop : GfxDriverInfo::sDesktopEnvironment) {
delete desktop;
desktop = nullptr;
}
for (uint32_t i = 0; i < WindowingMax; i++) {
delete GfxDriverInfo::sWindowProtocol[i];
GfxDriverInfo::sWindowProtocol[i] = nullptr;
for (auto& windowProtocol : GfxDriverInfo::sWindowProtocol) {
delete windowProtocol;
windowProtocol = nullptr;
}
for (uint32_t i = 0; i < DeviceVendorMax; i++) {
delete GfxDriverInfo::sDeviceVendors[i];
GfxDriverInfo::sDeviceVendors[i] = nullptr;
for (auto& deviceVendor : GfxDriverInfo::sDeviceVendors) {
delete deviceVendor;
deviceVendor = nullptr;
}
for (uint32_t i = 0; i < DriverVendorMax; i++) {
delete GfxDriverInfo::sDriverVendors[i];
GfxDriverInfo::sDriverVendors[i] = nullptr;
for (auto& driverVendor : GfxDriverInfo::sDriverVendors) {
delete driverVendor;
driverVendor = nullptr;
}
GfxInfoBase::sShutdownOccurred = true;
@ -339,7 +339,7 @@ static GfxDeviceFamily* BlacklistDevicesToDeviceFamily(
for (uint32_t i = 0; i < devices.Length(); ++i) {
// We make sure we don't add any "empty" device entries to the array, so
// we don't need to check if devices[i] is empty.
deviceIds->AppendElement(NS_ConvertUTF8toUTF16(devices[i]));
deviceIds->Append(NS_ConvertUTF8toUTF16(devices[i]));
}
return deviceIds;
@ -940,20 +940,20 @@ int32_t GfxInfoBase::FindBlocklistedDeviceInList(
}
if (info[i].mDevices != GfxDriverInfo::allDevices &&
info[i].mDevices->Length()) {
bool deviceMatches = false;
for (uint32_t j = 0; j < info[i].mDevices->Length(); j++) {
if ((*info[i].mDevices)[j].Equals(
adapterDeviceID[infoIndex],
nsCaseInsensitiveStringComparator())) {
deviceMatches = true;
break;
}
}
if (!deviceMatches) {
!info[i].mDevices->IsEmpty()) {
nsresult rv = info[i].mDevices->Contains(adapterDeviceID[infoIndex]);
if (rv == NS_ERROR_NOT_AVAILABLE) {
// Not found
continue;
}
if (rv != NS_OK) {
// Failed to search, allowlist should not match, blocklist should match
// for safety reasons
if (aForAllowing) {
continue;
}
break;
}
}
bool match = false;