Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Mar 2005 14:06:54 +0300
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        freebsd-hackers@freebsd.org
Subject:    Comments about vm_fault, vm_map_lookup and user-wired memory, part 2
Message-ID:  <20050331110654.GB340@pm514-9.comsys.ntu-kpi.kiev.ua>

next in thread | raw e-mail | index | archive | help
Greetings,

Second question.  Consider following code (listing is given at
the end of this letter): mmap() anonymous private read-only
memory, fork() and mlock() this memory only in one process.

Here we have: COW, NEEDS_COPY, read-only memory in both
processes, but in one process it is USER_WIRED.  Both memories
refer to the same vm_object.

Let's modify one byte in USER_WIRED memory from the debugger,
as the result both processes will get modification in own
memories:

1. When debugger wants to modify something in a memory, it
   calls vm_fault() with VM_PROT_WRITE and VM_PROT_OVERRIDE_WRITE.

2. vm_fault() calls vm_map_lookup().

3. Since VM_PROT_OVERRIDE_WITE is on, vm_map_lookup() takes
   entry->max_protection and finds out that VM_PROT_WRITE is Ok
   for this memory (first if() condition passes).  Since flag
   VM_PROT_OVERRIDE_WRITE is on, we continue (second if() condition
   passes).  Since fault is on wired memory, vm_map_lookup()
   drops fault_tipe to entry->protection, which has only VM_PROT_READ,
   since our memory is read-only.  As the result, shadow object
   is not created.

4. Debugger calls uiomove_fromphys() and modifies memory in the
   object, shared by both processes, but mappings are MAP_PRIVATE.

Here is my question: what is the idea of this code in vm_map_lookup(),
I mean modification of fault_type:

	*wired = (entry->wired_count != 0);
	if (*wired)
		prot = fault_type = entry->protection;

And the result question from both my questions.  As I understand
something is wrong here, at least I cannot find good explanation.
Is it allowed to create shadow objects for user-wired memory?  If yes,
then should pages in a shared object, which shadow user-wired pages,
be also user-wired?

-----
	if ( (addr = mmap((void *)0, 1, PROT_READ, MAP_ANON|MAP_PRIVATE,
	    -1, 0)) == MAP_FAILED)
		err(1, "mmap");
	printf("addr %p\n", addr);

	if (fork() == 0)
		for (;;) {
			printf("<%c>\n", *(char *)addr);
			sleep(1);
		}

	if (mlock(addr, 1) < 0)
		err(1, "mlock");

	for (;;) {
		printf("[%c]\n", *(char *)addr);
		sleep(1);
	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050331110654.GB340>