Skip to content

Commit f036c7f

Browse files
yianchen2018joergroedel
authored andcommitted
iommu/vt-d: Check VT-d RMRR region in BIOS is reported as reserved
VT-d RMRR (Reserved Memory Region Reporting) regions are reserved for device use only and should not be part of allocable memory pool of OS. BIOS e820_table reports complete memory map to OS, including OS usable memory ranges and BIOS reserved memory ranges etc. x86 BIOS may not be trusted to include RMRR regions as reserved type of memory in its e820 memory map, hence validate every RMRR entry with the e820 memory map to make sure the RMRR regions will not be used by OS for any other purposes. ia64 EFI is working fine so implement RMRR validation as a dummy function Reviewed-by: Lu Baolu <[email protected]> Reviewed-by: Sohil Mehta <[email protected]> Signed-off-by: Yian Chen <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent 1ee0186 commit f036c7f

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

arch/ia64/include/asm/iommu.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
#ifndef _ASM_IA64_IOMMU_H
33
#define _ASM_IA64_IOMMU_H 1
44

5+
#include <linux/acpi.h>
6+
57
/* 10 seconds */
68
#define DMAR_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
79

810
extern void no_iommu_init(void);
911
#ifdef CONFIG_INTEL_IOMMU
1012
extern int force_iommu, no_iommu;
1113
extern int iommu_detected;
14+
15+
static inline int __init
16+
arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr) { return 0; }
1217
#else
1318
#define no_iommu (1)
1419
#define iommu_detected (0)

arch/x86/include/asm/iommu.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,28 @@
22
#ifndef _ASM_X86_IOMMU_H
33
#define _ASM_X86_IOMMU_H
44

5+
#include <linux/acpi.h>
6+
7+
#include <asm/e820/api.h>
8+
59
extern int force_iommu, no_iommu;
610
extern int iommu_detected;
711

812
/* 10 seconds */
913
#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
1014

15+
static inline int __init
16+
arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
17+
{
18+
u64 start = rmrr->base_address;
19+
u64 end = rmrr->end_address + 1;
20+
21+
if (e820__mapped_all(start, end, E820_TYPE_RESERVED))
22+
return 0;
23+
24+
pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n",
25+
start, end - 1);
26+
return -EINVAL;
27+
}
28+
1129
#endif /* _ASM_X86_IOMMU_H */

drivers/iommu/intel-iommu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4311,13 +4311,19 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
43114311
{
43124312
struct acpi_dmar_reserved_memory *rmrr;
43134313
struct dmar_rmrr_unit *rmrru;
4314+
int ret;
4315+
4316+
rmrr = (struct acpi_dmar_reserved_memory *)header;
4317+
ret = arch_rmrr_sanity_check(rmrr);
4318+
if (ret)
4319+
return ret;
43144320

43154321
rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
43164322
if (!rmrru)
43174323
goto out;
43184324

43194325
rmrru->hdr = header;
4320-
rmrr = (struct acpi_dmar_reserved_memory *)header;
4326+
43214327
rmrru->base_address = rmrr->base_address;
43224328
rmrru->end_address = rmrr->end_address;
43234329

0 commit comments

Comments
 (0)