CONFIG_STRICT_DEVMEM和CONFIG_IO_STRICT_DEVMEM

来源:互联网 发布:php 判断域名 编辑:程序博客网 时间:2024/04/19 22:46

CONFIG_STRICT_DEVMEMCONFIG_IO_STRICT_DEVMEM dev/mem的关系.

首先会影响dev/mem中映射memory更严格的检测,具体flow如下:

#ifdef CONFIG_STRICT_DEVMEM

static inline int range_is_allowed(unsigned long pfn, unsigned long size)

{

u64 from = ((u64)pfn) << PAGE_SHIFT;

u64 to = from + size;

u64 cursor = from;

 

while (cursor < to) {

if (!devmem_is_allowed(pfn))

return 0;

cursor += PAGE_SIZE;

pfn++;

}

return 1;

}

#else

static inline int range_is_allowed(unsigned long pfn, unsigned long size)

{

return 1;

}

#endif

可以看到对mem.c的影响就是range_is_allowed不在直接返回1了,而是调用range_is_allowed 来做检测

 

#ifdef CONFIG_STRICT_DEVMEM

 

#include <linux/ioport.h>

 

/*

 * devmem_is_allowed() checks to see if /dev/mem access to a certain address

 * is valid. The argument is a physical page number.  We mimic x86 here by

 * disallowing access to system RAM as well as device-exclusive MMIO regions.

 * This effectively disable read()/write() on /dev/mem.

 */

int devmem_is_allowed(unsigned long pfn)

{

if (iomem_is_exclusive(pfn << PAGE_SHIFT))

return 0;

if (!page_is_ram(pfn))

return 1;

return 0;

}

 

 devmem_is_allowed的检测有分成两部分iomem_is_exclusive 和 page_is_ram

 

#ifdef CONFIG_STRICT_DEVMEM

static int strict_iomem_checks = 1;

#else

static int strict_iomem_checks;

#endif

/*

 * check if an address is reserved in the iomem resource tree

 * returns 1 if reserved, 0 if not reserved.

 */

int iomem_is_exclusive(u64 addr)

{

struct resource *p = &iomem_resource;

int err = 0;

loff_t l;

int size = PAGE_SIZE;

 

if (!strict_iomem_checks)

return 0;

 

addr = addr & PAGE_MASK;

 

read_lock(&resource_lock);

for (p = p->child; p ; p = r_next(NULL, p, &l)) {

/*

 * We can probably skip the resources without

 * IORESOURCE_IO attribute?

 */

if (p->start >= addr + size)

break;

if (p->end < addr)

continue;

/*

 * A resource is exclusive if IORESOURCE_EXCLUSIVE is set

 * or CONFIG_IO_STRICT_DEVMEM is enabled and the

 * resource is busy.

 */

if ((p->flags & IORESOURCE_BUSY) == 0)

continue;

if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)

|| p->flags & IORESOURCE_EXCLUSIVE) {

err = 1;

break;

}

}

read_unlock(&resource_lock);

 

return err;

}

static int __init strict_iomem(char *str)

{

if (strstr(str, "relaxed"))

strict_iomem_checks = 0;

if (strstr(str, "strict"))

strict_iomem_checks = 1;

return 1;

}

 

__setup("iomem=", strict_iomem);

 

/*

 * This generic page_is_ram() returns true if specified address is

 * registered as System RAM in iomem_resource list.

 */

int __weak page_is_ram(unsigned long pfn)

{

return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;

}

EXPORT_SYMBOL_GPL(page_is_ram);

因此即使开了CONFIG_STRICT_DEVMEMCONFIG_IO_STRICT_DEVMEM,也可以在bootloader中传递iomem=relaxed,这样就会在iomem_is_exclusive 函数的前面返回,不做严格检测.

int iomem_is_exclusive(u64 addr)

{

struct resource *p = &iomem_resource;

int err = 0;

loff_t l;

int size = PAGE_SIZE;

 

if (!strict_iomem_checks)

return 0;

}

 

 

 

 

0 0
原创粉丝点击