LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-06-2008, 08:14 PM   #1
Denes
Member
 
Registered: Mar 2004
Distribution: CentOS 4.3/4.5
Posts: 72

Rep: Reputation: 15
Interrupt/Signal on Memory Access


I am looking into creating a simulation of a hardware device. This hardware device is directly mapped into memory and its registers and memory are accessed that way in user space.

What I would like to be able to do is when a certain memory area (that I control via mapping or allocation of some type) is written, I would like to get some type of an interrupt or signal so that I can asynchronously get information written into a virtual register and use it. I would also like to get interrupted or signaled when a certain memory area is read so that I can update whatever is accessing it with the very latest information and results of some processing that I need to do.

My initial thinking was to use either SIGSEGV or some type of page fault handler in a module. My problem is that I believe I may be able to get this to work for one access, but I may have to make the memory area valid in the handler in order for the user code to continue so therefore it would not interrupt/signal on the next access. Does anyone know if these ideas would work? Are there other ideas anyone has?
 
Old 03-06-2008, 09:52 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
I don't have experience with your sort of problem, but my initial thought is to create a kernel module that creates a character device, give it a set of ioctls to protect or unprotect certain memory areas, then mmap that character device as "shared" and use the mapped memory for your virtual machine. All the module would need to do is maintain a table of protected memory addresses and create a signal if there's a violation. I'm sure there's a better way than this other than actually changing the protection of memory in the process' memory table, but I don't know that I'm awake enough to think it through any more than that.
ta0kira

Last edited by ta0kira; 03-06-2008 at 10:02 PM.
 
Old 04-28-2008, 05:31 PM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
I feel silly for not thinking of this before, but you could create two shared mappings using the same underlying file: one R/O for the virtual machine and the other R/W for the program managing it. They would both be the same memory, but the managing program would be able to make direct conversions between the R/O and R/W versions with simple pointer arithmetic.
Code:
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>


static void segv_handler(int sSignal)
{
	if (sSignal == SIGSEGV)
	{
	fprintf(stderr, "SIGSEGV caused by bad memory access!\n");
	signal(sSignal, SIG_DFL);
	raise(sSignal);
	}
}


int main()
{
	int mapping = open("./memory", O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (mapping < 0)
	{
	fprintf(stderr, "mapping error: %s\n", strerror(errno));
	return 1;
	}

	int memory_size = getpagesize();

	ftruncate(mapping, memory_size); //non-standard, but used for convenience

	setlinebuf(stdout);
	signal(SIGSEGV, &segv_handler);


	void *read_only = mmap(NULL, memory_size, PROT_READ, MAP_SHARED, mapping, 0);
	if (!read_only)
	{
	fprintf(stderr, "read error: %s\n", strerror(errno));
	return 1;
	}


	void *read_write = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, mapping, 0);
	if (!read_write)
	{
	fprintf(stderr, "write error: %s\n", strerror(errno));
	return 1;
	}


	char *write_to = (char*) read_write;
	snprintf(write_to, memory_size, "hello!");

	char *read_from = (char*) read_only;
	fprintf(stdout, "%s\n", read_from);


	snprintf(read_from, memory_size, "segfault here!");


	return 0;
}
ta0kira

Last edited by ta0kira; 04-28-2008 at 05:47 PM.
 
Old 04-28-2008, 06:15 PM   #4
Denes
Member
 
Registered: Mar 2004
Distribution: CentOS 4.3/4.5
Posts: 72

Original Poster
Rep: Reputation: 15
The requirement for this went away for a while so I haven't been thinking much about it. This seems logical for doing what I need at least on a write access. I will pursue this further when it comes up again. Thanks.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
No signal, no access? Pedroski Linux - Wireless Networking 7 02-21-2008 09:23 AM
CMC interrupt signal smallbook Linux - Newbie 0 01-27-2008 08:05 PM
How to obtain a interrupt or signal to press the tray key of CDROM? freedomli Linux - Enterprise 0 12-04-2007 02:31 AM
Signal() sigaction() and IO interrupt Linuxprocess Programming 2 09-20-2006 09:38 AM
RH 8.0 Mapping Virtual Memory to get access to VMIC Reflective Memory PCI card. Merlin53 Linux - Hardware 0 05-05-2003 12:50 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:58 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration