-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: add missing barrier to page table write #1796
Conversation
When updating a PTE, we need to make sure that the write to memory is visible before any possible reads of that virtual address occur. Signed-off-by: Stuart Yoder <stuart.yoder@arm.com> Reviewed-by: James King <james.king@arm.com>
I found this issue when testing the dynamic shared memory patches. A mapping was created for incoming message arguments (i.e. PTE was written), followed fairly quickly by a read of the memory. It appears the read got executed before the PTE write, resulting in a data abort. |
I'd like to have this at a higher level in order to be able to update several entries before doing |
core_mmu_set_entry_primitive() is called from 2 places: There are quite a few calls to area_set_entry() and core_mmu_set_entry() sprinkled around. Are we really concerned with performance here? ...it seems much more error prone to put the burden on higher level callers to do the dsb primitive. It's going to be real easy for someone to forget to add an explicit dsb() after calling certain functions. If you look at all the other uses of dsb in OP-TEE it seems that the practice has been to put synchronization primitives directly where the barrier is needed. |
Usually when the tables are updated there's a need to invalidate tlb also, so this change doesn't solve the problem it just hides it for a little longer. |
The TLB should be invalidated when something gets unmapped, as the virtual address is no longer valid. But, generally when something is mapped we should be guaranteed that the virtual address is not already in use, and so not sure why a TLB invalidate should be needed there. In any case, if there are missing TLB invalidates, that is a separate issue. My patch is dealing with one discrete issue-- a barrier needed after writing the PTE. |
There's many exceptions to that rule. Paging is one case, another is mapping of TAs. The |
@stuyoder, sequences that need to update mmu tables need to add the required dsb/isb synchro after a full mapping is updated and before system is allowed to use it. Syncing on each mmu descriptor update is inefficient and does not prevent from the final sync.
Indeed when one manipulates mmu table, he/she must be careful. It's not a common scenario to write to mmu tables. optee core developers usually use high level apis to map a virtual address range to a physical location. |
Here are the callers of area_set_entry() that need to be fixed up: Here are the callers of core_mmu_set_entry() that need to be fixed up: Fixing all those callers is beyond the scope of what I'm going to be able to do, so I guess I'll just open up an issue to log this. But, it is a real issue. As you say, when updating a page table entry synchronization is required before letting the system use the mapping. OP-TEE does not do that today. |
As an aside, here is how it's handled in the Linux kernel...if the mapping is a valid kernel mapping they do the dsb immediately at the lowest level:
|
@stuyoder what are you trying to prove? Without digging very deep into this it looks like it's |
Not trying to prove anything :) ...just pointing out that there are various callers that write PTEs. In addition to core_mmu_map_pages(), there are set_region(), set_pg_region(), core_mmu_unmap_pages(). For set_region/set_pg_region it's not clear to me where the dsb() is. Given that I know relatively little about the optee kernel, my preference would be that someone who is more intimately familiar with this apply a fix where needed. I'm happy to test it. Also, if it is expected that a caller must do the dsb() synchronization it would be a good idea to add a comment in the function header explicitly stating that, to avoid someone missing that in the future. |
This is fixed with #1827 |
When updating a PTE, we need to make sure that the write to memory
is visible before any possible reads of that virtual address occur.
Signed-off-by: Stuart Yoder stuart.yoder@arm.com
Reviewed-by: James King james.king@arm.com