proski
proski

Reputation: 3949

Emulating a device in Linux - need a way to allocate a resource in RAM

I'm writing a Linux device driver together with an emulator for that device. For the device driver to work, I need to give it memory resources. If using the emulator, I need to allocate those resources in the emulator.

The problem is, I cannot allocate the resources in system RAM, as ioremap() is not allowed on system RAM addresses.

The approach I'm using now is to limit the amount of memory visible by the system using the mem option in the kernel command line. I would prefer to use some other approach, as I don't want to tell all users to edit their GRUB settings and limit their RAM usage.

Ideally, I would prefer to reserve the memory in the emulator module and release it once the emulator module is unloaded. Another good, albeit less preferred approach would be to reserve the memory when the emulator is loaded for the first time and keep it in memory.

As I understand, the emulator should mark the memory as reserved or disconnected. But I don't see any exported functions that would do it. I need to do it from a kernel module. Asking users to recompile their kernels is not realistic.

I'm OK with using optional kernel interfaces, such as memory hotplug. They are enabled on popular distro kernels, so most users should be OK with it. But I cannot find any API available to the modules to reserve or "disconnect" a memory block.

Upvotes: 3

Views: 557

Answers (1)

proski
proski

Reputation: 3949

I was able to find a good solution. There are two aspects of the problem, the resource reservation and the resource remapping to the kernel address space.

The reservation issue can be fixed by finding the containing RAM resource and allocating the emulator resource under it using request_resource(). The driver under test can call request_region(), but it should use the parent resource of the device resource rather than iomem_resource. I believe it's a reasonable approach to take the resources from the parent rather than traverse the whole resource tree, although the later is a common practice in the kernel.

A more radical approach would be to unset IORESOUCE_BUSY on the RAM resource. That would accommodate the drivers that reserve resources under iomem_resource, but it seems quite unsafe to me.

The remapping issue is fixed by marking every "resource" memory page as reserved. There is a macro for it, which manipulates page flags. Just make sure to allocate page-aligned memory.

The working code is too long for this site; it can be found at http://marc.info/?l=linux-mm&m=149280134601521

Upvotes: 1

Related Questions