|
Re: shm_ctl() fails with SHMCTL_PHYS|SHMCTL_GLOBAL on ARM target
|
09/24/2008 12:43 PM
post13955
|
Re: shm_ctl() fails with SHMCTL_PHYS|SHMCTL_GLOBAL on ARM target
I failed to mention that when the code SIGSEGVs the reported address seems correct, like this:
Process 544791 (LMDispatcher) terminated SIGSEGV code=2 fltno=11 ip=001021a0 ref=811000004
Where 81100004 is the virtual pointer, mphys() translates that to physical address 0x5c030004, and the physical base
address of the shared region is 0x5c030000 so the address appears valid.
|
|
|
|
Re: shm_ctl() fails with SHMCTL_PHYS|SHMCTL_GLOBAL on ARM target
|
09/24/2008 12:49 PM
post13957
|
Re: shm_ctl() fails with SHMCTL_PHYS|SHMCTL_GLOBAL on ARM target
Ken Schumm wrote:
> Thanks, Sunil.
>
> It sort of works but we're still having some hard to understand problems.
>
> The original code calculated the address, and it was off by one, so it wasn't on a page boundary which caused errno 89
(sort of confusing).
The address and size must be page aligned.
Otherwise the shm_ctl() fails - and all failures come back with ENOSYS.
That is confusing and it should probably return different errno values
for different error conditions...
> The test code that we lifted from the shm_ctl() example mapped in address 0xb8000 which isn't valid in our memory map
and also returned errno 89 (also confusing).
That I don't understand - any (page-aligned) value should be OK for the
physical address.
> I tested it with 0x5c000000 and thought it failed but maybe I left a zero off on the command line and the support guys
who replicated it may have done the same.
>
> Anyway, your code allows PHYS|GLOBAL to work, but when we map the buffer in with those flags code that used to work
now inexplicably SIGSEGVs. Two processes share that space and they both use the same library code to map it in, each
process can read and write to the shared region, but at some point a read causes a SIGSEGV even though the pointer is
VALID and points to the correct physical address mphys() reports.
There is a bug in the 632 code where the book-keeping for the global
mappings wasn't always being done correctly which meant that after
various combinations of context switches the page tables don't have
the correct permissions.
There is a workaround for this:
- if all accessing processes have used ThreadCtl(_NTO_TCTL_IO) to gain I/O
privilege, you can use SHMCTL_PRIV in the shm_ctl call.
- otherwise, use SHMCTL_LOWERPROT
Either of these will not use the per-process protection gear so the bug
will not manifest itself.
> The same code works fine when the region is mmap()'d in directly from physical space (different virtual pointer values
in each process) but not when mmap'd in using the fd from the shm_ctl() call, even though the physical address is the
same in both cases.
mmap(MAP_SHARED|MAP_PHYS) will create the mapping in the normal process
address space. The shm_ctl/mmap combination creates a mapping at virtual
addresses that are globally visible to all processes.
Sunil.
|
|
|