Mark Kettenis wrote:
> The thing you guys are missing is that on some architectures making changes
> to instructions (PT_WRITE_I) requires some additional operations to
> guarantee that the CPU actually sees those updated instructions.  Typically
> this is the case on architectures with separate data and instruction caches,
> where the instruction cache doesn't snoop the data cache.  On such
> architectures (powerpc and arm are examples) you need to flush the data
> cache and invalidate the instruction cache.  That may be a somewhat
> expensive operation.
> As you probably guessed, pmap_proc_iflush() is the function that takes care
> of this.  Since you still call pmap_proc_iflush(), the diff isn't wrong from
> a correctness point of view, but I think we should keep the optimization of
> not calling pmap_proc_iflush() for PT_WRITE_D.

Well his makes sense. I pondered while making this change whether
or not I should change the second condition (the iflush one), obviously
I shouldn't have. Heh, I pay my lack of knowledge on !x86 arch.

Thanks for the input!

> As for the original issue.  Adding UVM_IO_FIXPROT for PT_WRITE_D as well,
> means that it will now be able to make changes to read-only data.  That is
> probably corrrect.
> 
> So I think the only thing that should be changed is the following bit:
> 
> >@@ -734,11 +724,11 @@ process_domem(struct proc *curp, struct proc *p,
> >struct uio *uio, int req)
> >     vm->vm_refcnt++;
> >
> >     error = uvm_io(&vm->vm_map, uio,
> >-        (req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
> >+        (uio->uio_rw == UIO_WRITE) ? UVM_IO_FIXPROT : 0);
> >
> 
> Is that indeed enough to fix the original problem?

Yes this is indeed enough, and I just confirmed it with my test program.
So here is (hopefully) the latest version of this diff, which is now way
shorter.

diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 60ec50e..09e56b9 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -734,7 +734,7 @@ process_domem(struct proc *curp, struct proc *p, struct uio 
*uio, int req)
        vm->vm_refcnt++;
 
        error = uvm_io(&vm->vm_map, uio,
-           (req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
+           (uio->uio_rw == UIO_WRITE) ? UVM_IO_FIXPROT : 0);
 
        uvmspace_free(vm);
 

Reply via email to