aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dmar.c
diff options
context:
space:
mode:
authorFenghua Yu <fenghua.yu@intel.com>2007-11-21 18:07:14 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-02-01 18:04:21 -0500
commit093f87d279669c74e84530e925e4735c9aae8898 (patch)
treeb388fed2eaedde4ad103d706666c84e5799dbe04 /drivers/pci/dmar.c
parent652c538eb5bc3fa04bc5f27db9014f0168aefe97 (diff)
PCI: More Sanity checks for DMAR
Add and changes a few sanity checks in dmar.c. 1. The haw field in ACPI DMAR table in VT-d spec doesn't describe the range of haw. But since DMA page size is 4KB in DMA remapping, haw should be at least 4KB. The current VT-d code in dmar.c returns failure when haw==0. This sanity check is not accurate and execution can pass when haw is less than one page size 4KB. This patch changes the haw sanity check to validate if haw is less than 4KB. 2. Add dmar_rmrr_units verification. 3. Add parse_dmar_table() verification. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Acked-by: mark gross <mgross@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/dmar.c')
-rw-r--r--drivers/pci/dmar.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 5dfdfdac92e1..91b2dc956be5 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/dmar.h> 27#include <linux/dmar.h>
28#include "iova.h"
28 29
29#undef PREFIX 30#undef PREFIX
30#define PREFIX "DMAR:" 31#define PREFIX "DMAR:"
@@ -263,8 +264,8 @@ parse_dmar_table(void)
263 if (!dmar) 264 if (!dmar)
264 return -ENODEV; 265 return -ENODEV;
265 266
266 if (!dmar->width) { 267 if (dmar->width < PAGE_SHIFT_4K - 1) {
267 printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n"); 268 printk(KERN_WARNING PREFIX "Invalid DMAR haw\n");
268 return -EINVAL; 269 return -EINVAL;
269 } 270 }
270 271
@@ -301,11 +302,24 @@ parse_dmar_table(void)
301int __init dmar_table_init(void) 302int __init dmar_table_init(void)
302{ 303{
303 304
304 parse_dmar_table(); 305 int ret;
306
307 ret = parse_dmar_table();
308 if (ret) {
309 printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
310 return ret;
311 }
312
305 if (list_empty(&dmar_drhd_units)) { 313 if (list_empty(&dmar_drhd_units)) {
306 printk(KERN_INFO PREFIX "No DMAR devices found\n"); 314 printk(KERN_INFO PREFIX "No DMAR devices found\n");
307 return -ENODEV; 315 return -ENODEV;
308 } 316 }
317
318 if (list_empty(&dmar_rmrr_units)) {
319 printk(KERN_INFO PREFIX "No RMRR found\n");
320 return -ENODEV;
321 }
322
309 return 0; 323 return 0;
310} 324}
311 325